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