def MainMenu(): if Prefs['search'] or Prefs['m3u_manual_reload'] or Prefs[ 'xmltv_manual_reload'] or Prefs['preferences']: oc = ObjectContainer() oc.add( DirectoryObject(key=Callback(ListGroups), title=unicode(L('View playlist')), thumb=R('icon-list.png'))) if Prefs['search']: oc.add( InputDirectoryObject( key=Callback(ListItems), title=unicode(L('Search')), #prompt = unicode(L('Search')), thumb=R('icon-search.png'))) if Prefs['m3u_manual_reload']: oc.add( DirectoryObject(key=Callback(ReloadPlaylist), title=unicode(L('Reload playlist')), thumb=R('icon-reload.png'))) if Prefs['xmltv'] and Prefs['xmltv_manual_reload']: oc.add( DirectoryObject(key=Callback(ReloadGuide), title=unicode(L('Reload program guide')), thumb=R('icon-reload.png'))) if Prefs['preferences']: oc.add( PrefsObject(title=unicode(L('Preferences')), thumb=R('icon-prefs.png'))) return oc else: return ListGroups()
def ListGroups(page = 1, **kwargs): if not Dict['groups']: LoadPlaylist() if not Dict['groups']: return ObjectContainer( title1 = unicode(L('Error')), header = unicode(L('Error')), message = unicode(L('Provided playlist files are invalid, missing or empty, check the log file for more information')) ) groups = Dict['groups'] groups_list = groups.values() use_groups = False for group in groups_list: if group['title'] not in [unicode('All'), unicode('No category')]: use_groups = True break if use_groups: if Prefs['sort_groups']: # Natural sort (http://stackoverflow.com/a/16090640) groups_list.sort(key = lambda d: [int(t) if t.isdigit() else t.lower() for t in re.split('(\d+)', d['title'].lower())]) else: groups_list.sort(key = lambda d: d['order']) oc = ObjectContainer(title1 = unicode(L('View playlist'))) oc.add( DirectoryObject( key = Callback(ListItems, group = unicode('All')), title = unicode(L('All')) ) ) for group in groups_list: if group['title'] not in [unicode('All'), unicode('No category')]: thumb = GetImage(group['thumb'], default = 'icon-folder.png', title = group['title']) art = GetImage(group['art'], default = 'art-default.png') oc.add( DirectoryObject( key = Callback(ListItems, group = group['title']), title = group['title'], thumb = thumb, art = art ) ) if unicode('No category') in groups.keys(): oc.add( DirectoryObject( key = Callback(ListItems, group = unicode('No category')), title = unicode(L('No category')) ) ) return oc else: return ListItems()
def ReloadPlaylist(): if Dict['playlist_loading_in_progress']: return ObjectContainer( title1=unicode(L('Warning')), header=unicode(L('Warning')), message=unicode( L('Playlist is reloading in the background, please wait'))) LoadPlaylist() if Dict['groups']: return ObjectContainer(title1=unicode(L('Success')), header=unicode(L('Success')), message=unicode( L('Playlist reloaded successfully'))) else: return ObjectContainer( title1=unicode(L('Error')), header=unicode(L('Error')), message=unicode( L('Provided playlist files are invalid, missing or empty, check the log file for more information' )))
def ReloadGuide(): if Dict['guide_loading_in_progress']: return ObjectContainer( title1 = unicode(L('Warning')), header = unicode(L('Warning')), message = unicode(L('Program guide is reloading in the background, please wait')) ) SmoothUtils.GuideReload() if Dict['guide']: return ObjectContainer( title1 = unicode(L('Success')), header = unicode(L('Success')), message = unicode(L('Program guide reloaded successfully')) ) else: return ObjectContainer( title1 = unicode(L('Error')), header = unicode(L('Error')), message = unicode(L('Provided program guide files are invalid, missing or empty, check the log file for more information')) )
def ListItems(group=unicode('All'), query='', page=1): if not Dict['streams']: LoadPlaylist() if not Dict['streams']: return ObjectContainer( title1=unicode(L('Error')), header=unicode(L('Error')), message=unicode( L('Provided playlist files are invalid, missing or empty, check the log file for more information' ))) group = unicode( group ) # Plex loses unicode formating when passing string between @route procedures if string is not a part of a @route streams = Dict['streams'] items_list = streams.get(group, dict()).values() # Filter if query: raw_items_list = items_list ql = query.lower() items_list = filter(lambda d: ql in d['title'].lower(), items_list) guide = Dict['guide'] if guide: current_datetime = Datetime.Now() try: guide_hours = int(Prefs['guide_hours']) except: guide_hours = 8 crop_time = current_datetime + Datetime.Delta(hours=guide_hours) for key in guide.keys(): # crop anything outside of our window first to limit the second search shows = filter( lambda d: d['start'] <= crop_time and d['stop'] > current_datetime, guide[key].values()) # now look for matches in the result set shows = filter(lambda d: ql in d['title'].lower(), shows) for show in shows: items_list = items_list + filter( lambda d: show['channel_id'] == d['id'], raw_items_list) # Sort if Prefs['sort_lists']: # Natural sort (http://stackoverflow.com/a/16090640) items_list.sort(key=lambda d: [ int(t) if t.isdigit() else t.lower() for t in re.split('(\d+)', d['title'].lower()) ]) else: items_list.sort(key=lambda d: d['order']) # Number of items per page try: items_per_page = int(Prefs['items_per_page']) except: items_per_page = 40 items_list_range = items_list[page * items_per_page - items_per_page:page * items_per_page] oc = ObjectContainer(title1=unicode(L('Search')) if query else group) for item in items_list_range: oc.add( CreateVideoClipObject( url=item['url'], title=item['title'], thumb=GetImage(item['thumb'], default='icon-tv.png', id=item['id'], name=item['name'], title=item['title']), art=GetImage(item['art'], default='art-default.jpg'), summary=GetSummary(item['id'], item['name'], item['title'], unicode(L('No description available'))), c_audio_codec=item['audio_codec'] if item['audio_codec'] else Prefs['audio_codec'] if Prefs['audio_codec'] else None, c_video_codec=item['video_codec'] if item['video_codec'] else Prefs['video_codec'] if Prefs['video_codec'] else None, c_container=item['container'] if item['container'] else Prefs['container'] if Prefs['container'] else None, c_protocol=item['protocol'] if item['protocol'] else Prefs['protocol'] if Prefs['protocol'] else None, c_user_agent=item.get('user_agent') if item.get('user_agent') else Prefs['user_agent'] if Prefs['user_agent'] else None, optimized_for_streaming=item['optimized_for_streaming'] in [ 'y', 'yes', 't', 'true', 'on', '1' ] if item['optimized_for_streaming'] else Prefs['optimized_for_streaming'], include_container=False)) if len(items_list) > page * items_per_page: oc.add( NextPageObject(key=Callback(ListItems, group=group, query=query, page=page + 1), thumb=R('icon-next.png'))) if len(oc) > 0: return oc else: return ObjectContainer(title1=unicode(L('Search')), header=unicode(L('Search')), message=unicode(L('No items were found')))
def ListItems(group=unicode('All'), query='', page=1): if not Dict['streams']: LoadPlaylist() if not Dict['streams']: return ObjectContainer( title1=unicode(L('Error')), header=unicode(L('Error')), message=unicode( L('Provided playlist files are invalid, missing or empty, check the log file for more information' ))) group = unicode( group ) # Plex loses unicode formating when passing string between @route procedures if string is not a part of a @route streams = Dict['streams'] items_list = streams.get(group, dict()).values() # Filter if query: items_list = filter(lambda d: query.lower() in d['title'].lower(), items_list) # Sort if Prefs['sort_lists']: # Natural sort (http://stackoverflow.com/a/16090640) items_list.sort(key=lambda d: [ int(t) if t.isdigit() else t.lower() for t in re.split('(\d+)', d['title'].lower()) ]) else: items_list.sort(key=lambda d: d['order']) # Number of items per page try: items_per_page = int(Prefs['items_per_page']) except: items_per_page = 40 items_list_range = items_list[page * items_per_page - items_per_page:page * items_per_page] oc = ObjectContainer(title1=unicode(L('Search')) if query else group) for item in items_list_range: oc.add( CreateVideoClipObject( url=item['url'], title=item['title'], thumb=GetImage(item['thumb'], default='icon-tv.png', id=item['id'], name=item['name'], title=item['title']), art=GetImage(item['art'], default='art-default.jpg'), summary=GetSummary(item['id'], item['name'], item['title'], unicode(L('No description available'))), c_audio_codec=item['audio_codec'] if item['audio_codec'] else None, c_video_codec=item['video_codec'] if item['video_codec'] else None, c_container=item['container'] if item['container'] else None, c_protocol=item['protocol'] if item['protocol'] else None, optimized_for_streaming=item['optimized_for_streaming'] in [ 'y', 'yes', 't', 'true', 'on', '1' ] if item['optimized_for_streaming'] else Prefs['optimized_for_streaming'], include_container=False)) if len(items_list) > page * items_per_page: oc.add( NextPageObject(key=Callback(ListItems, group=group, query=query, page=page + 1), thumb=R('icon-next.png'))) if len(oc) > 0: return oc else: return ObjectContainer(title1=unicode(L('Search')), header=unicode(L('Search')), message=unicode(L('No items were found')))
def SearchListItems(group = unicode('All'), query = ''): if not Dict['streams']: Log.Info(Dict['streams']) return ObjectContainer( title1 = unicode(L('Error')), header = unicode(L('Error')), message = unicode(L('Provided playlist files are invalid, missing or empty, check the log file for more information')) ) if not Dict['guide']: Log.Info(Dict['guide']) return ObjectContainer( title1 = unicode(L('Error')), header = unicode(L('Error')), message = unicode(L('Provided guide files are invalid, missing or empty, check the log file for more information')) ) schedule = False genre = None if query == 'schedule': query = '' schedule = True oc = ObjectContainer(title1=unicode(L('Sports Schedule'))) elif "genre," in query: genre = query.split(",")[1] query = "" Log.Info("Genre requested %s" % genre) oc = ObjectContainer(title1=unicode(L(genre))) else: oc = ObjectContainer(title1=unicode(L(query))) channels_list = Dict['streams'].get(group, dict()).values() guide = Dict['guide'] current_datetime = Datetime.Now() now = [] next = [] later = [] Log.Info(query) Log.Info(schedule) Log.Info(genre) for channel in channels_list: key = None id = channel['id'] name = channel['name'] title = channel['title'] if id: if id in guide.keys(): key = id if not key: channels = Dict['channels'] if channels: if name: if name in channels.keys(): id = channels[name] if id in guide.keys(): key = id if not key: if title: if title in channels.keys(): id = channels[title] if id in guide.keys(): key = id if key: items_list = guide[key].values() if items_list: try: guide_hours = int(Prefs['guide_hours']) except: guide_hours = 8 time_filtered_list = [program for program in items_list if program['start'] <= current_datetime + Datetime.Delta(hours=guide_hours) and program['stop'] > current_datetime] time_filtered_list.sort(key=lambda x: (x['start'])) # if time_filtered_list[0]['genre']: # Log.Info(title) # Log.Info(time_filtered_list[0]['title']) # Log.Info(time_filtered_list[0]['genre']) # Log.Info(genre) for program in time_filtered_list: if program['title'] and ( (schedule == True and program['genre'] and program['genre'].lower() in sports_list) or (schedule == False and genre == None and query.lower() in program['title'].lower()) or (genre and program['genre'] and program['genre'].lower() == genre.lower()) ): # Log.Info("Pass 1") new_chan = copy.deepcopy(channel) new_chan['title'] = program['title'] new_chan['time'] = program['start'] new_chan['usertime'] = program['start'].strftime('%H:%M') if time_filtered_list.index(program) == 0: new_chan['title'] = 'NOW ' + program['title'] now.append(new_chan) # Log.Info("Now") # Log.Info(title) # Log.Info(new_chan['title']) # Log.Info(new_chan['genre']) # Log.Info(genre) elif time_filtered_list.index(program) == 1: # Log.Info("Next") new_chan['title'] = 'NEXT ' + new_chan['usertime'] + ' ' + program['title'] now.append(new_chan) # Log.Info(title) # Log.Info(new_chan['title']) # Log.Info(new_chan['genre']) # Log.Info(genre) else: # Log.Info("Later") when = '' if program['start'].date() == current_datetime.date(): when = "LATER" else: when = calendar.day_name[program['start'].weekday()][:3].upper() new_chan['title'] = when + " " + new_chan['usertime'] + ' ' + program['title'] now.append(new_chan) # Log.Info(title) # Log.Info(new_chan['title']) # Log.Info(new_chan['genre']) # Log.Info(genre) now.sort(key = lambda x: (x['time'])) count = 0 for item in now: count+=1 oc.add( CreateVideoClipObject( url=item['url'] + "&tm=" + str(item['time']).replace(" ", ""), title=item['title'], thumb=GetImage(item['thumb'], default='icon-tv.png', id=item['id'], name=item['name'], title=item['title']), art=GetImage(item['art'], default='art-default.jpg'), summary=GetSummary(item['id'], item['name'], item['title'], unicode(L('No description available'))), c_audio_codec=item['audio_codec'] if item['audio_codec'] else None, c_video_codec=item['video_codec'] if item['video_codec'] else None, c_container=item['container'] if item['container'] else None, c_protocol=item['protocol'] if item['protocol'] else None, optimized_for_streaming=item['optimized_for_streaming'] in ['y', 'yes', 't', 'true', 'on', '1'] if item['optimized_for_streaming'] else 'No', include_container=False ) ) # next.sort(key=lambda x: (x['time'])) # for item in next: # count += 1 # oc.add( # CreateVideoClipObject( # url=item['url'] + "&tm=" + str(item['time']).replace(" ", ""), # title=item['title'], # thumb=GetImage(item['thumb'], default='icon-tv.png', id=item['id'], name=item['name'], # title=item['title']), # art=GetImage(item['art'], default='art-default.jpg'), # summary=GetSummary(item['id'], item['name'], item['title'], unicode(L('No description available'))), # c_audio_codec=item['audio_codec'] if item['audio_codec'] else None, # c_video_codec=item['video_codec'] if item['video_codec'] else None, # c_container=item['container'] if item['container'] else None, # c_protocol=item['protocol'] if item['protocol'] else None, # optimized_for_streaming=item['optimized_for_streaming'] in ['y', 'yes', 't', 'true', 'on', '1'] if # item['optimized_for_streaming'] else 'No', # include_container=False # ) # ) # later.sort(key=lambda x: (x['time'])) # for item in later: # new_chan['time'] = program['start'].strftime('%H:%M') # count += 1 # oc.add( # CreateVideoClipObject( # url=item['url'] + "&tm=" + str(item['time']).replace(" ", ""), # title=item['title'], # thumb=GetImage(item['thumb'], default='icon-tv.png', id=item['id'], name=item['name'], # title=item['title']), # art=GetImage(item['art'], default='art-default.jpg'), # summary=GetSummary(item['id'], item['name'], item['title'], unicode(L('No description available'))), # c_audio_codec=item['audio_codec'] if item['audio_codec'] else None, # c_video_codec=item['video_codec'] if item['video_codec'] else None, # c_container=item['container'] if item['container'] else None, # c_protocol=item['protocol'] if item['protocol'] else None, # optimized_for_streaming=item['optimized_for_streaming'] in ['y', 'yes', 't', 'true', 'on', '1'] if # item['optimized_for_streaming'] else 'No', # include_container=False # ) # ) return oc
def VideoMainMenu(): Log.Info(str(PLUGIN_VERSION) + ' VideoMainMenu called: ') oc = ObjectContainer() if PLUGIN_VERSION_LATEST > PLUGIN_VERSION: updateAvailable = " - plugin update available" else: updateAvailable = "" sourceType() SmoothUtils.GetServerUrlByName(Prefs["serverLocation"]) if Prefs['simple'] == 'Test': return test() elif Prefs['simple'] == 'SimpleStreams (No EPG)': return SimpleStreamsNoEPG() if not Dict['groups'] or not Dict['streams']: SmoothUtils.PlaylistReload() SmoothUtils.GuideReload() Thread(target=SmoothUtils.PlaylistReloader).start() Thread(target=SmoothUtils.GuideReloader).start() if Prefs['simple'] == 'SimpleStreams': ObjectContainer.title1 = NAME + updateAvailable return ListItems() else: # if (Dict['currentGuide'] == "Sports" and Prefs['sportsOnly']) or (Dict['currentGuide'] == "All" and not Prefs['sportsOnly']): # SmoothUtils.GetScheduleJson() if Dict['SPassW'] is None or Prefs['serverLocation'] is None or Prefs['username'] is None or Prefs['service'] is None: Log.Info('No password yet') ObjectContainer.title1 = NAME + updateAvailable + ' - Enter Login Details and Server Preferences then Refresh ->' oc.add(PrefsObject(title = "Preferences", thumb = R("icon-prefs.png"))) else: ObjectContainer.title1 = NAME + updateAvailable if not Dict['groups']: ReloadPlaylist() if not Dict['groups']: return ObjectContainer( title1=unicode(L('Error')), header=unicode(L('Error')), message=unicode(L( 'Provided playlist files are invalid, missing or empty, check the log file for more information')) ) groups = Dict['groups'] groups_list = groups.values() use_groups = False for group in groups_list: if group['title'] not in [unicode('All'), unicode('No category'), unicode('SSTV')]: use_groups = True break if use_groups: groups_list.sort(key=lambda d: d['order']) oc = ObjectContainer(title1=unicode(L(NAME)) + updateAvailable) oc.add( DirectoryObject( key=Callback(ListItems, group=unicode('All')), title=unicode(L('All')) ) ) for group in groups_list: if group['title'] not in [unicode('All'), unicode('No category')]: thumb = GetImage(group['thumb'], default='icon-folder.png', title=group['title']) art = GetImage(group['art'], default='art-default.png') oc.add( DirectoryObject( key=Callback(ListItems, group=group['title']), title=group['title'], thumb=thumb, art=art ) ) if unicode('No category') in groups.keys(): oc.add( DirectoryObject( key=Callback(ListItems, group=unicode('No category')), title=unicode(L('No category')) ) ) else: oc.add(DirectoryObject(key=Callback(ListItems), title="Channels", thumb=R('Icon-Default.png'), summary="Channel List")) # oc.add(DirectoryObject(key = Callback(LiveMenu), title = "Live Sports", thumb = SmoothUtils.GetChannelThumb(chanName = "Live Sports"), summary = "Live shows")) oc.add(DirectoryObject(key = Callback(CategoriesMenu), title = "Categories", thumb = SmoothUtils.GetChannelThumb(chanName = "Categories"), summary = "Category List")) oc.add(DirectoryObject(key = Callback(SearchListItems, query = 'schedule'), title = "Schedule Sports", thumb = SmoothUtils.GetChannelThumb(chanName = "Schedule"), summary = "Schedule List")) # TODO: add custom categories if not Prefs['mySearch'] is None and len(Prefs['mySearch']) > 2: for mySearch in Prefs['mySearch'].split(";"): if ":" in mySearch: title = mySearch.split(":")[0].strip() searchString = mySearch.split(":")[1].strip() else: title = mySearch searchString = mySearch thumb = SmoothUtils.GetChannelThumb(category = title.replace(" HD", "").replace(" NOW", "").replace(" NEXT", "").replace(" BEST", ""), large = False) oc.add(DirectoryObject(key = Callback(SearchListItems, query = searchString), title = title, thumb = thumb)) oc.add(InputDirectoryObject(key = Callback(ListItems), title = "Find Channel", prompt = 'Enter show title')) # Reload buttons oc.add( DirectoryObject( key=Callback(ReloadPlaylist), title=unicode(L('Reload playlist')), thumb=R('icon-reload.png') ) ) oc.add( DirectoryObject( key=Callback(ReloadGuide), title=unicode(L('Reload program guide')), thumb=R('icon-reload.png') ) ) # Preferences oc.add(PrefsObject(title = "Preferences", thumb = R("icon-prefs.png"))) return oc