1 # -*- coding: utf-8 -*-
3 # gPodder - A media aggregator and podcast client
4 # Copyright (c) 2005-2018 The gPodder Team
6 # gPodder is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 3 of the License, or
9 # (at your option) any later version.
11 # gPodder is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
21 # gpodder.vimeo - Vimeo download magic
22 # Thomas Perl <thp@gpodder.org>; 2012-01-03
30 from gpodder
import registry
, util
34 logger
= logging
.getLogger(__name__
)
37 VIMEOCOM_RE
= re
.compile(r
'http[s]?://vimeo\.com/(channels/[^/]+|\d+)$', re
.IGNORECASE
)
38 VIMEOCOM_VIDEO_RE
= re
.compile(r
'http[s]?://vimeo.com/channels/(?:[^/])+/(\d+)$', re
.IGNORECASE
)
39 MOOGALOOP_RE
= re
.compile(r
'http[s]?://vimeo\.com/moogaloop\.swf\?clip_id=(\d+)$', re
.IGNORECASE
)
40 SIGNATURE_RE
= re
.compile(r
'"timestamp":(\d+),"signature":"([^"]+)"')
42 # List of qualities, from lowest to highest
43 FILEFORMAT_RANKING
= ['270p', '360p', '720p', '1080p']
45 FORMATS
= tuple((x
, x
) for x
in FILEFORMAT_RANKING
)
48 class VimeoError(BaseException
):
52 @registry.download_url
.register
53 def vimeo_real_download_url(config
, episode
, allow_partial
):
54 fmt
= config
.vimeo
.fileformat
if config
else None
55 res
= get_real_download_url(episode
.url
, preferred_fileformat
=fmt
)
56 return None if res
== episode
.url
else res
59 def get_real_download_url(url
, preferred_fileformat
=None):
60 video_id
= get_vimeo_id(url
)
65 data_config_url
= 'https://player.vimeo.com/video/%s/config' % (video_id
,)
67 def get_urls(data_config_url
):
68 data_config
= util
.urlopen(data_config_url
).json()
69 for fileinfo
in list(data_config
['request']['files'].values()):
70 if not isinstance(fileinfo
, list):
74 yield (item
['quality'], item
['url'])
76 fileformat_to_url
= dict(get_urls(data_config_url
))
78 if preferred_fileformat
is not None and preferred_fileformat
in fileformat_to_url
:
79 logger
.debug('Picking preferred format: %s', preferred_fileformat
)
80 return fileformat_to_url
[preferred_fileformat
]
82 def fileformat_sort_key_func(fileformat
):
83 if fileformat
in FILEFORMAT_RANKING
:
84 return FILEFORMAT_RANKING
.index(fileformat
)
88 for fileformat
in sorted(fileformat_to_url
, key
=fileformat_sort_key_func
, reverse
=True):
89 logger
.debug('Picking best format: %s', fileformat
)
90 return fileformat_to_url
[fileformat
]
95 def get_vimeo_id(url
):
96 result
= MOOGALOOP_RE
.match(url
)
97 if result
is not None:
98 return result
.group(1)
100 result
= VIMEOCOM_RE
.match(url
)
101 if result
is not None:
102 return result
.group(1)
104 result
= VIMEOCOM_VIDEO_RE
.match(url
)
105 if result
is not None:
106 return result
.group(1)
111 def is_video_link(url
):
112 return (get_vimeo_id(url
) is not None)
115 def get_real_channel_url(url
):
116 result
= VIMEOCOM_RE
.match(url
)
117 if result
is not None:
118 return 'http://vimeo.com/%s/videos/rss' % result
.group(1)
123 def get_real_cover(url
):