# # This file is part of stov, written by Helmut Pozimski 2012-2014. # # stov is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, version 2 of the License. # # stov is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with stov. If not, see . # -*- coding: utf8 -*- from __future__ import unicode_literals import sys import ssl if sys.version_info >= (3,): import urllib.request as urllib2 else: import urllib2 from xml.dom.minidom import parseString from lib_stov import stov_exceptions class Parser(object): def __init__(self, api_result): self.__api_data = api_result def parse(self): """Take the youtube API data and extract the important entries""" dom = parseString(self.__api_data) channel = YtChannel() i = 0 for title in dom.getElementsByTagName('title'): xmlTag = title.toxml() if i == 0: channel.title = xmlTag.replace('', '') channel.title = channel.title.replace('', '') channel.title = channel.title.replace('&', '&') channel.title = channel.title.replace('"', '"') else: video_title = xmlTag.replace('', '') video_title = video_title.replace('', '') video_title = video_title.replace('&', '&') video_title = video_title.replace('"', '"') try: xmlTag = dom.getElementsByTagName('media:\ description')[i-1].toxml() video_description = xmlTag.replace('', '') video_description = video_description.replace('', '') except IndexError: video_description = "" video_id = dom.getElementsByTagName('yt:videoid')[i-1].toxml() video_id = video_id.replace('', '').replace( '', '') channel.videos.append(YtVideo(video_title, video_description, video_id)) i = i + 1 return channel class YtChannel(object): def __init__(self): self.title = "" self.videos = [] class YtVideo(object): def __init__(self, title, description, ytid): self.title = title self.description = description self.ytid = ytid class Connector(object): """Handles all connections to the youtube API and invokes the parsing functions. """ def __init__(self, type, name, search, conf): """Populates the object will all necessary variables.""" self._type = type self._name = name self._search = search self._conf = conf self._APIURL = self._ConstructAPIURL() def ParseAPIData(self, video_list): """Retrieves the youtube API data and parses them so they can be used by the object """ try: ConnectAPI = urllib2.urlopen(self._APIURL, timeout=30) APIResponse = ConnectAPI.read() ConnectAPI.close() except urllib2.HTTPError: raise stov_exceptions.NoDataFromYoutubeAPIException() except ssl.SSLError: raise stov_exceptions.YoutubeAPITimeoutException(self._name) else: parser = Parser(APIResponse) parsed_response = parser.parse() return parsed_response def _ConstructAPIURL(self): """Constructs the API URL which is used to retrieve API data""" if self._type == "channel": APIURL = "https://gdata.youtube.com/feeds/api/users/" \ + urllib2.quote(self._name)\ + "/uploads/?v=2&max-results=%s"\ % self._conf.values["maxvideos"] if self._search != "": APIURL = APIURL + "&q=" + "%22" \ + urllib2.quote(self._search) + "%22" elif self._type == "search": APIURL = "http://gdata.youtube.com/feeds/api/videos?q=" \ + urllib2.quote(self._search) + "&v=2" \ + "&max-results=%s" % self._conf.values["maxvideos"] elif self._type == "playlist": APIURL = "https://gdata.youtube.com/feeds/api/playlists/" \ + "%20" + urllib2.quote(self._name) + "%20?v=2" \ + "&max-results=%s" \ % self._conf.values["maxvideos"] return APIURL