| 
									
										
										
										
											2021-01-13 11:31:25 +01:00
										 |  |  | # SPDX-License-Identifier: AGPL-3.0-or-later | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  |  Invidious (Videos) | 
					
						
							|  |  |  | """
 | 
					
						
							| 
									
										
										
										
											2019-08-02 13:25:25 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-06 17:42:46 +02:00
										 |  |  | from urllib.parse import quote_plus | 
					
						
							| 
									
										
										
										
											2019-08-02 13:25:25 +02:00
										 |  |  | from dateutil import parser | 
					
						
							|  |  |  | import time | 
					
						
							| 
									
										
										
										
											2021-01-08 13:27:54 +01:00
										 |  |  | import random | 
					
						
							| 
									
										
										
										
											2019-08-02 13:25:25 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-13 11:31:25 +01:00
										 |  |  | # about | 
					
						
							|  |  |  | about = { | 
					
						
							| 
									
										
										
										
											2021-09-01 20:55:06 +02:00
										 |  |  |     "website": 'https://api.invidious.io/', | 
					
						
							| 
									
										
										
										
											2021-01-13 11:31:25 +01:00
										 |  |  |     "wikidata_id": 'Q79343316', | 
					
						
							| 
									
										
										
										
											2021-09-01 20:55:06 +02:00
										 |  |  |     "official_api_documentation": 'https://github.com/iv-org/documentation/blob/master/API.md', | 
					
						
							| 
									
										
										
										
											2021-01-13 11:31:25 +01:00
										 |  |  |     "use_official_api": True, | 
					
						
							|  |  |  |     "require_api_key": False, | 
					
						
							|  |  |  |     "results": 'JSON', | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-02 13:25:25 +02:00
										 |  |  | # engine dependent config | 
					
						
							|  |  |  | categories = ["videos", "music"] | 
					
						
							|  |  |  | paging = True | 
					
						
							|  |  |  | time_range_support = True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-08 13:27:54 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-02 13:25:25 +02:00
										 |  |  | # search-url | 
					
						
							| 
									
										
										
										
											2021-01-08 13:27:54 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | base_url = '' | 
					
						
							|  |  |  | base_url_rand = '' | 
					
						
							| 
									
										
										
										
											2019-08-02 13:25:25 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # do search-request | 
					
						
							|  |  |  | def request(query, params): | 
					
						
							| 
									
										
										
										
											2021-01-08 13:27:54 +01:00
										 |  |  |     global base_url_rand | 
					
						
							| 
									
										
										
										
											2019-08-02 13:25:25 +02:00
										 |  |  |     time_range_dict = { | 
					
						
							|  |  |  |         "day": "today", | 
					
						
							|  |  |  |         "week": "week", | 
					
						
							|  |  |  |         "month": "month", | 
					
						
							|  |  |  |         "year": "year", | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-01-08 13:27:54 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if isinstance(base_url, list): | 
					
						
							|  |  |  |         base_url_rand = random.choice(base_url) | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         base_url_rand = base_url | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     search_url = base_url_rand + "api/v1/search?q={query}" | 
					
						
							| 
									
										
										
										
											2021-12-27 09:26:22 +01:00
										 |  |  |     params["url"] = search_url.format(query=quote_plus(query)) + "&page={pageno}".format(pageno=params["pageno"]) | 
					
						
							| 
									
										
										
										
											2019-08-02 13:25:25 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if params["time_range"] in time_range_dict: | 
					
						
							| 
									
										
										
										
											2021-12-27 09:26:22 +01:00
										 |  |  |         params["url"] += "&date={timerange}".format(timerange=time_range_dict[params["time_range"]]) | 
					
						
							| 
									
										
										
										
											2019-08-02 13:25:25 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if params["language"] != "all": | 
					
						
							|  |  |  |         lang = params["language"].split("-") | 
					
						
							|  |  |  |         if len(lang) == 2: | 
					
						
							|  |  |  |             params["url"] += "&range={lrange}".format(lrange=lang[1]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return params | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # get response from search-request | 
					
						
							|  |  |  | def response(resp): | 
					
						
							|  |  |  |     results = [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     search_results = resp.json() | 
					
						
							|  |  |  |     embedded_url = ( | 
					
						
							|  |  |  |         '<iframe width="540" height="304" ' | 
					
						
							|  |  |  |         + 'data-src="' | 
					
						
							| 
									
										
										
										
											2021-01-08 13:27:54 +01:00
										 |  |  |         + base_url_rand | 
					
						
							| 
									
										
										
										
											2019-08-02 13:25:25 +02:00
										 |  |  |         + 'embed/{videoid}" ' | 
					
						
							|  |  |  |         + 'frameborder="0" allowfullscreen></iframe>' | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-08 13:27:54 +01:00
										 |  |  |     base_invidious_url = base_url_rand + "watch?v=" | 
					
						
							| 
									
										
										
										
											2019-08-02 13:25:25 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     for result in search_results: | 
					
						
							|  |  |  |         rtype = result.get("type", None) | 
					
						
							|  |  |  |         if rtype == "video": | 
					
						
							|  |  |  |             videoid = result.get("videoId", None) | 
					
						
							|  |  |  |             if not videoid: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             url = base_invidious_url + videoid | 
					
						
							|  |  |  |             embedded = embedded_url.format(videoid=videoid) | 
					
						
							|  |  |  |             thumbs = result.get("videoThumbnails", []) | 
					
						
							| 
									
										
										
										
											2021-12-27 09:26:22 +01:00
										 |  |  |             thumb = next((th for th in thumbs if th["quality"] == "sddefault"), None) | 
					
						
							| 
									
										
										
										
											2019-08-02 13:25:25 +02:00
										 |  |  |             if thumb: | 
					
						
							|  |  |  |                 thumbnail = thumb.get("url", "") | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 thumbnail = "" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-27 09:26:22 +01:00
										 |  |  |             publishedDate = parser.parse(time.ctime(result.get("published", 0))) | 
					
						
							| 
									
										
										
										
											2020-08-02 13:31:04 +02:00
										 |  |  |             length = time.gmtime(result.get("lengthSeconds")) | 
					
						
							|  |  |  |             if length.tm_hour: | 
					
						
							|  |  |  |                 length = time.strftime("%H:%M:%S", length) | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 length = time.strftime("%M:%S", length) | 
					
						
							| 
									
										
										
										
											2019-08-02 13:25:25 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             results.append( | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     "url": url, | 
					
						
							|  |  |  |                     "title": result.get("title", ""), | 
					
						
							|  |  |  |                     "content": result.get("description", ""), | 
					
						
							| 
									
										
										
										
											2020-08-02 13:31:04 +02:00
										 |  |  |                     'length': length, | 
					
						
							| 
									
										
										
										
											2019-08-02 13:25:25 +02:00
										 |  |  |                     "template": "videos.html", | 
					
						
							| 
									
										
										
										
											2020-08-02 13:30:38 +02:00
										 |  |  |                     "author": result.get("author"), | 
					
						
							| 
									
										
										
										
											2019-08-02 13:25:25 +02:00
										 |  |  |                     "publishedDate": publishedDate, | 
					
						
							|  |  |  |                     "embedded": embedded, | 
					
						
							|  |  |  |                     "thumbnail": thumbnail, | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return results |