party-upload: port to python 3
[clinton/unknownlamer-kodi-addons.git] / party-upload / admin.cgi
1 #!/usr/bin/python3
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 import cgi, cgitb
32 from datetime import datetime
33 import hashlib
34 import html
35 import numbers
36 import os
37 import random
38 import subprocess
39 from kodijson import Kodi
40 from yattag import Doc
41
42 import partyparty
43 from partyparty import Song, SongControls, Search, Playlist, PartyManager
44
45 cgitb.enable()
46 PAGE_SELF = os.environ['SCRIPT_NAME'] if 'SCRIPT_NAME' in os.environ else ''
47
48 print ("content-type: text/html; charset=utf-8\n\n")
49 print ("<!DOCTYPE html>\n<html><head><title>partyparty beb</title></head><body>")
50 print (partyparty.css ())
51
52 #print (os.environ)
53 #print (os.environ['SCRIPT_NAME'])
54
55 def show_menu ():
56 doc, tag, text = Doc().tagtext()
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')]:
62 with tag ('li'):
63 with tag ('a', href = target):
64 text (description)
65
66 print (doc.getvalue ())
67
68 xbmc = partyparty.connect (Kodi ("http://localhost:8080/jsonrpc"))
69
70 def print_escaped (item):
71 print (u"<p>{}</p>".format (html.escape (u"{}".format (item))))
72
73 show_menu ()
74
75 manager = PartyManager (cgi.FieldStorage ())
76 manager.process ()
77
78 playlist = Playlist()
79 #playpos = random.randint (1, totalitems / (1 if 'asap' not in form else 3))
80
81 class 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
99 controls = PlayerControls ()
100 print (controls.info ())
101
102 print ('<a name="controls"></a>')
103 print ('''
104 <form method="post" action="{}" style="display: inline-block">
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>
114 '''.format (html.escape (PAGE_SELF)))
115
116 print ('''
117 <form method="post" action="{}" style="display: inline-block">
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>
122 '''.format (html.escape (PAGE_SELF)))
123
124 print ('<a name="playlist"></a><h1>Playlist</h1>')
125 print (playlist.show ())
126
127
128
129
130 print ('<a name="search"></a>')
131 Search ().show_quick_search (thereal=True)
132 show_menu ()
133
134 print ('<form method="post" action="{}" style="display: inline-block">'.format (html.escape (PAGE_SELF)))
135 print ('<button name="partyon" value="true">re-enable party</button>')
136 #print ('<button name="lockon" value="true">lock em out</button>')
137 print ('<button name="lights" value="on">lights on</button>')
138 print ('<button name="lights" value="off">lights off</button>')
139 print ('</form>')
140 print ('</body></html>')