def Process_Search(self, queries): # Fetch List of Entries url = "https://www.googleapis.com/youtube/v3/search?%s" % plugin.urlencode(queries) with urlhandler.urlopen(url, 14400) as sourceObj: feed = load(sourceObj) # Fetch list of video ID from feed return (video[u"id"][u"videoId"] for video in feed["items"])
def Channels(self, **kargs): # Set Defautl parameters queries = self.set_default_queries(kargs) queries["fields"] = u"items(id,contentDetails/relatedPlaylists/uploads)" queries["part"] = u"contentDetails" # Fetch List of Entries url = "https://www.googleapis.com/youtube/v3/channels?%s" % plugin.urlencode(queries) with urlhandler.urlopen(url, -1) as sourceObj: feed = load(sourceObj)[u"items"][0] return (feed[u"id"], feed[u"contentDetails"][u"relatedPlaylists"][u"uploads"])
def Playlists(self, channelID, loop=False, **kargs): # Set Default parameters queries = self.set_default_queries(kargs) queries["fields"] = u"nextPageToken,items(id,contentDetails/itemCount,snippet(publishedAt,title,description,thumbnails/medium/url))" queries["part"] = u"snippet,contentDetails" queries["channelId"] = channelID # Add pageToken if needed if "pagetoken" in plugin: queries["pageToken"] = plugin["pagetoken"] localListItem = listitem.ListItem while True: # Fetch List of Entries url = "https://www.googleapis.com/youtube/v3/playlists?%s" % plugin.urlencode(queries) with urlhandler.urlopen(url, 14400) as sourceObj: feed = load(sourceObj) # Loop Entries for playlist in feed[u"items"]: # Create listitem object item = localListItem() item.setParamDict("action", "system.videohosts.YTPlaylistVideos") # Fetch Video ID item.setParamDict("playlistid", playlist[u"id"]) # Fetch video snippet snippet = playlist[u"snippet"] # Fetch Title and Video Cound for combining Title item.setLabel(u"%s (%s)" % (snippet[u"title"], playlist[u"contentDetails"][u"itemCount"])) # Fetch Image Url item.setThumb(snippet[u"thumbnails"][u"medium"][u"url"]) # Fetch Possible Plot and Check if Available item.setPlot(snippet[u"description"]) # Fetch Possible Date and Check if Available date = snippet[u"publishedAt"] item.setDate(date[:date.find("T")], "%Y-%m-%d") # Add InfoLabels and Data to Processed List yield item.getListitemTuple(False) # Fetch next Page Token if available if u"nextPageToken" in feed: if loop is True: queries["pageToken"] = feed[u"nextPageToken"] continue else: self.display_next_page(feed[u"nextPageToken"]) break else: break
def Process_PlaylistItems(self, queries): # Fetch List of Entries url = "https://www.googleapis.com/youtube/v3/playlistItems?%s" % plugin.urlencode(queries) with urlhandler.urlopen(url, 14400) as sourceObj: feed = load(sourceObj) # Fetch next Page Token if exists if u"nextPageToken" in feed: queries["pageToken"] = feed[u"nextPageToken"] elif "pageToken" in queries: del queries["pageToken"] # Fetch list of video ID from feed return (video[u"contentDetails"][u"videoId"] for video in feed["items"])
def category_api(self): # Create new Queries newQueries = self.set_default_queries({}) newQueries["fields"] = u"items(id,snippet/title)" newQueries["part"] = u"snippet" newQueries["id"] = u",".join(self.unmapedCats) # Fetch video Information url = u"https://www.googleapis.com/youtube/v3/videoCategories?%s" % plugin.urlencode(newQueries) with urlhandler.urlopen(url, -1) as sourceObj: items = load(sourceObj)[u"items"] for node in items: self.categorysMap[node[u"id"]] = node[u"snippet"][u"title"] self.categorysMap.close(sync=True)
def _videoItems(self, queries, processObj, loop=False): # Setup Optimizations localListItem = listitem.ListItem reFind = __import__("re").findall _plugin = plugin localInt = int # Check if Displaying related Videos isRelated = u"YTRelatedVideos" in _plugin["action"] _youTubeStr = _plugin.getuni(19103) # Fetch Youtube Video Quality Setting try: isHD = not _plugin.getAddonSetting("plugin.video.youtube", "hd_videos") == "1" except: isHD = True # Fetch categorys ID Maps self.categorysMap = categorysMap = CategoryFile() self.videoData = videoData = VideoFile("%s.json" % queries["playlistId"] if "playlistId" in queries else "video-data.json") self.unmapedCats = [] channelIDs = [] # Set Default parameters for second request newQueries = self.set_default_queries({}) newQueries["fields"] = u"items(id,snippet(publishedAt,channelId,title,description,thumbnails/medium/url,channelTitle,categoryId),contentDetails(duration,definition),statistics/viewCount)" newQueries["part"] = u"contentDetails,statistics,snippet" while True: # Fetch video Ids selectedVids = [] selectedVidsAppend = selectedVids.append fetchVids = [] fetchVidsAppend = fetchVids.append for videoId in processObj(queries): if videoId in videoData: selectedVidsAppend(videoData[videoId]) else: fetchVidsAppend(videoId) if fetchVids: # Fetch video Information newQueries["id"] = u",".join(fetchVids) url = u"https://www.googleapis.com/youtube/v3/videos?%s" % _plugin.urlencode(newQueries) with urlhandler.urlopen(url, -1) as sourceObj: for video in load(sourceObj)[u"items"]: selectedVidsAppend(video) videoData[video[u"id"]] = video # Sync videoData to file videoData.sync() # Loop Entries for video in selectedVids: # Create listitem object item = localListItem() item.setParamDict("action", "system.source.youtube_com") # Fetch Video ID item.setParamDict("url", video[u"id"]) # Fetch video snippet & contentDetails snippet = video[u"snippet"] contentDetails = video[u"contentDetails"] # Fetch Channel ID channelID = snippet[u"channelId"] if not channelID in channelIDs: channelIDs.append(channelID) # Fetch video Image url item.setThumb(snippet[u"thumbnails"][u"medium"][u"url"]) # Fetch Title item.setLabel(snippet[u"title"]) # Fetch Studio item.setStudio(snippet[u"channelTitle"]) # Fetch Description item.setPlot(snippet[u"description"]) # Fetch Possible Date date = snippet[u"publishedAt"] item.setDate(date[:date.find("T")], "%Y-%m-%d") # Fetch Viewcount item.setCount(video[u"statistics"][u"viewCount"]) # Fetch Category category = snippet[u"categoryId"] if category in categorysMap: item.setGenre(categorysMap[category]) elif not category in self.unmapedCats: self.unmapedCats.append(category) # Set Quality and Audio Overlays if isHD and contentDetails[u"definition"] == u"hd": item.setVideoFlags(True, "h264") else: item.setVideoFlags(False, "h264") item.setAudioFlags("aac", "en", 2) # Fetch Duration durationStr = contentDetails[u"duration"] durationStr = reFind("(\d+)(\w)", durationStr) if durationStr: duration = 0 for time, timeType in durationStr: if timeType == "H": duration += (localInt(time) * 3600) elif timeType == "M": duration += (localInt(time) * 60) elif timeType == "S": duration += (localInt(time)) # Set duration item.setDuration(duration) # Add Context item to link to related videos item.addRelatedContext(action="system.videohosts.YTRelatedVideos", videoid=video[u"id"], channelid=channelID) if isRelated: item.addContextMenuItem(_youTubeStr, "XBMC.Container.Update", action="system.videohosts.YTPlaylistVideos", channelid=channelID) # Add InfoLabels and Data to Processed List yield item.getListitemTuple(True) # Break from loop if needed if not (loop is True and "pageToken" in queries): break # Add Next Page, Playlists and fetch categorys if needed if "pageToken" in queries: self.display_next_page(queries["pageToken"]) if len(channelIDs) == 1 and not "pagetoken" in _plugin and _plugin.get("hasplaylists",u"false") == u"true" : self.display_Playlists(channelIDs[0]) setattr(listitem.VirtualFS, "finalize", self.finalize)
def loadModelData(self, name): """ Loads the model data of the given name. The model file must always be a .json file. """ path = self.resourceNameToPath(name, ".json") try: data = json.load(open(path, "r")) except Exception: # Temporary print("Exception during model load: ") import traceback traceback.print_exc() return {} # will probably cause other exceptions later on, TODO out = {} if data.get("version", 1) == 1: # Currently only one version, basic future-proofing # This version should get incremented with breaking changes to the structure # Materials out["materials"] = {} for name, matdata in data.get("materials", {}).items(): m = model.Material(self, name, matdata) out["materials"][name] = m out["default_material"] = out["materials"][data.get( "default_material", list(out["materials"].keys())[0])] # Bones out["bones"] = { "__root__": model.RootBone(self, "__root__", { "start_rot": [0, 0], "length": 0 }) } for name, bonedata in data.get("bones", {}).items(): b = model.Bone(self, name, bonedata) out["bones"][name] = b for name, bone in out["bones"].items(): if name == "__root__": continue bone.setParent(out["bones"][bone.bonedata["parent"]]) # Regions out["regions"] = {} for name, regdata in data.get("regions", {}).items(): r = model.Region(self, name, regdata) r.material = out["materials"][regdata.get( "material", out["default_material"])] r.bone = out["bones"][regdata.get("bone", "__root__")] out["bones"][regdata.get("bone", "__root__")].addRegion(r) out["regions"][name] = r # Animations out["animations"] = {} out["animations"]["static"] = model.Animation( self, "static", { "type": "static", "bones": {} }) for name, anidata in data.get("animations", {}).items(): a = model.Animation(self, name, anidata) a.setBones(out["bones"]) out["animations"][name] = a out["default_animation"] = out["animations"][data.get( "default_animation", out["animations"]["static"])] else: raise ValueError("Unknown version %s of model '%s'" % (data.get("version", 1), name)) self.modelcache[name] = out return out