party-upload: port to python 3
[clinton/unknownlamer-kodi-addons.git] / party-upload / admin.cgi
CommitLineData
b61367d1 1#!/usr/bin/python3
51a600c2
CE
2# Simple PartyMode Web Console
3# Copyright (c) 2015,2016 Clinton Ebadi <clinton@unknownlamer.org>
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation, either version 3 of the License, or
7# (at your option) any later version.
fffe2166 8
51a600c2
CE
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13
14# You should have received a copy of the GNU General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
fffe2166
CE
16
17# Trivial xbmc admin script to view active playlist, control volume,
18# etc.
19
20# I would not recommend putting this online, no attempt is made at
21# being even trivially secure (e.g. form values are passed directly to
22# kodi with zero verification)
23
51a600c2
CE
24# ADD COMMAND TO RESTART PARTY MODE
25# (probably should require confirmation)
26# also add undelete link to post-del link just in case (reinsert at old pos)
27
fffe2166
CE
28# todo
29# any kind of error checking
30
fffe2166 31import cgi, cgitb
51a600c2 32from datetime import datetime
a68240a2 33import hashlib
b61367d1 34import html
a68240a2 35import numbers
fffe2166 36import os
fffe2166 37import random
a68240a2 38import subprocess
b61367d1 39from kodijson import Kodi
a68240a2 40from yattag import Doc
fffe2166 41
51a600c2
CE
42import partyparty
43from partyparty import Song, SongControls, Search, Playlist, PartyManager
44
fffe2166 45cgitb.enable()
51a600c2 46PAGE_SELF = os.environ['SCRIPT_NAME'] if 'SCRIPT_NAME' in os.environ else ''
fffe2166
CE
47
48print ("content-type: text/html; charset=utf-8\n\n")
a68240a2 49print ("<!DOCTYPE html>\n<html><head><title>partyparty beb</title></head><body>")
51a600c2 50print (partyparty.css ())
fffe2166 51
51a600c2
CE
52#print (os.environ)
53#print (os.environ['SCRIPT_NAME'])
a68240a2
CE
54
55def show_menu ():
56 doc, tag, text = Doc().tagtext()
51a600c2
CE
57 with tag ('ul', klass = 'horiz-menu flex_row'):
58 for target, description in [('#playlist', 'playlist'),
59 ('#controls', 'controls'),
60 ('javascript:document.getElementById("quicksearch").focus()', 'search'),
61 (PAGE_SELF, 'reload')]:
a68240a2
CE
62 with tag ('li'):
63 with tag ('a', href = target):
64 text (description)
65
66 print (doc.getvalue ())
67
b61367d1 68xbmc = partyparty.connect (Kodi ("http://localhost:8080/jsonrpc"))
a68240a2
CE
69
70def print_escaped (item):
b61367d1 71 print (u"<p>{}</p>".format (html.escape (u"{}".format (item))))
51a600c2 72
a68240a2 73show_menu ()
fffe2166 74
51a600c2
CE
75manager = PartyManager (cgi.FieldStorage ())
76manager.process ()
77
78playlist = Playlist()
fffe2166
CE
79#playpos = random.randint (1, totalitems / (1 if 'asap' not in form else 3))
80
51a600c2
CE
81class PlayerControls:
82 def __init__ (self, name='controls'):
83 self.name = name
84
85 def info (self):
86 doc, tag, text = Doc().tagtext()
87 _playtime = xbmc.Player.GetProperties (playerid=0, properties = ['position', 'percentage', 'time', 'totaltime'])
88 pt = _playtime['result'] if 'result' in _playtime else None
89 with tag ('ul', klass = 'horiz-menu'):
90 for infotext in ['Volume {}%'.format(xbmc.Application.GetProperties (properties=['volume'])['result']['volume']),
91 'Time {:02d}:{:02d} / {:02d}:{:02d} ({:.2f}%) @ {:%H:%M:%S}'.format (pt['time']['hours'] * 60 + pt['time']['minutes'], pt['time']['seconds'], pt['totaltime']['hours'] * 60 + pt['totaltime']['minutes'], pt['totaltime']['seconds'], pt['percentage'], datetime.now())]:
92 with tag ('li'):
93 text (infotext)
94
95 return doc.getvalue ()
96
97
98
99controls = PlayerControls ()
100print (controls.info ())
101
fffe2166 102print ('<a name="controls"></a>')
fffe2166 103print ('''
51a600c2 104<form method="post" action="{}" style="display: inline-block">
fffe2166
CE
105<button name="volchange" value="5" type="submit">+5</button>
106<button name="volchange" value="-5" type="submit">-5</button>
107
108<button name="volchange" value="10" type="submit">+10</button>
109<button name="volchange" value="-10" type="submit">-10</button>
110
111<button name="volmute" value="1">Toggle Mute</button>
112
113</form>
b61367d1 114'''.format (html.escape (PAGE_SELF)))
fffe2166
CE
115
116print ('''
51a600c2 117<form method="post" action="{}" style="display: inline-block">
fffe2166
CE
118<button name="navigate" value="prev" type="submit">&#x23ee;</button>
119<button name="navigate" value="next" type="submit">&#x23ed;</button>
120<button name="navigate" value="playpause" type="submit">&#x23ef;</button>
121</form>
b61367d1 122'''.format (html.escape (PAGE_SELF)))
fffe2166
CE
123
124print ('<a name="playlist"></a><h1>Playlist</h1>')
51a600c2
CE
125print (playlist.show ())
126
127
128
fffe2166
CE
129
130print ('<a name="search"></a>')
a68240a2
CE
131Search ().show_quick_search (thereal=True)
132show_menu ()
133
b61367d1 134print ('<form method="post" action="{}" style="display: inline-block">'.format (html.escape (PAGE_SELF)))
a68240a2 135print ('<button name="partyon" value="true">re-enable party</button>')
51a600c2
CE
136#print ('<button name="lockon" value="true">lock em out</button>')
137print ('<button name="lights" value="on">lights on</button>')
138print ('<button name="lights" value="off">lights off</button>')
a68240a2
CE
139print ('</form>')
140print ('</body></html>')