56c523dceff023ed202843ecb0f62dfb3c1341d2
[clinton/unknownlamer-kodi-addons.git] / party-upload / admin.cgi
1 #!/usr/bin/python
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.
8
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/>.
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
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
28 # todo
29 # any kind of error checking
30
31 from __future__ import unicode_literals
32
33 # Python is being obnoxious as hell and refusing to .format() utf-8
34 # strings. I have no idea. Just hack around it and deal with the
35 # actual problem later instead of scattering the code with .encode
36 # calls.
37
38 import sys
39 reload(sys)
40 sys.setdefaultencoding ('utf-8')
41
42 import cgi, cgitb
43 from datetime import datetime
44 import hashlib
45 import numbers
46 import os
47 import random
48 import subprocess
49 from xbmcjson import XBMC
50 from yattag import Doc
51
52 import partyparty
53 from partyparty import Song, SongControls, Search, Playlist, PartyManager
54
55 cgitb.enable()
56 PAGE_SELF = os.environ['SCRIPT_NAME'] if 'SCRIPT_NAME' in os.environ else ''
57
58 print ("content-type: text/html; charset=utf-8\n\n")
59 print ("<!DOCTYPE html>\n<html><head><title>partyparty beb</title></head><body>")
60 print (partyparty.css ())
61
62 #print (os.environ)
63 #print (os.environ['SCRIPT_NAME'])
64
65 def show_menu ():
66 doc, tag, text = Doc().tagtext()
67 with tag ('ul', klass = 'horiz-menu flex_row'):
68 for target, description in [('#playlist', 'playlist'),
69 ('#controls', 'controls'),
70 ('javascript:document.getElementById("quicksearch").focus()', 'search'),
71 (PAGE_SELF, 'reload')]:
72 with tag ('li'):
73 with tag ('a', href = target):
74 text (description)
75
76 print (doc.getvalue ())
77
78 xbmc = partyparty.connect (XBMC ("http://localhost:8080/jsonrpc"))
79
80 def print_escaped (item):
81 print (u"<p>{}</p>".format (cgi.escape (u"{}".format (item))))
82
83 show_menu ()
84
85 manager = PartyManager (cgi.FieldStorage ())
86 manager.process ()
87
88 playlist = Playlist()
89 #playpos = random.randint (1, totalitems / (1 if 'asap' not in form else 3))
90
91 class PlayerControls:
92 def __init__ (self, name='controls'):
93 self.name = name
94
95 def info (self):
96 doc, tag, text = Doc().tagtext()
97 _playtime = xbmc.Player.GetProperties (playerid=0, properties = ['position', 'percentage', 'time', 'totaltime'])
98 pt = _playtime['result'] if 'result' in _playtime else None
99 with tag ('ul', klass = 'horiz-menu'):
100 for infotext in ['Volume {}%'.format(xbmc.Application.GetProperties (properties=['volume'])['result']['volume']),
101 '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())]:
102 with tag ('li'):
103 text (infotext)
104
105 return doc.getvalue ()
106
107
108
109 controls = PlayerControls ()
110 print (controls.info ())
111
112 print ('<a name="controls"></a>')
113 print ('''
114 <form method="post" action="{}" style="display: inline-block">
115 <button name="volchange" value="5" type="submit">+5</button>
116 <button name="volchange" value="-5" type="submit">-5</button>
117
118 <button name="volchange" value="10" type="submit">+10</button>
119 <button name="volchange" value="-10" type="submit">-10</button>
120
121 <button name="volmute" value="1">Toggle Mute</button>
122
123 </form>
124 '''.format (cgi.escape (PAGE_SELF)))
125
126 print ('''
127 <form method="post" action="{}" style="display: inline-block">
128 <button name="navigate" value="prev" type="submit">&#x23ee;</button>
129 <button name="navigate" value="next" type="submit">&#x23ed;</button>
130 <button name="navigate" value="playpause" type="submit">&#x23ef;</button>
131 </form>
132 '''.format (cgi.escape (PAGE_SELF)))
133
134 print ('<a name="playlist"></a><h1>Playlist</h1>')
135 print (playlist.show ())
136
137
138
139
140 print ('<a name="search"></a>')
141 Search ().show_quick_search (thereal=True)
142 show_menu ()
143
144 print ('<form method="post" action="{}" style="display: inline-block">'.format (cgi.escape (PAGE_SELF)))
145 print ('<button name="partyon" value="true">re-enable party</button>')
146 #print ('<button name="lockon" value="true">lock em out</button>')
147 print ('<button name="lights" value="on">lights on</button>')
148 print ('<button name="lights" value="off">lights off</button>')
149 print ('</form>')
150 print ('</body></html>')