aboutsummaryrefslogtreecommitdiff
path: root/glifestream/apis/youtube.py
diff options
context:
space:
mode:
Diffstat (limited to 'glifestream/apis/youtube.py')
-rw-r--r--glifestream/apis/youtube.py143
1 files changed, 111 insertions, 32 deletions
diff --git a/glifestream/apis/youtube.py b/glifestream/apis/youtube.py
index d08ac75..6511756 100644
--- a/glifestream/apis/youtube.py
+++ b/glifestream/apis/youtube.py
@@ -13,51 +13,130 @@
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
+import datetime
from django.utils.translation import ugettext as _
from glifestream.stream import media
-from glifestream.apis import webfeed
+from glifestream.stream.models import Entry
+from glifestream.utils import httpclient
+from glifestream.utils.time import mtime, now
-class API (webfeed.API):
- name = 'YouTube API v2'
+class API:
+ name = 'YouTube API v3'
limit_sec = 3600
+ playlist_types = {}
+
+ def __init__(self, service, verbose=0, force_overwrite=False):
+ self.service = service
+ self.verbose = verbose
+ self.force_overwrite = force_overwrite
+ if self.verbose:
+ print('%s: %s' % (self.name, self.service))
def get_urls(self):
- if self.service.url.startswith('http://'):
+ if self.service.url.startswith('http://') or \
+ self.service.url.startswith('https://'):
return (self.service.url,)
else:
- h = 'http://gdata.youtube.com/feeds/api/users/%s' % self.service.url
- return ('%s/favorites?v=2' % h,
- '%s/uploads?v=2' % h)
-
- def custom_process(self, e, ent):
- if 'yt_videoid' in ent:
- vid = ent['yt_videoid']
- elif 'media_player' in ent and 'url' in ent['media_player']:
- vid = ent['media_player']['url'][22:]
- else:
- vid = None
+ urls = []
+ if ':' in self.service.url:
+ apikey, playlists = self.service.url.split(':')
+ for playlist in playlists.split(','):
+ if '#' in playlist:
+ playlist, kind = playlist.split('#')
+ else:
+ kind = 'video'
+ url = ('https://www.googleapis.com/youtube/v3/'
+ 'playlistItems?part=snippet,contentDetails,status&'
+ 'playlistId=%s&'
+ 'maxResults=25&'
+ 'key=%s' % (playlist, apikey))
+ self.playlist_types[url] = kind
+ urls.append(url)
+ return urls
+
+ def run(self):
+ for url in self.get_urls():
+ try:
+ self.fetch(url)
+ except:
+ pass
+
+ def fetch(self, url):
+ try:
+ r = httpclient.get(url)
+ if r.status_code == 200:
+ self.json = r.json()
+ self.service.last_checked = now()
+ self.service.save()
+ self.process(url)
+ elif self.verbose:
+ print('%s (%d) HTTP: %s' % (self.service.api,
+ self.service.id, r.reason))
+ except Exception as e:
+ if self.verbose:
+ import sys
+ import traceback
+ print('%s (%d) Exception: %s' % (self.service.api,
+ self.service.id, e))
+ traceback.print_exc(file=sys.stdout)
+
+ def process(self, url):
+ for ent in self.json.get('items', ()):
+ snippet = ent.get('snippet', {})
+ date = snippet['publishedAt'][:10]
+
+ vid = ent['contentDetails']['videoId']
+ if self.playlist_types[url] == 'favorite':
+ guid = 'tag:youtube.com,2008:favorite:%s' % ent.get('id')
+ else:
+ guid = 'tag:youtube.com,2008:video:%s' % vid
- if vid and 'media_thumbnail' in ent and len(ent.media_thumbnail):
- tn = None
- for mt in ent.media_thumbnail:
- if 'name' in mt and mt['name'] == 'hqdefault':
- tn = mt
+ t = datetime.datetime.strptime(snippet['publishedAt'],
+ '%Y-%m-%dT%H:%M:%S.000Z')
+
+ if self.verbose:
+ print("ID: %s" % guid)
+ try:
+ e = Entry.objects.get(service=self.service, guid=guid)
+ if not self.force_overwrite and e.date_updated \
+ and mtime(t.timetuple()) <= e.date_updated:
+ continue
+ if e.protected:
+ continue
+ except Entry.DoesNotExist:
+ e = Entry(service=self.service, guid=guid)
+
+ e.title = snippet['title']
+ e.link = 'https://www.youtube.com/watch?v=%s' % vid
+ e.date_published = t
+ e.date_updated = t
+ e.author_name = snippet['channelTitle']
+
+ if vid and 'thumbnails' in snippet:
+ tn = None
+ if 'high' in snippet['thumbnails']:
+ tn = snippet['thumbnails']['high']
tn['width'], tn['height'] = 200, 150
- if not tn:
- tn = ent.media_thumbnail[0]
+ elif 'medium' in snippet['thumbnails']:
+ tn = snippet['thumbnails']['medium']
+ tn['width'], tn['height'] = 200, 150
+ if not tn:
+ tn = snippet['thumbnails']['default']
- if self.service.public:
- tn['url'] = media.save_image(tn['url'], downscale=True,
- size=(200, 150))
+ if self.service.public:
+ tn['url'] = media.save_image(tn['url'], downscale=True,
+ size=(200, 150))
- e.link = e.link.replace('&feature=youtube_gdata', '')
- e.content = """<table class="vc"><tr><td><div id="youtube-%s" class="play-video"><a href="%s" rel="nofollow"><img src="%s" width="%s" height="%s" alt="YouTube Video" /></a><div class="playbutton"></div></div></td></tr></table>""" % (
- vid, e.link, tn['url'], tn['width'], tn['height'])
- else:
- e.content = ent.get('yt_state', '<a href="%s">%s</a>' %
- (ent.get('link', '#').replace(
- '&feature=youtube_gdata', ''), ent.get('title', '')))
+ e.content = """<table class="vc"><tr><td><div id="youtube-%s" class="play-video"><a href="%s" rel="nofollow"><img src="%s" width="%s" height="%s" alt="YouTube Video" /></a><div class="playbutton"></div></div></td></tr></table>""" % (
+ vid, e.link, tn['url'], tn['width'], tn['height'])
+ else:
+ e.content = '<a href="%s">%s</a>' % (e.link, e.title)
+
+ try:
+ e.save()
+ except Exception as exc:
+ print(exc)
def filter_title(entry):

Return to:

Send suggestions and report system problems to the System administrator.