10
10
from cloudbot .util .formatting import pluralize_suffix
11
11
12
12
youtube_re = re .compile (
13
- r' (?:youtube.*?(?:v=|/v/)|youtu\.be/|yooouuutuuube.*?id=)([-_a-zA-Z0-9]+)' , re .I
13
+ r" (?:youtube.*?(?:v=|/v/)|youtu\.be/|yooouuutuuube.*?id=)([-_a-zA-Z0-9]+)" , re .I
14
14
)
15
15
ytpl_re = re .compile (
16
- r' (.*:)//(www.youtube.com/playlist|youtube.com/playlist)(:[0-9]+)?(.*)' , re .I
16
+ r" (.*:)//(www.youtube.com/playlist|youtube.com/playlist)(:[0-9]+)?(.*)" , re .I
17
17
)
18
18
19
19
20
- base_url = ' https://www.googleapis.com/youtube/v3/'
20
+ base_url = " https://www.googleapis.com/youtube/v3/"
21
21
22
22
23
23
class APIError (Exception ):
@@ -46,13 +46,16 @@ def raise_api_errors(response: requests.Response) -> None:
46
46
except ValueError :
47
47
raise e
48
48
49
- errors = data .get ('errors' )
49
+ errors = data .get ("errors" )
50
+ if not errors :
51
+ errors = data .get ("error" , {}).get ("errors" )
52
+
50
53
if not errors :
51
54
return
52
55
53
56
first_error = errors [0 ]
54
- domain = first_error [' domain' ]
55
- reason = first_error [' reason' ]
57
+ domain = first_error [" domain" ]
58
+ reason = first_error [" reason" ]
56
59
raise APIError ("API Error ({}/{})" .format (domain , reason ), data ) from e
57
60
58
61
@@ -75,81 +78,81 @@ def do_request(
75
78
if params :
76
79
kwargs .update (params )
77
80
78
- kwargs [' part' ] = ',' .join (parts )
79
- kwargs [' key' ] = api_key
81
+ kwargs [" part" ] = "," .join (parts )
82
+ kwargs [" key" ] = api_key
80
83
return requests .get (base_url + method , kwargs )
81
84
82
85
83
86
def get_video (video_id : str , parts : Parts ) -> requests .Response :
84
- return do_request (' videos' , parts , params = {' maxResults' : 1 , 'id' : video_id })
87
+ return do_request (" videos" , parts , params = {" maxResults" : 1 , "id" : video_id })
85
88
86
89
87
90
def get_playlist (playlist_id : str , parts : Parts ) -> requests .Response :
88
- return do_request (' playlists' , parts , params = {' maxResults' : 1 , 'id' : playlist_id })
91
+ return do_request (" playlists" , parts , params = {" maxResults" : 1 , "id" : playlist_id })
89
92
90
93
91
- def do_search (term : str , result_type : str = ' video' ) -> requests .Response :
94
+ def do_search (term : str , result_type : str = " video" ) -> requests .Response :
92
95
return do_request (
93
- ' search' , [' snippet' ], params = {' maxResults' : 1 , 'q' : term , ' type' : result_type }
96
+ " search" , [" snippet" ], params = {" maxResults" : 1 , "q" : term , " type" : result_type }
94
97
)
95
98
96
99
97
100
def get_video_description (video_id : str ) -> str :
98
- parts = [' statistics' , ' contentDetails' , ' snippet' ]
101
+ parts = [" statistics" , " contentDetails" , " snippet" ]
99
102
request = get_video (video_id , parts )
100
103
raise_api_errors (request )
101
104
102
105
json = request .json ()
103
106
104
- data = json [' items' ]
107
+ data = json [" items" ]
105
108
if not data :
106
109
raise NoResultsError ()
107
110
108
111
item = data [0 ]
109
- snippet = item [' snippet' ]
110
- statistics = item [' statistics' ]
111
- content_details = item [' contentDetails' ]
112
+ snippet = item [" snippet" ]
113
+ statistics = item [" statistics" ]
114
+ content_details = item [" contentDetails" ]
112
115
113
- out = ' \x02 {}\x02 ' .format (snippet [' title' ])
116
+ out = " \x02 {}\x02 " .format (snippet [" title" ])
114
117
115
- if not content_details .get (' duration' ):
118
+ if not content_details .get (" duration" ):
116
119
return out
117
120
118
- length = isodate .parse_duration (content_details [' duration' ])
119
- out += ' - length \x02 {}\x02 ' .format (
121
+ length = isodate .parse_duration (content_details [" duration" ])
122
+ out += " - length \x02 {}\x02 " .format (
120
123
timeformat .format_time (int (length .total_seconds ()), simple = True )
121
124
)
122
125
try :
123
- total_votes = float (statistics [' likeCount' ]) + float (statistics [' dislikeCount' ])
126
+ total_votes = float (statistics [" likeCount" ]) + float (statistics [" dislikeCount" ])
124
127
except (LookupError , ValueError ):
125
128
total_votes = 0
126
129
127
130
if total_votes != 0 :
128
131
# format
129
- likes = pluralize_suffix (int (statistics [' likeCount' ]), "like" )
130
- dislikes = pluralize_suffix (int (statistics [' dislikeCount' ]), "dislike" )
132
+ likes = pluralize_suffix (int (statistics [" likeCount" ]), "like" )
133
+ dislikes = pluralize_suffix (int (statistics [" dislikeCount" ]), "dislike" )
131
134
132
- percent = 100 * float (statistics [' likeCount' ]) / total_votes
133
- out += ' - {}, {} (\x02 {:.1f}\x02 %)' .format (likes , dislikes , percent )
135
+ percent = 100 * float (statistics [" likeCount" ]) / total_votes
136
+ out += " - {}, {} (\x02 {:.1f}\x02 %)" .format (likes , dislikes , percent )
134
137
135
- if ' viewCount' in statistics :
136
- views = int (statistics [' viewCount' ])
137
- out += ' - \x02 {:,}\x02 view{}' .format (views , "s" [views == 1 :])
138
+ if " viewCount" in statistics :
139
+ views = int (statistics [" viewCount" ])
140
+ out += " - \x02 {:,}\x02 view{}" .format (views , "s" [views == 1 :])
138
141
139
- uploader = snippet [' channelTitle' ]
142
+ uploader = snippet [" channelTitle" ]
140
143
141
- upload_time = isodate .parse_datetime (snippet [' publishedAt' ])
142
- out += ' - \x02 {}\x02 on \x02 {}\x02 ' .format (
144
+ upload_time = isodate .parse_datetime (snippet [" publishedAt" ])
145
+ out += " - \x02 {}\x02 on \x02 {}\x02 " .format (
143
146
uploader , upload_time .strftime ("%Y.%m.%d" )
144
147
)
145
148
146
149
try :
147
- yt_rating = content_details [' contentRating' ][ ' ytRating' ]
150
+ yt_rating = content_details [" contentRating" ][ " ytRating" ]
148
151
except KeyError :
149
152
pass
150
153
else :
151
154
if yt_rating == "ytAgeRestricted" :
152
- out += colors .parse (' - $(red)NSFW$(reset)' )
155
+ out += colors .parse (" - $(red)NSFW$(reset)" )
153
156
154
157
return out
155
158
@@ -163,10 +166,10 @@ def get_video_id(text: str) -> str:
163
166
raise_api_errors (request )
164
167
json = request .json ()
165
168
166
- if not json .get (' items' ):
169
+ if not json .get (" items" ):
167
170
raise NoResultsError ()
168
171
169
- video_id = json [' items' ][0 ]['id' ][ ' videoId' ] # type: str
172
+ video_id = json [" items" ][0 ]["id" ][ " videoId" ] # type: str
170
173
return video_id
171
174
172
175
@@ -191,7 +194,7 @@ def youtube(text: str, reply) -> str:
191
194
@hook .command ("youtime" , "ytime" )
192
195
def youtime (text : str , reply ) -> str :
193
196
"""<query> - Gets the total run time of the first YouTube search result for <query>."""
194
- parts = [' statistics' , ' contentDetails' , ' snippet' ]
197
+ parts = [" statistics" , " contentDetails" , " snippet" ]
195
198
try :
196
199
video_id = get_video_id (text )
197
200
request = get_video (video_id , parts )
@@ -204,50 +207,50 @@ def youtime(text: str, reply) -> str:
204
207
205
208
json = request .json ()
206
209
207
- data = json [' items' ]
210
+ data = json [" items" ]
208
211
item = data [0 ]
209
- snippet = item [' snippet' ]
210
- content_details = item [' contentDetails' ]
211
- statistics = item [' statistics' ]
212
+ snippet = item [" snippet" ]
213
+ content_details = item [" contentDetails" ]
214
+ statistics = item [" statistics" ]
212
215
213
- duration = content_details .get (' duration' )
216
+ duration = content_details .get (" duration" )
214
217
if not duration :
215
218
return "Missing duration in API response"
216
219
217
220
length = isodate .parse_duration (duration )
218
221
l_sec = int (length .total_seconds ())
219
- views = int (statistics [' viewCount' ])
222
+ views = int (statistics [" viewCount" ])
220
223
total = int (l_sec * views )
221
224
222
225
length_text = timeformat .format_time (l_sec , simple = True )
223
226
total_text = timeformat .format_time (total , accuracy = 8 )
224
227
225
228
return (
226
- ' The video \x02 {}\x02 has a length of {} and has been viewed {:,} times for '
227
- ' a total run time of {}!' .format (
228
- snippet [' title' ], length_text , views , total_text
229
+ " The video \x02 {}\x02 has a length of {} and has been viewed {:,} times for "
230
+ " a total run time of {}!" .format (
231
+ snippet [" title" ], length_text , views , total_text
229
232
)
230
233
)
231
234
232
235
233
236
@hook .regex (ytpl_re )
234
237
def ytplaylist_url (match : Match [str ]) -> str :
235
238
location = match .group (4 ).split ("=" )[- 1 ]
236
- request = get_playlist (location , [' contentDetails' , ' snippet' ])
239
+ request = get_playlist (location , [" contentDetails" , " snippet" ])
237
240
raise_api_errors (request )
238
241
239
242
json = request .json ()
240
243
241
- data = json [' items' ]
244
+ data = json [" items" ]
242
245
if not data :
243
246
raise NoResultsError ()
244
247
245
248
item = data [0 ]
246
- snippet = item [' snippet' ]
247
- content_details = item [' contentDetails' ]
249
+ snippet = item [" snippet" ]
250
+ content_details = item [" contentDetails" ]
248
251
249
- title = snippet [' title' ]
250
- author = snippet [' channelTitle' ]
251
- num_videos = int (content_details [' itemCount' ])
252
- count_videos = ' - \x02 {:,}\x02 video{}' .format (num_videos , "s" [num_videos == 1 :])
252
+ title = snippet [" title" ]
253
+ author = snippet [" channelTitle" ]
254
+ num_videos = int (content_details [" itemCount" ])
255
+ count_videos = " - \x02 {:,}\x02 video{}" .format (num_videos , "s" [num_videos == 1 :])
253
256
return "\x02 {}\x02 {} - \x02 {}\x02 " .format (title , count_videos , author )
0 commit comments