diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..12fb62e8f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +Pipfile +Pipfile.lock \ No newline at end of file diff --git a/Serato-Now-Playing/SeratoNowPlaying.py b/Serato-Now-Playing/SeratoNowPlaying.py old mode 100755 new mode 100644 index 9b3737299..9023ee824 --- a/Serato-Now-Playing/SeratoNowPlaying.py +++ b/Serato-Now-Playing/SeratoNowPlaying.py @@ -26,6 +26,8 @@ from time import sleep, time import os import sys +from eyed3.id3.tag import Tag +import mimetypes # define global variables ini = paused = 0 @@ -60,6 +62,7 @@ def __init__(self, cparser, cfile): self.libpath = config.get('Settings', 'libpath') self.url = config.get('Settings', 'url') self.file = config.get('Settings', 'file') + self.cover = is_bool(config.get('Settings', 'cover')) self.interval = config.get('Settings', 'interval') self.delay = config.get('Settings', 'delay') self.multi = is_bool(config.get('Settings', 'multi')) @@ -80,11 +83,12 @@ def __init__(self, cparser, cfile): except configparser.NoOptionError: pass - def put(self, local, libpath, url, file, interval, delay, multi, quote, a_pref, a_suff, s_pref, s_suff, notif): + def put(self, local, libpath, url, file, interval, delay, multi, quote, a_pref, a_suff, s_pref, s_suff, notif, cover): self.cparser.set('Settings', 'local', local) self.cparser.set('Settings', 'libpath', libpath) self.cparser.set('Settings', 'url', url) self.cparser.set('Settings', 'file', file) + self.cparser.set('Settings', 'cover', cover) self.cparser.set('Settings', 'interval', interval) self.cparser.set('Settings', 'delay', delay) self.cparser.set('Settings', 'multi', str(multi)) @@ -115,6 +119,7 @@ def __init__(self, conf, conffile, icn): self.layoutH0a = QHBoxLayout() self.layoutH1 = QHBoxLayout() self.layoutH2 = QHBoxLayout() + self.layoutH8 = QHBoxLayout() self.layoutH3 = QHBoxLayout() self.layoutH4 = QHBoxLayout() self.layoutH5 = QHBoxLayout() @@ -237,6 +242,17 @@ def __init__(self, conf, conffile, icn): self.multiDesc.setStyleSheet('color: grey') self.layoutH2.addWidget(self.multiDesc) self.layoutV.addLayout(self.layoutH2) + # cover + self.coverLabel = QLabel('Cover File') + self.coverLabel.setFont(self.fBold) + self.layoutV.addWidget(self.coverLabel) + self.coverCbox = QCheckBox() + self.coverCbox.setMaximumWidth(25) + self.layoutH8.addWidget(self.coverCbox) + self.coverDesc = QLabel('Write a cover image to the same folder as track information.') + self.coverDesc.setStyleSheet('color: grey') + self.layoutH8.addWidget(self.coverDesc) + self.layoutV.addLayout(self.layoutH8) # quotes self.quoteLabel = QLabel('Song Quote Indicator') self.quoteLabel.setFont(self.fBold) @@ -323,6 +339,7 @@ def upd_win(self): self.intervalEdit.setText(str(c.interval)) self.delayEdit.setText(str(c.delay)) self.multiCbox.setChecked(c.multi) + self.coverCbox.setChecked(c.cover) self.quoteCbox.setChecked(c.quote) self.a_prefixEdit.setText(c.a_pref) self.a_suffixEdit.setText(c.a_suff) @@ -339,6 +356,7 @@ def upd_conf(self): interval = self.intervalEdit.text() delay = self.delayEdit.text() multi = str(self.multiCbox.isChecked()) + cover = str(self.coverCbox.isChecked()) quote = str(self.quoteCbox.isChecked()) a_pref = self.a_prefixEdit.text().replace(" ", "|_0") a_suff = self.a_suffixEdit.text().replace(" ", "|_0") @@ -347,7 +365,7 @@ def upd_conf(self): notif = str(self.notifCbox.isChecked()) c = ConfigFile(self.conf, self.conffile) - c.put(local, libpath, url, file, interval, delay, multi, quote, a_pref, a_suff, s_pref, s_suff, notif) + c.put(local, libpath, url, file, interval, delay, multi, quote, a_pref, a_suff, s_pref, s_suff, notif, cover) # radio button action def on_radiobutton_select(self, b): @@ -581,7 +599,7 @@ def gettrack(c, t): # get last played track sera_dir = conf.libpath hist_dir = os.path.abspath(os.path.join(sera_dir, "History")) sess_dir = os.path.abspath(os.path.join(hist_dir, "Sessions")) - tdat = getlasttrack(sess_dir) + tdat = getlasttrack(sess_dir, conf) if tdat is False: return False else: # remotely derived @@ -657,7 +675,7 @@ def getsessfile(directory, showlast=True): return file -def getlasttrack(s): # function to parse out last track from binary session file +def getlasttrack(s, conf): # function to parse out last track from binary session file # get latest session file sess = getsessfile(s) if sess is False: @@ -670,10 +688,10 @@ def getlasttrack(s): # function to parse out last track from binary session fil with open(sess, "rb") as f: raw = f.read() - # decode and split out last track of session file - binstr = raw.decode('latin').rsplit('oent') # split tracks - byt = binstr[-1] # last track chunk - # print(byt) + index = raw.rfind(b'\x6f\x65\x6e\x74') + bytr = raw[index:] # last track chunk + byt = bytr.decode('latin') + # determine if playing if (byt.find('\x00\x00\x00-') > 0 or # ejected or is byt.find('\x00\x00\x00\x003') > 0): # loaded, but not played @@ -701,16 +719,38 @@ def getlasttrack(s): # function to parse out last track from binary session fil if ay == -1: ay = byt.find('\x00\x00\x00\x00\x0f') + # parse song file + if(conf.cover == 1): + mx = byt.find('\x00\x00\x00\x02') # field start + + if mx > 0: + my = byt.find('\x00\x00\x00\x06') # field end + + if mx > 0: + bin_mp3 = bytr[mx + 4:my] + bin_mp3 = bin_mp3[4:-2] + str_mp3 = bin_mp3.decode('utf-16-be') + tag = Tag() + tag.parse(str_mp3) + dir_name = os.path.dirname(os.path.abspath(conf.file)) + if len(tag.images) > 0: + extension = mimetypes.guess_extension(tag.images[0].mime_type) + f = open(os.path.join(dir_name, 'cover'+extension), 'wb') + f.write(tag.images[0].image_data) + f.close() + # cleanup and return if ax > 0: - bin_artist = byt[ax + 4:ay].replace('\x00', '') - str_artist = bin_artist[2:] + bin_artist = bytr[ax + 4:ay] + bin_artist = bin_artist[5:-1] + str_artist = bin_artist.decode('utf-16-be') else: str_artist = '.' if sx > 0: - bin_song = byt[sx + 4:sy].replace('\x00', '') - str_song = bin_song[2:] + bin_song = bytr[sx + 4:sy] + bin_song = bin_song[5:-1] + str_song = bin_song.decode('utf-16-be') else: str_song = '.' diff --git a/Serato-Now-Playing/bin/config.ini b/Serato-Now-Playing/bin/config.ini index bdd1f419c..97a5e6401 100644 --- a/Serato-Now-Playing/bin/config.ini +++ b/Serato-Now-Playing/bin/config.ini @@ -12,4 +12,4 @@ a_suff = s_pref = s_suff = notif = False - +cover = False diff --git a/requirements.txt b/requirements.txt index 8c6ba68af..53c40681f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,5 @@ PyQT5 polling2 +lxml +requests +eyed3 \ No newline at end of file