KekikStream 2.0.6__tar.gz → 2.0.8__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Extractors/VidMoly.py +47 -31
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Extractors/YTDLP.py +87 -53
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream.egg-info/PKG-INFO +1 -1
- {kekikstream-2.0.6 → kekikstream-2.0.8}/PKG-INFO +1 -1
- {kekikstream-2.0.6 → kekikstream-2.0.8}/setup.py +1 -1
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/CLI/__init__.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/CLI/pypi_kontrol.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Core/Extractor/ExtractorBase.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Core/Extractor/ExtractorLoader.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Core/Extractor/ExtractorManager.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Core/Extractor/ExtractorModels.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Core/Extractor/YTDLPCache.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Core/Media/MediaHandler.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Core/Media/MediaManager.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Core/Plugin/PluginBase.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Core/Plugin/PluginLoader.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Core/Plugin/PluginManager.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Core/Plugin/PluginModels.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Core/UI/UIManager.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Core/__init__.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Extractors/CloseLoad.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Extractors/ContentX.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Extractors/DonilasPlay.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Extractors/DzenRu.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Extractors/ExPlay.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Extractors/FirePlayer.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Extractors/HDPlayerSystem.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Extractors/JetTv.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Extractors/MailRu.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Extractors/MixPlayHD.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Extractors/MixTiger.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Extractors/MolyStream.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Extractors/Odnoklassniki.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Extractors/PeaceMakerst.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Extractors/PixelDrain.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Extractors/PlayerFilmIzle.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Extractors/RapidVid.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Extractors/SetPlay.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Extractors/SetPrime.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Extractors/SibNet.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Extractors/Sobreatsesuyp.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Extractors/TRsTX.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Extractors/TauVideo.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Extractors/TurboImgz.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Extractors/TurkeyPlayer.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Extractors/VCTPlay.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Extractors/VidHide.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Extractors/VidMoxy.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Extractors/VidPapi.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Extractors/VideoSeyred.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Extractors/YildizKisaFilm.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Plugins/BelgeselX.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Plugins/DiziBox.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Plugins/DiziPal.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Plugins/DiziYou.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Plugins/Dizilla.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Plugins/FilmBip.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Plugins/FilmMakinesi.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Plugins/FilmModu.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Plugins/FullHDFilm.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Plugins/FullHDFilmizlesene.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Plugins/HDFilmCehennemi.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Plugins/JetFilmizle.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Plugins/KultFilmler.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Plugins/RecTV.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Plugins/RoketDizi.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Plugins/SelcukFlix.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Plugins/SetFilmIzle.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Plugins/SezonlukDizi.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Plugins/SineWix.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Plugins/Sinefy.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Plugins/SinemaCX.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Plugins/Sinezy.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Plugins/SuperFilmGeldi.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/Plugins/UgurFilm.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/__init__.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/__main__.py +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream/requirements.txt +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream.egg-info/SOURCES.txt +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream.egg-info/dependency_links.txt +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream.egg-info/entry_points.txt +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream.egg-info/requires.txt +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/KekikStream.egg-info/top_level.txt +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/LICENSE +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/MANIFEST.in +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/README.md +0 -0
- {kekikstream-2.0.6 → kekikstream-2.0.8}/setup.cfg +0 -0
|
@@ -23,11 +23,11 @@ class VidMoly(ExtractorBase):
|
|
|
23
23
|
"Sec-Fetch-Dest" : "iframe",
|
|
24
24
|
})
|
|
25
25
|
|
|
26
|
-
if
|
|
27
|
-
self.main_url = self.main_url.replace(".me", ".net")
|
|
26
|
+
if ".me" in url:
|
|
28
27
|
url = url.replace(".me", ".net")
|
|
29
28
|
|
|
30
|
-
|
|
29
|
+
# VidMoly bazen redirect ediyor, takip et
|
|
30
|
+
response = await self.httpx.get(url, follow_redirects=True)
|
|
31
31
|
if "Select number" in response.text:
|
|
32
32
|
secici = Selector(response.text)
|
|
33
33
|
response = await self.httpx.post(
|
|
@@ -39,21 +39,10 @@ class VidMoly(ExtractorBase):
|
|
|
39
39
|
"ts" : secici.css("input[name='ts']::attr(value)").get(),
|
|
40
40
|
"nonce" : secici.css("input[name='nonce']::attr(value)").get(),
|
|
41
41
|
"ctok" : secici.css("input[name='ctok']::attr(value)").get()
|
|
42
|
-
}
|
|
42
|
+
},
|
|
43
|
+
follow_redirects=True
|
|
43
44
|
)
|
|
44
45
|
|
|
45
|
-
script_match = re.search(r"sources:\s*\[(.*?)\],", response.text, re.DOTALL)
|
|
46
|
-
script_content = script_match[1] if script_match else None
|
|
47
|
-
|
|
48
|
-
if not script_content:
|
|
49
|
-
raise ValueError("Gerekli script bulunamadı.")
|
|
50
|
-
|
|
51
|
-
# Video kaynaklarını ayrıştır
|
|
52
|
-
video_data = self._add_marks(script_content, "file")
|
|
53
|
-
try:
|
|
54
|
-
video_sources = json.loads(f"[{video_data}]")
|
|
55
|
-
except json.JSONDecodeError as hata:
|
|
56
|
-
raise ValueError("Video kaynakları ayrıştırılamadı.") from hata
|
|
57
46
|
|
|
58
47
|
# Altyazı kaynaklarını ayrıştır
|
|
59
48
|
subtitles = []
|
|
@@ -72,22 +61,49 @@ class VidMoly(ExtractorBase):
|
|
|
72
61
|
for sub in subtitle_sources
|
|
73
62
|
if sub.get("kind") == "captions"
|
|
74
63
|
]
|
|
75
|
-
# İlk video kaynağını al
|
|
76
|
-
video_url = None
|
|
77
|
-
for source in video_sources:
|
|
78
|
-
if file_url := source.get("file"):
|
|
79
|
-
video_url = file_url
|
|
80
|
-
break
|
|
81
64
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
65
|
+
script_match = re.search(r"sources:\s*\[(.*?)\],", response.text, re.DOTALL)
|
|
66
|
+
if script_match:
|
|
67
|
+
script_content = script_match[1]
|
|
68
|
+
# Video kaynaklarını ayrıştır
|
|
69
|
+
video_data = self._add_marks(script_content, "file")
|
|
70
|
+
try:
|
|
71
|
+
video_sources = json.loads(f"[{video_data}]")
|
|
72
|
+
# İlk video kaynağını al
|
|
73
|
+
for source in video_sources:
|
|
74
|
+
if file_url := source.get("file"):
|
|
75
|
+
return ExtractResult(
|
|
76
|
+
name = self.name,
|
|
77
|
+
url = file_url,
|
|
78
|
+
referer = self.main_url,
|
|
79
|
+
subtitles = subtitles
|
|
80
|
+
)
|
|
81
|
+
except json.JSONDecodeError:
|
|
82
|
+
pass
|
|
83
|
+
|
|
84
|
+
# Fallback: Doğrudan file regex ile ara (Kotlin mantığı)
|
|
85
|
+
# file:"..." veya file: "..."
|
|
86
|
+
if file_match := re.search(r'file\s*:\s*["\']([^"\']+\.m3u8[^"\']*)["\']', response.text):
|
|
87
|
+
return ExtractResult(
|
|
88
|
+
name = self.name,
|
|
89
|
+
url = file_match.group(1),
|
|
90
|
+
referer = self.main_url,
|
|
91
|
+
subtitles = subtitles
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
# Fallback 2: Herhangi bir file (m3u8 olma şartı olmadan ama tercihen)
|
|
95
|
+
if file_match := re.search(r'file\s*:\s*["\']([^"\']+)["\']', response.text):
|
|
96
|
+
url_candidate = file_match.group(1)
|
|
97
|
+
# Resim dosyalarını hariç tut
|
|
98
|
+
if not url_candidate.endswith(('.jpg', '.png', '.jpeg')):
|
|
99
|
+
return ExtractResult(
|
|
100
|
+
name = self.name,
|
|
101
|
+
url = url_candidate,
|
|
102
|
+
referer = self.main_url,
|
|
103
|
+
subtitles = subtitles
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
raise ValueError("Video URL bulunamadı.")
|
|
91
107
|
|
|
92
108
|
def _add_marks(self, text: str, field: str) -> str:
|
|
93
109
|
"""
|
|
@@ -10,6 +10,86 @@ class YTDLP(ExtractorBase):
|
|
|
10
10
|
|
|
11
11
|
_FAST_DOMAIN_RE = None # compiled mega-regex (host üstünden)
|
|
12
12
|
|
|
13
|
+
_POPULAR_TLDS = {
|
|
14
|
+
"com", "net", "org", "tv", "io", "co", "me", "ly", "ru", "fr", "de", "es", "it",
|
|
15
|
+
"nl", "be", "ch", "at", "uk", "ca", "au", "jp", "kr", "cn", "in", "br", "mx",
|
|
16
|
+
"ar", "tr", "gov", "edu", "mil", "int", "info", "biz", "name", "pro", "aero",
|
|
17
|
+
"coop", "museum", "onion"
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
# 1. Literal TLD Regex: youtube\.com, vimeo\.com
|
|
21
|
+
# sorted by reverse length to prevent partial matches (e.g. 'co' matching 'com')
|
|
22
|
+
_LITERAL_TLD_RE = re.compile(
|
|
23
|
+
rf"([a-z0-9][-a-z0-9]*(?:\\\.[-a-z0-9]+)*\\\.(?:{'|'.join(sorted(_POPULAR_TLDS, key=len, reverse=True))}))",
|
|
24
|
+
re.IGNORECASE
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
# 2. Regex TLD Regex: dailymotion\.[a-z]{2,3}
|
|
28
|
+
_REGEX_TLD_RE = re.compile(
|
|
29
|
+
r"([a-z0-9][-a-z0-9]*)\\\.\[a-z\]\{?\d*,?\d*\}?",
|
|
30
|
+
re.IGNORECASE
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
# 3. Alternation TLD Regex: \.(?:com|net|org)
|
|
34
|
+
_ALT_TLD_RE = re.compile(
|
|
35
|
+
r"\\\.\(\?:([a-z|]+)\)",
|
|
36
|
+
re.IGNORECASE
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
# Kelime yakalayıcı (domain bulmak için)
|
|
40
|
+
_DOMAIN_WORD_RE = re.compile(
|
|
41
|
+
r"([a-z0-9][-a-z0-9]*)",
|
|
42
|
+
re.IGNORECASE
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
@classmethod
|
|
46
|
+
def _extract_literal_domains(cls, valid_url: str) -> set[str]:
|
|
47
|
+
"""Pattern 1: Literal TLD domainlerini (youtube.com) çıkarır."""
|
|
48
|
+
return {
|
|
49
|
+
m.replace(r"\.", ".").lower()
|
|
50
|
+
for m in cls._LITERAL_TLD_RE.findall(valid_url)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@classmethod
|
|
54
|
+
def _extract_regex_tld_domains(cls, valid_url: str) -> set[str]:
|
|
55
|
+
"""Pattern 2: Regex TLD domainlerini (dailymotion.[...]) çıkarır ve popüler TLD'lerle birleştirir."""
|
|
56
|
+
domains = set()
|
|
57
|
+
for base in cls._REGEX_TLD_RE.findall(valid_url):
|
|
58
|
+
base_domain = base.lower()
|
|
59
|
+
for tld in cls._POPULAR_TLDS:
|
|
60
|
+
domains.add(f"{base_domain}.{tld}")
|
|
61
|
+
return domains
|
|
62
|
+
|
|
63
|
+
@classmethod
|
|
64
|
+
def _extract_alternation_domains(cls, valid_url: str) -> set[str]:
|
|
65
|
+
"""Pattern 3: Alternation TLD domainlerini (pornhub.(?:com|net)) çıkarır."""
|
|
66
|
+
domains = set()
|
|
67
|
+
for m in cls._ALT_TLD_RE.finditer(valid_url):
|
|
68
|
+
tlds = m.group(1).split("|")
|
|
69
|
+
start = m.start()
|
|
70
|
+
|
|
71
|
+
# Geriye doğru git ve domain'i bul
|
|
72
|
+
before = valid_url[:start]
|
|
73
|
+
|
|
74
|
+
# 1. Named Groups (?P<name> temizle
|
|
75
|
+
before = re.sub(r"\(\?P<[^>]+>", "", before)
|
|
76
|
+
|
|
77
|
+
# 2. Simple Non-Capturing Groups (?:xxx)? temizle (sadece alphanumeric ve escape)
|
|
78
|
+
before = re.sub(r"\(\?:[a-z0-9-]+\)\??", "", before)
|
|
79
|
+
|
|
80
|
+
# Son domain-like kelimeyi al
|
|
81
|
+
words = cls._DOMAIN_WORD_RE.findall(before)
|
|
82
|
+
if not words:
|
|
83
|
+
continue
|
|
84
|
+
|
|
85
|
+
base = words[-1].lower()
|
|
86
|
+
for tld in tlds:
|
|
87
|
+
tld = tld.strip().lower()
|
|
88
|
+
if tld and len(tld) <= 6:
|
|
89
|
+
domains.add(f"{base}.{tld}")
|
|
90
|
+
|
|
91
|
+
return domains
|
|
92
|
+
|
|
13
93
|
@classmethod
|
|
14
94
|
def _init_fast_domain_regex(cls):
|
|
15
95
|
"""
|
|
@@ -19,44 +99,31 @@ class YTDLP(ExtractorBase):
|
|
|
19
99
|
return
|
|
20
100
|
|
|
21
101
|
domains = set()
|
|
22
|
-
|
|
23
|
-
# Merkezi cache'den extractorları al
|
|
24
102
|
extractors = get_ytdlp_extractors()
|
|
25
103
|
|
|
26
|
-
# yt-dlp extractor'larının _VALID_URL regex'lerinden domain yakala
|
|
27
|
-
# Regex metinlerinde domainler genelde "\." şeklinde geçer.
|
|
28
|
-
domain_pat = re.compile(r"(?:[a-z0-9-]+\\\.)+[a-z]{2,}", re.IGNORECASE)
|
|
29
|
-
|
|
30
104
|
for ie in extractors:
|
|
31
105
|
valid = getattr(ie, "_VALID_URL", None)
|
|
32
106
|
if not valid or not isinstance(valid, str):
|
|
33
107
|
continue
|
|
34
108
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
# Çok agresif/şüpheli şeyleri elemek istersen burada filtre koyabilirsin
|
|
39
|
-
# (genelde gerek kalmıyor)
|
|
40
|
-
domains.add(d)
|
|
109
|
+
domains |= cls._extract_literal_domains(valid)
|
|
110
|
+
domains |= cls._extract_regex_tld_domains(valid)
|
|
111
|
+
domains |= cls._extract_alternation_domains(valid)
|
|
41
112
|
|
|
42
113
|
# Hiç domain çıkmazsa (çok uç durum) fallback: boş regex
|
|
43
114
|
if not domains:
|
|
44
115
|
cls._FAST_DOMAIN_RE = re.compile(r"$^") # hiçbir şeye match etmez
|
|
45
116
|
return
|
|
46
117
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
joined = "|".join(sorted(re.escape(d) for d in domains))
|
|
50
|
-
pattern = rf"(?:^|.*\.)(?:{joined})$"
|
|
51
|
-
cls._FAST_DOMAIN_RE = re.compile(pattern, re.IGNORECASE)
|
|
118
|
+
joined = "|".join(re.escape(d) for d in sorted(domains))
|
|
119
|
+
cls._FAST_DOMAIN_RE = re.compile(rf"(?:^|.*\.)(?:{joined})$", re.IGNORECASE)
|
|
52
120
|
|
|
53
121
|
def __init__(self):
|
|
54
122
|
self.__class__._init_fast_domain_regex()
|
|
55
123
|
|
|
56
124
|
def can_handle_url(self, url: str) -> bool:
|
|
57
125
|
"""
|
|
58
|
-
Fast-path: URL host'unu tek mega-regex ile kontrol et
|
|
59
|
-
Slow-path: gerekirse mevcut extract_info tabanlı kontrolün
|
|
126
|
+
Fast-path: URL host'unu tek mega-regex ile kontrol et
|
|
60
127
|
"""
|
|
61
128
|
# URL parse + host al
|
|
62
129
|
try:
|
|
@@ -77,40 +144,7 @@ class YTDLP(ExtractorBase):
|
|
|
77
144
|
if host and self.__class__._FAST_DOMAIN_RE.search(host):
|
|
78
145
|
return True
|
|
79
146
|
|
|
80
|
-
#
|
|
81
|
-
# try:
|
|
82
|
-
# # stderr'ı geçici olarak kapat (hata mesajlarını gizle)
|
|
83
|
-
# old_stderr = sys.stderr
|
|
84
|
-
# sys.stderr = open(os.devnull, "w")
|
|
85
|
-
|
|
86
|
-
# try:
|
|
87
|
-
# ydl_opts = {
|
|
88
|
-
# "simulate" : True, # Download yok, sadece tespit
|
|
89
|
-
# "quiet" : True, # Log kirliliği yok
|
|
90
|
-
# "no_warnings" : True, # Uyarı mesajları yok
|
|
91
|
-
# "extract_flat" : True, # Minimal işlem
|
|
92
|
-
# "no_check_certificates" : True,
|
|
93
|
-
# "ignoreerrors" : True, # Hataları yoksay
|
|
94
|
-
# "socket_timeout" : 3,
|
|
95
|
-
# "retries" : 1
|
|
96
|
-
# }
|
|
97
|
-
|
|
98
|
-
# with yt_dlp.YoutubeDL(ydl_opts) as ydl:
|
|
99
|
-
# # URL'yi işleyebiliyor mu kontrol et
|
|
100
|
-
# info = ydl.extract_info(url, download=False, process=False)
|
|
101
|
-
|
|
102
|
-
# # Generic extractor ise atla
|
|
103
|
-
# if info and info.get("extractor_key") != "Generic":
|
|
104
|
-
# return True
|
|
105
|
-
|
|
106
|
-
# return False
|
|
107
|
-
# finally:
|
|
108
|
-
# # stderr'ı geri yükle
|
|
109
|
-
# sys.stderr.close()
|
|
110
|
-
# sys.stderr = old_stderr
|
|
111
|
-
|
|
112
|
-
# except Exception:
|
|
113
|
-
# yt-dlp işleyemezse False döndür
|
|
147
|
+
# yt-dlp işleyemezse False döndür
|
|
114
148
|
return False
|
|
115
149
|
|
|
116
150
|
async def extract(self, url: str, referer: str | None = None) -> ExtractResult:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: KekikStream
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.8
|
|
4
4
|
Summary: terminal üzerinden medya içeriği aramanızı ve VLC/MPV gibi popüler medya oynatıcılar aracılığıyla doğrudan izlemenizi sağlayan modüler ve genişletilebilir bir bıdı bıdı
|
|
5
5
|
Home-page: https://github.com/keyiflerolsun/KekikStream
|
|
6
6
|
Author: keyiflerolsun
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: KekikStream
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.8
|
|
4
4
|
Summary: terminal üzerinden medya içeriği aramanızı ve VLC/MPV gibi popüler medya oynatıcılar aracılığıyla doğrudan izlemenizi sağlayan modüler ve genişletilebilir bir bıdı bıdı
|
|
5
5
|
Home-page: https://github.com/keyiflerolsun/KekikStream
|
|
6
6
|
Author: keyiflerolsun
|
|
@@ -6,7 +6,7 @@ from io import open
|
|
|
6
6
|
setup(
|
|
7
7
|
# ? Genel Bilgiler
|
|
8
8
|
name = "KekikStream",
|
|
9
|
-
version = "2.0.
|
|
9
|
+
version = "2.0.8",
|
|
10
10
|
url = "https://github.com/keyiflerolsun/KekikStream",
|
|
11
11
|
description = "terminal üzerinden medya içeriği aramanızı ve VLC/MPV gibi popüler medya oynatıcılar aracılığıyla doğrudan izlemenizi sağlayan modüler ve genişletilebilir bir bıdı bıdı",
|
|
12
12
|
keywords = ["KekikStream", "KekikAkademi", "keyiflerolsun"],
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|