2014-01-16 20:07:01 -06:00
from __future__ import unicode_literals
2013-06-23 15:31:12 -05:00
from . common import InfoExtractor
2016-03-25 14:46:57 -05:00
from . . compat import compat_urllib_parse_urlencode
2013-06-23 15:31:12 -05:00
from . . utils import (
2015-11-01 06:38:11 -06:00
ExtractorError ,
2015-10-31 20:08:19 -05:00
int_or_none ,
qualities ,
2013-06-23 15:31:12 -05:00
)
class FlickrIE ( InfoExtractor ) :
2015-10-31 20:08:19 -05:00
_VALID_URL = r ' https?://(?:www \ .|secure \ .)?flickr \ .com/photos/[ \ w \ -_@]+/(?P<id> \ d+) '
2013-06-27 13:46:46 -05:00
_TEST = {
2014-01-16 20:07:01 -06:00
' url ' : ' http://www.flickr.com/photos/forestwander-nature-pictures/5645318632/in/photostream/ ' ,
2015-10-31 20:08:19 -05:00
' md5 ' : ' 164fe3fa6c22e18d448d4d5af2330f31 ' ,
2014-01-16 20:07:01 -06:00
' info_dict ' : {
2014-09-24 03:46:33 -05:00
' id ' : ' 5645318632 ' ,
2015-10-31 20:08:19 -05:00
' ext ' : ' mpg ' ,
' description ' : ' Waterfalls in the Springtime at Dark Hollow Waterfalls. These are located just off of Skyline Drive in Virginia. They are only about 6/10 of a mile hike but it is a pretty steep hill and a good climb back up. ' ,
' title ' : ' Dark Hollow Waterfalls ' ,
' duration ' : 19 ,
' timestamp ' : 1303528740 ,
' upload_date ' : ' 20110423 ' ,
' uploader_id ' : ' 10922353@N03 ' ,
' uploader ' : ' Forest Wander ' ,
2016-05-07 09:15:40 -05:00
' uploader_url ' : ' https://www.flickr.com/photos/forestwander-nature-pictures/ ' ,
2015-10-31 20:08:19 -05:00
' comment_count ' : int ,
2015-12-20 17:20:22 -06:00
' view_count ' : int ,
' tags ' : list ,
2016-05-07 09:12:20 -05:00
' license ' : ' Attribution-ShareAlike ' ,
2013-06-27 13:46:46 -05:00
}
}
2015-10-31 20:08:19 -05:00
_API_BASE_URL = ' https://api.flickr.com/services/rest? '
2016-05-07 09:12:20 -05:00
# https://help.yahoo.com/kb/flickr/SLN25525.html
_LICENSES = {
' 0 ' : ' All Rights Reserved ' ,
' 1 ' : ' Attribution-NonCommercial-ShareAlike ' ,
' 2 ' : ' Attribution-NonCommercial ' ,
' 3 ' : ' Attribution-NonCommercial-NoDerivs ' ,
' 4 ' : ' Attribution ' ,
' 5 ' : ' Attribution-ShareAlike ' ,
' 6 ' : ' Attribution-NoDerivs ' ,
' 7 ' : ' No known copyright restrictions ' ,
' 8 ' : ' United States government work ' ,
' 9 ' : ' Public Domain Dedication (CC0) ' ,
' 10 ' : ' Public Domain Work ' ,
}
2015-04-22 12:24:14 -05:00
2015-11-01 06:23:23 -06:00
def _call_api ( self , method , video_id , api_key , note , secret = None ) :
2015-10-31 20:08:19 -05:00
query = {
' photo_id ' : video_id ,
' method ' : ' flickr. %s ' % method ,
2015-11-01 06:23:23 -06:00
' api_key ' : api_key ,
2015-10-31 20:08:19 -05:00
' format ' : ' json ' ,
' nojsoncallback ' : 1 ,
}
if secret :
query [ ' secret ' ] = secret
2016-03-25 14:46:57 -05:00
data = self . _download_json ( self . _API_BASE_URL + compat_urllib_parse_urlencode ( query ) , video_id , note )
2015-11-01 06:38:11 -06:00
if data [ ' stat ' ] != ' ok ' :
raise ExtractorError ( data [ ' message ' ] )
return data
2013-06-23 15:31:12 -05:00
2015-10-31 20:08:19 -05:00
def _real_extract ( self , url ) :
video_id = self . _match_id ( url )
2013-06-23 15:31:12 -05:00
2015-12-21 15:10:16 -06:00
api_key = self . _download_json (
' https://www.flickr.com/hermes_error_beacon.gne ' , video_id ,
' Downloading api key ' ) [ ' site_key ' ]
2015-11-01 06:23:23 -06:00
2015-12-21 15:10:16 -06:00
video_info = self . _call_api (
' photos.getInfo ' , video_id , api_key , ' Downloading video info ' ) [ ' photo ' ]
2015-10-31 20:08:19 -05:00
if video_info [ ' media ' ] == ' video ' :
2015-12-21 15:10:16 -06:00
streams = self . _call_api (
' video.getStreamInfo ' , video_id , api_key ,
' Downloading streams info ' , video_info [ ' secret ' ] ) [ ' streams ' ]
2013-06-23 15:31:12 -05:00
2015-12-21 15:10:16 -06:00
preference = qualities (
[ ' 288p ' , ' iphone_wifi ' , ' 100 ' , ' 300 ' , ' 700 ' , ' 360p ' , ' appletv ' , ' 720p ' , ' 1080p ' , ' orig ' ] )
2013-06-23 15:31:12 -05:00
2015-10-31 20:08:19 -05:00
formats = [ ]
for stream in streams [ ' stream ' ] :
stream_type = str ( stream . get ( ' type ' ) )
formats . append ( {
' format_id ' : stream_type ,
' url ' : stream [ ' _content ' ] ,
' preference ' : preference ( stream_type ) ,
} )
self . _sort_formats ( formats )
2013-06-23 15:31:12 -05:00
2015-10-31 20:08:19 -05:00
owner = video_info . get ( ' owner ' , { } )
2016-05-07 09:15:40 -05:00
uploader_id = owner . get ( ' nsid ' )
uploader_path = owner . get ( ' path_alias ' ) or uploader_id
uploader_url = ' https://www.flickr.com/photos/ %s / ' % uploader_path if uploader_path else None
2013-06-23 15:31:12 -05:00
2015-10-31 20:08:19 -05:00
return {
' id ' : video_id ,
' title ' : video_info [ ' title ' ] [ ' _content ' ] ,
' description ' : video_info . get ( ' description ' , { } ) . get ( ' _content ' ) ,
' formats ' : formats ,
' timestamp ' : int_or_none ( video_info . get ( ' dateuploaded ' ) ) ,
' duration ' : int_or_none ( video_info . get ( ' video ' , { } ) . get ( ' duration ' ) ) ,
2016-05-07 09:15:40 -05:00
' uploader_id ' : uploader_id ,
2015-10-31 20:08:19 -05:00
' uploader ' : owner . get ( ' realname ' ) ,
2016-05-07 09:15:40 -05:00
' uploader_url ' : uploader_url ,
2015-10-31 20:08:19 -05:00
' comment_count ' : int_or_none ( video_info . get ( ' comments ' , { } ) . get ( ' _content ' ) ) ,
2015-12-20 17:20:22 -06:00
' view_count ' : int_or_none ( video_info . get ( ' views ' ) ) ,
2016-05-07 09:12:20 -05:00
' tags ' : [ tag . get ( ' _content ' ) for tag in video_info . get ( ' tags ' , { } ) . get ( ' tag ' , [ ] ) ] ,
' license ' : self . _LICENSES . get ( video_info . get ( ' license ' ) ) ,
2015-10-31 20:08:19 -05:00
}
2015-11-05 11:01:13 -06:00
else :
raise ExtractorError ( ' not a video ' , expected = True )