2 from __future__ 
import unicode_literals
 
   7 from .common 
import InfoExtractor
 
  10     compat_urllib_request
, 
  19 class NiconicoIE(InfoExtractor
): 
  24         'url': 'http://www.nicovideo.jp/watch/sm22312215', 
  25         'md5': 'd1a75c0823e2f629128c43e1212760f9', 
  29             'title': 'Big Buck Bunny', 
  30             'uploader': 'takuya0301', 
  31             'uploader_id': '2698420', 
  32             'upload_date': '20131123', 
  33             'description': '(c) copyright 2008, Blender Foundation / www.bigbuckbunny.org', 
  37             'username': 'ydl.niconico@gmail.com', 
  38             'password': 'youtube-dl', 
  42     _VALID_URL 
= r
'https?://(?:www\.|secure\.)?nicovideo\.jp/watch/((?:[a-z]{2})?[0-9]+)' 
  43     _NETRC_MACHINE 
= 'niconico' 
  44     # Determine whether the downloader used authentication to download video 
  45     _AUTHENTICATED 
= False 
  47     def _real_initialize(self
): 
  51         (username
, password
) = self
._get
_login
_info
() 
  52         # No authentication to be performed 
  61         # Convert to UTF-8 *before* urlencode because Python 2.x's urlencode 
  63         login_form 
= dict((k
.encode('utf-8'), v
.encode('utf-8')) for k
, v 
in login_form_strs
.items()) 
  64         login_data 
= compat_urllib_parse
.urlencode(login_form
).encode('utf-8') 
  65         request 
= compat_urllib_request
.Request( 
  66             'https://secure.nicovideo.jp/secure/login', login_data
) 
  67         login_results 
= self
._download
_webpage
( 
  68             request
, None, note
='Logging in', errnote
='Unable to log in') 
  69         if re
.search(r
'(?i)<h1 class="mb8p4">Log in error</h1>', login_results
) is not None: 
  70             self
._downloader
.report_warning('unable to log in: bad username or password') 
  73         self
._AUTHENTICATED 
= True 
  76     def _real_extract(self
, url
): 
  77         mobj 
= re
.match(self
._VALID
_URL
, url
) 
  78         video_id 
= mobj
.group(1) 
  80         # Get video webpage. We are not actually interested in it, but need 
  81         # the cookies in order to be able to download the info webpage 
  82         self
._download
_webpage
('http://www.nicovideo.jp/watch/' + video_id
, video_id
) 
  84         video_info 
= self
._download
_xml
( 
  85             'http://ext.nicovideo.jp/api/getthumbinfo/' + video_id
, video_id
, 
  86             note
='Downloading video info page') 
  88         if self
._AUTHENTICATED
: 
  90             flv_info_webpage 
= self
._download
_webpage
( 
  91                 'http://flapi.nicovideo.jp/api/getflv?v=' + video_id
, 
  92                 video_id
, 'Downloading flv info') 
  94             # Get external player info 
  95             ext_player_info 
= self
._download
_webpage
( 
  96                 'http://ext.nicovideo.jp/thumb_watch/' + video_id
, video_id
) 
  97             thumb_play_key 
= self
._search
_regex
( 
  98                 r
'\'thumbPlayKey
\'\s
*:\s
*\'(.*?
)\'', ext_player_info, 'thumbPlayKey
') 
 101             flv_info_data = compat_urllib_parse.urlencode({ 
 105             flv_info_request = compat_urllib_request.Request( 
 106                 'http
://ext
.nicovideo
.jp
/thumb_watch
', flv_info_data, 
 107                 {'Content
-Type
': 'application
/x
-www
-form
-urlencoded
'}) 
 108             flv_info_webpage = self._download_webpage( 
 109                 flv_info_request, video_id, 
 110                 note='Downloading flv info
', errnote='Unable to download flv info
') 
 112         if 'deleted
=' in flv_info_webpage: 
 113             raise ExtractorError('The video has been deleted
.', 
 115         video_real_url = compat_urlparse.parse_qs(flv_info_webpage)['url
'][0] 
 117         # Start extracting information 
 118         title = video_info.find('.//title
').text 
 119         extension = video_info.find('.//movie_type
').text 
 120         video_format = extension.upper() 
 121         thumbnail = video_info.find('.//thumbnail_url
').text 
 122         description = video_info.find('.//description
').text 
 123         upload_date = unified_strdate(video_info.find('.//first_retrieve
').text.split('+')[0]) 
 124         view_count = int_or_none(video_info.find('.//view_counter
').text) 
 125         comment_count = int_or_none(video_info.find('.//comment_num
').text) 
 126         duration = parse_duration(video_info.find('.//length
').text) 
 127         webpage_url = video_info.find('.//watch_url
').text 
 129         if video_info.find('.//ch_id
') is not None: 
 130             uploader_id = video_info.find('.//ch_id
').text 
 131             uploader = video_info.find('.//ch_name
').text 
 132         elif video_info.find('.//user_id
') is not None: 
 133             uploader_id = video_info.find('.//user_id
').text 
 134             uploader = video_info.find('.//user_nickname
').text 
 136             uploader_id = uploader = None 
 140             'url
': video_real_url, 
 143             'format
': video_format, 
 144             'thumbnail
': thumbnail, 
 145             'description
': description, 
 146             'uploader
': uploader, 
 147             'upload_date
': upload_date, 
 148             'uploader_id
': uploader_id, 
 149             'view_count
': view_count, 
 150             'comment_count
': comment_count, 
 151             'duration
': duration, 
 152             'webpage_url
': webpage_url, 
 156 class NiconicoPlaylistIE(InfoExtractor): 
 157     _VALID_URL = r'https?
://www\
.nicovideo\
.jp
/mylist
/(?P
<id>\d
+)' 
 160         'url
': 'http
://www
.nicovideo
.jp
/mylist
/27411728', 
 163             'title
': 'AKB48のオールナイトニッポン
', 
 165         'playlist_mincount
': 225, 
 168     def _real_extract(self, url): 
 169         list_id = self._match_id(url) 
 170         webpage = self._download_webpage(url, list_id) 
 172         entries_json = self._search_regex(r'Mylist\
.preload\
(\d
+, (\
[.*\
])\
);', 
 174         entries = json.loads(entries_json) 
 177             'ie_key
': NiconicoIE.ie_key(), 
 178             'url
': ('http
://www
.nicovideo
.jp
/watch
/%s' % 
 179                     entry['item_data
']['video_id
']), 
 180         } for entry in entries] 
 184             'title
': self._search_regex(r'\s
+name
: "(.*?)"', webpage, 'title
'),