StreamingCommunity 3.0.1__tar.gz → 3.0.3__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.
Potentially problematic release.
This version of StreamingCommunity might be problematic. Click here for more details.
- {streamingcommunity-3.0.1/StreamingCommunity.egg-info → streamingcommunity-3.0.3}/PKG-INFO +17 -2
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/README.md +16 -2
- streamingcommunity-3.0.3/StreamingCommunity/Api/Player/hdplayer.py +65 -0
- streamingcommunity-3.0.3/StreamingCommunity/Api/Player/mixdrop.py +145 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/1337xx/site.py +1 -1
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/altadefinizione/site.py +1 -1
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/animeunity/site.py +2 -1
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/animeworld/site.py +7 -3
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/ddlstreamitaly/site.py +1 -1
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/guardaserie/site.py +1 -1
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/raiplay/site.py +2 -2
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/streamingcommunity/series.py +2 -2
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/streamingcommunity/site.py +1 -1
- streamingcommunity-3.0.3/StreamingCommunity/Api/Site/streamingwatch/__init__.py +95 -0
- streamingcommunity-3.0.3/StreamingCommunity/Api/Site/streamingwatch/film.py +61 -0
- streamingcommunity-3.0.3/StreamingCommunity/Api/Site/streamingwatch/series.py +160 -0
- streamingcommunity-3.0.3/StreamingCommunity/Api/Site/streamingwatch/site.py +111 -0
- streamingcommunity-3.0.3/StreamingCommunity/Api/Site/streamingwatch/util/ScrapeSerie.py +118 -0
- streamingcommunity-3.0.3/StreamingCommunity/Lib/Proxies/proxy.py +232 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Upload/update.py +23 -22
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Upload/version.py +1 -1
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Util/os.py +38 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/global_search.py +16 -4
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/run.py +11 -2
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3/StreamingCommunity.egg-info}/PKG-INFO +17 -2
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity.egg-info/SOURCES.txt +8 -1
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity.egg-info/requires.txt +1 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/requirements.txt +2 -1
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/setup.py +1 -1
- streamingcommunity-3.0.1/StreamingCommunity/Api/Player/maxstream.py +0 -140
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/LICENSE +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/MANIFEST.in +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Player/Helper/Vixcloud/js_parser.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Player/Helper/Vixcloud/util.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Player/ddl.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Player/mediapolisvod.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Player/supervideo.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Player/sweetpixel.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Player/vixcloud.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/1337xx/__init__.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/1337xx/title.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/altadefinizione/__init__.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/altadefinizione/film.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/altadefinizione/series.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/altadefinizione/util/ScrapeSerie.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/animeunity/__init__.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/animeunity/film.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/animeunity/serie.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/animeunity/util/ScrapeSerie.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/animeworld/__init__.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/animeworld/film.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/animeworld/serie.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/animeworld/util/ScrapeSerie.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/ddlstreamitaly/__init__.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/ddlstreamitaly/series.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/ddlstreamitaly/util/ScrapeSerie.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/guardaserie/__init__.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/guardaserie/series.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/guardaserie/util/ScrapeSerie.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/raiplay/__init__.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/raiplay/film.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/raiplay/series.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/raiplay/util/ScrapeSerie.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/streamingcommunity/__init__.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/streamingcommunity/film.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/streamingcommunity/util/ScrapeSerie.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Template/Class/SearchType.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Template/Util/__init__.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Template/Util/manage_ep.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Template/__init__.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Template/config_loader.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Template/site.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Lib/Downloader/HLS/downloader.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Lib/Downloader/HLS/segments.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Lib/Downloader/MP4/downloader.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Lib/Downloader/TOR/downloader.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Lib/Downloader/__init__.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Lib/FFmpeg/__init__.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Lib/FFmpeg/capture.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Lib/FFmpeg/command.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Lib/FFmpeg/util.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Lib/M3U8/__init__.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Lib/M3U8/decryptor.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Lib/M3U8/estimator.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Lib/M3U8/parser.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Lib/M3U8/url_fixer.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Lib/TMBD/__init__.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Lib/TMBD/obj_tmbd.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Lib/TMBD/tmdb.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/TelegramHelp/__init__.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/TelegramHelp/telegram_bot.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Util/color.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Util/config_json.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Util/ffmpeg_installer.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Util/headers.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Util/logger.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Util/message.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Util/table.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/__init__.py +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity.egg-info/dependency_links.txt +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity.egg-info/entry_points.txt +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity.egg-info/top_level.txt +0 -0
- {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: StreamingCommunity
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.3
|
|
4
4
|
Home-page: https://github.com/Lovi-0/StreamingCommunity
|
|
5
5
|
Author: Lovi-0
|
|
6
6
|
Project-URL: Bug Reports, https://github.com/Lovi-0/StreamingCommunity/issues
|
|
@@ -17,6 +17,7 @@ Requires-Dist: m3u8
|
|
|
17
17
|
Requires-Dist: certifi
|
|
18
18
|
Requires-Dist: psutil
|
|
19
19
|
Requires-Dist: unidecode
|
|
20
|
+
Requires-Dist: dnspython
|
|
20
21
|
Requires-Dist: jsbeautifier
|
|
21
22
|
Requires-Dist: pathvalidate
|
|
22
23
|
Requires-Dist: pycryptodomex
|
|
@@ -832,11 +833,25 @@ Contributions are welcome! Steps:
|
|
|
832
833
|
4. Push to branch (`git push origin feature/AmazingFeature`)
|
|
833
834
|
5. Open Pull Request
|
|
834
835
|
|
|
835
|
-
|
|
836
836
|
# Disclaimer
|
|
837
837
|
|
|
838
838
|
This software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or the use or other dealings in the software.
|
|
839
839
|
|
|
840
|
+
## Useful Project
|
|
841
|
+
|
|
842
|
+
### 🎯 [Unit3Dup](https://github.com/31December99/Unit3Dup)
|
|
843
|
+
Bot in Python per la generazione e l'upload automatico di torrent su tracker basati su Unit3D.
|
|
844
|
+
|
|
845
|
+
|
|
846
|
+
### 🇮🇹 [MammaMia](https://github.com/UrloMythus/MammaMia)
|
|
847
|
+
Addon per Stremio che consente lo streaming HTTPS di film, serie, anime e TV in diretta in lingua italiana.
|
|
848
|
+
|
|
849
|
+
### 🧩 [streamingcommunity-unofficialapi](https://github.com/Blu-Tiger/streamingcommunity-unofficialapi)
|
|
850
|
+
API non ufficiale per accedere ai contenuti del sito italiano StreamingCommunity.
|
|
851
|
+
|
|
852
|
+
### 🎥 [stream-buddy](https://github.com/Bbalduzz/stream-buddy)
|
|
853
|
+
Tool per guardare o scaricare film dalla piattaforma StreamingCommunity.
|
|
854
|
+
|
|
840
855
|
## Contributors
|
|
841
856
|
|
|
842
857
|
<a href="https://github.com/Arrowar/StreamingCommunity/graphs/contributors" alt="View Contributors">
|
|
@@ -797,13 +797,27 @@ Contributions are welcome! Steps:
|
|
|
797
797
|
4. Push to branch (`git push origin feature/AmazingFeature`)
|
|
798
798
|
5. Open Pull Request
|
|
799
799
|
|
|
800
|
-
|
|
801
800
|
# Disclaimer
|
|
802
801
|
|
|
803
802
|
This software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or the use or other dealings in the software.
|
|
804
803
|
|
|
804
|
+
## Useful Project
|
|
805
|
+
|
|
806
|
+
### 🎯 [Unit3Dup](https://github.com/31December99/Unit3Dup)
|
|
807
|
+
Bot in Python per la generazione e l'upload automatico di torrent su tracker basati su Unit3D.
|
|
808
|
+
|
|
809
|
+
|
|
810
|
+
### 🇮🇹 [MammaMia](https://github.com/UrloMythus/MammaMia)
|
|
811
|
+
Addon per Stremio che consente lo streaming HTTPS di film, serie, anime e TV in diretta in lingua italiana.
|
|
812
|
+
|
|
813
|
+
### 🧩 [streamingcommunity-unofficialapi](https://github.com/Blu-Tiger/streamingcommunity-unofficialapi)
|
|
814
|
+
API non ufficiale per accedere ai contenuti del sito italiano StreamingCommunity.
|
|
815
|
+
|
|
816
|
+
### 🎥 [stream-buddy](https://github.com/Bbalduzz/stream-buddy)
|
|
817
|
+
Tool per guardare o scaricare film dalla piattaforma StreamingCommunity.
|
|
818
|
+
|
|
805
819
|
## Contributors
|
|
806
820
|
|
|
807
821
|
<a href="https://github.com/Arrowar/StreamingCommunity/graphs/contributors" alt="View Contributors">
|
|
808
822
|
<img src="https://contrib.rocks/image?repo=Arrowar/StreamingCommunity&max=1000&columns=10" alt="Contributors" />
|
|
809
|
-
</a>
|
|
823
|
+
</a>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# 29.04.25
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
|
|
5
|
+
# External library
|
|
6
|
+
import httpx
|
|
7
|
+
from bs4 import BeautifulSoup
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# Internal utilities
|
|
11
|
+
from StreamingCommunity.Util.headers import get_userAgent
|
|
12
|
+
from StreamingCommunity.Util.config_json import config_manager
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
# Variable
|
|
16
|
+
MAX_TIMEOUT = config_manager.get_int("REQUESTS", "timeout")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class VideoSource:
|
|
20
|
+
def __init__(self, proxy=None):
|
|
21
|
+
self.client = httpx.Client(headers={'user-agent': get_userAgent()}, timeout=MAX_TIMEOUT, proxy=proxy)
|
|
22
|
+
|
|
23
|
+
def extractLinkHdPlayer(self, response):
|
|
24
|
+
"""Extract iframe source from the page."""
|
|
25
|
+
soup = BeautifulSoup(response.content, 'html.parser')
|
|
26
|
+
iframes = soup.find_all("iframe")
|
|
27
|
+
if iframes:
|
|
28
|
+
return iframes[0].get('data-lazy-src')
|
|
29
|
+
return None
|
|
30
|
+
|
|
31
|
+
def get_m3u8_url(self, page_url):
|
|
32
|
+
"""
|
|
33
|
+
Extract m3u8 URL from hdPlayer page.
|
|
34
|
+
"""
|
|
35
|
+
try:
|
|
36
|
+
base_domain = re.match(r'https?://(?:www\.)?([^/]+)', page_url).group(0)
|
|
37
|
+
self.client.headers.update({'referer': base_domain})
|
|
38
|
+
|
|
39
|
+
# Get the page content
|
|
40
|
+
response = self.client.get(page_url)
|
|
41
|
+
|
|
42
|
+
# Extract HDPlayer iframe URL
|
|
43
|
+
iframe_url = self.extractLinkHdPlayer(response)
|
|
44
|
+
if not iframe_url:
|
|
45
|
+
return None
|
|
46
|
+
|
|
47
|
+
# Get HDPlayer page content
|
|
48
|
+
response_hdplayer = self.client.get(iframe_url)
|
|
49
|
+
if response_hdplayer.status_code != 200:
|
|
50
|
+
return None
|
|
51
|
+
|
|
52
|
+
sources_pattern = r'file:"([^"]+)"'
|
|
53
|
+
match = re.search(sources_pattern, response_hdplayer.text)
|
|
54
|
+
|
|
55
|
+
if match:
|
|
56
|
+
return match.group(1)
|
|
57
|
+
|
|
58
|
+
return None
|
|
59
|
+
|
|
60
|
+
except Exception as e:
|
|
61
|
+
print(f"Error in HDPlayer: {str(e)}")
|
|
62
|
+
return None
|
|
63
|
+
|
|
64
|
+
finally:
|
|
65
|
+
self.client.close()
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# 05.07.24
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
import logging
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# External libraries
|
|
8
|
+
import httpx
|
|
9
|
+
import jsbeautifier
|
|
10
|
+
from bs4 import BeautifulSoup
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# Internal utilities
|
|
14
|
+
from StreamingCommunity.Util.config_json import config_manager
|
|
15
|
+
from StreamingCommunity.Util.headers import get_userAgent
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# Variable
|
|
19
|
+
MAX_TIMEOUT = config_manager.get_int("REQUESTS", "timeout")
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class VideoSource:
|
|
23
|
+
STAYONLINE_BASE_URL = "https://stayonline.pro"
|
|
24
|
+
MIXDROP_BASE_URL = "https://mixdrop.sb"
|
|
25
|
+
|
|
26
|
+
def __init__(self, url: str):
|
|
27
|
+
self.url = url
|
|
28
|
+
self.redirect_url: str | None = None
|
|
29
|
+
self._init_headers()
|
|
30
|
+
|
|
31
|
+
def _init_headers(self) -> None:
|
|
32
|
+
"""Initialize the base headers used for requests."""
|
|
33
|
+
self.headers = {
|
|
34
|
+
'origin': self.STAYONLINE_BASE_URL,
|
|
35
|
+
'user-agent': get_userAgent(),
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
def _get_mixdrop_headers(self) -> dict:
|
|
39
|
+
"""Get headers specifically for MixDrop requests."""
|
|
40
|
+
return {
|
|
41
|
+
'referer': 'https://mixdrop.club/',
|
|
42
|
+
'user-agent': get_userAgent()
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
def get_redirect_url(self) -> str:
|
|
46
|
+
"""Extract the stayonline redirect URL from the initial page."""
|
|
47
|
+
try:
|
|
48
|
+
response = httpx.get(self.url, headers=self.headers, follow_redirects=True, timeout=MAX_TIMEOUT)
|
|
49
|
+
response.raise_for_status()
|
|
50
|
+
soup = BeautifulSoup(response.text, "html.parser")
|
|
51
|
+
|
|
52
|
+
for link in soup.find_all('a'):
|
|
53
|
+
href = link.get('href')
|
|
54
|
+
if href and 'stayonline' in href:
|
|
55
|
+
self.redirect_url = href
|
|
56
|
+
logging.info(f"Redirect URL: {self.redirect_url}")
|
|
57
|
+
return self.redirect_url
|
|
58
|
+
|
|
59
|
+
raise ValueError("Stayonline URL not found")
|
|
60
|
+
|
|
61
|
+
except Exception as e:
|
|
62
|
+
logging.error(f"Error getting redirect URL: {e}")
|
|
63
|
+
raise
|
|
64
|
+
|
|
65
|
+
def get_link_id(self) -> str:
|
|
66
|
+
"""Extract the link ID from the redirect page."""
|
|
67
|
+
if not self.redirect_url:
|
|
68
|
+
raise ValueError("Redirect URL not set. Call get_redirect_url first.")
|
|
69
|
+
|
|
70
|
+
try:
|
|
71
|
+
response = httpx.get(self.redirect_url, headers=self.headers, follow_redirects=True, timeout=MAX_TIMEOUT)
|
|
72
|
+
response.raise_for_status()
|
|
73
|
+
soup = BeautifulSoup(response.text, "html.parser")
|
|
74
|
+
|
|
75
|
+
for script in soup.find_all('script'):
|
|
76
|
+
match = re.search(r'var\s+linkId\s*=\s*"([^"]+)"', script.text)
|
|
77
|
+
if match:
|
|
78
|
+
return match.group(1)
|
|
79
|
+
|
|
80
|
+
raise ValueError("LinkId not found")
|
|
81
|
+
|
|
82
|
+
except Exception as e:
|
|
83
|
+
logging.error(f"Error getting link ID: {e}")
|
|
84
|
+
raise
|
|
85
|
+
|
|
86
|
+
def get_final_url(self, link_id: str) -> str:
|
|
87
|
+
"""Get the final URL using the link ID."""
|
|
88
|
+
try:
|
|
89
|
+
self.headers['referer'] = f'{self.STAYONLINE_BASE_URL}/l/{link_id}/'
|
|
90
|
+
data = {'id': link_id, 'ref': ''}
|
|
91
|
+
|
|
92
|
+
response = httpx.post(f'{self.STAYONLINE_BASE_URL}/ajax/linkView.php', headers=self.headers, data=data, timeout=MAX_TIMEOUT)
|
|
93
|
+
response.raise_for_status()
|
|
94
|
+
return response.json()['data']['value']
|
|
95
|
+
|
|
96
|
+
except Exception as e:
|
|
97
|
+
logging.error(f"Error getting final URL: {e}")
|
|
98
|
+
raise
|
|
99
|
+
|
|
100
|
+
def _extract_video_id(self, final_url: str) -> str:
|
|
101
|
+
"""Extract video ID from the final URL."""
|
|
102
|
+
parts = final_url.split('/')
|
|
103
|
+
if len(parts) < 5:
|
|
104
|
+
raise ValueError("Invalid final URL format")
|
|
105
|
+
return parts[4]
|
|
106
|
+
|
|
107
|
+
def _extract_delivery_url(self, script_text: str) -> str:
|
|
108
|
+
"""Extract delivery URL from beautified JavaScript."""
|
|
109
|
+
beautified = jsbeautifier.beautify(script_text)
|
|
110
|
+
for line in beautified.splitlines():
|
|
111
|
+
if 'MDCore.wurl' in line:
|
|
112
|
+
url = line.split('= ')[1].strip('"').strip(';')
|
|
113
|
+
return f"https:{url}"
|
|
114
|
+
raise ValueError("Delivery URL not found in script")
|
|
115
|
+
|
|
116
|
+
def get_playlist(self) -> str:
|
|
117
|
+
"""
|
|
118
|
+
Execute the entire flow to obtain the final video URL.
|
|
119
|
+
Returns:
|
|
120
|
+
str: The final video delivery URL
|
|
121
|
+
"""
|
|
122
|
+
self.get_redirect_url()
|
|
123
|
+
link_id = self.get_link_id()
|
|
124
|
+
|
|
125
|
+
final_url = self.get_final_url(link_id)
|
|
126
|
+
video_id = self._extract_video_id(final_url)
|
|
127
|
+
|
|
128
|
+
response = httpx.get(
|
|
129
|
+
f'{self.MIXDROP_BASE_URL}/e/{video_id}',
|
|
130
|
+
headers=self._get_mixdrop_headers(),
|
|
131
|
+
timeout=MAX_TIMEOUT
|
|
132
|
+
)
|
|
133
|
+
response.raise_for_status()
|
|
134
|
+
soup = BeautifulSoup(response.text, "html.parser")
|
|
135
|
+
|
|
136
|
+
script_text = next(
|
|
137
|
+
(script.text for script in soup.find_all('script')
|
|
138
|
+
if "eval" in str(script.text)),
|
|
139
|
+
None
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
if not script_text:
|
|
143
|
+
raise ValueError("Required script not found")
|
|
144
|
+
|
|
145
|
+
return self._extract_delivery_url(script_text).replace('"', '')
|
{streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/1337xx/site.py
RENAMED
|
@@ -52,7 +52,7 @@ def title_search(query: str) -> int:
|
|
|
52
52
|
response.raise_for_status()
|
|
53
53
|
|
|
54
54
|
except Exception as e:
|
|
55
|
-
console.print(f"Site: {site_constant.SITE_NAME}, request search error: {e}")
|
|
55
|
+
console.print(f"[red]Site: {site_constant.SITE_NAME}, request search error: {e}")
|
|
56
56
|
return 0
|
|
57
57
|
|
|
58
58
|
# Create soup and find table
|
|
@@ -55,7 +55,7 @@ def title_search(query: str) -> int:
|
|
|
55
55
|
response.raise_for_status()
|
|
56
56
|
|
|
57
57
|
except Exception as e:
|
|
58
|
-
console.print(f"Site: {site_constant.SITE_NAME}, request search error: {e}")
|
|
58
|
+
console.print(f"[red]Site: {site_constant.SITE_NAME}, request search error: {e}")
|
|
59
59
|
if site_constant.TELEGRAM_BOT:
|
|
60
60
|
bot.send_message(f"ERRORE\n\nErrore nella richiesta di ricerca:\n\n{e}", None)
|
|
61
61
|
return 0
|
{streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/animeunity/site.py
RENAMED
|
@@ -119,7 +119,8 @@ def title_search(query: str) -> int:
|
|
|
119
119
|
process_results(response1.json()['records'], seen_titles, media_search_manager, choices)
|
|
120
120
|
|
|
121
121
|
except Exception as e:
|
|
122
|
-
console.print(f"Site: {site_constant.SITE_NAME},
|
|
122
|
+
console.print(f"[red]Site: {site_constant.SITE_NAME}, request search error: {e}")
|
|
123
|
+
return 0
|
|
123
124
|
|
|
124
125
|
# Second API call - archivio
|
|
125
126
|
try:
|
{streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/animeworld/site.py
RENAMED
|
@@ -31,7 +31,11 @@ def get_session_and_csrf() -> dict:
|
|
|
31
31
|
Get the session ID and CSRF token from the website's cookies and HTML meta data.
|
|
32
32
|
"""
|
|
33
33
|
# Send an initial GET request to the website
|
|
34
|
-
response = httpx.get(
|
|
34
|
+
response = httpx.get(
|
|
35
|
+
site_constant.FULL_URL,
|
|
36
|
+
headers=get_headers(),
|
|
37
|
+
verify=False
|
|
38
|
+
)
|
|
35
39
|
|
|
36
40
|
# Extract the sessionId from the cookies
|
|
37
41
|
session_id = response.cookies.get('sessionId')
|
|
@@ -78,7 +82,7 @@ def title_search(query: str) -> int:
|
|
|
78
82
|
)
|
|
79
83
|
|
|
80
84
|
except Exception as e:
|
|
81
|
-
console.print(f"Site: {site_constant.SITE_NAME}, request search error: {e}")
|
|
85
|
+
console.print(f"[red]Site: {site_constant.SITE_NAME}, request search error: {e}")
|
|
82
86
|
return 0
|
|
83
87
|
|
|
84
88
|
# Create soup istance
|
|
@@ -114,4 +118,4 @@ def title_search(query: str) -> int:
|
|
|
114
118
|
print(f"Error parsing a film entry: {e}")
|
|
115
119
|
|
|
116
120
|
# Return the length of media search manager
|
|
117
|
-
return media_search_manager.get_length()
|
|
121
|
+
return media_search_manager.get_length()
|
|
@@ -53,7 +53,7 @@ def title_search(query: str) -> int:
|
|
|
53
53
|
response.raise_for_status()
|
|
54
54
|
|
|
55
55
|
except Exception as e:
|
|
56
|
-
console.print(f"Site: {site_constant.SITE_NAME}, request search error: {e}")
|
|
56
|
+
console.print(f"[red]Site: {site_constant.SITE_NAME}, request search error: {e}")
|
|
57
57
|
return 0
|
|
58
58
|
|
|
59
59
|
# Create soup and find table
|
|
@@ -54,7 +54,7 @@ def title_search(query: str) -> int:
|
|
|
54
54
|
response.raise_for_status()
|
|
55
55
|
|
|
56
56
|
except Exception as e:
|
|
57
|
-
console.print(f"Site: {site_constant.SITE_NAME}, request search error: {e}")
|
|
57
|
+
console.print(f"[red]Site: {site_constant.SITE_NAME}, request search error: {e}")
|
|
58
58
|
return 0
|
|
59
59
|
|
|
60
60
|
# Create soup and find table
|
{streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/raiplay/site.py
RENAMED
|
@@ -26,7 +26,7 @@ console = Console()
|
|
|
26
26
|
media_search_manager = MediaManager()
|
|
27
27
|
table_show_manager = TVShowManager()
|
|
28
28
|
max_timeout = config_manager.get_int("REQUESTS", "timeout")
|
|
29
|
-
MAX_THREADS =
|
|
29
|
+
MAX_THREADS = 12
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
def determine_media_type(title):
|
|
@@ -134,7 +134,7 @@ def title_search(query: str) -> int:
|
|
|
134
134
|
response.raise_for_status()
|
|
135
135
|
|
|
136
136
|
except Exception as e:
|
|
137
|
-
console.print(f"Site: {site_constant.SITE_NAME}, request search error: {e}")
|
|
137
|
+
console.print(f"[red]Site: {site_constant.SITE_NAME}, request search error: {e}")
|
|
138
138
|
return 0
|
|
139
139
|
|
|
140
140
|
# Limit to only 15 results for performance
|
|
@@ -155,7 +155,7 @@ def download_series(select_season: MediaItem, season_selection: str = None, epis
|
|
|
155
155
|
|
|
156
156
|
# Init class
|
|
157
157
|
video_source = VideoSource(site_constant.FULL_URL, True, select_season.id)
|
|
158
|
-
scrape_serie = GetSerieInfo(site_constant.FULL_URL, select_season.id, select_season.
|
|
158
|
+
scrape_serie = GetSerieInfo(site_constant.FULL_URL, select_season.id, select_season.slug)
|
|
159
159
|
|
|
160
160
|
# Collect information about season
|
|
161
161
|
scrape_serie.getNumberSeason()
|
|
@@ -219,4 +219,4 @@ def download_series(select_season: MediaItem, season_selection: str = None, epis
|
|
|
219
219
|
# Get script_id
|
|
220
220
|
script_id = TelegramSession.get_session()
|
|
221
221
|
if script_id != "unknown":
|
|
222
|
-
TelegramSession.deleteScriptId(script_id)
|
|
222
|
+
TelegramSession.deleteScriptId(script_id)
|
|
@@ -55,7 +55,7 @@ def title_search(query: str) -> int:
|
|
|
55
55
|
response.raise_for_status()
|
|
56
56
|
|
|
57
57
|
except Exception as e:
|
|
58
|
-
console.print(f"Site: {site_constant.SITE_NAME}, request search error: {e}")
|
|
58
|
+
console.print(f"[red]Site: {site_constant.SITE_NAME}, request search error: {e}")
|
|
59
59
|
if site_constant.TELEGRAM_BOT:
|
|
60
60
|
bot.send_message(f"ERRORE\n\nErrore nella richiesta di ricerca:\n\n{e}", None)
|
|
61
61
|
return 0
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# 29.04.25
|
|
2
|
+
|
|
3
|
+
# External library
|
|
4
|
+
from rich.console import Console
|
|
5
|
+
from rich.prompt import Prompt
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# Internal utilities
|
|
9
|
+
from StreamingCommunity.Api.Template import get_select_title
|
|
10
|
+
from StreamingCommunity.Lib.Proxies.proxy import ProxyFinder
|
|
11
|
+
from StreamingCommunity.Api.Template.config_loader import site_constant
|
|
12
|
+
from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
# Logic class
|
|
16
|
+
from .site import title_search, table_show_manager, media_search_manager
|
|
17
|
+
from .film import download_film
|
|
18
|
+
from .series import download_series
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# Variable
|
|
22
|
+
indice = 8
|
|
23
|
+
_useFor = "film_serie"
|
|
24
|
+
_priority = 10 # !!! MOLTO LENTO
|
|
25
|
+
_engineDownload = "hls"
|
|
26
|
+
|
|
27
|
+
msg = Prompt()
|
|
28
|
+
console = Console()
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def get_user_input(string_to_search: str = None):
|
|
32
|
+
"""
|
|
33
|
+
Asks the user to input a search term.
|
|
34
|
+
Handles both Telegram bot input and direct input.
|
|
35
|
+
"""
|
|
36
|
+
string_to_search = msg.ask(f"\n[purple]Insert a word to search in [green]{site_constant.SITE_NAME}").strip()
|
|
37
|
+
return string_to_search
|
|
38
|
+
|
|
39
|
+
def process_search_result(select_title, selections=None, proxy=None):
|
|
40
|
+
"""
|
|
41
|
+
Handles the search result and initiates the download for either a film or series.
|
|
42
|
+
|
|
43
|
+
Parameters:
|
|
44
|
+
select_title (MediaItem): The selected media item
|
|
45
|
+
selections (dict, optional): Dictionary containing selection inputs that bypass manual input
|
|
46
|
+
{'season': season_selection, 'episode': episode_selection}
|
|
47
|
+
"""
|
|
48
|
+
if select_title.type == 'tv':
|
|
49
|
+
season_selection = None
|
|
50
|
+
episode_selection = None
|
|
51
|
+
|
|
52
|
+
if selections:
|
|
53
|
+
season_selection = selections.get('season')
|
|
54
|
+
episode_selection = selections.get('episode')
|
|
55
|
+
|
|
56
|
+
download_series(select_title, season_selection, episode_selection, proxy)
|
|
57
|
+
|
|
58
|
+
else:
|
|
59
|
+
download_film(select_title, proxy)
|
|
60
|
+
|
|
61
|
+
def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_item: dict = None, selections: dict = None):
|
|
62
|
+
"""
|
|
63
|
+
Main function of the application for search.
|
|
64
|
+
|
|
65
|
+
Parameters:
|
|
66
|
+
string_to_search (str, optional): String to search for
|
|
67
|
+
get_onlyDatabase (bool, optional): If True, return only the database object
|
|
68
|
+
direct_item (dict, optional): Direct item to process (bypass search)
|
|
69
|
+
selections (dict, optional): Dictionary containing selection inputs that bypass manual input
|
|
70
|
+
{'season': season_selection, 'episode': episode_selection}
|
|
71
|
+
"""
|
|
72
|
+
if direct_item:
|
|
73
|
+
select_title = MediaItem(**direct_item)
|
|
74
|
+
process_search_result(select_title, selections) # DONT SUPPORT PROXY FOR NOW
|
|
75
|
+
return
|
|
76
|
+
|
|
77
|
+
if string_to_search is None:
|
|
78
|
+
string_to_search = msg.ask(f"\n[purple]Insert a word to search in [green]{site_constant.SITE_NAME}").strip()
|
|
79
|
+
|
|
80
|
+
finder = ProxyFinder(url=f"{site_constant.FULL_URL}/serie/euphoria/")
|
|
81
|
+
proxy, response_serie, _ = finder.find_fast_proxy()
|
|
82
|
+
len_database = title_search(string_to_search, [proxy, response_serie])
|
|
83
|
+
|
|
84
|
+
# If only the database is needed, return the manager
|
|
85
|
+
if get_onlyDatabase:
|
|
86
|
+
return media_search_manager
|
|
87
|
+
|
|
88
|
+
if len_database > 0:
|
|
89
|
+
select_title = get_select_title(table_show_manager, media_search_manager)
|
|
90
|
+
process_search_result(select_title, selections, proxy)
|
|
91
|
+
|
|
92
|
+
else:
|
|
93
|
+
# If no results are found, ask again
|
|
94
|
+
console.print(f"\n[red]Nothing matching was found for[white]: [purple]{string_to_search}")
|
|
95
|
+
search()
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# 29.04.25
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
# External library
|
|
7
|
+
from rich.console import Console
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# Internal utilities
|
|
11
|
+
from StreamingCommunity.Util.os import os_manager
|
|
12
|
+
from StreamingCommunity.Util.message import start_message
|
|
13
|
+
from StreamingCommunity.Lib.Downloader import HLS_Downloader
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# Logic class
|
|
17
|
+
from StreamingCommunity.Api.Template.config_loader import site_constant
|
|
18
|
+
from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# Player
|
|
22
|
+
from StreamingCommunity.Api.Player.hdplayer import VideoSource
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# Variable
|
|
26
|
+
console = Console()
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def download_film(select_title: MediaItem, proxy) -> str:
|
|
30
|
+
"""
|
|
31
|
+
Downloads a film using the provided film ID, title name, and domain.
|
|
32
|
+
|
|
33
|
+
Parameters:
|
|
34
|
+
- domain (str): The domain of the site
|
|
35
|
+
- version (str): Version of site.
|
|
36
|
+
|
|
37
|
+
Return:
|
|
38
|
+
- str: output path
|
|
39
|
+
"""
|
|
40
|
+
start_message()
|
|
41
|
+
console.print(f"[bold yellow]Download:[/bold yellow] [red]{site_constant.SITE_NAME}[/red] → [cyan]{select_title.name}[/cyan] \n")
|
|
42
|
+
|
|
43
|
+
# Get master playlists
|
|
44
|
+
video_source = VideoSource(proxy)
|
|
45
|
+
master_playlist = video_source.get_m3u8_url(select_title.url)
|
|
46
|
+
|
|
47
|
+
# Define the filename and path for the downloaded film
|
|
48
|
+
title_name = os_manager.get_sanitize_file(select_title.name) + ".mp4"
|
|
49
|
+
mp4_path = os.path.join(site_constant.MOVIE_FOLDER, title_name.replace(".mp4", ""))
|
|
50
|
+
|
|
51
|
+
# Download the film using the m3u8 playlist, and output filename
|
|
52
|
+
r_proc = HLS_Downloader(
|
|
53
|
+
m3u8_url=master_playlist,
|
|
54
|
+
output_path=os.path.join(mp4_path, title_name)
|
|
55
|
+
).start()
|
|
56
|
+
|
|
57
|
+
if r_proc['error'] is not None:
|
|
58
|
+
try: os.remove(r_proc['path'])
|
|
59
|
+
except: pass
|
|
60
|
+
|
|
61
|
+
return r_proc['path']
|