2011-11-20 22:23:31 +13:00
import re
import time
2013-12-11 17:17:56 +13:00
from util import hook , http , timeformat
2011-11-20 22:23:31 +13:00
youtube_re = ( r ' (?:youtube.*?(?:v=|/v/)|youtu \ .be/|yooouuutuuube.*?id=) '
2012-02-28 23:10:36 -08:00
' ([-_a-zA-Z0-9]+) ' , re . I )
2011-11-20 22:23:31 +13:00
base_url = ' http://gdata.youtube.com/feeds/api/ '
2012-11-12 23:46:38 +13:00
api_url = base_url + ' videos/ {} ?v=2&alt=jsonc '
2011-11-20 22:23:31 +13:00
search_api_url = base_url + ' videos?v=2&alt=jsonc&max-results=1 '
2012-08-21 08:34:24 +12:00
video_url = " http://youtu.be/ %s "
2011-11-20 22:23:31 +13:00
2013-11-29 16:35:41 +13:00
def plural ( num = 0 , text = ' ' ) :
2014-02-13 15:02:44 +13:00
return " {:,} {} {} " . format ( num , text , " s " [ num == 1 : ] )
2013-11-30 21:16:44 +13:00
2012-11-12 23:46:38 +13:00
def get_video_description ( video_id ) :
request = http . get_json ( api_url . format ( video_id ) )
2011-11-20 22:23:31 +13:00
2012-08-28 07:08:09 +12:00
if request . get ( ' error ' ) :
2011-11-20 22:23:31 +13:00
return
2012-08-28 07:08:09 +12:00
data = request [ ' data ' ]
2011-12-01 01:37:22 +13:00
2013-12-03 22:54:38 +13:00
out = u ' \x02 {} \x02 ' . format ( data [ ' title ' ] )
2011-11-20 22:23:31 +13:00
2012-08-28 07:08:09 +12:00
if not data . get ( ' duration ' ) :
2011-11-20 22:23:31 +13:00
return out
2012-08-28 07:08:09 +12:00
length = data [ ' duration ' ]
2013-12-11 17:17:56 +13:00
out + = u ' - length \x02 {} \x02 ' . format ( timeformat . format_time ( length , simple = True ) )
2011-11-20 22:23:31 +13:00
2013-11-29 16:30:06 +13:00
if ' ratingCount ' in data :
2013-11-29 16:35:41 +13:00
likes = plural ( int ( data [ ' likeCount ' ] ) , " like " )
dislikes = plural ( data [ ' ratingCount ' ] - int ( data [ ' likeCount ' ] ) , " dislike " )
2013-11-29 16:30:06 +13:00
2014-02-13 15:02:44 +13:00
percent = 100 * float ( data [ ' likeCount ' ] ) / float ( data [ ' ratingCount ' ] )
2013-12-03 22:54:38 +13:00
out + = u ' - {} , {} ( \x02 {:.1f} \x02 % ) ' . format ( likes ,
2014-02-13 15:02:44 +13:00
dislikes , percent )
2012-03-04 13:47:14 +13:00
2012-08-30 22:30:29 +12:00
if ' viewCount ' in data :
2013-11-30 19:19:04 +13:00
views = data [ ' viewCount ' ]
2014-02-13 15:02:44 +13:00
out + = u ' - \x02 {:,} \x02 view {} ' . format ( views , " s " [ views == 1 : ] )
2011-11-20 22:23:31 +13:00
2013-09-21 20:18:08 +08:00
try :
2014-02-13 15:02:44 +13:00
uploader = http . get_json ( base_url + " users/ {} ?alt=json " . format ( data [ " uploader " ] ) ) [ " entry " ] [ " author " ] [ 0 ] [ " name " ] [
" $t " ]
2013-09-21 20:18:08 +08:00
except :
uploader = data [ " uploader " ]
2014-02-13 15:02:44 +13:00
2012-08-28 07:08:09 +12:00
upload_time = time . strptime ( data [ ' uploaded ' ] , " % Y- % m- %d T % H: % M: % S.000Z " )
2013-12-03 22:54:38 +13:00
out + = u ' - \x02 {} \x02 on \x02 {} \x02 ' . format ( uploader ,
2014-02-13 15:02:44 +13:00
time . strftime ( " % Y. % m. %d " , upload_time ) )
2011-11-20 22:23:31 +13:00
2012-08-28 07:08:09 +12:00
if ' contentRating ' in data :
2013-12-03 22:54:38 +13:00
out + = u ' - \x03 4NSFW \x02 '
2011-11-20 22:23:31 +13:00
2011-12-01 01:37:22 +13:00
return out
2011-11-20 22:23:31 +13:00
2012-02-28 21:58:38 -08:00
2011-11-20 22:23:31 +13:00
@hook.regex ( * youtube_re )
def youtube_url ( match ) :
return get_video_description ( match . group ( 1 ) )
2012-02-28 21:58:38 -08:00
2013-12-03 22:54:38 +13:00
@hook.command ( ' you ' )
2012-02-15 20:06:52 +13:00
@hook.command ( ' yt ' )
2011-11-20 22:23:31 +13:00
@hook.command ( ' y ' )
@hook.command
def youtube ( inp ) :
2013-09-04 18:30:04 +08:00
""" youtube <query> -- Returns the first YouTube search result for <query>. """
2012-08-28 07:08:09 +12:00
request = http . get_json ( search_api_url , q = inp )
2011-11-20 22:23:31 +13:00
2012-08-28 07:08:09 +12:00
if ' error ' in request :
2011-11-20 22:23:31 +13:00
return ' error performing search '
2012-08-28 07:08:09 +12:00
if request [ ' data ' ] [ ' totalItems ' ] == 0 :
2011-11-20 22:23:31 +13:00
return ' no results found '
2012-08-28 07:08:09 +12:00
video_id = request [ ' data ' ] [ ' items ' ] [ 0 ] [ ' id ' ]
2011-11-20 22:23:31 +13:00
2013-12-03 22:54:38 +13:00
return get_video_description ( video_id ) + u " - " + video_url % video_id
2013-06-27 18:42:18 +08:00
2013-09-04 18:30:04 +08:00
2013-11-30 21:16:44 +13:00
@hook.command ( ' ytime ' )
@hook.command
def youtime ( inp ) :
""" youtime <query> -- Gets the total run time of the first YouTube search result for <query>. """
request = http . get_json ( search_api_url , q = inp )
if ' error ' in request :
return ' error performing search '
if request [ ' data ' ] [ ' totalItems ' ] == 0 :
return ' no results found '
video_id = request [ ' data ' ] [ ' items ' ] [ 0 ] [ ' id ' ]
request = http . get_json ( api_url . format ( video_id ) )
if request . get ( ' error ' ) :
return
data = request [ ' data ' ]
if not data . get ( ' duration ' ) :
return
length = data [ ' duration ' ]
views = data [ ' viewCount ' ]
total = int ( length * views )
2013-12-11 17:17:56 +13:00
length_text = timeformat . format_time ( length , simple = True )
total_text = timeformat . format_time ( total , accuracy = 8 )
2013-11-30 21:16:44 +13:00
return u ' The video \x02 {} \x02 has a length of {} and has been viewed {:,} times for ' \
2014-02-13 15:02:44 +13:00
u ' a total run time of {} ! ' . format ( data [ ' title ' ] , length_text , views ,
total_text )
2013-11-30 21:16:44 +13:00
2013-06-27 18:42:18 +08:00
ytpl_re = ( r ' (.*:)//(www.youtube.com/playlist|youtube.com/playlist)(:[0-9]+)?(.*) ' , re . I )
2013-09-04 18:30:04 +08:00
2013-06-27 18:42:18 +08:00
@hook.regex ( * ytpl_re )
def ytplaylist_url ( match ) :
location = match . group ( 4 ) . split ( " = " ) [ - 1 ]
try :
2013-09-04 18:30:04 +08:00
soup = http . get_soup ( " https://www.youtube.com/playlist?list= " + location )
2013-06-27 18:42:18 +08:00
except Exception :
2013-09-04 18:30:04 +08:00
return " \x03 4 \x02 Invalid response. "
2013-06-27 18:42:18 +08:00
title = soup . find ( ' title ' ) . text . split ( ' - ' ) [ 0 ] . strip ( )
author = soup . find ( ' img ' , { ' class ' : ' channel-header-profile-image ' } ) [ ' title ' ]
2014-02-13 15:02:44 +13:00
num_videos = soup . find ( ' ul ' , { ' class ' : ' header-stats ' } ) . findAll ( ' li ' ) [ 0 ] . text . split ( ' ' ) [ 0 ]
2013-06-27 18:42:18 +08:00
views = soup . find ( ' ul ' , { ' class ' : ' header-stats ' } ) . findAll ( ' li ' ) [ 1 ] . text . split ( ' ' ) [ 0 ]
2014-02-13 15:02:44 +13:00
return u " \x02 %s \x02 - \x02 %s \x02 views - \x02 %s \x02 videos - \x02 %s \x02 " % ( title , views , num_videos , author )