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.
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.
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/>.
17 # Trivial xbmc admin script to view active playlist, control volume,
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)
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)
29 # any kind of error checking
31 from __future__ import unicode_literals
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
40 sys
.setdefaultencoding
('utf-8')
43 from datetime import datetime
49 from xbmcjson import XBMC
50 from yattag import Doc
53 from partyparty import Song
, SongControls
, Search
, Playlist
, PartyManager
56 PAGE_SELF
= os
.environ
['SCRIPT_NAME'] if 'SCRIPT_NAME' in os
.environ
else ''
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
())
63 #print (os.environ['SCRIPT_NAME'])
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')]:
73 with tag
('a', href
= target
):
76 print (doc
.getvalue
())
78 xbmc
= partyparty
.connect (XBMC
("http://localhost:8080/jsonrpc"))
80 def print_escaped
(item
):
81 print (u
"<p>{}</p>".format
(cgi
.escape
(u
"{}".format
(item
))))
85 manager
= PartyManager
(cgi
.FieldStorage
())
89 #playpos = random.randint (1, totalitems / (1 if 'asap' not in form else 3))
92 def __init__
(self
, name
='controls'):
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
())]:
105 return doc
.getvalue
()
109 controls
= PlayerControls
()
110 print (controls
.info
())
112 print ('<a name="controls"></a>')
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>
118 <button name="volchange" value="10" type="submit">+10</button>
119 <button name="volchange" value="-10" type="submit">-10</button>
121 <button name="volmute" value="1">Toggle Mute</button>
124 '''.format
(cgi
.escape
(PAGE_SELF
)))
127 <form method="post" action="{}" style="display: inline-block">
128 <button name="navigate" value="prev" type="submit">⏮</button>
129 <button name="navigate" value="next" type="submit">⏭</button>
130 <button name="navigate" value="playpause" type="submit">⏯</button>
132 '''.format
(cgi
.escape
(PAGE_SELF
)))
134 print ('<a name="playlist"></a><h1>Playlist</h1>')
135 print (playlist
.show
())
140 print ('<a name="search"></a>')
141 Search
().show_quick_search
(thereal
=True
)
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>')
150 print ('</body></html>')