Commit | Line | Data |
---|---|---|
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 | 31 | import cgi, cgitb |
51a600c2 | 32 | from datetime import datetime |
a68240a2 | 33 | import hashlib |
b61367d1 | 34 | import html |
a68240a2 | 35 | import numbers |
fffe2166 | 36 | import os |
fffe2166 | 37 | import random |
a68240a2 | 38 | import subprocess |
b61367d1 | 39 | from kodijson import Kodi |
a68240a2 | 40 | from yattag import Doc |
fffe2166 | 41 | |
51a600c2 CE |
42 | import partyparty |
43 | from partyparty import Song, SongControls, Search, Playlist, PartyManager | |
44 | ||
fffe2166 | 45 | cgitb.enable() |
51a600c2 | 46 | PAGE_SELF = os.environ['SCRIPT_NAME'] if 'SCRIPT_NAME' in os.environ else '' |
fffe2166 CE |
47 | |
48 | print ("content-type: text/html; charset=utf-8\n\n") | |
a68240a2 | 49 | print ("<!DOCTYPE html>\n<html><head><title>partyparty beb</title></head><body>") |
51a600c2 | 50 | print (partyparty.css ()) |
fffe2166 | 51 | |
51a600c2 CE |
52 | #print (os.environ) |
53 | #print (os.environ['SCRIPT_NAME']) | |
a68240a2 CE |
54 | |
55 | def 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 | 68 | xbmc = partyparty.connect (Kodi ("http://localhost:8080/jsonrpc")) |
a68240a2 CE |
69 | |
70 | def print_escaped (item): | |
b61367d1 | 71 | print (u"<p>{}</p>".format (html.escape (u"{}".format (item)))) |
51a600c2 | 72 | |
a68240a2 | 73 | show_menu () |
fffe2166 | 74 | |
51a600c2 CE |
75 | manager = PartyManager (cgi.FieldStorage ()) |
76 | manager.process () | |
77 | ||
78 | playlist = Playlist() | |
fffe2166 CE |
79 | #playpos = random.randint (1, totalitems / (1 if 'asap' not in form else 3)) |
80 | ||
51a600c2 CE |
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 | ||
fffe2166 | 102 | print ('<a name="controls"></a>') |
fffe2166 | 103 | print (''' |
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 | |
116 | print (''' | |
51a600c2 | 117 | <form method="post" action="{}" style="display: inline-block"> |
fffe2166 CE |
118 | <button name="navigate" value="prev" type="submit">⏮</button> |
119 | <button name="navigate" value="next" type="submit">⏭</button> | |
120 | <button name="navigate" value="playpause" type="submit">⏯</button> | |
121 | </form> | |
b61367d1 | 122 | '''.format (html.escape (PAGE_SELF))) |
fffe2166 CE |
123 | |
124 | print ('<a name="playlist"></a><h1>Playlist</h1>') | |
51a600c2 CE |
125 | print (playlist.show ()) |
126 | ||
127 | ||
128 | ||
fffe2166 CE |
129 | |
130 | print ('<a name="search"></a>') | |
a68240a2 CE |
131 | Search ().show_quick_search (thereal=True) |
132 | show_menu () | |
133 | ||
b61367d1 | 134 | print ('<form method="post" action="{}" style="display: inline-block">'.format (html.escape (PAGE_SELF))) |
a68240a2 | 135 | print ('<button name="partyon" value="true">re-enable party</button>') |
51a600c2 CE |
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>') | |
a68240a2 CE |
139 | print ('</form>') |
140 | print ('</body></html>') |