import cgi, cgitb
from datetime import datetime
import hashlib
+import html
import itertools
import numbers
import os
import re
import subprocess
import urllib
-from xbmcjson import XBMC
+from kodijson import Kodi
from yattag import Doc
import youtube_dl
-xbmc = None
+kodi = None
-def connect (_xbmc):
- global xbmc
- xbmc = _xbmc
- return xbmc
+def connect (_kodi):
+ global kodi
+ kodi = _kodi
+ return kodi
SONG_PROPERTIES = ['album', 'artist', 'albumartist', 'dateadded', 'userrating', 'displayartist']
PAGE_SELF = os.environ['SCRIPT_NAME'] if 'SCRIPT_NAME' in os.environ else ''
if 'id' in song:
# item from playlist
- self.key = hashlib.sha256(str(song['id'])).hexdigest()
+ self.key = hashlib.sha256(str(song['id']).encode('utf-8')).hexdigest()
self.kodi_id = song['id']
# the playlist will not update things like ratings if we
# update via RPC. Just grab it from the library instead.
if 'userrating' in song:
- libsong = xbmc.AudioLibrary.GetSongDetails (songid = song['id'], properties = ['userrating'])
+ libsong = kodi.AudioLibrary.GetSongDetails (songid = song['id'], properties = ['userrating'])
#print (libsong)
if 'result' in libsong and 'songdetails' in libsong['result']:
song['userrating'] = libsong['result']['songdetails']['userrating']
elif 'songid' in song:
# search results
- self.key = hashlib.sha256(str(song['songid'])).hexdigest()
+ self.key = hashlib.sha256(str(song['songid']).encode('utf-8')).hexdigest()
self.kodi_id = song['songid']
else:
- self.key = hashlib.sha256(song['label'] + self.artist).hexdigest()
+ self.key = hashlib.sha256((song['label'] + self.artist).encode('utf-8')).hexdigest()
self.kodi_id = 0
# videos can still be labeled as songs, but the rating will be a
return [Song(item) for item in items]
def get_playlist (playlistid=0):
- return songs (xbmc.Playlist.GetItems (playlistid=playlistid, properties=SONG_PROPERTIES)['result']['items'])
+ return songs (kodi.Playlist.GetItems (playlistid=playlistid, properties=SONG_PROPERTIES)['result']['items'])
class SongControls:
aactions = {'songup': 'up', 'songdown': 'down', 'songtop': 'next!', 'songbottom': 'banish!',
return {}
if (self.prop != 'any'):
- res = xbmc.AudioLibrary.GetSongs (filter={'operator': "contains", 'field': self.prop, 'value': self.term}, properties=SONG_PROPERTIES, sort={'order': 'ascending', 'method': 'artist'})['result']
+ res = kodi.AudioLibrary.GetSongs (filter={'operator': "contains", 'field': self.prop, 'value': self.term}, properties=SONG_PROPERTIES, sort={'order': 'ascending', 'method': 'artist'})['result']
if 'songs' in res:
return songs(res['songs'])
else:
return []
else:
- all_songs = [xbmc.AudioLibrary.GetSongs (filter={'operator': "contains", 'field': p, 'value': self.term}, properties=SONG_PROPERTIES, sort={'order': 'ascending', 'method': 'artist'})['result']
+ all_songs = [kodi.AudioLibrary.GetSongs (filter={'operator': "contains", 'field': p, 'value': self.term}, properties=SONG_PROPERTIES, sort={'order': 'ascending', 'method': 'artist'})['result']
for p
in self.ANY_SEARCH_PROPERTIES]
# does not remove duplicates...
text (prop)
with tag ('button', type = 'submit', name = 'searchgo', value = '1'):
text ('Search')
- print doc.getvalue ()
+ print (doc.getvalue ())
def show_search_results (self):
doc, tag, text = Doc().tagtext()
return doc.getvalue ()
def get_playlist (self, playlistid=0):
- return songs (xbmc.Playlist.GetItems (playlistid=playlistid, properties=SONG_PROPERTIES)['result']['items'])
+ return songs (kodi.Playlist.GetItems (playlistid=playlistid, properties=SONG_PROPERTIES)['result']['items'])
class Upload:
upload_dir = '/srv/archive/incoming/stolen-moosic'
# works instead of dealing with MIME. For now.
def attempt_rpgain (self):
subprocess.call (["/usr/bin/vorbisgain", "-q", self.filename])
- subprocess.call (["/usr/bin/mp3gain", "-q", "-s", "i", self.filename])
+ subprocess.call (["/usr/local/bin/mp3gain", "-q", "-s", "i", self.filename])
subprocess.call (["/usr/bin/aacgain", "-q", "-s", "i", self.filename])
subprocess.call (["/usr/bin/metaflac", "--add-replay-gain", self.filename])
def save (self):
- fout = file (os.path.join(self.upload_dir, self.fileitem.filename), 'wb')
+ fout = open (os.path.join(self.upload_dir, self.fileitem.filename), 'wb')
fout.write (self.fileitem.value)
fout.close()
self.attempt_rpgain ()
return doc.getvalue ()
def print_escaped (item):
- print (u"<p>{}</p>".format (cgi.escape (u"{}".format (item))))
+ print (u"<p>{}</p>".format (html.escape (u"{}".format (item))))
# This is awful
class PartyManager:
# divisor) songs
if divisor is None:
divisor = self.DEFAULT_QUEUE_DIVISOR
- totalitems = xbmc.Playlist.GetItems (playlistid=0)['result']['limits']['total']
+ totalitems = kodi.Playlist.GetItems (playlistid=0)['result']['limits']['total']
playpos = random.randint (1, totalitems / divisor + 1)
- print_escaped (xbmc.Playlist.Insert (playlistid=0, item=item, position=playpos))
- print '<p style="font-size: x-large">Your song is number {0} in the queue ({1} songs in playlist).</p>'.format (playpos, totalitems+1)
+ print_escaped (kodi.Playlist.Insert (playlistid=0, item=item, position=playpos))
+ print ('<p style="font-size: x-large">Your song is number {0} in the queue ({1} songs in playlist).</p>'.format (playpos, totalitems+1))
return (playpos, totalitems+1)
def process (self):
songid = form['songdel'].value
print (u"<p>{}</p>".format (songid))
(pos,song) = next ((i,s) for i,s in enumerate(get_playlist ()) if s.key == songid)
- print (u'<p>Deleted {}</p>'.format(cgi.escape (song.label)))
- print_escaped (xbmc.Playlist.Remove (playlistid=0, position=pos))
+ print (u'<p>Deleted {}</p>'.format(html.escape (song.label)))
+ print_escaped (kodi.Playlist.Remove (playlistid=0, position=pos))
elif 'songup' in form:
songid = form['songup'].value
print (u"<p>{}</p>".format (songid))
(pos,song) = next ((i,s) for i,s in enumerate(get_playlist ()) if s.key == songid)
- print (u"<p>Promoted {}</p>".format(cgi.escape(song.label)))
- print_escaped (xbmc.Playlist.Swap (playlistid=0, position1=pos, position2=pos-1))
+ print (u"<p>Promoted {}</p>".format(html.escape(song.label)))
+ print_escaped (kodi.Playlist.Swap (playlistid=0, position1=pos, position2=pos-1))
elif 'songdown' in form:
songid = form['songdown'].value
print (u"<p>{}</p>".format (songid))
(pos,song) = next ((i,s) for i,s in enumerate(get_playlist ()) if s.key == songid)
- print (u"<p>Demoted {}</p>".format(cgi.escape(song.label)))
- print_escaped (xbmc.Playlist.Swap (playlistid=0, position1=pos, position2=pos+1))
+ print (u"<p>Demoted {}</p>".format(html.escape(song.label)))
+ print_escaped (kodi.Playlist.Swap (playlistid=0, position1=pos, position2=pos+1))
elif 'songtop' in form:
songid = form['songtop'].value
print (u"<p>{}</p>".format (songid))
(pos,song) = next ((i,s) for i,s in enumerate(get_playlist ()) if s.key == songid)
- print (u"<p>Bumped Up {}</p>".format(cgi.escape(song.label)))
+ print (u"<p>Bumped Up {}</p>".format(html.escape(song.label)))
for i in range (pos, 1, -1):
- print_escaped (xbmc.Playlist.Swap (playlistid=0, position1=i, position2=i-1))
+ print_escaped (kodi.Playlist.Swap (playlistid=0, position1=i, position2=i-1))
elif 'songbottom' in form:
songid = form['songbottom'].value
print (u"<p>{}</p>".format (songid))
playlist = get_playlist ()
(pos,song) = next ((i,s) for i,s in enumerate(playlist) if s.key == songid)
- print (u"<p>Banished {}</p>".format(cgi.escape(song.label)))
+ print (u"<p>Banished {}</p>".format(html.escape(song.label)))
for i in range (pos, len (playlist), 1):
- print_escaped (xbmc.Playlist.Swap (playlistid=0, position1=i, position2=i+1))
+ print_escaped (kodi.Playlist.Swap (playlistid=0, position1=i, position2=i+1))
elif 'volchange' in form:
- curvolume = xbmc.Application.GetProperties (properties=['volume'])['result']['volume']
+ curvolume = kodi.Application.GetProperties (properties=['volume'])['result']['volume']
newvolume = max (0, min (int (form['volchange'].value) + curvolume, 100))
- print_escaped (xbmc.Application.SetVolume (volume=newvolume))
+ print_escaped (kodi.Application.SetVolume (volume=newvolume))
elif 'volmute' in form:
- print_escaped (xbmc.Application.SetMute (mute="toggle"))
+ print_escaped (kodi.Application.SetMute (mute="toggle"))
elif 'navigate' in form:
action = form['navigate'].value
if action == 'prev':
- print_escaped (xbmc.Player.GoTo (to="previous", playerid=0))
+ print_escaped (kodi.Player.GoTo (to="previous", playerid=0))
elif action == 'next':
- print_escaped (xbmc.Player.GoTo (to="next", playerid=0))
+ print_escaped (kodi.Player.GoTo (to="next", playerid=0))
elif action == 'playpause':
- print_escaped (xbmc.Player.PlayPause (play="toggle", playerid=0))
+ print_escaped (kodi.Player.PlayPause (play="toggle", playerid=0))
elif 'searchgo' in form:
term = form['searchterm'].value
field = form['searchfield'].value
newrating = int(form['songrating'].value)
print (songid)
print (newrating)
- print_escaped (xbmc.AudioLibrary.SetSongDetails (songid = songid, userrating = newrating))
+ print_escaped (kodi.AudioLibrary.SetSongDetails (songid = songid, userrating = newrating))
print_escaped (u'Rating Changed')
elif 'browseartists' in form:
- artists = xbmc.AudioLibrary.GetArtists (sort={'order': 'ascending', 'method': 'artist'})['result']['artists']
+ artists = kodi.AudioLibrary.GetArtists (sort={'order': 'ascending', 'method': 'artist'})['result']['artists']
doc, tag, text = Doc().tagtext()
with tag ('ol', klass='flex_list'):
for artist in artists:
item = youtube.save ()
self.randomqueue (item, 1 if 'asap' not in form else 3)
elif 'partyon' in form:
- if 'error' in xbmc.Player.SetPartymode (partymode=True, playerid=0):
- xbmc.Player.Open (item={"partymode": "music"})
+ if 'error' in kodi.Player.SetPartymode (partymode=True, playerid=0):
+ kodi.Player.Open (item={"partymode": "music"})
elif 'lockon' in form:
subprocess.call (['/usr/bin/xscreensaver-command', 'lock'])
elif 'lights' in form: