def __init__(self, url): Plugin.__init__(self, url) self._hosted_chain = [] match = _url_re.match(url).groupdict() parsed = urlparse(url) self.params = parse_query(parsed.query) self.subdomain = match.get("subdomain") self.video_id = None self.video_type = None self._channel_id = None self._channel = None self.clip_name = None if self.subdomain == "player": # pop-out player if self.params.get("video"): try: self.video_type = self.params["video"][0] self.video_id = self.params["video"][1:] except IndexError: self.logger.debug("Invalid video param: {0}", self.params["video"]) self._channel = self.params.get("channel") elif self.subdomain == "clips": # clip share URL self.clip_name = match.get("channel") else: self._channel = match.get("channel") and match.get("channel").lower() self.video_type = match.get("video_type") if match.get("videos_id"): self.video_type = "v" self.video_id = match.get("video_id") or match.get("videos_id") self.clip_name = match.get("clip_name") self.api = TwitchAPI(beta=self.subdomain == "beta", version=5) self.usher = UsherService()
def __init__(self, url): Plugin.__init__(self, url) self._headers = { 'Referer': self.url, 'User-Agent': useragents.FIREFOX } self._room_id = None self._stream_urls = None
def __init__(self, url): Plugin.__init__(self, url) live_match = _live_url_re.match(url) if live_match: self.live = True self.channel_path = live_match.group("channel_path") else: self.live = False
def stream_weight(cls, stream): match = re.match("(\w+)_3d", stream) if match: weight, group = Plugin.stream_weight(match.group(1)) weight -= 1 group = "youtube_3d" else: weight, group = Plugin.stream_weight(stream) return weight, group
def stream_weight(cls, stream): match = re.match("mobile_(\w+)", stream) if match: weight, group = Plugin.stream_weight(match.group(1)) weight -= 1 group = "mobile_ustream" elif stream == "recorded": weight, group = 720, "ustream" else: weight, group = Plugin.stream_weight(stream) return weight, group
def get_formatter(plugin: Plugin): return Formatter( { "url": lambda: args.url, "author": lambda: plugin.get_author(), "category": lambda: plugin.get_category(), "game": lambda: plugin.get_category(), "title": lambda: plugin.get_title(), "time": lambda: datetime.now() }, { "time": lambda dt, fmt: dt.strftime(fmt) })
def __init__(self, url): Plugin.__init__(self, url) match = _url_re.match(url).groupdict() self.channel = match.get("channel").lower() self.subdomain = match.get("subdomain") self.video_type = match.get("video_type") self.video_id = match.get("video_id") parsed = urlparse(url) self.params = parse_query(parsed.query) self.api = TwitchAPI(beta=self.subdomain == "beta") self.usher = UsherService()
def test_cookie_store_load(self): session = Mock() session.http.cookies = requests.cookies.RequestsCookieJar() Plugin.bind(session, 'tests.test_plugin') Plugin.cache = Mock() Plugin.cache.get_all.return_value = { "__cookie:test-name:test.se:80:/": self._create_cookie_dict("test-name", "test-value", None) } plugin = Plugin("http://test.se") self.assertSequenceEqual( list(map(self._cookie_to_dict, session.http.cookies)), [self._cookie_to_dict(requests.cookies.create_cookie("test-name", "test-value", domain="test.se"))] )
def stream_weight(cls, stream): match_3d = re.match(r"(\w+)_3d", stream) match_hfr = re.match(r"(\d+p)(\d+)", stream) if match_3d: weight, group = Plugin.stream_weight(match_3d.group(1)) weight -= 1 group = "youtube_3d" elif match_hfr: weight, group = Plugin.stream_weight(match_hfr.group(1)) weight += 1 group = "high_frame_rate" else: weight, group = Plugin.stream_weight(stream) return weight, group
def test_cookie_store_save(self): session = Mock() session.http.cookies = [ requests.cookies.create_cookie("test-name", "test-value", domain="test.se") ] Plugin.bind(session, 'tests.test_plugin') Plugin.cache = Mock() Plugin.cache.get_all.return_value = {} plugin = Plugin("http://test.se") plugin.save_cookies(default_expires=3600) Plugin.cache.set.assert_called_with("__cookie:test-name:test.se:80:/", self._create_cookie_dict("test-name", "test-value", None), 3600)
def format_valid_streams(plugin: Plugin, streams: Streams) -> str: """Formats a dict of streams. Filters out synonyms and displays them next to the stream they point to. Streams are sorted according to their quality (based on plugin.stream_weight). """ delimiter = ", " validstreams = [] for name, stream in sorted( streams.items(), key=lambda stream: plugin.stream_weight(stream[0])): if name in STREAM_SYNONYMS: continue def synonymfilter(n): return stream is streams[n] and n is not name synonyms = list(filter(synonymfilter, streams.keys())) if len(synonyms) > 0: joined = delimiter.join(synonyms) name = f"{name} ({joined})" validstreams.append(name) return delimiter.join(validstreams)
def stream_weight(cls, stream): if stream == "source": weight = 1080 else: weight, group = Plugin.stream_weight(stream) return weight, "azubutv"
def stream_weight(cls, key): # NHL.tv may provide any combination of broadcasts depending on the game. # Prioritize national > home > away > french > multicam for best quality synonym try: (name, quality) = key.split("_") if quality == "audio": # radio feeds are all 48k audio weight = 48 else: if quality.endswith("p60"): weight = int(quality[:-3]) + 10 else: weight = int(quality.rstrip("p")) if key.startswith("national"): weight += cls.NATIONAL_WEIGHT elif key.startswith("home"): weight += cls.HOME_WEIGHT elif key.startswith("away"): weight += cls.AWAY_WEIGHT elif key.startswith("french"): weight += cls.FRENCH_WEIGHT return weight, "nhltv" except ValueError: pass return Plugin.stream_weight(key)
def stream_weight(cls, key): match_ultra = QUALITY_WEIGHTS_ULTRA.match(key) if match_ultra: ultra_level = int(match_ultra.group('level')) return 1080 * (ultra_level + 1), "bliptv" weight = QUALITY_WEIGHTS.get(key) if weight: return weight, "bliptv" return Plugin.stream_weight(key)
def test_cookie_store_save_expires(self): with freezegun.freeze_time(datetime.datetime(2018, 1, 1)): session = Mock() session.http.cookies = [ requests.cookies.create_cookie("test-name", "test-value", domain="test.se", expires=time.time() + 3600, rest={'HttpOnly': None}) ] Plugin.bind(session, 'tests.test_plugin') Plugin.cache = Mock() Plugin.cache.get_all.return_value = {} plugin = Plugin("http://test.se") plugin.save_cookies(default_expires=60) Plugin.cache.set.assert_called_with("__cookie:test-name:test.se:80:/", self._create_cookie_dict("test-name", "test-value", 1514768400), 3600)
def __init__(self, url): Plugin.__init__(self, url) match = _url_re.match(url).groupdict() self._channel = match.get("channel") and match.get("channel").lower() self._channel_id = None self.subdomain = match.get("subdomain") self.video_type = match.get("video_type") if match.get("videos_id"): self.video_type = "v" self.video_id = match.get("video_id") or match.get("videos_id") self.clip_name = match.get("clip_name") self._hosted_chain = [] parsed = urlparse(url) self.params = parse_query(parsed.query) self.api = TwitchAPI(beta=self.subdomain == "beta", version=5) self.usher = UsherService()
def handle_stream(plugin: Plugin, streams: Streams, stream_name: str) -> None: """Decides what to do with the selected stream. Depending on arguments it can be one of these: - Output JSON represenation - Output the stream URL - Continuously output the stream over HTTP - Output stream data to selected output """ stream_name = resolve_stream_name(streams, stream_name) stream = streams[stream_name] # Print JSON representation of the stream if args.json: console.msg_json(stream, metadata=plugin.get_metadata()) elif args.stream_url: try: console.msg(stream.to_url()) except TypeError: console.exit("The stream specified cannot be translated to a URL") # Output the stream else: # Find any streams with a '_alt' suffix and attempt # to use these in case the main stream is not usable. alt_streams = list( filter(lambda k: stream_name + "_alt" in k, sorted(streams.keys()))) file_output = args.output or args.stdout formatter = get_formatter(plugin) for stream_name in [stream_name] + alt_streams: stream = streams[stream_name] stream_type = type(stream).shortname() if stream_type in args.player_passthrough and not file_output: log.info(f"Opening stream: {stream_name} ({stream_type})") success = output_stream_passthrough(stream, formatter) elif args.player_external_http: return output_stream_http(plugin, streams, formatter, external=True, port=args.player_external_http_port) elif args.player_continuous_http and not file_output: return output_stream_http(plugin, streams, formatter) else: log.info(f"Opening stream: {stream_name} ({stream_type})") success = output_stream(stream, formatter) if success: break
def __init__(self, url): Plugin.__init__(self, url) live_match = _live_url_re.match(url) if live_match: self.live = True self.stream_id = live_match.group("stream_id") # Remove slashes self.stream_id.replace("/", "") # Remove dashes self.stream_id.replace("-", "") # Rondo is identified as ras3 if self.stream_id == "rondo": self.stream_id = "ras3" else: self.live = False
def test_cookie_store_clear_filter(self): session = Mock() session.http.cookies = requests.cookies.RequestsCookieJar() Plugin.bind(session, 'tests.test_plugin') Plugin.cache = Mock() Plugin.cache.get_all.return_value = { "__cookie:test-name:test.se:80:/": self._create_cookie_dict("test-name", "test-value", None), "__cookie:test-name2:test.se:80:/": self._create_cookie_dict("test-name2", "test-value2", None) } plugin = Plugin("http://test.se") # non-empty cookiejar self.assertTrue(len(session.http.cookies.get_dict()) > 0) plugin.clear_cookies(lambda c: c.name.endswith("2")) self.assertSequenceEqual( Plugin.cache.set.mock_calls, [call("__cookie:test-name2:test.se:80:/", None, 0)]) self.assertSequenceEqual( list(map(self._cookie_to_dict, session.http.cookies)), [ self._cookie_to_dict( requests.cookies.create_cookie( "test-name", "test-value", domain="test.se")) ])
def test_cookie_store_clear(self): session = Mock() session.http.cookies = requests.cookies.RequestsCookieJar() Plugin.bind(session, 'tests.test_plugin') Plugin.cache = Mock() Plugin.cache.get_all.return_value = { "__cookie:test-name:test.se:80:/": self._create_cookie_dict("test-name", "test-value", None), "__cookie:test-name2:test.se:80:/": self._create_cookie_dict("test-name2", "test-value2", None) } plugin = Plugin("http://test.se") # non-empty cookiejar self.assertTrue(len(session.http.cookies.get_dict()) > 0) plugin.clear_cookies() self.assertSequenceEqual( Plugin.cache.set.mock_calls, [call("__cookie:test-name:test.se:80:/", None, 0), call("__cookie:test-name2:test.se:80:/", None, 0)]) self.assertSequenceEqual(session.http.cookies, [])
def test_cookie_store_clear_filter(self): session = Mock() session.http.cookies = requests.cookies.RequestsCookieJar() Plugin.bind(session, 'tests.test_plugin') Plugin.cache = Mock() Plugin.cache.get_all.return_value = { "__cookie:test-name:test.se:80:/": self._create_cookie_dict("test-name", "test-value", None), "__cookie:test-name2:test.se:80:/": self._create_cookie_dict("test-name2", "test-value2", None) } plugin = Plugin("http://test.se") # non-empty cookiejar self.assertTrue(len(session.http.cookies.get_dict()) > 0) plugin.clear_cookies(lambda c: c.name.endswith("2")) self.assertSequenceEqual( Plugin.cache.set.mock_calls, [call("__cookie:test-name2:test.se:80:/", None, 0)]) self.assertSequenceEqual( list(map(self._cookie_to_dict, session.http.cookies)), [self._cookie_to_dict(requests.cookies.create_cookie("test-name", "test-value", domain="test.se"))] )
def test_cookie_store_save_expires(self): with freezegun.freeze_time(lambda: datetime.datetime(2018, 1, 1)): session = Mock() session.http.cookies = [ requests.cookies.create_cookie("test-name", "test-value", domain="test.se", expires=time.time() + 3600, rest={'HttpOnly': None}) ] Plugin.bind(session, 'tests.test_plugin') Plugin.cache = Mock() Plugin.cache.get_all.return_value = {} plugin = Plugin("http://test.se") plugin.save_cookies(default_expires=60) Plugin.cache.set.assert_called_with("__cookie:test-name:test.se:80:/", self._create_cookie_dict("test-name", "test-value", 1514768400), 3600)
def stream_weight(cls, key): weight = QUALITY_WEIGHTS.get(key) if weight: return weight, "afreeca" return Plugin.stream_weight(key)
def stream_weight(cls, stream): if stream in _quality_weights: return _quality_weights.get(stream), "quality" return Plugin.stream_weight(stream)
def stream_weight(cls, key): weight = STREAM_WEIGHTS.get(key) if weight: return weight, "crunchyroll" return Plugin.stream_weight(key)
def stream_weight(cls, stream): if stream in STREAM_WEIGHTS: return STREAM_WEIGHTS[stream], "douyutv" return Plugin.stream_weight(stream)
def stream_weight(cls, key): weight = QUALITY_WEIGHTS.get(key) if weight: return weight, "zdf_mediathek" return Plugin.stream_weight(key)
def stream_weight(cls, key): weight = cls.quality_weights.get(key) if weight: return weight, "filmon" return Plugin.stream_weight(key)
def stream_weight(cls, key): weight = cls.QUALITY_WEIGHTS.get(key) if weight: return weight, 'huya' return Plugin.stream_weight(key)
def __init__(self, url): Plugin.__init__(self, url) match = _url_re.match(url) self._stream = match and match.groupdict()["stream"]
def stream_weight(cls, key): weight = QUALITY_WEIGHTS.get(key) if weight: return weight, "gaminglive" return Plugin.stream_weight(key)
def __init__(self, url): Plugin.__init__(self, url) self._headers = {'Referer': self.url} self._room_id = None self._stream_urls = None
def stream_weight(cls, key): weight = QUALITY_MAP.get(key) if weight: return weight, "beat" return Plugin.stream_weight(key)
def stream_weight(cls, stream): if stream in STREAM_WEIGHTS: return STREAM_WEIGHTS[stream], "Bilibili" return Plugin.stream_weight(stream)
def __init__(self, url): Plugin.__init__(self, url) self.session.http.headers = {"User-Agent": useragents.SAFARI_8} self.zclient = ZTNRClient(self.secret_key, self.session)
def __init__(self, url): Plugin.__init__(self, url) match = _url_re.match(url).groupdict() self.channel_path = match["channel_path"]
def stream_weight(cls, stream): if stream in STREAM_WEIGHTS: return STREAM_WEIGHTS[stream], "kingkong" return Plugin.stream_weight(stream)
def stream_weight(cls, stream): if stream in cls.STREAM_WEIGHTS: return cls.STREAM_WEIGHTS[stream], "ustreamtv" return Plugin.stream_weight(stream)
def stream_weight(cls, key): weight = QUALITY_WEIGHTS.get(key) if weight: return weight, "twitch" return Plugin.stream_weight(key)
def __init__(self, url): Plugin.__init__(self, url) self.url = url self.isVod = self._re_url_vod.search(url) is not None