def autoPlay(url, name, autoPlay_type): import random from domains import sitesBase, parse_reddit_link, build_DirectoryItem_url_based_on_media_type from utils import unescape, post_is_filtered_out, log, clean_str from actions import setting_gif_repeat_count from reddit import reddit_request, determine_if_video_media_from_reddit_json gif_repeat_count=setting_gif_repeat_count() entries = [] playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) playlist.clear() log("**********autoPlay %s*************" %autoPlay_type) content = reddit_request(url) if not content: return content = json.loads(content.replace('\\"', '\'')) log("Autoplay %s - Parsing %d items" %( autoPlay_type, len(content['data']['children']) ) ) for j_entry in content['data']['children']: try: if post_is_filtered_out( j_entry ): continue title = clean_str(j_entry, ['data','title']) try: media_url = j_entry['data']['url'] except: media_url = j_entry['data']['media']['oembed']['url'] is_a_video = determine_if_video_media_from_reddit_json(j_entry) ld=parse_reddit_link(link_url=media_url, assume_is_video=is_a_video, needs_preview=False, get_playable_url=True ) DirectoryItem_url, setProperty_IsPlayable, isFolder, title_prefix = build_DirectoryItem_url_based_on_media_type(ld, media_url, title, on_autoplay=True) if ld: if ld.media_type not in [sitesBase.TYPE_VIDEO, sitesBase.TYPE_GIF, sitesBase.TYPE_VIDS, sitesBase.TYPE_MIXED]: continue autoPlay_type_entries_append( entries, autoPlay_type, title, DirectoryItem_url) if ld.media_type == sitesBase.TYPE_GIF: for _ in range( 0, gif_repeat_count ): autoPlay_type_entries_append( entries, autoPlay_type, title, DirectoryItem_url) except Exception as e: log(" EXCEPTION Autoplay "+ str( sys.exc_info()[0]) + " " + str(e) ) if autoplayRandomize: random.shuffle(entries) for title, url in entries: listitem = xbmcgui.ListItem(title) playlist.add(url, listitem) log('add to playlist: %s %s' %(title.ljust(25)[:25],url )) xbmc.Player().play(playlist)
def parse_url_and_play(url, name, type_): from domains import parse_reddit_link, sitesBase, ydtl_get_playable_url, build_DirectoryItem_url_based_on_media_type log('parse_url_and_play url='+url) playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) ld=parse_reddit_link(url,True, False, False ) DirectoryItem_url, setProperty_IsPlayable, isFolder, title_prefix = build_DirectoryItem_url_based_on_media_type(ld, url) if setProperty_IsPlayable=='true': log( '---------IsPlayable---------->'+ DirectoryItem_url) playVideo(DirectoryItem_url,'','') else: if isFolder: #showing album log( '---------using ActivateWindow------>'+ DirectoryItem_url) xbmc.executebuiltin('ActivateWindow(Videos,'+ DirectoryItem_url+')') else: #viewing image log( '---------using setResolvedUrl------>'+ DirectoryItem_url) listitem = xbmcgui.ListItem(path='') listitem.setProperty('IsPlayable', 'false') xbmcplugin.setResolvedUrl(pluginhandle, True, listitem) xbmc.executebuiltin('RunPlugin(%s)' % ( DirectoryItem_url ) )
def listRelatedVideo(url,name,type_): #type_: 'channel' -other videos in the channel # 'related' -related videos #only youtube is supported for now from domains import ClassYoutube from domains import parse_reddit_link, build_DirectoryItem_url_based_on_media_type match=re.compile( ClassYoutube.regex, re.I).findall( url ) if match: #log('***** isYouTubeable' + repr(link_url)) yt=ClassYoutube(url) links_dictList=yt.ret_album_list(type_) #returns a list of dict same as one used for albums if links_dictList: #log(pprint.pformat(links_dictList)) for _, d in enumerate(links_dictList): label=d.get('li_label') label2=d.get('li_label2') #li_iconImage=d.get('li_iconImage') ti=d.get('li_thumbnailImage') media_url=d.get('DirectoryItem_url') #media_type=d.get('type') #media_thumb=d.get('thumb') #isPlayable=d.get('isPlayable') #link_action=d.get('link_action') #channel_id=d.get('channel_id') #video_id=d.get('video_id') liz=xbmcgui.ListItem(label,label2) liz.setInfo( type='video', infoLabels=d['infoLabels'] ) #this tricks the skin to show the plot. where we stored the descriptions liz.setArt({"thumb": ti,'icon': ti, "poster":ti, "banner":ti, "fanart":ti, "landscape":ti }) #a little overkill considering we're only matching for youtube ld=parse_reddit_link(media_url) DirectoryItem_url, setProperty_IsPlayable, isFolder, _ = build_DirectoryItem_url_based_on_media_type(ld, media_url, '', '', script_to_call="") #directory_items.append( (url_for_DirectoryItem, liz, False,) ) liz.setProperty('IsPlayable', setProperty_IsPlayable) xbmcplugin.addDirectoryItem(pluginhandle, DirectoryItem_url, liz, isFolder) xbmcplugin.endOfDirectory(handle=pluginhandle, succeeded=True, updateListing=False, #setting this to True causes the ".." entry to quit the plugin cacheToDisc=True) else: xbmc_notify('Nothing to list', url) else: xbmc_notify('cannot identify youtube url', url)
def parse_url_and_play(url, name, type_): from domains import parse_reddit_link, sitesBase, ydtl_get_playable_url, build_DirectoryItem_url_based_on_media_type #from actions import viewImage log('parse_url_and_play url=' + url) #log('pluginhandle='+str(pluginhandle) ) playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) ld = parse_reddit_link(url, True, False, False) DirectoryItem_url, setProperty_IsPlayable, isFolder, title_prefix = build_DirectoryItem_url_based_on_media_type( ld, url) if setProperty_IsPlayable == 'true': log('---------IsPlayable---------->' + DirectoryItem_url) playVideo(DirectoryItem_url, '', '') else: if isFolder: #showing album log('---------using ActivateWindow------>' + DirectoryItem_url) xbmc.executebuiltin('ActivateWindow(Videos,' + DirectoryItem_url + ')') else: #viewing image log('---------using setResolvedUrl------>' + DirectoryItem_url) #viewImage(DirectoryItem_url,'','' ) #error message after picture is displayed, kore remote will be unresponsive #playVideo(DirectoryItem_url,'','') #endless loop. picture windowxml opens after closing, opens again after closing.... #xbmc.executebuiltin('ActivateWindow(Videos,'+ DirectoryItem_url+')') #log( 'Container.Update(%s?path=%s?prl=zaza&mode=viewImage&url=%s)' % ( sys.argv[0], sys.argv[0], urllib.quote_plus(url) ) ) #xbmc.executebuiltin('Container.Update(%s?path=%s?prl=zaza&mode=viewImage&url=%s)' % ( sys.argv[0], sys.argv[0], urllib.quote_plus(url) ) ) listitem = xbmcgui.ListItem(path='') listitem.setProperty('IsPlayable', 'false') xbmcplugin.setResolvedUrl(pluginhandle, True, listitem) #DirectoryItem_url=DirectoryItem_url.replace('plugin://', 'script://') #xbmc.executebuiltin('RunScript(script.reddit.reader)' ) #xbmc.executebuiltin('RunScript(script.reddit.reader,mode=viewImage&url=%s)' %urllib.quote_plus(url) ) #xbmc.executebuiltin('RunPlugin(%s?path=%s?prl=zaza&mode=viewImage&url=%s)' % ( sys.argv[0], sys.argv[0], urllib.quote_plus(url) ) ) xbmc.executebuiltin('RunPlugin(%s)' % (DirectoryItem_url))
def parse_url_and_play(url, name, type_): from domains import parse_reddit_link, sitesBase, ydtl_get_playable_url, build_DirectoryItem_url_based_on_media_type #from actions import viewImage log('parse_url_and_play url='+url) #log('pluginhandle='+str(pluginhandle) ) playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) ld=parse_reddit_link(url,True, False, False ) DirectoryItem_url, setProperty_IsPlayable, isFolder, title_prefix = build_DirectoryItem_url_based_on_media_type(ld, url) if setProperty_IsPlayable=='true': log( '---------IsPlayable---------->'+ DirectoryItem_url) playVideo(DirectoryItem_url,'','') else: if isFolder: #showing album log( '---------using ActivateWindow------>'+ DirectoryItem_url) xbmc.executebuiltin('ActivateWindow(Videos,'+ DirectoryItem_url+')') else: #viewing image log( '---------using setResolvedUrl------>'+ DirectoryItem_url) #viewImage(DirectoryItem_url,'','' ) #error message after picture is displayed, kore remote will be unresponsive #playVideo(DirectoryItem_url,'','') #endless loop. picture windowxml opens after closing, opens again after closing.... #xbmc.executebuiltin('ActivateWindow(Videos,'+ DirectoryItem_url+')') #log( 'Container.Update(%s?path=%s?prl=zaza&mode=viewImage&url=%s)' % ( sys.argv[0], sys.argv[0], urllib.quote_plus(url) ) ) #xbmc.executebuiltin('Container.Update(%s?path=%s?prl=zaza&mode=viewImage&url=%s)' % ( sys.argv[0], sys.argv[0], urllib.quote_plus(url) ) ) listitem = xbmcgui.ListItem(path='') listitem.setProperty('IsPlayable', 'false') xbmcplugin.setResolvedUrl(pluginhandle, True, listitem) #DirectoryItem_url=DirectoryItem_url.replace('plugin://', 'script://') #xbmc.executebuiltin('RunScript(script.reddit.reader)' ) #xbmc.executebuiltin('RunScript(script.reddit.reader,mode=viewImage&url=%s)' %urllib.quote_plus(url) ) #xbmc.executebuiltin('RunPlugin(%s?path=%s?prl=zaza&mode=viewImage&url=%s)' % ( sys.argv[0], sys.argv[0], urllib.quote_plus(url) ) ) xbmc.executebuiltin('RunPlugin(%s)' % ( DirectoryItem_url ) )
def listRelatedVideo(url,name,type_): from domains import ClassYoutube from domains import parse_reddit_link, build_DirectoryItem_url_based_on_media_type match=re.compile( ClassYoutube.regex, re.I).findall( url ) if match: yt=ClassYoutube(url) links_dictList=yt.ret_album_list(type_) #returns a list of dict same as one used for albums if links_dictList: for _, d in enumerate(links_dictList): label=d.get('li_label') label2=d.get('li_label2') ti=d.get('li_thumbnailImage') media_url=d.get('DirectoryItem_url') liz=xbmcgui.ListItem(label,label2) liz.setInfo( type='video', infoLabels=d['infoLabels'] ) #this tricks the skin to show the plot. where we stored the descriptions liz.setArt({"thumb": ti,'icon': ti, "poster":ti, "banner":ti, "fanart":ti, "landscape":ti }) ld=parse_reddit_link(media_url) DirectoryItem_url, setProperty_IsPlayable, isFolder, _ = build_DirectoryItem_url_based_on_media_type(ld, media_url, '', '', script_to_call="") liz.setProperty('IsPlayable', setProperty_IsPlayable) xbmcplugin.addDirectoryItem(pluginhandle, DirectoryItem_url, liz, isFolder) xbmcplugin.endOfDirectory(handle=pluginhandle, succeeded=True, updateListing=False, #setting this to True causes the ".." entry to quit the plugin cacheToDisc=True) else: xbmc_notify('Nothing to list', url) else: xbmc_notify('cannot identify youtube url', url)
def autoSlideshow(url, name, type_): log('starting slideshow ' + url) ev = threading.Event() entries = [] preview_w = 0 preview_h = 0 image = '' content = reddit_request(url) if not content: return content = json.loads(content) log("slideshow %s:Parsing %d items: %s" % (type_, len(content['data']['children']), 'random' if random_post_order else 'normal order')) data_children = content['data']['children'] if random_post_order: random.shuffle(data_children) for j_entry in data_children: try: title = unescape(j_entry['data']['title'].encode('utf-8')) log(" TITLE:%s [r/%s]" % (title, j_entry.get('data').get('subreddit'))) try: description = unescape(j_entry['data']['media']['oembed'] ['description'].encode('utf-8')) except: description = '' try: post_selftext = unescape( j_entry['data']['selftext'].encode('utf-8')) except: post_selftext = '' description = post_selftext + '[CR]' + description if post_selftext else description try: media_url = j_entry['data']['url'] except: media_url = j_entry['data']['media']['oembed']['url'] try: preview = j_entry['data']['preview']['images'][0]['source'][ 'url'].encode('utf-8').replace('&', '&') try: preview_h = float(j_entry['data']['preview']['images'][0] ['source']['height']) preview_w = float(j_entry['data']['preview']['images'][0] ['source']['width']) except: preview_w = 0 preview_h = 0 except Exception as e: preview = "" ld = parse_reddit_link(link_url=media_url, assume_is_video=False, needs_preview=True, get_playable_url=True) if ld: if not preview: preview = ld.poster if (addon.getSetting('include_albums') == 'true') and (ld.media_type == sitesBase.TYPE_ALBUM): dictlist = listAlbum(media_url, title, 'return_dictlist') for d in dictlist: t2 = d.get('li_label') if d.get('li_label') else title d['li_label'] = t2 entries.append(d) else: if addon.getSetting('use_reddit_preview') == 'true': if preview: image = preview elif ld.poster: image = ld.poster else: if ld.poster: image = ld.poster #entries.append([title,ld.poster,preview_w, preview_h,len(entries)]) elif preview: image = preview #entries.append([title,preview,preview_w, preview_h,len(entries)]) append_entry(entries, title, image, preview_w, preview_h, description) else: append_entry(entries, title, preview, preview_w, preview_h, description) except Exception as e: log(' autoPlay exception:' + str(e)) entries = remove_dict_duplicates(entries, 'DirectoryItem_url') for i, e in enumerate(entries): log(' possible playable items({0}) {1}...{2}x{3} {4}'.format( i, e['li_label'].ljust(15)[:15], repr(e.get('width')), repr(e.get('height')), e.get('DirectoryItem_url'))) if len(entries) == 0: log(' Play All: no playable items') xbmc.executebuiltin( 'XBMC.Notification("%s","%s")' % (translation(32054), translation(32055))) #Play All No playable items return log("**********playing slideshow*************") for e in entries: q.put(e) s = ScreensaverManager(ev, q) try: s.start_loop() except Exception as e: log(" EXCEPTION slideshowAlbum:=" + str(sys.exc_info()[0]) + " " + str(e)) return
def autoSlideshow(url, name, type_): log('starting slideshow ' + url) ev = threading.Event() entries = [] #watchdog_counter=0 preview_w = 0 preview_h = 0 image = '' #content = opener.open(url).read() content = reddit_request(url) if not content: return #log( str(content) ) #content = json.loads(content.replace('\\"', '\'')) content = json.loads(content) log("slideshow %s:Parsing %d items: %s" % (type_, len(content['data']['children']), 'random' if random_post_order else 'normal order')) data_children = content['data']['children'] if random_post_order: random.shuffle(data_children) for j_entry in data_children: try: title = unescape(j_entry['data']['title'].encode('utf-8')) log(" TITLE:%s [r/%s]" % (title, j_entry.get('data').get('subreddit'))) try: description = unescape(j_entry['data']['media']['oembed'] ['description'].encode('utf-8')) except: description = '' #log(' description [%s]' %description) try: post_selftext = unescape( j_entry['data']['selftext'].encode('utf-8')) except: post_selftext = '' #log(' post_selftext[%s]' %post_selftext) description = post_selftext + '[CR]' + description if post_selftext else description try: media_url = j_entry['data']['url'] except: media_url = j_entry['data']['media']['oembed']['url'] try: preview = j_entry['data']['preview']['images'][0]['source'][ 'url'].encode('utf-8').replace('&', '&') try: preview_h = float(j_entry['data']['preview']['images'][0] ['source']['height']) preview_w = float(j_entry['data']['preview']['images'][0] ['source']['width']) except: preview_w = 0 preview_h = 0 except Exception as e: #log(" getting preview image EXCEPTION:="+ str( sys.exc_info()[0]) + " " + str(e) ) preview = "" ld = parse_reddit_link(link_url=media_url, assume_is_video=False, needs_preview=True, get_playable_url=True) if ld: if not preview: preview = ld.poster if (addon.getSetting('include_albums') == 'true') and (ld.media_type == sitesBase.TYPE_ALBUM): dictlist = listAlbum(media_url, title, 'return_dictlist') for d in dictlist: #log(' (S) adding items from album ' + title +' ' + d.get('DirectoryItem_url') ) t2 = d.get('li_label') if d.get('li_label') else title #entries.append([ t2, d.get('DirectoryItem_url'), d.get('width'), d.get('height'), len(entries)]) d['li_label'] = t2 entries.append(d) #title='' #only put the title in once. else: if addon.getSetting('use_reddit_preview') == 'true': if preview: image = preview elif ld.poster: image = ld.poster #if preview: entries.append([title,preview,preview_w, preview_h,len(entries)]) #log(' (N)added preview:%s %s' %( title,preview) ) #elif ld.poster: entries.append([title,ld.poster,preview_w, preview_h,len(entries)]) #log(' (N)added poster:%s %s' % ( title,ld.poster) ) else: if ld.poster: image = ld.poster #entries.append([title,ld.poster,preview_w, preview_h,len(entries)]) elif preview: image = preview #entries.append([title,preview,preview_w, preview_h,len(entries)]) #if ld.poster: entries.append([title,ld.poster,preview_w, preview_h,len(entries)]) #elif preview: entries.append([title,preview,preview_w, preview_h,len(entries)]) append_entry(entries, title, image, preview_w, preview_h, description) else: append_entry(entries, title, preview, preview_w, preview_h, description) #log(' (N)added preview:%s' % title ) except Exception as e: log(' autoPlay exception:' + str(e)) #log( repr(entries)) entries = remove_dict_duplicates(entries, 'DirectoryItem_url') # #for i,e in enumerate(entries): log(' e1-%d %s' %(i, e[1]) ) # def k2(x): return x[1] # entries=remove_duplicates(entries, k2) # #for i,e in enumerate(entries): log(' e2-%d %s' %(i, e[1]) ) for i, e in enumerate(entries): log(' possible playable items({0}) {1}...{2}x{3} {4}'.format( i, e['li_label'].ljust(15)[:15], repr(e.get('width')), repr(e.get('height')), e.get('DirectoryItem_url'))) if len(entries) == 0: log(' Play All: no playable items') xbmc.executebuiltin( 'XBMC.Notification("%s","%s")' % (translation(32054), translation(32055))) #Play All No playable items return #if type.endswith("_RANDOM"): # random.shuffle(entries) #for title, url in entries: # log(" added to playlist:"+ title + " " + url ) log("**********playing slideshow*************") for e in entries: q.put(e) #s= HorizontalSlideScreensaver(ev,q) s = ScreensaverManager(ev, q) try: s.start_loop() except Exception as e: log(" EXCEPTION slideshowAlbum:=" + str(sys.exc_info()[0]) + " " + str(e)) return
def display_album_from(dictlist, album_name): from domains import parse_reddit_link, build_DirectoryItem_url_based_on_media_type, sitesBase from utils import build_script directory_items = [] album_viewMode = addon.getSetting("album_viewMode") if album_viewMode == '450': #using custom gui using_custom_gui = True else: using_custom_gui = False #log( repr(dictlist)) for _, d in enumerate(dictlist): ti = d['li_thumbnailImage'] media_url = d.get('DirectoryItem_url') #log(' display_album_from list:'+ media_url + " " ) #There is only 1 textbox for Title and description in our custom gui. # I don't know how to achieve this in the xml file so it is done here: # combine title and description without [CR] if label is empty. [B]$INFO[Container(53).ListItem.Label][/B][CR]$INFO[Container(53).ListItem.Plot] # new note: this is how it is done: # $INFO[Container(53).ListItem.Label,[B],[/B][CR]] $INFO[Container(53).ListItem.Plot] #if the infolabel is empty, nothing is printed for that block #combined = '[B]'+ d['li_label2'] + "[/B][CR]" if d['li_label2'] else "" combined = d['infoLabels'].get('plot') if d['infoLabels'].get( 'plot') else "" d['infoLabels']['plot'] = combined liz = xbmcgui.ListItem(label=d.get('li_label'), label2=d.get('li_label2')) #parse the link so that we can determine whether it is image or video. ld = parse_reddit_link(media_url) DirectoryItem_url, setProperty_IsPlayable, isFolder, _ = build_DirectoryItem_url_based_on_media_type( ld, media_url, '', '', script_to_call="") #log('isFolder:' + repr(isFolder)+ ' IsPlayable:'+repr(setProperty_IsPlayable) + ' DirectoryItem_url:' + repr(DirectoryItem_url)) if using_custom_gui: url_for_DirectoryItem = media_url liz.setProperty('onClick_action', DirectoryItem_url) liz.setProperty('is_video', 'true') #if setProperty_IsPlayable=='true': if ld: if ld.link_action == sitesBase.DI_ACTION_PLAYABLE: liz.setProperty('item_type', 'playable') else: #this part is for playing video that needs to be resolved first. (youtube_dl) #I could not get this to work --> #Attempt to use invalid handle -1 #I think you can't setresolvedUrl a listitem from a custom gui #url_for_DirectoryItem=DirectoryItem_url liz.setProperty('item_type', 'script') else: #sys.argv[0]+"?url="+ urllib.quote_plus(d['DirectoryItem_url']) +"&mode=viewImage" #with xbmc's standard gui, we need to specify to call the plugin to open the gui that shows image #log('***'+'isFolder:' + repr(isFolder)+ ' IsPlayable:'+repr(setProperty_IsPlayable) +'**[diu]:'+ DirectoryItem_url) liz.setProperty('IsPlayable', setProperty_IsPlayable) url_for_DirectoryItem = DirectoryItem_url liz.setInfo( type='video', infoLabels=d['infoLabels'] ) #this tricks the skin to show the plot. where we stored the picture descriptions liz.setArt({ "thumb": ti, 'icon': ti, "poster": media_url, "banner": media_url, "fanart": media_url, "landscape": media_url }) directory_items.append((url_for_DirectoryItem, liz, isFolder)) if using_custom_gui: from guis import cGUI li = [] for di in directory_items: li.append(di[1]) ui = cGUI('view_450_slideshow.xml', addon_path, defaultSkin='Default', defaultRes='1080i', listing=li, id=53) ui.include_parent_directory_entry = False ui.doModal() del ui else: if album_viewMode != '0': xbmc.executebuiltin('Container.SetViewMode(' + album_viewMode + ')') xbmcplugin.addDirectoryItems(handle=pluginhandle, items=directory_items) xbmcplugin.endOfDirectory(pluginhandle)
def addLink(title, title_line2, iconimage, previewimage,preview_w,preview_h,domain, description, credate, reddit_says_is_video, commentsUrl, subreddit, link_url, over_18, posted_by="", num_comments=0,post_id=''): from utils import ret_info_type_icon, build_script,colored_subreddit #from reddit import assemble_reddit_filter_string from domains import parse_reddit_link, sitesBase from ContextMenus import build_context_menu_entries preview_ar=0.0 DirectoryItem_url='' if over_18: mpaa="R" title_line2 = "[COLOR red][NSFW][/COLOR] "+title_line2 else: mpaa="" post_title=title if len(post_title) > 100 or description: il_description='[B]%s[/B][CR][CR]%s' %( post_title, description ) else: il_description='' il={ "title": post_title, "plot": il_description, "Aired": credate, "mpaa": mpaa, "Genre": "r/"+subreddit, "studio": domain, "director": posted_by } #, "duration": 1271} (duration uses seconds for titan skin liz=xbmcgui.ListItem(label=post_title ,label2=title_line2 ,path='') #path not used by gui. if preview_w==0 or preview_h==0: preview_ar=0.0 else: preview_ar=float(preview_w) / preview_h #log(' preview_ar:'+repr(preview_ar)) if preview_ar>1.4: #this triggers whether the (control id 203) will show up #the gui checks for this: String.IsEmpty(Container(55).ListItem.Property(preview_ar)) to show/hide a wider preview # this is overridden if the post is an album. liz.setProperty('preview_ar', str(preview_ar) ) # -- $INFO[ListItem.property(preview_ar)] #text_below_image=il_description+title_line2 + colored_subreddit( posted_by, 'dimgrey',False ) text_below_image='[B]%s[/B][CR]%s %s[CR]%s' %( post_title, title_line2, colored_subreddit( ' by '+posted_by, 'dimgrey',False ), description ) liz.setInfo(type='video', infoLabels={"plotoutline": text_below_image, } ) #makes the gui use a control that allows the user scroll tall image if preview_ar<0.3: liz.setProperty('very_tall_image', str(preview_ar) ) # -- IsEmpty(Container(55).ListItem.Property(very_tall_image)) elif preview_ar<0.5: liz.setProperty('tall_image', str(preview_ar) ) # -- IsEmpty(Container(55).ListItem.Property(tall_image)) if num_comments > 0 or description: liz.setProperty('comments_action', build_script('listLinksInComment', commentsUrl ) ) liz.setProperty('link_url', link_url ) liz.setInfo(type='video', infoLabels=il) #use clearart to indicate if link is video, album or image. here, we default to unsupported. clearart=ret_info_type_icon('', '') liz.setArt({ "clearart": clearart }) #force all links to ytdl to see if they are playable liz.setProperty('item_type','script') liz.setProperty('onClick_action', build_script('playYTDLVideo', link_url,'',previewimage) ) #liz.setProperty('onClick_action', build_script('playYTDLVideo', link_url,'','') ) #get meta_ogimage_content for links that do not have a preview image if previewimage: needs_preview=False else: if any(site in domain for site in sites_that_will_ban_if_excessive_connections): previewimage=iconimage needs_preview=False else: needs_preview=True #reddit has no thumbnail for this link. please get one ld=parse_reddit_link(link_url,reddit_says_is_video, needs_preview, False, preview_ar ) if previewimage=="": if domain.startswith('self.'): liz.setArt({"thumb": ld.thumb if ld else '', "banner": '' , }) else: liz.setArt({"thumb": iconimage, "banner": ld.poster if ld else '' , }) else: liz.setArt({"thumb": iconimage, "banner":previewimage, }) #log( ' %s' %(domain)) #log( ' reddit thumb[%s] ' %(iconimage )) #log( ' reddit preview[%s] ar=%f %dx%d' %(previewimage, preview_ar, preview_w,preview_h )) #if ld: log( ' new-thumb[%s] poster[%s] ' %( ld.thumb, ld.poster )) if ld: #use clearart to indicate the type of link(video, album, image etc.) clearart=ret_info_type_icon(ld.media_type, ld.link_action, domain ) liz.setArt({ "clearart": clearart }) if iconimage in ["","nsfw", "default"]: iconimage=ld.thumb #we gathered a description from the link if ld.desctiption: liz.setInfo(type='video', infoLabels={'plot': il_description + '[CR]' + ld.desctiption, }) if ld.dictlist: #log('****has album images') #listItem is not json serializable so dictlist_to_listItems() is done in the gui #image_listItems=dictlist_to_listItems(ld.dictlist) liz.setProperty('album_images', json.dumps( ld.dictlist ) ) # dictlist=json.loads(string) #overrride the preview_ar flag. (easier to do this here than have the xml figure it out in <visible> liz.setProperty('preview_ar', None ) #log( liz.getProperty('album_images')) #link_action set in domains.py - parse_reddit_link if ld.link_action == sitesBase.DI_ACTION_PLAYABLE: property_link_type=ld.link_action DirectoryItem_url =ld.playable_url else: property_link_type='script' if ld.link_action=='viewTallImage' : #viewTallImage take different args DirectoryItem_url = build_script(mode=ld.link_action, url=ld.playable_url, name=str(preview_w), type_=str(preview_h) ) else: #log( '****' + repr( ld.dictlist )) DirectoryItem_url = build_script(mode=ld.link_action, url=ld.playable_url, name=post_title , type_=previewimage ) #log(' action %s--%s' %( ld.link_action, DirectoryItem_url) ) liz.setProperty('item_type',property_link_type) liz.setProperty('onClick_action',DirectoryItem_url) else: #unsupported type here: pass #***build context menu*** # convert a list of tuple into a string then set it as a property # in GUI, the string is converted back via ast.literal_eval() and put into listItems liz.setProperty('context_menu', str(build_context_menu_entries(num_comments, commentsUrl, subreddit, domain, link_url, post_id, post_title, posted_by, liz.getProperty('onClick_action'), iconimage )) ) return liz
def reddit_comment_worker(idx, h, q_out,submitter,delay=0): from domains import parse_reddit_link, sitesBase from utils import format_description, ret_info_type_icon, build_script, is_filtered from ContextMenus import build_youtube_context_menu_entries, build_reddit_context_menu_entries, build_link_in_browser_context_menu_entries, build_open_browser_to_pair_context_menu_entries if delay>0: xbmc.Monitor().waitForAbort( float(delay)/1000 ) #xbmc.sleep(delay) # h[0]=score, # h[1]=link_desc, # h[2]=link_http, # h[3]=post_text, # h[4]=post_html, # h[5]=d, # h[6]="t1", # h[7]=author, # h[8]=created_utc, try: #log(str(i)+" score:"+ str(h[0]).zfill(5)+" "+ h[1] +'|'+ h[3] ) comment_score=h[0] #log("score %d < %d (%s)" %(comment_score,int_CommentTreshold, CommentTreshold) ) link_url=h[2] desc100=h[3].replace('\n',' ')[0:100] #first 100 characters of description kind=h[6] #reddit uses t1 for user comments and t3 for OP text of the post. like a poster describing the post. d=h[5] #depth of the comment tab=" "*d if d>0 else "-" author=h[7] domain='' if link_url.startswith('/r/'): domain='subreddit' elif link_url.startswith('/u/'): domain='redditor' elif link_url.startswith('#'): #some sort of css flair link_url='' else: domain = '{uri.netloc}'.format( uri=urlparse.urlparse( link_url ) ) if link_url: log( ' comment %s TITLE:%s... link[%s]' % ( str(d).zfill(3), desc100.ljust(20)[:20],link_url ) ) ld=parse_reddit_link(link_url=link_url, assume_is_video=False, needs_preview=True, get_playable_url=True ) plot=format_description(h[3]) if author==submitter:#add a submitter tag author="[COLOR cadetblue][B]%s[/B][/COLOR][S]" %author plot="[B][OP][/B] "+plot else: author="[COLOR cadetblue]%s[/COLOR]" %author if kind=='t1': t_prepend=r"%s" %( tab ) elif kind=='t3': t_prepend=r"[B]Post text:[/B]" liz=xbmcgui.ListItem(label=t_prepend + author + ': '+ desc100 , label2="") liz.setInfo( type="Video", infoLabels={ "Title": h[1], "plot": plot, "studio": domain, "votes": str(comment_score), "director": author } ) liz.setProperty('comment_depth',str(d)) liz.setProperty('plot',plot) #cannot retrieve infolabels in the gui. we put 'plot' here too. liz.setProperty('author',author)# and 'author' too. #force all links to ytdl to see if it can be played if link_url: #log(' there is a link from %s' %domain) if not ld: #log(' link is not supported ') liz.setProperty('item_type','script') liz.setProperty('onClick_action', build_script('playYTDLVideo', link_url) ) plot= "[COLOR greenyellow][%s] %s"%('?', plot ) + "[/COLOR]" liz.setLabel(tab+plot) liz.setProperty('link_url', link_url ) #just used as text at bottom of the screen clearart=ret_info_type_icon('', '') liz.setArt({ "clearart": clearart }) if ld: #use clearart to indicate if link is video, album or image. here, we default to unsupported. #clearart=ret_info_type_icon(setInfo_type, mode_type) clearart=ret_info_type_icon(ld.media_type, ld.link_action, domain ) liz.setArt({ "clearart": clearart }) if ld.link_action == sitesBase.DI_ACTION_PLAYABLE: property_link_type=ld.link_action DirectoryItem_url =ld.playable_url else: property_link_type='script' DirectoryItem_url = build_script(mode=ld.link_action, url=ld.playable_url, name='' , type_='' ) #(score, link_desc, link_http, post_text, post_html, d, ) #list_item_name=str(h[0]).zfill(3) #log(str(i)+" score:"+ str(h[0]).zfill(5)+" desc["+ h[1] +']|text:['+ h[3]+']' +link_url + ' videoID['+videoID+']' + 'playable:'+ setProperty_IsPlayable ) #log( h[4] + ' -- videoID['+videoID+']' ) #log("sss:"+ supportedPluginUrl ) #fl= re.compile('\[(.*?)\]\(.*?\)',re.IGNORECASE) #match '[...](...)' with a capture group inside the []'s as capturegroup1 #result = fl.sub(r"[B]\1[/B]", h[3]) #replace the match with [B] [/B] with capturegroup1 in the middle of the [B]'s #turn link green if DirectoryItem_url: plot= "[COLOR greenyellow][%s] %s"%(domain, plot ) + "[/COLOR]" liz.setLabel(tab+plot) #liz.setArt({"thumb": thumb_url, "poster":thumb_url, "banner":thumb_url, "fanart":thumb_url, "landscape":thumb_url }) liz.setArt({"thumb": ld.thumb,"banner":ld.poster }) liz.setProperty('item_type',property_link_type) #script or playable liz.setProperty('onClick_action', DirectoryItem_url) #<-- needed by the xml gui skin liz.setProperty('link_url', link_url ) #just used as text at bottom of the screen #liz.setPath(DirectoryItem_url) context_menu_list=[] context_menu_list.extend(build_youtube_context_menu_entries(previous_listing_was_of_type='',youtube_url=link_url,video_id=None)) context_menu_list.extend(build_reddit_context_menu_entries(link_url)) context_menu_list.extend(build_link_in_browser_context_menu_entries(link_url)) context_menu_list.extend(build_open_browser_to_pair_context_menu_entries(link_url)) liz.setProperty('context_menu', str(context_menu_list) ) #directory_items.append( (DirectoryItem_url, liz,) ) else: #this section are for comments that have no links or unsupported links #if not ShowOnlyCommentsWithlink: #directory_items.append( ("", liz, ) ) pass #END section are for comments that have no links or unsupported links q_out.put( [idx, liz] ) except Exception as e: log('EXCEPTION comments_worker '+ str(e))
def listLinksInComment(url, name, type_): from domains import parse_reddit_link, build_DirectoryItem_url_based_on_media_type from utils import markdown_to_bbcode, unescape from guis import progressBG #from resources.domains import make_addon_url_from #called from context menu log('listLinksInComment:%s:%s' %(type_,url) ) #does not work for list comments coz key is the playable url (not reddit comments url) #msg=WINDOW.getProperty(url) #WINDOW.clearProperty( url ) #log( ' msg=' + msg ) directory_items=[] author="" ShowOnlyCommentsWithlink=False if type_=='linksOnly': ShowOnlyCommentsWithlink=True #url='https://www.reddit.com/r/Music/comments/4k02t1/bonnie_tyler_total_eclipse_of_the_heart_80s_pop/' + '.json' #only get up to "https://www.reddit.com/r/Music/comments/4k02t1". # do not include "/bonnie_tyler_total_eclipse_of_the_heart_80s_pop/" # because we'll have problem when it looks like this: "https://www.reddit.com/r/Overwatch/comments/4nx91h/ever_get_that_feeling_déjà _vu/" #url=re.findall(r'(.*/comments/[A-Za-z0-9]+)',url)[0] #use safe='' argument in quoteplus to encode only the weird chars part url=urllib.quote_plus(url,safe=':/?&') if '?' in url: url=url.split('?', 1)[0]+'.json?'+url.split('?', 1)[1] else: url+= '.json' loading_indicator=progressBG(translation(30024)) loading_indicator.update(0,'Retrieving comments') content = reddit_request(url) if not content: loading_indicator.end() return loading_indicator.update(10,'Parsing') content = json.loads(content) del harvest[:] #harvest links in the post text (just 1) r_linkHunter(content[0]['data']['children']) try:submitter=content[0]['data']['children'][0]['data']['author'] except: submitter='' #the post title is provided in json, we'll just use that instead of messages from addLink() try:post_title=content[0]['data']['children'][0]['data']['title'] except:post_title='' #for i, h in enumerate(harvest): # log("aaaaa first harvest "+h[2]) #harvest links in the post itself r_linkHunter(content[1]['data']['children']) comment_score=0 loading_indicator.set_tick_total(len(harvest)) for i, h in enumerate(harvest): try: #log(str(i)+" score:"+ str(h[0]).zfill(5)+" "+ h[1] +'|'+ h[3] ) comment_score=h[0] #log("score %d < %d (%s)" %(comment_score,int_CommentTreshold, CommentTreshold) ) link_url=h[2] desc100=h[3].replace('\n',' ')[0:100] #first 100 characters of description kind=h[6] #reddit uses t1 for user comments and t3 for OP text of the post. like a poster describing the post. d=h[5] #depth of the comment tab=" "*d if d>0 else "-" from urlparse import urlparse domain = '{uri.netloc}'.format( uri=urlparse( link_url ) ) author=h[7] DirectoryItem_url='' if comment_score < int_CommentTreshold: continue #hoster, DirectoryItem_url, videoID, mode_type, thumb_url,poster_url, isFolder,setInfo_type, setProperty_IsPlayable =make_addon_url_from(h[2]) #if link_url: # log( ' comment %s TITLE:%s... link[%s]' % ( str(d).zfill(3), desc100.ljust(20)[:20],link_url ) ) ld=parse_reddit_link(link_url=link_url, assume_is_video=False, needs_preview=True, get_playable_url=True ) if kind=='t1': list_title=r"[COLOR cadetblue]%3d[/COLOR] %s" %( h[0], tab ) elif kind=='t3': list_title=r"[COLOR cadetblue]Title [/COLOR] %s" %( tab ) #helps the the textbox control treat [url description] and (url) as separate words. so that they can be separated into 2 lines plot=h[3].replace('](', '] (') plot= markdown_to_bbcode(plot) plot=unescape(plot) #convert html entities e.g.:(') liz=xbmcgui.ListItem(label=list_title +': '+ desc100) liz.setInfo( type="Video", infoLabels={ "Title": h[1], "plot": plot, "studio": domain, "votes": str(comment_score), "director": author } ) isFolder=False #force all links to ytdl to see if it can be played if link_url: DirectoryItem_url, setProperty_IsPlayable, isFolder, title_prefix = build_DirectoryItem_url_based_on_media_type(ld, link_url) liz.setProperty('IsPlayable', setProperty_IsPlayable) liz.setProperty('url', DirectoryItem_url) #<-- needed by the xml gui skin liz.setPath(DirectoryItem_url) if domain: plot= " [COLOR greenyellow][%s] %s"%(domain, plot ) + "[/COLOR]" else: plot= " [COLOR greenyellow][%s]"%( plot ) + "[/COLOR]" liz.setLabel(list_title+plot) if ld: liz.setArt({"thumb": ld.poster, "poster":ld.poster, "banner":ld.poster, "fanart":ld.poster, "landscape":ld.poster }) if DirectoryItem_url: #log( 'IsPlayable:'+setProperty_IsPlayable ) directory_items.append( (DirectoryItem_url, liz, isFolder,) ) #xbmcplugin.addDirectoryItem(handle=pluginhandle,url=DirectoryItem_url,listitem=liz,isFolder=isFolder) else: #this section are for comments that have no links if not ShowOnlyCommentsWithlink: result=h[3].replace('](', '] (') result=markdown_to_bbcode(result) liz=xbmcgui.ListItem(label=list_title + desc100) liz.setInfo( type="Video", infoLabels={ "Title": h[1], "plot": result, "studio": domain, "votes": str(h[0]), "director": author } ) liz.setProperty('IsPlayable', 'false') directory_items.append( ("", liz, False,) ) #xbmcplugin.addDirectoryItem(handle=pluginhandle,url="",listitem=liz,isFolder=False) #END section are for comments that have no links or unsupported links except Exception as e: log(' EXCEPTION:' + str(e) ) #for di in directory_items: # log( str(di) ) loading_indicator.tick(1, desc100) loading_indicator.end() #log(' comments_view id=%s' %comments_viewMode) #xbmcplugin.setContent(pluginhandle, "mixed") #in estuary, mixed have limited view id's available. it has widelist which is nice for comments but we'll just stick with 'movies' xbmcplugin.setContent(pluginhandle, "episodes") #files, songs, artists, albums, movies, tvshows, episodes, musicvideos xbmcplugin.setPluginCategory(pluginhandle,'Comments') xbmcplugin.addDirectoryItems(handle=pluginhandle, items=directory_items ) xbmcplugin.endOfDirectory(pluginhandle) if comments_viewMode: xbmc.executebuiltin('Container.SetViewMode(%s)' %comments_viewMode)
def autoPlay(url, name, type_): from domains import sitesBase, parse_reddit_link, ydtl_get_playable_url from utils import unescape, post_is_filtered_out, strip_emoji,xbmc_busy, translation, xbmc_notify from reddit import reddit_request, determine_if_video_media_from_reddit_json from actions import setting_gif_repeat_count #collect a list of title and urls as entries[] from the j_entries obtained from reddit #then create a playlist from those entries #then play the playlist gif_repeat_count=setting_gif_repeat_count() entries = [] watchdog_counter=0 playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) playlist.clear() xbmc_busy() content = reddit_request(url) if not content: return #log( str(content) ) #content = json.loads(content.replace('\\"', '\'')) content = json.loads(content) log("Autoplay %s - Parsing %d items" %( type_, len(content['data']['children']) ) ) for j_entry in content['data']['children']: try: title=unescape(j_entry['data']['title'].encode('utf-8')) title=strip_emoji(title) try: media_url = j_entry['data']['url'] except (AttributeError,TypeError,ValueError): media_url = j_entry['data']['media']['oembed']['url'] is_a_video = determine_if_video_media_from_reddit_json(j_entry) log(" %cTITLE:%s" %( ("v" if is_a_video else " "), title ) ) ld=parse_reddit_link(link_url=media_url, assume_is_video=False, needs_preview=False, get_playable_url=True ) if ld: log(' type:%s %s' %( ld.media_type, ld.link_action) ) if ld.media_type in [sitesBase.TYPE_VIDEO, sitesBase.TYPE_GIF, sitesBase.TYPE_VIDS, sitesBase.TYPE_MIXED]: if ld.media_type==sitesBase.TYPE_GIF: entries.append([title,ld.playable_url, sitesBase.DI_ACTION_PLAYABLE]) for _ in range( 0, gif_repeat_count ): entries.append([title,ld.playable_url, sitesBase.DI_ACTION_PLAYABLE]) else: entries.append([title,ld.playable_url, ld.link_action]) else: #log(' checking if ytdl supports %s' %media_url ) playable_video_url=ydtl_get_playable_url(media_url) if playable_video_url: for u in playable_video_url: entries.append([title, u, sitesBase.DI_ACTION_PLAYABLE]) except Exception as e: log( ' autoPlay exception:' + str(e) ) #for i,e in enumerate(entries): log(' e1-%d %s:' %(i, e[1]) ) #def k2(x): return x[1] #entries=remove_duplicates(entries, k2) #***disable removal of duplicates because it will also remove looping for gif videos #for i,e in enumerate(entries): log(' e2-%d %s:' %(i, e[1]) ) for i,e in enumerate(entries): try: log(' possible playable items(%.2d) %s...%s (%s)' %(i, e[0].ljust(15)[:15], e[1],e[2]) ) except: continue if len(entries)==0: xbmc_notify(translation(32025), translation(32026)) #Play All No playable items xbmc_busy(False) return entries_to_buffer=4 #log(' entries:%d buffer:%d' %( len(entries), entries_to_buffer ) ) if len(entries) < entries_to_buffer: entries_to_buffer=len(entries) #log('entries to buffer reduced to %d' %entries_to_buffer ) #for title, url in entries: # log(" added to playlist:"+ title + " " + url ) log("**********autoPlay*************") #play_list=[] ev = threading.Event() t = Worker(entries, q, ev) t.daemon = True t.start() #t.run() #wait for worker to finish processing 1st item #e.wait(200) while True: #log( ' c-wait+get buffer(%d) wdt=%d ' %(playlist.size(), watchdog_counter) ) try: #playable_url = q.get(True, 10) playable_entry = q.get(True, 10) #playable_url=playable_entry[1] q.task_done() #play_list.append(playable_entry[1]) playlist.add(playable_entry[1], xbmcgui.ListItem(playable_entry[0])) log( ' c-buffered(%d):%s...%s' %(playlist.size(), playable_entry[0].ljust(15)[:15], playable_entry[1]) ) except: watchdog_counter+=1 if ev.is_set():#p is done producing break #if got 3 empty from queue. pass watchdog_counter+=1 #log(' playlist:%d buffer:%d' %( playlist.size(), entries_to_buffer ) ) if playlist.size() >= entries_to_buffer: #q.qsize() log(' c-buffer count met') break if watchdog_counter > entries_to_buffer: break log(' c-buffering done') xbmc_busy(False) xbmc.Player().play(playlist) watchdog_counter=0 while True: #log( ' c-get buffer(%d) wdt=%d ' %(playlist.size(), watchdog_counter) ) #q.join() #log( ' c- join-ed, get... ' ) try: #playable_url = q.get(True,10) playable_entry = q.get(True,10) q.task_done() #log( ' c- got next item... ' + playable_entry[1] ) #play_list.append(playable_entry[1]) playlist.add(playable_entry[1], xbmcgui.ListItem(playable_entry[0])) log( ' c-got next item(%d):%s...%s' %(playlist.size(), playable_entry[0].ljust(15)[:15], playable_entry[1]) ) except: watchdog_counter+=1 if ev.isSet(): #p is done producing break pass #xbmc.PlayList(1).add(playable_url) if ev.isSet() and q.empty(): log( ' c- ev is set and q.empty --> break ' ) break if watchdog_counter > 2: break log( ' c-all done ' )
def autoPlay(url, name, autoPlay_type): import random from domains import sitesBase, parse_reddit_link, build_DirectoryItem_url_based_on_media_type from utils import unescape, post_is_filtered_out, log, clean_str from actions import setting_gif_repeat_count from reddit import reddit_request, determine_if_video_media_from_reddit_json gif_repeat_count = setting_gif_repeat_count() entries = [] playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) playlist.clear() log("**********autoPlay %s*************" % autoPlay_type) content = reddit_request(url) if not content: return content = json.loads(content.replace('\\"', '\'')) log("Autoplay %s - Parsing %d items" % (autoPlay_type, len(content['data']['children']))) for j_entry in content['data']['children']: try: if post_is_filtered_out(j_entry): continue title = clean_str(j_entry, ['data', 'title']) try: media_url = j_entry['data']['url'] except: media_url = j_entry['data']['media']['oembed']['url'] is_a_video = determine_if_video_media_from_reddit_json(j_entry) ld = parse_reddit_link(link_url=media_url, assume_is_video=is_a_video, needs_preview=False, get_playable_url=True) DirectoryItem_url, setProperty_IsPlayable, isFolder, title_prefix = build_DirectoryItem_url_based_on_media_type( ld, media_url, title, on_autoplay=True) if ld: if ld.media_type not in [ sitesBase.TYPE_VIDEO, sitesBase.TYPE_GIF, sitesBase.TYPE_VIDS, sitesBase.TYPE_MIXED ]: continue autoPlay_type_entries_append(entries, autoPlay_type, title, DirectoryItem_url) if ld.media_type == sitesBase.TYPE_GIF: for _ in range(0, gif_repeat_count): autoPlay_type_entries_append(entries, autoPlay_type, title, DirectoryItem_url) except Exception as e: log(" EXCEPTION Autoplay " + str(sys.exc_info()[0]) + " " + str(e)) if autoplayRandomize: random.shuffle(entries) for title, url in entries: listitem = xbmcgui.ListItem(title) playlist.add(url, listitem) log('add to playlist: %s %s' % (title.ljust(25)[:25], url)) xbmc.Player().play(playlist)
def addLink(title, title_line2, iconimage, previewimage, preview_w, preview_h, domain, description, credate, reddit_says_is_video, commentsUrl, subreddit, media_url, over_18, posted_by="", num_comments=0, post_index=1, post_id=''): from domains import parse_reddit_link, build_DirectoryItem_url_based_on_media_type post_title = title il_description = "" n = "" #will hold red nsfw asterisk string isFolder = True thumb_url = '' h = "[B]" + domain + "[/B]: " if over_18: mpaa = "R" n = "[COLOR red]*[/COLOR] " #description = "[B]" + hoster + "[/B]:[COLOR red][NSFW][/COLOR] "+title+"\n" + description il_description = "[COLOR red][NSFW][/COLOR] " + h + title + "[CR]" + "[COLOR grey]" + description + "[/COLOR]" else: mpaa = "" n = "" il_description = h + title + "[CR]" + "[COLOR grey]" + description + "[/COLOR]" if TitleAddtlInfo: #put the additional info on the description if setting set to single line titles #log( repr(title_line2 )) post_title = n + title + "[CR][LIGHT]" + title_line2 + '[/LIGHT]' else: post_title = n + title il_description = title_line2 + "[CR]" + il_description il = { "title": post_title, "plot": il_description, "plotoutline": il_description, "Aired": credate, "mpaa": mpaa, "Genre": "r/" + subreddit, "studio": domain, "director": posted_by } #, "duration": 1271} (duration uses seconds for titan skin liz = xbmcgui.ListItem(label=post_title) #this is a video plugin, set type to video so that infolabels show up. liz.setInfo(type='video', infoLabels=il) if iconimage in ["", "nsfw", "default"]: #log( title+ ' iconimage blank['+iconimage+']['+thumb_url+ ']media_url:'+media_url ) iconimage = thumb_url preview_ar = 0.0 if (preview_w == 0 or preview_h == 0) != True: preview_ar = float(preview_w) / preview_h #log("preview ar: "+ repr(preview_ar)) if previewimage: needs_preview = False else: if iconimage: #some sites ban us if we send too many requests asking for preview image(meta og image) needs_preview = False previewimage = iconimage else: needs_preview = True #reddit has no thumbnail for this link. please get one #DirectoryItem_url=sys.argv[0]+"?url="+ urllib.quote_plus(media_url) +"&mode=play" if DoNotResolveLinks: ld = None DirectoryItem_url=sys.argv[0]\ +"?url="+ urllib.quote_plus(media_url) \ +"&name="+urllib.quote_plus(title) \ +"&mode=play" setProperty_IsPlayable = 'true' isFolder = False title_prefix = '' else: ld = parse_reddit_link(media_url, reddit_says_is_video, needs_preview, False, preview_ar) if needs_preview and ld: queried_preview_image = next( (i for i in [ld.poster, ld.thumb] if i), '') previewimage = queried_preview_image iconimage = ld.thumb arg_name = title arg_type = previewimage #if ld: #log(' ' + ld.media_type + ' -> ' + ld.link_action ) #log(' ***icon:' + ld.thumb + ' -> ' + ld.link_action ) #log(' ***poster:' + ld.poster + ' ' ) #if iconimage in ["","nsfw", "default"]: iconimage=ld.thumb DirectoryItem_url, setProperty_IsPlayable, isFolder, title_prefix = build_DirectoryItem_url_based_on_media_type( ld, media_url, arg_name, arg_type, script_to_call="", on_autoplay=False, img_w=preview_w, img_h=preview_h) if title_prefix: liz.setLabel(title_prefix + ' ' + post_title) liz.setProperty('IsPlayable', setProperty_IsPlayable) liz.setInfo('video', { "title": liz.getLabel(), }) liz.setContentLookup(False) liz.setArt({ "thumb": iconimage, "poster": previewimage, "banner": iconimage, "fanart": previewimage, "landscape": previewimage, }) entries = build_context_menu_entries( num_comments, commentsUrl, subreddit, domain, media_url, post_id) #entries for listbox for when you type 'c' or rt-click liz.addContextMenuItems(entries) #liz.setProperty('isFolder', isFolder) #liz.setPath(DirectoryItem_url) #log( 'playcount=' + repr(getPlayCount(DirectoryItem_url))) #log( 'DirectoryItem_url=' + DirectoryItem_url) #xbmcplugin.addDirectoryItem(pluginhandle, DirectoryItem_url, listitem=liz, isFolder=isFolder, totalItems=post_total) return (DirectoryItem_url, liz, isFolder) #tuple for addDirectoryItems
def autoPlay(url, name, type_): from domains import sitesBase, parse_reddit_link, ydtl_get_playable_url from utils import unescape, post_is_filtered_out, strip_emoji, xbmc_busy, log, translation from reddit import reddit_request, determine_if_video_media_from_reddit_json from actions import setting_gif_repeat_count #collect a list of title and urls as entries[] from the j_entries obtained from reddit #then create a playlist from those entries #then play the playlist gif_repeat_count = setting_gif_repeat_count() entries = [] watchdog_counter = 0 playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) playlist.clear() xbmc_busy() content = reddit_request(url) if not content: return #log( str(content) ) #content = json.loads(content.replace('\\"', '\'')) content = json.loads(content) log("Autoplay %s - Parsing %d items" % (type_, len(content['data']['children']))) for j_entry in content['data']['children']: try: title = unescape(j_entry['data']['title'].encode('utf-8')) title = strip_emoji(title) try: media_url = j_entry['data']['url'] except (AttributeError, TypeError, ValueError): media_url = j_entry['data']['media']['oembed']['url'] is_a_video = determine_if_video_media_from_reddit_json(j_entry) log(" %cTITLE:%s" % (("v" if is_a_video else " "), title)) ld = parse_reddit_link(link_url=media_url, assume_is_video=False, needs_preview=False, get_playable_url=True) if ld: log(' type:%s %s' % (ld.media_type, ld.link_action)) if ld.media_type in [ sitesBase.TYPE_VIDEO, sitesBase.TYPE_GIF, sitesBase.TYPE_VIDS, sitesBase.TYPE_MIXED ]: if ld.media_type == sitesBase.TYPE_GIF: entries.append([ title, ld.playable_url, sitesBase.DI_ACTION_PLAYABLE ]) for _ in range(0, gif_repeat_count): entries.append([ title, ld.playable_url, sitesBase.DI_ACTION_PLAYABLE ]) else: entries.append( [title, ld.playable_url, ld.link_action]) else: #log(' checking if ytdl supports %s' %media_url ) playable_video_url = ydtl_get_playable_url(media_url) if playable_video_url: for u in playable_video_url: entries.append( [title, u, sitesBase.DI_ACTION_PLAYABLE]) except Exception as e: log(' autoPlay exception:' + str(e)) #for i,e in enumerate(entries): log(' e1-%d %s:' %(i, e[1]) ) #def k2(x): return x[1] #entries=remove_duplicates(entries, k2) #***disable removal of duplicates because it will also remove looping for gif videos #for i,e in enumerate(entries): log(' e2-%d %s:' %(i, e[1]) ) for i, e in enumerate(entries): try: log(' possible playable items(%.2d) %s...%s (%s)' % (i, e[0].ljust(15)[:15], e[1], e[2])) except: continue if len(entries) == 0: log(' Play All: no playable items') xbmc.executebuiltin( 'XBMC.Notification("%s","%s")' % (translation(32054), translation(32055))) #Play All No playable items return entries_to_buffer = 4 #log(' entries:%d buffer:%d' %( len(entries), entries_to_buffer ) ) if len(entries) < entries_to_buffer: entries_to_buffer = len(entries) #log('entries to buffer reduced to %d' %entries_to_buffer ) #for title, url in entries: # log(" added to playlist:"+ title + " " + url ) log("**********autoPlay*************") #play_list=[] ev = threading.Event() t = Worker(entries, q, ev) t.daemon = True t.start() #t.run() #wait for worker to finish processing 1st item #e.wait(200) while True: #log( ' c-wait+get buffer(%d) wdt=%d ' %(playlist.size(), watchdog_counter) ) try: #playable_url = q.get(True, 10) playable_entry = q.get(True, 10) #playable_url=playable_entry[1] q.task_done() #play_list.append(playable_entry[1]) playlist.add(playable_entry[1], xbmcgui.ListItem(playable_entry[0])) log(' c-buffered(%d):%s...%s' % (playlist.size(), playable_entry[0].ljust(15)[:15], playable_entry[1])) except: watchdog_counter += 1 if ev.is_set(): #p is done producing break #if got 3 empty from queue. pass watchdog_counter += 1 #log(' playlist:%d buffer:%d' %( playlist.size(), entries_to_buffer ) ) if playlist.size() >= entries_to_buffer: #q.qsize() log(' c-buffer count met') break if watchdog_counter > entries_to_buffer: break log(' c-buffering done') #xbmc_busy(False) xbmc.Player().play(playlist) watchdog_counter = 0 while True: #log( ' c-get buffer(%d) wdt=%d ' %(playlist.size(), watchdog_counter) ) #q.join() #log( ' c- join-ed, get... ' ) try: #playable_url = q.get(True,10) playable_entry = q.get(True, 10) q.task_done() #log( ' c- got next item... ' + playable_entry[1] ) #play_list.append(playable_entry[1]) playlist.add(playable_entry[1], xbmcgui.ListItem(playable_entry[0])) log(' c-got next item(%d):%s...%s' % (playlist.size(), playable_entry[0].ljust(15)[:15], playable_entry[1])) except: watchdog_counter += 1 if ev.isSet(): #p is done producing break pass #xbmc.PlayList(1).add(playable_url) if ev.isSet() and q.empty(): log(' c- ev is set and q.empty --> break ') break if watchdog_counter > 2: break log(' c-all done ')
def display_album_from(dictlist, album_name): from domains import parse_reddit_link, build_DirectoryItem_url_based_on_media_type, sitesBase from utils import build_script directory_items=[] album_viewMode=addon.getSetting("album_viewMode") if album_viewMode=='450': #using custom gui using_custom_gui=True else: using_custom_gui=False for _, d in enumerate(dictlist): ti=d['li_thumbnailImage'] media_url=d.get('DirectoryItem_url') combined = d['infoLabels'].get('plot') if d['infoLabels'].get('plot') else "" d['infoLabels']['plot'] = combined liz=xbmcgui.ListItem(label=d.get('li_label'), label2=d.get('li_label2') ) ld=parse_reddit_link(media_url) DirectoryItem_url, setProperty_IsPlayable, isFolder, _ = build_DirectoryItem_url_based_on_media_type(ld, media_url, '', '', script_to_call="") if using_custom_gui: url_for_DirectoryItem=media_url liz.setProperty('onClick_action', DirectoryItem_url ) liz.setProperty('is_video','true') if ld.link_action == sitesBase.DI_ACTION_PLAYABLE: liz.setProperty('item_type','playable') else: liz.setProperty('item_type','script') else: liz.setProperty('IsPlayable',setProperty_IsPlayable) url_for_DirectoryItem=DirectoryItem_url liz.setInfo( type='video', infoLabels=d['infoLabels'] ) #this tricks the skin to show the plot. where we stored the picture descriptions liz.setArt({"thumb": ti,'icon': ti, "poster":media_url, "banner":media_url, "fanart":media_url, "landscape":media_url }) directory_items.append( (url_for_DirectoryItem, liz, isFolder) ) if using_custom_gui: from guis import cGUI li=[] for di in directory_items: li.append( di[1] ) ui = cGUI('view_450_slideshow.xml' , addon_path, defaultSkin='Default', defaultRes='1080i', listing=li, id=53) ui.include_parent_directory_entry=False ui.doModal() del ui else: if album_viewMode!='0': xbmc.executebuiltin('Container.SetViewMode('+album_viewMode+')') xbmcplugin.addDirectoryItems(handle=pluginhandle, items=directory_items ) xbmcplugin.endOfDirectory(pluginhandle)
def addLink(title, title_line2, iconimage, previewimage, preview_w, preview_h, domain, description, credate, reddit_says_is_video, commentsUrl, subreddit, link_url, over_18, posted_by="", num_comments=0, post_id=''): from utils import ret_info_type_icon, build_script, colored_subreddit #from reddit import assemble_reddit_filter_string from domains import parse_reddit_link, sitesBase preview_ar = 0.0 DirectoryItem_url = '' if over_18: mpaa = "R" title_line2 = "[COLOR red][NSFW][/COLOR] " + title_line2 else: mpaa = "" post_title = title if len(post_title) > 100 or description: il_description = '[B]%s[/B][CR][CR]%s' % (post_title, description) else: il_description = '' il = { "title": post_title, "plot": il_description, "Aired": credate, "mpaa": mpaa, "Genre": "r/" + subreddit, "studio": domain, "director": posted_by } #, "duration": 1271} (duration uses seconds for titan skin liz = xbmcgui.ListItem(label=post_title, label2=title_line2, path='') #path not used by gui. if preview_w == 0 or preview_h == 0: preview_ar = 0.0 else: preview_ar = float(preview_w) / preview_h log(' preview_ar:' + repr(preview_ar)) if preview_ar > 1.4: #this triggers whether the (control id 203) will show up #log(' ar and description criteria met') #the gui checks for this: String.IsEmpty(Container(55).ListItem.Property(preview_ar)) to show/hide preview and description liz.setProperty( 'preview_ar', str(preview_ar)) # -- $INFO[ListItem.property(preview_ar)] #text_below_image=il_description+title_line2 + colored_subreddit( posted_by, 'dimgrey',False ) text_below_image = '[B]%s[/B][CR]%s %s[CR]%s' % ( post_title, title_line2, colored_subreddit(' by ' + posted_by, 'dimgrey', False), description) liz.setInfo(type='video', infoLabels={ "plotoutline": text_below_image, }) #makes the gui use a control that allows the user scroll tall image if preview_ar < 0.3: liz.setProperty( 'very_tall_image', str(preview_ar) ) # -- IsEmpty(Container(55).ListItem.Property(very_tall_image)) elif preview_ar < 0.5: liz.setProperty( 'tall_image', str(preview_ar) ) # -- IsEmpty(Container(55).ListItem.Property(tall_image)) if num_comments > 0 or description: liz.setProperty('comments_action', build_script('listLinksInComment', commentsUrl)) liz.setProperty('link_url', link_url) liz.setInfo(type='video', infoLabels=il) #use clearart to indicate if link is video, album or image. here, we default to unsupported. clearart = ret_info_type_icon('', '') liz.setArt({"clearart": clearart}) #force all links to ytdl to see if they are playable liz.setProperty('item_type', 'script') liz.setProperty('onClick_action', build_script('playYTDLVideo', link_url, '', previewimage)) #***build context menu*** # convert a list of tuple into a string then set it as a property # in GUI, the string is converted back via ast.literal_eval() and put into listItems liz.setProperty( 'context_menu', str( build_context_menu_entries(num_comments, commentsUrl, subreddit, domain, link_url, post_id, post_title, posted_by))) if previewimage: needs_preview = False else: needs_preview = True #reddit has no thumbnail for this link. please get one ld = parse_reddit_link(link_url, reddit_says_is_video, needs_preview, False, preview_ar) if previewimage == "": if domain.startswith('self.'): liz.setArt({ "thumb": ld.thumb if ld else '', "banner": '', }) else: liz.setArt({ "thumb": iconimage, "banner": ld.poster if ld else '', }) else: liz.setArt({ "thumb": iconimage, "banner": previewimage, }) #log( ' reddit thumb[%s] ' %(iconimage )) #log( ' reddit preview[%s] ar=%f %dx%d' %(previewimage, preview_ar, preview_w,preview_h )) #if ld: log( ' new-thumb[%s] poster[%s] ' %( ld.thumb, ld.poster )) if ld: #use clearart to indicate the type of link(video, album, image etc.) clearart = ret_info_type_icon(ld.media_type, ld.link_action, domain) liz.setArt({"clearart": clearart}) if iconimage in ["", "nsfw", "default"]: iconimage = ld.thumb #we gathered a description from the link if ld.desctiption: liz.setInfo(type='video', infoLabels={ 'plot': il_description + '[CR]' + ld.desctiption, }) #link_action set in domains.py - parse_reddit_link if ld.link_action == sitesBase.DI_ACTION_PLAYABLE: property_link_type = ld.link_action DirectoryItem_url = ld.playable_url else: property_link_type = 'script' if ld.link_action == 'viewTallImage': #viewTallImage take different args DirectoryItem_url = build_script(mode=ld.link_action, url=ld.playable_url, name=str(preview_w), type_=str(preview_h)) else: #log( '****' + repr( ld.dictlist )) DirectoryItem_url = build_script(mode=ld.link_action, url=ld.playable_url, name=post_title, type_=previewimage) #log(' action %s--%s' %( ld.link_action, DirectoryItem_url) ) liz.setProperty('item_type', property_link_type) liz.setProperty('onClick_action', DirectoryItem_url) liz.setProperty('album_images', json.dumps(ld.dictlist)) # dictlist=json.loads(string) #log( liz.getProperty('album_images')) else: #unsupported type here: pass return liz
def autoSlideshow(url, name, type_): log('starting slideshow '+ url) ev=threading.Event() entries = [] preview_w=0 preview_h=0 image='' content = reddit_request(url) if not content: return content = json.loads(content) log("slideshow %s:Parsing %d items: %s" %( type_, len(content['data']['children']), 'random' if random_post_order else 'normal order' ) ) data_children = content['data']['children'] if random_post_order: random.shuffle(data_children) for j_entry in data_children: try: title = unescape(j_entry['data']['title'].encode('utf-8')) log(" TITLE:%s [r/%s]" %( title, j_entry.get('data').get('subreddit') ) ) try: description = unescape(j_entry['data']['media']['oembed']['description'].encode('utf-8')) except: description = '' try: post_selftext=unescape(j_entry['data']['selftext'].encode('utf-8')) except: post_selftext='' description=post_selftext+'[CR]'+description if post_selftext else description try: media_url = j_entry['data']['url'] except: media_url = j_entry['data']['media']['oembed']['url'] try: preview=j_entry['data']['preview']['images'][0]['source']['url'].encode('utf-8').replace('&','&') try: preview_h = float( j_entry['data']['preview']['images'][0]['source']['height'] ) preview_w = float( j_entry['data']['preview']['images'][0]['source']['width'] ) except: preview_w=0 preview_h=0 except Exception as e: preview="" ld=parse_reddit_link(link_url=media_url, assume_is_video=False, needs_preview=True, get_playable_url=True ) if ld: if not preview: preview = ld.poster if (addon.getSetting('include_albums')=='true') and (ld.media_type==sitesBase.TYPE_ALBUM) : dictlist = listAlbum( media_url, title, 'return_dictlist') for d in dictlist: t2=d.get('li_label') if d.get('li_label') else title d['li_label']=t2 entries.append( d ) else: if addon.getSetting('use_reddit_preview')=='true': if preview: image=preview elif ld.poster: image=ld.poster else: if ld.poster: image=ld.poster #entries.append([title,ld.poster,preview_w, preview_h,len(entries)]) elif preview: image=preview #entries.append([title,preview,preview_w, preview_h,len(entries)]) append_entry( entries, title,image,preview_w, preview_h, description ) else: append_entry( entries, title,preview,preview_w, preview_h, description ) except Exception as e: log( ' autoPlay exception:' + str(e) ) entries = remove_dict_duplicates( entries, 'DirectoryItem_url') for i, e in enumerate(entries): log(' possible playable items({0}) {1}...{2}x{3} {4}'.format( i, e['li_label'].ljust(15)[:15], repr(e.get('width')),repr(e.get('height')), e.get('DirectoryItem_url')) ) if len(entries)==0: log(' Play All: no playable items' ) xbmc.executebuiltin('XBMC.Notification("%s","%s")' %(translation(32054), translation(32055) ) ) #Play All No playable items return log("**********playing slideshow*************") for e in entries: q.put(e) s= ScreensaverManager(ev,q) try: s.start_loop() except Exception as e: log(" EXCEPTION slideshowAlbum:="+ str( sys.exc_info()[0]) + " " + str(e) ) return
def reddit_comment_worker(idx, h, q_out, submitter): from domains import parse_reddit_link, sitesBase from utils import format_description, ret_info_type_icon, build_script # h[0]=score, # h[1]=link_desc, # h[2]=link_http, # h[3]=post_text, # h[4]=post_html, # h[5]=d, # h[6]="t1", # h[7]=author, # h[8]=created_utc, try: #log(str(i)+" score:"+ str(h[0]).zfill(5)+" "+ h[1] +'|'+ h[3] ) comment_score = h[0] #log("score %d < %d (%s)" %(comment_score,int_CommentTreshold, CommentTreshold) ) link_url = h[2] desc100 = h[3].replace( '\n', ' ')[0:100] #first 100 characters of description kind = h[ 6] #reddit uses t1 for user comments and t3 for OP text of the post. like a poster describing the post. d = h[5] #depth of the comment tab = " " * d if d > 0 else "-" author = h[7] if link_url.startswith('/r/'): domain = 'subreddit' elif link_url.startswith('/u/'): domain = 'redditor' elif link_url.startswith( '#' ): #don't know what these are. they are to be replaced with image on reddit domain = link_url else: from urlparse import urlparse domain = '{uri.netloc}'.format(uri=urlparse(link_url)) #log( ' %s TITLE:%s... link[%s]' % ( str(comment_score).zfill(4), desc100.ljust(20)[:20],link_url ) ) if link_url: log(' comment %s TITLE:%s... link[%s]' % (str(d).zfill(3), desc100.ljust(20)[:20], link_url)) ld = parse_reddit_link(link_url=link_url, assume_is_video=False, needs_preview=True, get_playable_url=True) if author == submitter: #add a submitter tag author = "[COLOR cadetblue][B]%s[/B][/COLOR][S]" % author else: author = "[COLOR cadetblue]%s[/COLOR]" % author if kind == 't1': t_prepend = r"%s" % (tab) elif kind == 't3': t_prepend = r"[B]Post text:[/B]" plot = format_description(h[3]) liz = xbmcgui.ListItem(label=t_prepend + author + ': ' + desc100, label2="") liz.setInfo(type="Video", infoLabels={ "Title": h[1], "plot": plot, "studio": domain, "votes": str(comment_score), "director": author }) #force all links to ytdl to see if it can be played if link_url: #log(' there is a link from %s' %domain) if not ld: #log(' link is not supported ') liz.setProperty('item_type', 'script') liz.setProperty('onClick_action', build_script('playYTDLVideo', link_url)) plot = "[COLOR greenyellow][%s] %s" % ('?', plot) + "[/COLOR]" liz.setLabel(tab + plot) liz.setProperty( 'link_url', link_url) #just used as text at bottom of the screen clearart = ret_info_type_icon('', '') liz.setArt({"clearart": clearart}) if ld: #use clearart to indicate if link is video, album or image. here, we default to unsupported. #clearart=ret_info_type_icon(setInfo_type, mode_type) clearart = ret_info_type_icon(ld.media_type, ld.link_action, domain) liz.setArt({"clearart": clearart}) if ld.link_action == sitesBase.DI_ACTION_PLAYABLE: property_link_type = ld.link_action DirectoryItem_url = ld.playable_url else: property_link_type = 'script' DirectoryItem_url = build_script(mode=ld.link_action, url=ld.playable_url, name='', type_='') #(score, link_desc, link_http, post_text, post_html, d, ) #list_item_name=str(h[0]).zfill(3) #log(str(i)+" score:"+ str(h[0]).zfill(5)+" desc["+ h[1] +']|text:['+ h[3]+']' +link_url + ' videoID['+videoID+']' + 'playable:'+ setProperty_IsPlayable ) #log( h[4] + ' -- videoID['+videoID+']' ) #log("sss:"+ supportedPluginUrl ) #fl= re.compile('\[(.*?)\]\(.*?\)',re.IGNORECASE) #match '[...](...)' with a capture group inside the []'s as capturegroup1 #result = fl.sub(r"[B]\1[/B]", h[3]) #replace the match with [B] [/B] with capturegroup1 in the middle of the [B]'s #turn link green if DirectoryItem_url: plot = "[COLOR greenyellow][%s] %s" % (domain, plot) + "[/COLOR]" liz.setLabel(tab + plot) #liz.setArt({"thumb": thumb_url, "poster":thumb_url, "banner":thumb_url, "fanart":thumb_url, "landscape":thumb_url }) liz.setArt({"thumb": ld.poster}) liz.setProperty('item_type', property_link_type) #script or playable liz.setProperty( 'onClick_action', DirectoryItem_url) #<-- needed by the xml gui skin liz.setProperty( 'link_url', link_url) #just used as text at bottom of the screen #liz.setPath(DirectoryItem_url) #directory_items.append( (DirectoryItem_url, liz,) ) else: #this section are for comments that have no links or unsupported links #if not ShowOnlyCommentsWithlink: #directory_items.append( ("", liz, ) ) pass #END section are for comments that have no links or unsupported links q_out.put([idx, liz]) except Exception as e: log('EXCEPTION comments_worker' + str(e))
def listRelatedVideo(url, name, type_): #type_: 'channel' -other videos in the channel # 'related' -related videos #only youtube is supported for now from domains import ClassYoutube from domains import parse_reddit_link, build_DirectoryItem_url_based_on_media_type match = re.compile(ClassYoutube.regex, re.I).findall(url) if match: #log('***** isYouTubeable' + repr(link_url)) yt = ClassYoutube(url) links_dictList = yt.ret_album_list( type_) #returns a list of dict same as one used for albums if links_dictList: #log(pprint.pformat(links_dictList)) for _, d in enumerate(links_dictList): label = d.get('li_label') label2 = d.get('li_label2') #li_iconImage=d.get('li_iconImage') ti = d.get('li_thumbnailImage') media_url = d.get('DirectoryItem_url') #media_type=d.get('type') #media_thumb=d.get('thumb') #isPlayable=d.get('isPlayable') #link_action=d.get('link_action') #channel_id=d.get('channel_id') #video_id=d.get('video_id') liz = xbmcgui.ListItem(label, label2) liz.setInfo( type='video', infoLabels=d['infoLabels'] ) #this tricks the skin to show the plot. where we stored the descriptions liz.setArt({ "thumb": ti, 'icon': ti, "poster": ti, "banner": ti, "fanart": ti, "landscape": ti }) #a little overkill considering we're only matching for youtube ld = parse_reddit_link(media_url) DirectoryItem_url, setProperty_IsPlayable, isFolder, _ = build_DirectoryItem_url_based_on_media_type( ld, media_url, '', '', script_to_call="") #directory_items.append( (url_for_DirectoryItem, liz, False,) ) liz.setProperty('IsPlayable', setProperty_IsPlayable) xbmcplugin.addDirectoryItem(pluginhandle, DirectoryItem_url, liz, isFolder) xbmcplugin.endOfDirectory( handle=pluginhandle, succeeded=True, updateListing= False, #setting this to True causes the ".." entry to quit the plugin cacheToDisc=True) else: xbmc_notify('Nothing to list', url) else: xbmc_notify('cannot identify youtube url', url)
def listLinksInComment(url, name, type_): from domains import parse_reddit_link, build_DirectoryItem_url_based_on_media_type from utils import markdown_to_bbcode, unescape from guis import progressBG log('listLinksInComment:%s:%s' %(type_,url) ) directory_items=[] author="" ShowOnlyCommentsWithlink=False if type_=='linksOnly': ShowOnlyCommentsWithlink=True url=urllib.quote_plus(url,safe=':/?&') if '?' in url: url=url.split('?', 1)[0]+'.json?'+url.split('?', 1)[1] else: url+= '.json' loading_indicator=progressBG(translation(30024)) loading_indicator.update(0,'Retrieving comments') content = reddit_request(url) if not content: loading_indicator.end() return loading_indicator.update(10,'Parsing') content = json.loads(content) del harvest[:] r_linkHunter(content[0]['data']['children']) try:submitter=content[0]['data']['children'][0]['data']['author'] except: submitter='' try:post_title=content[0]['data']['children'][0]['data']['title'] except:post_title='' r_linkHunter(content[1]['data']['children']) comment_score=0 loading_indicator.set_tick_total(len(harvest)) for i, h in enumerate(harvest): try: comment_score=h[0] link_url=h[2] desc100=h[3].replace('\n',' ')[0:100] #first 100 characters of description kind=h[6] #reddit uses t1 for user comments and t3 for OP text of the post. like a poster describing the post. d=h[5] #depth of the comment tab=" "*d if d>0 else "-" from urlparse import urlparse domain = '{uri.netloc}'.format( uri=urlparse( link_url ) ) author=h[7] DirectoryItem_url='' if comment_score < int_CommentTreshold: continue ld=parse_reddit_link(link_url=link_url, assume_is_video=False, needs_preview=True, get_playable_url=True ) if kind=='t1': list_title=r"[COLOR cadetblue]%3d[/COLOR] %s" %( h[0], tab ) elif kind=='t3': list_title=r"[COLOR cadetblue]Title [/COLOR] %s" %( tab ) plot=h[3].replace('](', '] (') plot= markdown_to_bbcode(plot) plot=unescape(plot) #convert html entities e.g.:(') liz=xbmcgui.ListItem(label=list_title +': '+ desc100) liz.setInfo( type="Video", infoLabels={ "Title": h[1], "plot": plot, "studio": domain, "votes": str(comment_score), "director": author } ) isFolder=False if link_url: DirectoryItem_url, setProperty_IsPlayable, isFolder, title_prefix = build_DirectoryItem_url_based_on_media_type(ld, link_url) liz.setProperty('IsPlayable', setProperty_IsPlayable) liz.setProperty('url', DirectoryItem_url) #<-- needed by the xml gui skin liz.setPath(DirectoryItem_url) if domain: plot= " [COLOR greenyellow][%s] %s"%(domain, plot ) + "[/COLOR]" else: plot= " [COLOR greenyellow][%s]"%( plot ) + "[/COLOR]" liz.setLabel(list_title+plot) if ld: liz.setArt({"thumb": ld.poster, "poster":ld.poster, "banner":ld.poster, "fanart":ld.poster, "landscape":ld.poster }) if DirectoryItem_url: directory_items.append( (DirectoryItem_url, liz, isFolder,) ) else: if not ShowOnlyCommentsWithlink: result=h[3].replace('](', '] (') result=markdown_to_bbcode(result) liz=xbmcgui.ListItem(label=list_title + desc100) liz.setInfo( type="Video", infoLabels={ "Title": h[1], "plot": result, "studio": domain, "votes": str(h[0]), "director": author } ) liz.setProperty('IsPlayable', 'false') directory_items.append( ("", liz, False,) ) except Exception as e: log(' EXCEPTION:' + str(e) ) loading_indicator.tick(1, desc100) loading_indicator.end() xbmcplugin.setContent(pluginhandle, "movies") #files, songs, artists, albums, movies, tvshows, episodes, musicvideos xbmcplugin.setPluginCategory(pluginhandle,'Comments') xbmcplugin.addDirectoryItems(handle=pluginhandle, items=directory_items ) xbmcplugin.endOfDirectory(pluginhandle) if comments_viewMode: xbmc.executebuiltin('Container.SetViewMode(%s)' %comments_viewMode)
def addLink(title, title_line2, iconimage, previewimage,preview_w,preview_h,domain,description, credate, reddit_says_is_video, commentsUrl, subreddit, media_url, over_18, posted_by="", num_comments=0,post_index=1,post_id=''): from domains import parse_reddit_link, build_DirectoryItem_url_based_on_media_type post_title=title il_description="" n="" #will hold red nsfw asterisk string isFolder=True thumb_url='' h="[B]" + domain + "[/B]: " if over_18: mpaa="R" n = "[COLOR red]*[/COLOR] " #description = "[B]" + hoster + "[/B]:[COLOR red][NSFW][/COLOR] "+title+"\n" + description il_description = "[COLOR red][NSFW][/COLOR] "+ h+title+"[CR]" + "[COLOR grey]" + description + "[/COLOR]" else: mpaa="" n="" il_description = h+title+"[CR]" + "[COLOR grey]" + description + "[/COLOR]" if TitleAddtlInfo: #put the additional info on the description if setting set to single line titles #log( repr(title_line2 )) post_title=n+title+"[CR][LIGHT]"+title_line2+'[/LIGHT]' else: post_title=n+title il_description=title_line2+"[CR]"+il_description il={"title": post_title, "plot": il_description, "plotoutline": il_description, "Aired": credate, "mpaa": mpaa, "Genre": "r/"+subreddit, "studio": domain, "director": posted_by } #, "duration": 1271} (duration uses seconds for titan skin liz=xbmcgui.ListItem(label=post_title) #this is a video plugin, set type to video so that infolabels show up. liz.setInfo(type='video', infoLabels=il) if iconimage in ["","nsfw", "default"]: #log( title+ ' iconimage blank['+iconimage+']['+thumb_url+ ']media_url:'+media_url ) iconimage=thumb_url preview_ar=0.0 if (preview_w==0 or preview_h==0) != True: preview_ar=float(preview_w) / preview_h #log("preview ar: "+ repr(preview_ar)) if previewimage: needs_preview=False else: if iconimage: #some sites ban us if we send too many requests asking for preview image(meta og image) needs_preview=False previewimage=iconimage else: needs_preview=True #reddit has no thumbnail for this link. please get one #DirectoryItem_url=sys.argv[0]+"?url="+ urllib.quote_plus(media_url) +"&mode=play" if DoNotResolveLinks: ld=None DirectoryItem_url=sys.argv[0]\ +"?url="+ urllib.quote_plus(media_url) \ +"&name="+urllib.quote_plus(title) \ +"&mode=play" setProperty_IsPlayable='true' isFolder=False title_prefix='' else: ld=parse_reddit_link(media_url,reddit_says_is_video, needs_preview, False, preview_ar ) if needs_preview and ld: queried_preview_image= next((i for i in [ld.poster,ld.thumb] if i ), '') previewimage=queried_preview_image iconimage=ld.thumb arg_name=title arg_type=previewimage #if ld: #log(' ' + ld.media_type + ' -> ' + ld.link_action ) #log(' ***icon:' + ld.thumb + ' -> ' + ld.link_action ) #log(' ***poster:' + ld.poster + ' ' ) #if iconimage in ["","nsfw", "default"]: iconimage=ld.thumb DirectoryItem_url, setProperty_IsPlayable, isFolder, title_prefix = build_DirectoryItem_url_based_on_media_type(ld, media_url, arg_name, arg_type, script_to_call="", on_autoplay=False, img_w=preview_w, img_h=preview_h) if title_prefix: liz.setLabel( title_prefix+' '+post_title ) liz.setProperty('IsPlayable', setProperty_IsPlayable) liz.setInfo('video', {"title": liz.getLabel(), } ) liz.setContentLookup(False) liz.setArt({"thumb": iconimage, "poster":previewimage, "banner":iconimage, "fanart":previewimage, "landscape":previewimage, }) entries = build_context_menu_entries(num_comments, commentsUrl, subreddit, domain, media_url, post_id) #entries for listbox for when you type 'c' or rt-click liz.addContextMenuItems(entries) #liz.setProperty('isFolder', isFolder) #liz.setPath(DirectoryItem_url) #log( 'playcount=' + repr(getPlayCount(DirectoryItem_url))) #log( 'DirectoryItem_url=' + DirectoryItem_url) #xbmcplugin.addDirectoryItem(pluginhandle, DirectoryItem_url, listitem=liz, isFolder=isFolder, totalItems=post_total) return (DirectoryItem_url,liz,isFolder) #tuple for addDirectoryItems
def autoSlideshow(url, name, type_): log('starting slideshow '+ url) ev=threading.Event() entries = [] #watchdog_counter=0 preview_w=0 preview_h=0 image='' #content = opener.open(url).read() content = reddit_request(url) if not content: return #log( str(content) ) #content = json.loads(content.replace('\\"', '\'')) content = json.loads(content) log("slideshow %s:Parsing %d items: %s" %( type_, len(content['data']['children']), 'random' if random_post_order else 'normal order' ) ) data_children = content['data']['children'] if random_post_order: random.shuffle(data_children) for j_entry in data_children: try: title = unescape(j_entry['data']['title'].encode('utf-8')) log(" TITLE:%s [r/%s]" %( title, j_entry.get('data').get('subreddit') ) ) try: description = unescape(j_entry['data']['media']['oembed']['description'].encode('utf-8')) except: description = '' #log(' description [%s]' %description) try: post_selftext=unescape(j_entry['data']['selftext'].encode('utf-8')) except: post_selftext='' #log(' post_selftext[%s]' %post_selftext) description=post_selftext+'[CR]'+description if post_selftext else description try: media_url = j_entry['data']['url'] except: media_url = j_entry['data']['media']['oembed']['url'] try: preview=j_entry['data']['preview']['images'][0]['source']['url'].encode('utf-8').replace('&','&') try: preview_h = float( j_entry['data']['preview']['images'][0]['source']['height'] ) preview_w = float( j_entry['data']['preview']['images'][0]['source']['width'] ) except: preview_w=0 preview_h=0 except Exception as e: #log(" getting preview image EXCEPTION:="+ str( sys.exc_info()[0]) + " " + str(e) ) preview="" ld=parse_reddit_link(link_url=media_url, assume_is_video=False, needs_preview=True, get_playable_url=True ) if ld: if not preview: preview = ld.poster if (addon.getSetting('include_albums')=='true') and (ld.media_type==sitesBase.TYPE_ALBUM) : dictlist = listAlbum( media_url, title, 'return_dictlist') for d in dictlist: #log(' (S) adding items from album ' + title +' ' + d.get('DirectoryItem_url') ) t2=d.get('li_label') if d.get('li_label') else title #entries.append([ t2, d.get('DirectoryItem_url'), d.get('width'), d.get('height'), len(entries)]) d['li_label']=t2 entries.append( d ) #title='' #only put the title in once. else: if addon.getSetting('use_reddit_preview')=='true': if preview: image=preview elif ld.poster: image=ld.poster #if preview: entries.append([title,preview,preview_w, preview_h,len(entries)]) #log(' (N)added preview:%s %s' %( title,preview) ) #elif ld.poster: entries.append([title,ld.poster,preview_w, preview_h,len(entries)]) #log(' (N)added poster:%s %s' % ( title,ld.poster) ) else: if ld.poster: image=ld.poster #entries.append([title,ld.poster,preview_w, preview_h,len(entries)]) elif preview: image=preview #entries.append([title,preview,preview_w, preview_h,len(entries)]) #if ld.poster: entries.append([title,ld.poster,preview_w, preview_h,len(entries)]) #elif preview: entries.append([title,preview,preview_w, preview_h,len(entries)]) append_entry( entries, title,image,preview_w, preview_h, description ) else: append_entry( entries, title,preview,preview_w, preview_h, description ) #log(' (N)added preview:%s' % title ) except Exception as e: log( ' autoPlay exception:' + str(e) ) #log( repr(entries)) entries = remove_dict_duplicates( entries, 'DirectoryItem_url') # #for i,e in enumerate(entries): log(' e1-%d %s' %(i, e[1]) ) # def k2(x): return x[1] # entries=remove_duplicates(entries, k2) # #for i,e in enumerate(entries): log(' e2-%d %s' %(i, e[1]) ) for i, e in enumerate(entries): log(' possible playable items({0}) {1}...{2}x{3} {4}'.format( i, e['li_label'].ljust(15)[:15], repr(e.get('width')),repr(e.get('height')), e.get('DirectoryItem_url')) ) if len(entries)==0: log(' Play All: no playable items' ) xbmc.executebuiltin('XBMC.Notification("%s","%s")' %(translation(32054), translation(32055) ) ) #Play All No playable items return #if type.endswith("_RANDOM"): # random.shuffle(entries) #for title, url in entries: # log(" added to playlist:"+ title + " " + url ) log("**********playing slideshow*************") for e in entries: q.put(e) #s= HorizontalSlideScreensaver(ev,q) s= ScreensaverManager(ev,q) try: s.start_loop() except Exception as e: log(" EXCEPTION slideshowAlbum:="+ str( sys.exc_info()[0]) + " " + str(e) ) return
def listRecentlyPlayed(url,name,type_): from utils import db_getLastPlayedVideos,build_script,ret_info_type_icon,truncate_middle,pretty_datediff_wrap from domains import parse_reddit_link,sitesBase from ContextMenus import build_youtube_context_menu_entries,build_reddit_search_context_menu_entries recently_played_links=db_getLastPlayedVideos() directory_items=[] for idx, recently_played_tuple in enumerate(recently_played_links): #log(repr(recently_played_tuple)) last_played, recently_played_url=recently_played_tuple pretty_date=pretty_datediff_wrap(last_played,use_utc_as_base=False) #log("---{0} {1}".format(pretty_date, last_played ) ) parsed_web_url=parse_web_url_from(recently_played_url) #grabs the (youtube) url from plugin://plugin.video... #log('recent{0}:{1}'.format(idx, recently_played_url)) if not parsed_web_url: log(' listRecentlyPlayed skipping:{0}'.format(recently_played_url)) continue link_components=urlparse.urlparse( parsed_web_url ) domain=link_components.netloc label=parsed_web_url #recently_played_url.split("|", 1)[0] #remove |Useragent:... liz=xbmcgui.ListItem(label=truncate_middle(label, 110), label2=pretty_date ) liz.setInfo( type="Video", infoLabels={ "Title": parsed_web_url, "plot": recently_played_url, "studio": domain } ) ld=parse_reddit_link(link_url=parsed_web_url, assume_is_video=True, needs_preview=False ) if ld: #use clearart to indicate if link is video, album or image. here, we default to unsupported. #clearart=ret_info_type_icon(setInfo_type, mode_type) clearart=ret_info_type_icon(ld.media_type, ld.link_action, domain ) liz.setArt({ "clearart": clearart }) if ld.link_action == sitesBase.DI_ACTION_PLAYABLE: property_link_type=ld.link_action DirectoryItem_url =ld.playable_url else: property_link_type='script' DirectoryItem_url = build_script(mode=ld.link_action, url=ld.playable_url, name='' , type_='' ) if DirectoryItem_url: #log(DirectoryItem_url) liz.setArt({"thumb": ld.thumb,"banner":ld.poster }) liz.setProperty('item_type',property_link_type) #script or playable liz.setProperty('onClick_action', DirectoryItem_url) #<-- needed by the xml gui skin liz.setProperty('link_url', recently_played_url ) #just used as text at bottom of the screen #liz.setPath(DirectoryItem_url) context_menu_list=[] context_menu_list.extend(build_youtube_context_menu_entries(previous_listing_was_of_type='',youtube_url=parsed_web_url,video_id=None)) context_menu_list.extend(build_reddit_search_context_menu_entries(False,'',parsed_web_url) ) #context_menu_list.extend(build_reddit_context_menu_entries(link_url)) liz.setProperty('context_menu', str(context_menu_list) ) #directory_items.append( (DirectoryItem_url, liz,) ) else: log("*************not ld*****************") directory_items.append( liz ) #from guis import text_to_links_gui #ui = text_to_links_gui('srr_links_in_text.xml' , addon_path, defaultSkin='Default', defaultRes='1080i', listing=directory_items, title='Recently Played', poster=None) from guis import cGUI ui = cGUI('srr_history_list.xml' , addon_path, defaultSkin='Default', defaultRes='1080i', listing=directory_items, id=55, title='Recently Played') ui.include_parent_directory_entry=False ui.doModal() del ui
def display_album_from(dictlist, album_name): from domains import parse_reddit_link, build_DirectoryItem_url_based_on_media_type, sitesBase from utils import build_script directory_items=[] album_viewMode=addon.getSetting("album_viewMode") if album_viewMode=='450': #using custom gui using_custom_gui=True else: using_custom_gui=False #log( repr(dictlist)) for _, d in enumerate(dictlist): ti=d['li_thumbnailImage'] media_url=d.get('DirectoryItem_url') #log(' display_album_from list:'+ media_url + " " ) #There is only 1 textbox for Title and description in our custom gui. # I don't know how to achieve this in the xml file so it is done here: # combine title and description without [CR] if label is empty. [B]$INFO[Container(53).ListItem.Label][/B][CR]$INFO[Container(53).ListItem.Plot] # new note: this is how it is done: # $INFO[Container(53).ListItem.Label,[B],[/B][CR]] $INFO[Container(53).ListItem.Plot] #if the infolabel is empty, nothing is printed for that block #combined = '[B]'+ d['li_label2'] + "[/B][CR]" if d['li_label2'] else "" combined = d['infoLabels'].get('plot') if d['infoLabels'].get('plot') else "" d['infoLabels']['plot'] = combined liz=xbmcgui.ListItem(label=d.get('li_label'), label2=d.get('li_label2') ) #parse the link so that we can determine whether it is image or video. ld=parse_reddit_link(media_url) DirectoryItem_url, setProperty_IsPlayable, isFolder, _ = build_DirectoryItem_url_based_on_media_type(ld, media_url, '', '', script_to_call="") #log('isFolder:' + repr(isFolder)+ ' IsPlayable:'+repr(setProperty_IsPlayable) + ' DirectoryItem_url:' + repr(DirectoryItem_url)) if using_custom_gui: url_for_DirectoryItem=media_url liz.setProperty('onClick_action', DirectoryItem_url ) liz.setProperty('is_video','true') #if setProperty_IsPlayable=='true': if ld: if ld.link_action == sitesBase.DI_ACTION_PLAYABLE: liz.setProperty('item_type','playable') else: #this part is for playing video that needs to be resolved first. (youtube_dl) #I could not get this to work --> #Attempt to use invalid handle -1 #I think you can't setresolvedUrl a listitem from a custom gui #url_for_DirectoryItem=DirectoryItem_url liz.setProperty('item_type','script') else: #sys.argv[0]+"?url="+ urllib.quote_plus(d['DirectoryItem_url']) +"&mode=viewImage" #with xbmc's standard gui, we need to specify to call the plugin to open the gui that shows image #log('***'+'isFolder:' + repr(isFolder)+ ' IsPlayable:'+repr(setProperty_IsPlayable) +'**[diu]:'+ DirectoryItem_url) liz.setProperty('IsPlayable',setProperty_IsPlayable) url_for_DirectoryItem=DirectoryItem_url liz.setInfo( type='video', infoLabels=d['infoLabels'] ) #this tricks the skin to show the plot. where we stored the picture descriptions liz.setArt({"thumb": ti,'icon': ti, "poster":media_url, "banner":media_url, "fanart":media_url, "landscape":media_url }) directory_items.append( (url_for_DirectoryItem, liz, isFolder) ) if using_custom_gui: from guis import cGUI li=[] for di in directory_items: li.append( di[1] ) ui = cGUI('view_450_slideshow.xml' , addon_path, defaultSkin='Default', defaultRes='1080i', listing=li, id=53) ui.include_parent_directory_entry=False ui.doModal() del ui else: if album_viewMode!='0': xbmc.executebuiltin('Container.SetViewMode('+album_viewMode+')') xbmcplugin.addDirectoryItems(handle=pluginhandle, items=directory_items ) xbmcplugin.endOfDirectory(pluginhandle)
def autoPlay(url, name, autoPlay_type): import random from domains import sitesBase, parse_reddit_link, build_DirectoryItem_url_based_on_media_type from utils import unescape, post_is_filtered_out, log, clean_str from actions import setting_gif_repeat_count from reddit import reddit_request, determine_if_video_media_from_reddit_json #collect a list of title and urls as entries[] from the j_entries obtained from reddit #then create a playlist from those entries #then play the playlist gif_repeat_count=setting_gif_repeat_count() entries = [] playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) playlist.clear() log("**********autoPlay %s*************" %autoPlay_type) content = reddit_request(url) if not content: return content = json.loads(content.replace('\\"', '\'')) log("Autoplay %s - Parsing %d items" %( autoPlay_type, len(content['data']['children']) ) ) for j_entry in content['data']['children']: try: if post_is_filtered_out( j_entry ): continue title = clean_str(j_entry, ['data','title']) try: media_url = j_entry['data']['url'] except: media_url = j_entry['data']['media']['oembed']['url'] is_a_video = determine_if_video_media_from_reddit_json(j_entry) #log(" Title:%s -%c %s" %( title, ("v" if is_a_video else " "), media_url ) ) #hoster, DirectoryItem_url, videoID, mode_type, thumb_url,poster_url, isFolder,setInfo_type, IsPlayable=make_addon_url_from(media_url,is_a_video) ld=parse_reddit_link(link_url=media_url, assume_is_video=is_a_video, needs_preview=False, get_playable_url=True ) DirectoryItem_url, setProperty_IsPlayable, isFolder, title_prefix = build_DirectoryItem_url_based_on_media_type(ld, media_url, title, on_autoplay=True) if ld: if ld.media_type not in [sitesBase.TYPE_VIDEO, sitesBase.TYPE_GIF, sitesBase.TYPE_VIDS, sitesBase.TYPE_MIXED]: continue autoPlay_type_entries_append( entries, autoPlay_type, title, DirectoryItem_url) if ld.media_type == sitesBase.TYPE_GIF: for _ in range( 0, gif_repeat_count ): autoPlay_type_entries_append( entries, autoPlay_type, title, DirectoryItem_url) except Exception as e: log(" EXCEPTION Autoplay "+ str( sys.exc_info()[0]) + " " + str(e) ) #def k2(x): return x[1] #entries=remove_duplicates(entries, k2) if autoplayRandomize: random.shuffle(entries) #for title, url in entries: # log(" added to playlist:"+ title + " " + urllib.unquote_plus(url) ) for title, url in entries: listitem = xbmcgui.ListItem(title) playlist.add(url, listitem) log('add to playlist: %s %s' %(title.ljust(25)[:25],url )) xbmc.Player().play(playlist)
def autoPlay(url, name, autoPlay_type): import random from domains import sitesBase, parse_reddit_link, build_DirectoryItem_url_based_on_media_type from utils import unescape, post_is_filtered_out, log, clean_str from actions import setting_gif_repeat_count from reddit import reddit_request, determine_if_video_media_from_reddit_json #collect a list of title and urls as entries[] from the j_entries obtained from reddit #then create a playlist from those entries #then play the playlist gif_repeat_count = setting_gif_repeat_count() entries = [] playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) playlist.clear() log("**********autoPlay %s*************" % autoPlay_type) content = reddit_request(url) if not content: return content = json.loads(content.replace('\\"', '\'')) log("Autoplay %s - Parsing %d items" % (autoPlay_type, len(content['data']['children']))) for j_entry in content['data']['children']: try: if post_is_filtered_out(j_entry): continue title = clean_str(j_entry, ['data', 'title']) try: media_url = j_entry['data']['url'] except: media_url = j_entry['data']['media']['oembed']['url'] is_a_video = determine_if_video_media_from_reddit_json(j_entry) #log(" Title:%s -%c %s" %( title, ("v" if is_a_video else " "), media_url ) ) #hoster, DirectoryItem_url, videoID, mode_type, thumb_url,poster_url, isFolder,setInfo_type, IsPlayable=make_addon_url_from(media_url,is_a_video) ld = parse_reddit_link(link_url=media_url, assume_is_video=is_a_video, needs_preview=False, get_playable_url=True) DirectoryItem_url, setProperty_IsPlayable, isFolder, title_prefix = build_DirectoryItem_url_based_on_media_type( ld, media_url, title, on_autoplay=True) if ld: if ld.media_type not in [ sitesBase.TYPE_VIDEO, sitesBase.TYPE_GIF, sitesBase.TYPE_VIDS, sitesBase.TYPE_MIXED ]: continue autoPlay_type_entries_append(entries, autoPlay_type, title, DirectoryItem_url) if ld.media_type == sitesBase.TYPE_GIF: for _ in range(0, gif_repeat_count): autoPlay_type_entries_append(entries, autoPlay_type, title, DirectoryItem_url) except Exception as e: log(" EXCEPTION Autoplay " + str(sys.exc_info()[0]) + " " + str(e)) #def k2(x): return x[1] #entries=remove_duplicates(entries, k2) if autoplayRandomize: random.shuffle(entries) #for title, url in entries: # log(" added to playlist:"+ title + " " + urllib.unquote_plus(url) ) for title, url in entries: listitem = xbmcgui.ListItem(title) playlist.add(url, listitem) log('add to playlist: %s %s' % (title.ljust(25)[:25], url)) xbmc.Player().play(playlist)
def listLinksInComment(url, name, type_): from domains import parse_reddit_link, build_DirectoryItem_url_based_on_media_type from utils import markdown_to_bbcode, unescape from guis import progressBG #from resources.domains import make_addon_url_from #called from context menu log('listLinksInComment:%s:%s' % (type_, url)) #does not work for list comments coz key is the playable url (not reddit comments url) #msg=WINDOW.getProperty(url) #WINDOW.clearProperty( url ) #log( ' msg=' + msg ) directory_items = [] author = "" ShowOnlyCommentsWithlink = False if type_ == 'linksOnly': ShowOnlyCommentsWithlink = True #url='https://www.reddit.com/r/Music/comments/4k02t1/bonnie_tyler_total_eclipse_of_the_heart_80s_pop/' + '.json' #only get up to "https://www.reddit.com/r/Music/comments/4k02t1". # do not include "/bonnie_tyler_total_eclipse_of_the_heart_80s_pop/" # because we'll have problem when it looks like this: "https://www.reddit.com/r/Overwatch/comments/4nx91h/ever_get_that_feeling_déjà _vu/" #url=re.findall(r'(.*/comments/[A-Za-z0-9]+)',url)[0] #use safe='' argument in quoteplus to encode only the weird chars part url = urllib.quote_plus(url, safe=':/?&') if '?' in url: url = url.split('?', 1)[0] + '.json?' + url.split('?', 1)[1] else: url += '.json' loading_indicator = progressBG(translation(30024)) loading_indicator.update(0, 'Retrieving comments') content = reddit_request(url) if not content: loading_indicator.end() return loading_indicator.update(10, 'Parsing') content = json.loads(content) del harvest[:] #harvest links in the post text (just 1) r_linkHunter(content[0]['data']['children']) try: submitter = content[0]['data']['children'][0]['data']['author'] except: submitter = '' #the post title is provided in json, we'll just use that instead of messages from addLink() try: post_title = content[0]['data']['children'][0]['data']['title'] except: post_title = '' #for i, h in enumerate(harvest): # log("aaaaa first harvest "+h[2]) #harvest links in the post itself r_linkHunter(content[1]['data']['children']) comment_score = 0 loading_indicator.set_tick_total(len(harvest)) for i, h in enumerate(harvest): try: #log(str(i)+" score:"+ str(h[0]).zfill(5)+" "+ h[1] +'|'+ h[3] ) comment_score = h[0] #log("score %d < %d (%s)" %(comment_score,int_CommentTreshold, CommentTreshold) ) link_url = h[2] desc100 = h[3].replace( '\n', ' ')[0:100] #first 100 characters of description kind = h[ 6] #reddit uses t1 for user comments and t3 for OP text of the post. like a poster describing the post. d = h[5] #depth of the comment tab = " " * d if d > 0 else "-" from urlparse import urlparse domain = '{uri.netloc}'.format(uri=urlparse(link_url)) author = h[7] DirectoryItem_url = '' if comment_score < int_CommentTreshold: continue #hoster, DirectoryItem_url, videoID, mode_type, thumb_url,poster_url, isFolder,setInfo_type, setProperty_IsPlayable =make_addon_url_from(h[2]) #if link_url: # log( ' comment %s TITLE:%s... link[%s]' % ( str(d).zfill(3), desc100.ljust(20)[:20],link_url ) ) ld = parse_reddit_link(link_url=link_url, assume_is_video=False, needs_preview=True, get_playable_url=True) if kind == 't1': list_title = r"[COLOR cadetblue]%3d[/COLOR] %s" % (h[0], tab) elif kind == 't3': list_title = r"[COLOR cadetblue]Title [/COLOR] %s" % (tab) #helps the the textbox control treat [url description] and (url) as separate words. so that they can be separated into 2 lines plot = h[3].replace('](', '] (') plot = markdown_to_bbcode(plot) plot = unescape(plot) #convert html entities e.g.:(') liz = xbmcgui.ListItem(label=list_title + ': ' + desc100) liz.setInfo(type="Video", infoLabels={ "Title": h[1], "plot": plot, "studio": domain, "votes": str(comment_score), "director": author }) isFolder = False #force all links to ytdl to see if it can be played if link_url: DirectoryItem_url, setProperty_IsPlayable, isFolder, title_prefix = build_DirectoryItem_url_based_on_media_type( ld, link_url) liz.setProperty('IsPlayable', setProperty_IsPlayable) liz.setProperty( 'url', DirectoryItem_url) #<-- needed by the xml gui skin liz.setPath(DirectoryItem_url) if domain: plot = " [COLOR greenyellow][%s] %s" % (domain, plot) + "[/COLOR]" else: plot = " [COLOR greenyellow][%s]" % (plot) + "[/COLOR]" liz.setLabel(list_title + plot) if ld: liz.setArt({ "thumb": ld.poster, "poster": ld.poster, "banner": ld.poster, "fanart": ld.poster, "landscape": ld.poster }) if DirectoryItem_url: #log( 'IsPlayable:'+setProperty_IsPlayable ) directory_items.append(( DirectoryItem_url, liz, isFolder, )) #xbmcplugin.addDirectoryItem(handle=pluginhandle,url=DirectoryItem_url,listitem=liz,isFolder=isFolder) else: #this section are for comments that have no links if not ShowOnlyCommentsWithlink: result = h[3].replace('](', '] (') result = markdown_to_bbcode(result) liz = xbmcgui.ListItem(label=list_title + desc100) liz.setInfo(type="Video", infoLabels={ "Title": h[1], "plot": result, "studio": domain, "votes": str(h[0]), "director": author }) liz.setProperty('IsPlayable', 'false') directory_items.append(( "", liz, False, )) #xbmcplugin.addDirectoryItem(handle=pluginhandle,url="",listitem=liz,isFolder=False) #END section are for comments that have no links or unsupported links except Exception as e: log(' EXCEPTION:' + str(e)) #for di in directory_items: # log( str(di) ) loading_indicator.tick(1, desc100) loading_indicator.end() #log(' comments_view id=%s' %comments_viewMode) #xbmcplugin.setContent(pluginhandle, "mixed") #in estuary, mixed have limited view id's available. it has widelist which is nice for comments but we'll just stick with 'movies' xbmcplugin.setContent( pluginhandle, "episodes" ) #files, songs, artists, albums, movies, tvshows, episodes, musicvideos xbmcplugin.setPluginCategory(pluginhandle, 'Comments') xbmcplugin.addDirectoryItems(handle=pluginhandle, items=directory_items) xbmcplugin.endOfDirectory(pluginhandle) if comments_viewMode: xbmc.executebuiltin('Container.SetViewMode(%s)' % comments_viewMode)
def addLink(title, title_line2, iconimage, previewimage,preview_w,preview_h,domain,description, credate, reddit_says_is_video, commentsUrl, subreddit, media_url, over_18, posted_by="", num_comments=0,post_index=1,post_id=''): from domains import parse_reddit_link, build_DirectoryItem_url_based_on_media_type post_title=title il_description="" n="" #will hold red nsfw asterisk string isFolder=True thumb_url='' h="[B]" + domain + "[/B]: " if over_18: mpaa="R" n = "[COLOR red]*[/COLOR] " il_description = "[COLOR red][NSFW][/COLOR] "+ h+title+"[CR]" + "[COLOR grey]" + description + "[/COLOR]" else: mpaa="" n="" il_description = h+title+"[CR]" + "[COLOR grey]" + description + "[/COLOR]" if TitleAddtlInfo: #put the additional info on the description if setting set to single line titles post_title=n+title+"[CR][LIGHT]"+title_line2+'[/LIGHT]' else: post_title=n+title il_description=title_line2+"[CR]"+il_description il={"title": post_title, "plot": il_description, "plotoutline": il_description, "Aired": credate, "mpaa": mpaa, "Genre": "r/"+subreddit, "studio": domain, "director": posted_by } #, "duration": 1271} (duration uses seconds for titan skin liz=xbmcgui.ListItem(label=post_title) liz.setInfo(type='video', infoLabels=il) if iconimage in ["","nsfw", "default"]: iconimage=thumb_url preview_ar=0.0 if (preview_w==0 or preview_h==0) != True: preview_ar=float(preview_w) / preview_h if previewimage: needs_preview=False else: needs_preview=True #reddit has no thumbnail for this link. please get one if DoNotResolveLinks: ld=None DirectoryItem_url=sys.argv[0]\ +"?url="+ urllib.quote_plus(media_url) \ +"&name="+urllib.quote_plus(title) \ +"&mode=play" setProperty_IsPlayable='true' isFolder=False title_prefix='' else: ld=parse_reddit_link(media_url,reddit_says_is_video, needs_preview, False, preview_ar ) if needs_preview and ld: queried_preview_image= next((i for i in [ld.poster,ld.thumb] if i ), '') previewimage=queried_preview_image iconimage=ld.thumb arg_name=title arg_type=previewimage DirectoryItem_url, setProperty_IsPlayable, isFolder, title_prefix = build_DirectoryItem_url_based_on_media_type(ld, media_url, arg_name, arg_type, script_to_call="", on_autoplay=False, img_w=preview_w, img_h=preview_h) if title_prefix: liz.setLabel( title_prefix+' '+post_title ) liz.setProperty('IsPlayable', setProperty_IsPlayable) liz.setInfo('video', {"title": liz.getLabel(), } ) liz.setArt({"thumb": iconimage, "poster":previewimage, "banner":iconimage, "fanart":previewimage, "landscape":previewimage, }) entries = build_context_menu_entries(num_comments, commentsUrl, subreddit, domain, media_url, post_id) #entries for listbox for when you type 'c' or rt-click liz.addContextMenuItems(entries) return (DirectoryItem_url,liz,isFolder) #tuple for addDirectoryItems