content notification

This commit is contained in:
angelblue05 2018-10-04 00:41:31 -05:00
parent 969629ec37
commit c63bfd1346
9 changed files with 79 additions and 21 deletions

View file

@ -486,6 +486,10 @@ msgctxt "#33048"
msgid "You may need to verify your network credentials in the add-on settings or use the Emby path substitution to format your path correctly (Emby dashboard > library). Stop syncing?" msgid "You may need to verify your network credentials in the add-on settings or use the Emby path substitution to format your path correctly (Emby dashboard > library). Stop syncing?"
msgstr "" msgstr ""
msgctxt "#33049"
msgid "New"
msgstr ""
msgctxt "#33054" msgctxt "#33054"
msgid "Add user to session" msgid "Add user to session"
msgstr "" msgstr ""

View file

@ -18,10 +18,10 @@ LOG = logging.getLogger("EMBY."+__name__)
class API(object): class API(object):
def __init__(self, item, server): def __init__(self, item, server=None):
''' Get item information in special cases. ''' Get item information in special cases.
server is the server address server is the server address, provide if your functions requires it.
''' '''
self.item = item self.item = item
self.server = server self.server = server
@ -33,6 +33,25 @@ class API(object):
''' '''
return (playcount or 1) if played else None return (playcount or 1) if played else None
def get_naming(self):
if self.item['Type'] == 'Episode':
if 'SeriesName' in self.item:
return "%s: %s" % (self.item['SeriesName'], self.item['Name'])
elif self.item['Type'] == 'MusicAlbum':
if 'AlbumArtist' in self.item:
return "%s: %s" % (self.item['AlbumArtist'], self.item['Name'])
elif self.item['Type'] == 'Audio':
if self.item.get('Artists'):
return "%s: %s" % (self.item['Artists'][0], self.item['Name'])
return self.item['Name']
def get_actors(self): def get_actors(self):
cast = [] cast = []

View file

@ -406,8 +406,9 @@ def copy_file(path, dest):
def normalize_string(text): def normalize_string(text):
''' For theme media, do not modify unless ''' For theme media, do not modify unless modified in TV Tunes.
modified in TV Tunes. Remove dots from the last character as windows can not have directories
with dots at the end
''' '''
text = text.replace(":", "") text = text.replace(":", "")
text = text.replace("/", "-") text = text.replace("/", "-")
@ -418,13 +419,14 @@ def normalize_string(text):
text = text.replace("?", "") text = text.replace("?", "")
text = text.replace('|', "") text = text.replace('|', "")
text = text.strip() text = text.strip()
# Remove dots from the last character as windows can not have directories
# with dots at the end
text = text.rstrip('.') text = text.rstrip('.')
text = unicodedata.normalize('NFKD', unicode(text, 'utf-8')).encode('ascii', 'ignore') text = unicodedata.normalize('NFKD', unicode(text, 'utf-8')).encode('ascii', 'ignore')
return text return text
def split_list(itemlist, size): def split_list(itemlist, size):
# Split up list in pieces of size. Will generate a list of lists
''' Split up list in pieces of size. Will generate a list of lists
'''
return [itemlist[i:i+size] for i in range(0, len(itemlist), size)] return [itemlist[i:i+size] for i in range(0, len(itemlist), size)]

View file

@ -16,7 +16,7 @@ from database import Database, emby_db, get_sync, save_sync
from full_sync import FullSync from full_sync import FullSync
from views import Views from views import Views
from downloader import GetItemWorker from downloader import GetItemWorker
from helper import _, stop, settings, window, dialog, event, progress, LibraryException from helper import _, api, stop, settings, window, dialog, event, progress, LibraryException
from helper.utils import split_list, set_screensaver, get_screensaver from helper.utils import split_list, set_screensaver, get_screensaver
from emby import Emby from emby import Emby
@ -58,6 +58,7 @@ class Library(threading.Thread):
self.direct_path = settings('useDirectPaths') == "1" self.direct_path = settings('useDirectPaths') == "1"
self.progress_display = int(settings('syncProgress') or 50) self.progress_display = int(settings('syncProgress') or 50)
self.monitor = monitor self.monitor = monitor
self.player = monitor.monitor.player
self.server = Emby() self.server = Emby()
self.updated_queue = Queue.Queue() self.updated_queue = Queue.Queue()
self.userdata_queue = Queue.Queue() self.userdata_queue = Queue.Queue()
@ -65,9 +66,11 @@ class Library(threading.Thread):
self.updated_output = self.__new_queues__() self.updated_output = self.__new_queues__()
self.userdata_output = self.__new_queues__() self.userdata_output = self.__new_queues__()
self.removed_output = self.__new_queues__() self.removed_output = self.__new_queues__()
self.notify_output = Queue.Queue()
self.emby_threads = [] self.emby_threads = []
self.download_threads = [] self.download_threads = []
self.notify_threads = []
self.writer_threads = {'updated': [], 'userdata': [], 'removed': []} self.writer_threads = {'updated': [], 'userdata': [], 'removed': []}
self.database_lock = threading.Lock() self.database_lock = threading.Lock()
self.music_database_lock = threading.Lock() self.music_database_lock = threading.Lock()
@ -132,10 +135,11 @@ class Library(threading.Thread):
self.worker_updates() self.worker_updates()
self.worker_userdata() self.worker_userdata()
self.worker_remove() self.worker_remove()
self.worker_notify()
if self.pending_refresh: if self.pending_refresh:
if self.total_updates > self.progress_display: if self.total_updates > self.progress_display and (not self.player.isPlayingVideo() or xbmc.getCondVisibility('VideoPlayer.Content(livetv)')):
queue_size = self.worker_queue_size() queue_size = self.worker_queue_size()
if self.progress_updates is None: if self.progress_updates is None:
@ -227,9 +231,9 @@ class Library(threading.Thread):
if queue.qsize() and len(self.writer_threads['updated']) < 4: if queue.qsize() and len(self.writer_threads['updated']) < 4:
if queues in ('Audio', 'MusicArtist', 'AlbumArtist', 'MusicAlbum'): if queues in ('Audio', 'MusicArtist', 'AlbumArtist', 'MusicAlbum'):
new_thread = UpdatedWorker(queue, self.music_database_lock, "music", self.server, self.direct_path) new_thread = UpdatedWorker(queue, self.notify_output, self.music_database_lock, "music", self.server, self.direct_path)
else: else:
new_thread = UpdatedWorker(queue, self.database_lock, "video", self.server, self.direct_path) new_thread = UpdatedWorker(queue, self.notify_output, self.database_lock, "video", self.server, self.direct_path)
new_thread.start() new_thread.start()
LOG.info("-->[ q:updated/%s/%s ]", queues, id(new_thread)) LOG.info("-->[ q:updated/%s/%s ]", queues, id(new_thread))
@ -274,6 +278,17 @@ class Library(threading.Thread):
self.writer_threads['removed'].append(new_thread) self.writer_threads['removed'].append(new_thread)
self.pending_refresh = True self.pending_refresh = True
def worker_notify(self):
''' Notify the user of new additions.
'''
if self.notify_output.qsize() and len(self.notify_threads) < 1:
new_thread = NotifyWorker(self.notify_output, self.player)
new_thread.start()
LOG.info("-->[ q:notify/%s ]", id(new_thread))
self.notify_threads.append(new_thread)
def startup(self): def startup(self):
@ -587,9 +602,11 @@ class UpdatedWorker(threading.Thread):
is_done = False is_done = False
def __init__(self, queue, lock, database, *args): def __init__(self, queue, notify, lock, database, *args):
self.queue = queue self.queue = queue
self.notify_output = notify
self.notify = settings('newContent.bool')
self.lock = lock self.lock = lock
self.database = Database(database) self.database = Database(database)
self.args = args self.args = args
@ -613,9 +630,10 @@ class UpdatedWorker(threading.Thread):
break break
obj = MEDIA[item['Type']](self.args[0], embydb, kodidb, self.args[1])[item['Type']] obj = MEDIA[item['Type']](self.args[0], embydb, kodidb, self.args[1])[item['Type']]
LOG.info(item['Type'])
try: try:
obj(item) if obj(item) and self.notify:
self.notify_output.put((item['Type'], api.API(item).get_naming()))
except LibraryException as error: except LibraryException as error:
if error.status == 'StopCalled': if error.status == 'StopCalled':
break break
@ -763,8 +781,13 @@ class NotifyWorker(threading.Thread):
is_done = False is_done = False
def __init__(self, queue): def __init__(self, queue, player):
self.queue = queue self.queue = queue
self.video_time = int(settings('newvideotime')) * 1000
self.music_time = int(settings('newmusictime')) * 1000
self.player = player
threading.Thread.__init__(self)
def run(self): def run(self):
@ -779,11 +802,13 @@ class NotifyWorker(threading.Thread):
break break
time = self.music_time if item[0] == 'Audio' else self.video_time
if time and (not self.player.isPlayingVideo() or xbmc.getCondVisibility('VideoPlayer.Content(livetv)')):
dialog("notification", heading="%s %s" % (_(33049), item[0]), message=item[1],
icon="{emby}", time=time, sound=False)
self.queue.task_done() self.queue.task_done()
if xbmc.Monitor().abortRequested(): if window('emby_should_stop.bool'):
break break
if not self.pdialog and self.content_msg and self.new_time and (not xbmc.Player().isPlayingVideo() or xbmc.getCondVisibility('VideoPlayer.Content(livetv)')):
dialog("notification", heading="{emby}", message="%s %s" % (lang(33049), name),
icon="{emby}", time=self.new_time, sound=False)

View file

@ -129,6 +129,8 @@ class Movies(KodiDb):
self.item_ids.append(obj['Id']) self.item_ids.append(obj['Id'])
return not update
def movie_add(self, obj): def movie_add(self, obj):
''' Add object to kodi. ''' Add object to kodi.

View file

@ -294,6 +294,8 @@ class Music(KodiDb):
if obj['SongAlbumId'] is None: if obj['SongAlbumId'] is None:
self.artwork.add(obj['Artwork'], obj['AlbumId'], "album") self.artwork.add(obj['Artwork'], obj['AlbumId'], "album")
return not update
def song_add(self, obj): def song_add(self, obj):
''' Add object to kodi. ''' Add object to kodi.

View file

@ -137,6 +137,8 @@ class MusicVideos(KodiDb):
self.add_streams(*values(obj, QU.add_streams_obj)) self.add_streams(*values(obj, QU.add_streams_obj))
self.artwork.add(obj['Artwork'], obj['MvideoId'], "musicvideo") self.artwork.add(obj['Artwork'], obj['MvideoId'], "musicvideo")
return not update
def musicvideo_add(self, obj): def musicvideo_add(self, obj):
''' Add object to kodi. ''' Add object to kodi.

View file

@ -346,6 +346,8 @@ class TVShows(KodiDb):
self.update_file(*values(temp_obj, QU.update_file_obj)) self.update_file(*values(temp_obj, QU.update_file_obj))
self.add_playstate(*values(temp_obj, QU.add_bookmark_obj)) self.add_playstate(*values(temp_obj, QU.add_bookmark_obj))
return not update
def episode_add(self, obj): def episode_add(self, obj):
''' Add object to kodi. ''' Add object to kodi.

View file

@ -21,7 +21,6 @@
<category label="30506"><!-- Sync Options --> <category label="30506"><!-- Sync Options -->
<setting label="33137" id="kodiCompanion" type="bool" default="true" /> <setting label="33137" id="kodiCompanion" type="bool" default="true" />
<setting label="30507" id="syncIndicator" type="number" default="99" visible="eq(-1,true)" subsetting="true"/> <setting label="30507" id="syncIndicator" type="number" default="99" visible="eq(-1,true)" subsetting="true"/>
<setting label="33177" id="syncProgress" type="number" default="15" visible="true" />
<setting label="30536" id="dbSyncScreensaver" type="bool" default="true" /> <setting label="30536" id="dbSyncScreensaver" type="bool" default="true" />
<setting label="33111" type="lsep" /> <setting label="33111" type="lsep" />
<setting label="30511" id="useDirectPaths" type="enum" lvalues="33036|33037" default="1" /> <setting label="30511" id="useDirectPaths" type="enum" lvalues="33036|33037" default="1" />
@ -75,6 +74,7 @@
<setting label="30530" id="restartMsg" type="bool" default="true" /> <setting label="30530" id="restartMsg" type="bool" default="true" />
<setting label="30547" id="displayMessage" type="slider" default="4" range="4,1,20" option="int" /> <setting label="30547" id="displayMessage" type="slider" default="4" range="4,1,20" option="int" />
<setting label="33108" type="lsep" /> <setting label="33108" type="lsep" />
<setting label="33177" id="syncProgress" type="number" default="15" visible="true" />
<setting label="30531" id="newContent" type="bool" default="false" /> <setting label="30531" id="newContent" type="bool" default="false" />
<setting label="30532" id="newvideotime" type="number" visible="eq(-1,true)" default="5" option="int" subsetting="true" /> <setting label="30532" id="newvideotime" type="number" visible="eq(-1,true)" default="5" option="int" subsetting="true" />
<setting label="30533" id="newmusictime" type="number" visible="eq(-2,true)" default="2" option="int" subsetting="true" /> <setting label="30533" id="newmusictime" type="number" visible="eq(-2,true)" default="2" option="int" subsetting="true" />