| 
									
										
										
										
											2015-10-18 09:32:08 +06:00
										 |  |  | # coding: utf-8 | 
					
						
							| 
									
										
										
										
											2014-01-31 14:17:21 +01:00
										 |  |  | from __future__ import unicode_literals | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-23 22:26:30 +02:00
										 |  |  | import re | 
					
						
							| 
									
										
										
										
											2014-05-10 23:18:20 -04:00
										 |  |  | import itertools | 
					
						
							| 
									
										
										
										
											2013-06-23 22:26:30 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | from .common import InfoExtractor | 
					
						
							| 
									
										
										
										
											2015-10-18 09:32:08 +06:00
										 |  |  | from ..utils import ( | 
					
						
							| 
									
										
										
										
											2017-02-03 21:56:48 +07:00
										 |  |  |     determine_ext, | 
					
						
							| 
									
										
										
										
											2015-10-18 09:32:08 +06:00
										 |  |  |     int_or_none, | 
					
						
							| 
									
										
										
										
											2017-02-03 21:56:48 +07:00
										 |  |  |     unified_timestamp, | 
					
						
							| 
									
										
										
										
											2015-10-18 09:32:08 +06:00
										 |  |  | ) | 
					
						
							| 
									
										
										
										
											2013-06-23 22:26:30 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class VineIE(InfoExtractor): | 
					
						
							| 
									
										
										
										
											2015-04-09 22:40:18 +06:00
										 |  |  |     _VALID_URL = r'https?://(?:www\.)?vine\.co/(?:v|oembed)/(?P<id>\w+)' | 
					
						
							| 
									
										
										
										
											2015-04-09 22:37:54 +06:00
										 |  |  |     _TESTS = [{ | 
					
						
							| 
									
										
										
										
											2014-01-31 14:17:21 +01:00
										 |  |  |         'url': 'https://vine.co/v/b9KOOWX7HUx', | 
					
						
							|  |  |  |         'md5': '2f36fed6235b16da96ce9b4dc890940d', | 
					
						
							|  |  |  |         'info_dict': { | 
					
						
							|  |  |  |             'id': 'b9KOOWX7HUx', | 
					
						
							|  |  |  |             'ext': 'mp4', | 
					
						
							|  |  |  |             'title': 'Chicken.', | 
					
						
							| 
									
										
										
										
											2017-02-03 21:56:48 +07:00
										 |  |  |             'alt_title': 'Vine by Jack', | 
					
						
							|  |  |  |             'timestamp': 1368997951, | 
					
						
							| 
									
										
										
										
											2014-02-23 19:01:15 +07:00
										 |  |  |             'upload_date': '20130519', | 
					
						
							| 
									
										
										
										
											2017-02-03 21:56:48 +07:00
										 |  |  |             'uploader': 'Jack', | 
					
						
							| 
									
										
										
										
											2014-02-23 19:01:15 +07:00
										 |  |  |             'uploader_id': '76', | 
					
						
							| 
									
										
										
										
											2016-06-21 11:36:54 +02:00
										 |  |  |             'view_count': int, | 
					
						
							| 
									
										
										
										
											2015-10-18 09:36:19 +06:00
										 |  |  |             'like_count': int, | 
					
						
							|  |  |  |             'comment_count': int, | 
					
						
							|  |  |  |             'repost_count': int, | 
					
						
							| 
									
										
										
										
											2014-01-31 14:17:21 +01:00
										 |  |  |         }, | 
					
						
							| 
									
										
										
										
											2015-10-17 22:25:08 +02:00
										 |  |  |     }, { | 
					
						
							|  |  |  |         'url': 'https://vine.co/v/e192BnZnZ9V', | 
					
						
							|  |  |  |         'info_dict': { | 
					
						
							|  |  |  |             'id': 'e192BnZnZ9V', | 
					
						
							|  |  |  |             'ext': 'mp4', | 
					
						
							| 
									
										
										
										
											2015-10-18 09:32:08 +06:00
										 |  |  |             'title': 'ยิ้ม~ เขิน~ อาย~ น่าร้ากอ้ะ >//< @n_whitewo @orlameena #lovesicktheseries  #lovesickseason2', | 
					
						
							| 
									
										
										
										
											2015-10-17 22:25:08 +02:00
										 |  |  |             'alt_title': 'Vine by Pimry_zaa', | 
					
						
							| 
									
										
										
										
											2017-02-03 21:56:48 +07:00
										 |  |  |             'timestamp': 1436057405, | 
					
						
							| 
									
										
										
										
											2015-10-17 22:25:08 +02:00
										 |  |  |             'upload_date': '20150705', | 
					
						
							|  |  |  |             'uploader': 'Pimry_zaa', | 
					
						
							|  |  |  |             'uploader_id': '1135760698325307392', | 
					
						
							| 
									
										
										
										
											2016-06-21 11:36:54 +02:00
										 |  |  |             'view_count': int, | 
					
						
							| 
									
										
										
										
											2015-10-18 09:36:19 +06:00
										 |  |  |             'like_count': int, | 
					
						
							|  |  |  |             'comment_count': int, | 
					
						
							|  |  |  |             'repost_count': int, | 
					
						
							| 
									
										
										
										
											2015-10-17 22:25:08 +02:00
										 |  |  |         }, | 
					
						
							|  |  |  |         'params': { | 
					
						
							|  |  |  |             'skip_download': True, | 
					
						
							|  |  |  |         }, | 
					
						
							| 
									
										
										
										
											2017-02-03 21:56:48 +07:00
										 |  |  |     }, { | 
					
						
							|  |  |  |         'url': 'https://vine.co/v/MYxVapFvz2z', | 
					
						
							|  |  |  |         'only_matching': True, | 
					
						
							|  |  |  |     }, { | 
					
						
							|  |  |  |         'url': 'https://vine.co/v/bxVjBbZlPUH', | 
					
						
							|  |  |  |         'only_matching': True, | 
					
						
							|  |  |  |     }, { | 
					
						
							|  |  |  |         'url': 'https://vine.co/oembed/MYxVapFvz2z.json', | 
					
						
							|  |  |  |         'only_matching': True, | 
					
						
							| 
									
										
										
										
											2015-04-09 22:37:54 +06:00
										 |  |  |     }] | 
					
						
							| 
									
										
										
										
											2013-06-23 22:26:30 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def _real_extract(self, url): | 
					
						
							| 
									
										
										
										
											2014-12-12 02:59:52 +01:00
										 |  |  |         video_id = self._match_id(url) | 
					
						
							| 
									
										
										
										
											2016-07-02 02:45:00 +07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-03 21:56:48 +07:00
										 |  |  |         data = self._download_json( | 
					
						
							|  |  |  |             'https://archive.vine.co/posts/%s.json' % video_id, video_id) | 
					
						
							| 
									
										
										
										
											2014-04-30 14:12:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-03 21:56:48 +07:00
										 |  |  |         def video_url(kind): | 
					
						
							|  |  |  |             for url_suffix in ('Url', 'URL'): | 
					
						
							|  |  |  |                 format_url = data.get('video%s%s' % (kind, url_suffix)) | 
					
						
							|  |  |  |                 if format_url: | 
					
						
							|  |  |  |                     return format_url | 
					
						
							| 
									
										
										
										
											2015-03-20 01:50:36 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-03 21:56:48 +07:00
										 |  |  |         formats = [] | 
					
						
							|  |  |  |         for quality, format_id in enumerate(('low', '', 'dash')): | 
					
						
							|  |  |  |             format_url = video_url(format_id.capitalize()) | 
					
						
							|  |  |  |             if not format_url: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             # DASH link returns plain mp4 | 
					
						
							|  |  |  |             if format_id == 'dash' and determine_ext(format_url) == 'mpd': | 
					
						
							|  |  |  |                 formats.extend(self._extract_mpd_formats( | 
					
						
							|  |  |  |                     format_url, video_id, mpd_id='dash', fatal=False)) | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 formats.append({ | 
					
						
							|  |  |  |                     'url': format_url, | 
					
						
							|  |  |  |                     'format_id': format_id or 'standard', | 
					
						
							|  |  |  |                     'quality': quality, | 
					
						
							|  |  |  |                 }) | 
					
						
							| 
									
										
										
										
											2015-03-20 01:50:36 +02:00
										 |  |  |         self._sort_formats(formats) | 
					
						
							| 
									
										
										
										
											2013-06-23 22:26:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-18 09:32:08 +06:00
										 |  |  |         username = data.get('username') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-11 16:05:15 +08:00
										 |  |  |         alt_title = 'Vine by %s' % username if username else None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-31 14:17:21 +01:00
										 |  |  |         return { | 
					
						
							|  |  |  |             'id': video_id, | 
					
						
							| 
									
										
										
										
											2017-07-11 16:05:15 +08:00
										 |  |  |             'title': data.get('description') or alt_title or 'Vine video', | 
					
						
							|  |  |  |             'alt_title': alt_title, | 
					
						
							| 
									
										
										
										
											2015-10-18 09:32:08 +06:00
										 |  |  |             'thumbnail': data.get('thumbnailUrl'), | 
					
						
							| 
									
										
										
										
											2017-02-03 21:56:48 +07:00
										 |  |  |             'timestamp': unified_timestamp(data.get('created')), | 
					
						
							| 
									
										
										
										
											2015-10-18 09:32:08 +06:00
										 |  |  |             'uploader': username, | 
					
						
							|  |  |  |             'uploader_id': data.get('userIdStr'), | 
					
						
							| 
									
										
										
										
											2017-02-03 21:56:48 +07:00
										 |  |  |             'view_count': int_or_none(data.get('loops')), | 
					
						
							|  |  |  |             'like_count': int_or_none(data.get('likes')), | 
					
						
							|  |  |  |             'comment_count': int_or_none(data.get('comments')), | 
					
						
							|  |  |  |             'repost_count': int_or_none(data.get('reposts')), | 
					
						
							| 
									
										
										
										
											2014-02-23 19:01:15 +07:00
										 |  |  |             'formats': formats, | 
					
						
							| 
									
										
										
										
											2014-04-30 10:02:03 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2014-05-10 23:18:20 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-13 09:50:03 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-10 23:18:20 -04:00
										 |  |  | class VineUserIE(InfoExtractor): | 
					
						
							|  |  |  |     IE_NAME = 'vine:user' | 
					
						
							| 
									
										
										
										
											2014-12-04 20:12:06 +06:00
										 |  |  |     _VALID_URL = r'(?:https?://)?vine\.co/(?P<u>u/)?(?P<user>[^/]+)/?(\?.*)?$' | 
					
						
							| 
									
										
										
										
											2016-02-14 15:37:17 +06:00
										 |  |  |     _VINE_BASE_URL = 'https://vine.co/' | 
					
						
							| 
									
										
										
										
											2014-12-04 20:12:06 +06:00
										 |  |  |     _TESTS = [ | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             'url': 'https://vine.co/Visa', | 
					
						
							|  |  |  |             'info_dict': { | 
					
						
							|  |  |  |                 'id': 'Visa', | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             'playlist_mincount': 46, | 
					
						
							| 
									
										
										
										
											2014-08-28 00:58:24 +02:00
										 |  |  |         }, | 
					
						
							| 
									
										
										
										
											2014-12-04 20:12:06 +06:00
										 |  |  |         { | 
					
						
							|  |  |  |             'url': 'https://vine.co/u/941705360593584128', | 
					
						
							|  |  |  |             'only_matching': True, | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |     ] | 
					
						
							| 
									
										
										
										
											2014-05-10 23:18:20 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-13 09:50:03 +02:00
										 |  |  |     def _real_extract(self, url): | 
					
						
							|  |  |  |         mobj = re.match(self._VALID_URL, url) | 
					
						
							|  |  |  |         user = mobj.group('user') | 
					
						
							| 
									
										
										
										
											2014-12-04 20:12:06 +06:00
										 |  |  |         u = mobj.group('u') | 
					
						
							| 
									
										
										
										
											2014-05-10 23:18:20 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-14 15:37:17 +06:00
										 |  |  |         profile_url = '%sapi/users/profiles/%s%s' % ( | 
					
						
							| 
									
										
										
										
											2014-12-04 20:12:06 +06:00
										 |  |  |             self._VINE_BASE_URL, 'vanity/' if not u else '', user) | 
					
						
							| 
									
										
										
										
											2014-05-13 09:50:03 +02:00
										 |  |  |         profile_data = self._download_json( | 
					
						
							|  |  |  |             profile_url, user, note='Downloading user profile data') | 
					
						
							| 
									
										
										
										
											2014-05-10 23:18:20 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         user_id = profile_data['data']['userId'] | 
					
						
							|  |  |  |         timeline_data = [] | 
					
						
							|  |  |  |         for pagenum in itertools.count(1): | 
					
						
							| 
									
										
										
										
											2016-02-14 15:37:17 +06:00
										 |  |  |             timeline_url = '%sapi/timelines/users/%s?page=%s&size=100' % ( | 
					
						
							| 
									
										
										
										
											2014-05-13 09:50:03 +02:00
										 |  |  |                 self._VINE_BASE_URL, user_id, pagenum) | 
					
						
							|  |  |  |             timeline_page = self._download_json( | 
					
						
							|  |  |  |                 timeline_url, user, note='Downloading page %d' % pagenum) | 
					
						
							| 
									
										
										
										
											2014-05-10 23:18:20 -04:00
										 |  |  |             timeline_data.extend(timeline_page['data']['records']) | 
					
						
							|  |  |  |             if timeline_page['data']['nextPage'] is None: | 
					
						
							|  |  |  |                 break | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-13 09:50:03 +02:00
										 |  |  |         entries = [ | 
					
						
							|  |  |  |             self.url_result(e['permalinkUrl'], 'Vine') for e in timeline_data] | 
					
						
							| 
									
										
										
										
											2014-05-10 23:18:20 -04:00
										 |  |  |         return self.playlist_result(entries, user) |