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.

Files changed (103) hide show
  1. {streamingcommunity-3.0.1/StreamingCommunity.egg-info → streamingcommunity-3.0.3}/PKG-INFO +17 -2
  2. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/README.md +16 -2
  3. streamingcommunity-3.0.3/StreamingCommunity/Api/Player/hdplayer.py +65 -0
  4. streamingcommunity-3.0.3/StreamingCommunity/Api/Player/mixdrop.py +145 -0
  5. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/1337xx/site.py +1 -1
  6. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/altadefinizione/site.py +1 -1
  7. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/animeunity/site.py +2 -1
  8. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/animeworld/site.py +7 -3
  9. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/ddlstreamitaly/site.py +1 -1
  10. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/guardaserie/site.py +1 -1
  11. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/raiplay/site.py +2 -2
  12. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/streamingcommunity/series.py +2 -2
  13. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/streamingcommunity/site.py +1 -1
  14. streamingcommunity-3.0.3/StreamingCommunity/Api/Site/streamingwatch/__init__.py +95 -0
  15. streamingcommunity-3.0.3/StreamingCommunity/Api/Site/streamingwatch/film.py +61 -0
  16. streamingcommunity-3.0.3/StreamingCommunity/Api/Site/streamingwatch/series.py +160 -0
  17. streamingcommunity-3.0.3/StreamingCommunity/Api/Site/streamingwatch/site.py +111 -0
  18. streamingcommunity-3.0.3/StreamingCommunity/Api/Site/streamingwatch/util/ScrapeSerie.py +118 -0
  19. streamingcommunity-3.0.3/StreamingCommunity/Lib/Proxies/proxy.py +232 -0
  20. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Upload/update.py +23 -22
  21. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Upload/version.py +1 -1
  22. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Util/os.py +38 -0
  23. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/global_search.py +16 -4
  24. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/run.py +11 -2
  25. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3/StreamingCommunity.egg-info}/PKG-INFO +17 -2
  26. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity.egg-info/SOURCES.txt +8 -1
  27. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity.egg-info/requires.txt +1 -0
  28. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/requirements.txt +2 -1
  29. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/setup.py +1 -1
  30. streamingcommunity-3.0.1/StreamingCommunity/Api/Player/maxstream.py +0 -140
  31. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/LICENSE +0 -0
  32. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/MANIFEST.in +0 -0
  33. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Player/Helper/Vixcloud/js_parser.py +0 -0
  34. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Player/Helper/Vixcloud/util.py +0 -0
  35. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Player/ddl.py +0 -0
  36. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Player/mediapolisvod.py +0 -0
  37. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Player/supervideo.py +0 -0
  38. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Player/sweetpixel.py +0 -0
  39. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Player/vixcloud.py +0 -0
  40. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/1337xx/__init__.py +0 -0
  41. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/1337xx/title.py +0 -0
  42. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/altadefinizione/__init__.py +0 -0
  43. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/altadefinizione/film.py +0 -0
  44. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/altadefinizione/series.py +0 -0
  45. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/altadefinizione/util/ScrapeSerie.py +0 -0
  46. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/animeunity/__init__.py +0 -0
  47. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/animeunity/film.py +0 -0
  48. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/animeunity/serie.py +0 -0
  49. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/animeunity/util/ScrapeSerie.py +0 -0
  50. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/animeworld/__init__.py +0 -0
  51. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/animeworld/film.py +0 -0
  52. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/animeworld/serie.py +0 -0
  53. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/animeworld/util/ScrapeSerie.py +0 -0
  54. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/ddlstreamitaly/__init__.py +0 -0
  55. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/ddlstreamitaly/series.py +0 -0
  56. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/ddlstreamitaly/util/ScrapeSerie.py +0 -0
  57. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/guardaserie/__init__.py +0 -0
  58. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/guardaserie/series.py +0 -0
  59. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/guardaserie/util/ScrapeSerie.py +0 -0
  60. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/raiplay/__init__.py +0 -0
  61. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/raiplay/film.py +0 -0
  62. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/raiplay/series.py +0 -0
  63. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/raiplay/util/ScrapeSerie.py +0 -0
  64. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/streamingcommunity/__init__.py +0 -0
  65. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/streamingcommunity/film.py +0 -0
  66. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Site/streamingcommunity/util/ScrapeSerie.py +0 -0
  67. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Template/Class/SearchType.py +0 -0
  68. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Template/Util/__init__.py +0 -0
  69. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Template/Util/manage_ep.py +0 -0
  70. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Template/__init__.py +0 -0
  71. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Template/config_loader.py +0 -0
  72. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Api/Template/site.py +0 -0
  73. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Lib/Downloader/HLS/downloader.py +0 -0
  74. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Lib/Downloader/HLS/segments.py +0 -0
  75. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Lib/Downloader/MP4/downloader.py +0 -0
  76. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Lib/Downloader/TOR/downloader.py +0 -0
  77. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Lib/Downloader/__init__.py +0 -0
  78. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Lib/FFmpeg/__init__.py +0 -0
  79. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Lib/FFmpeg/capture.py +0 -0
  80. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Lib/FFmpeg/command.py +0 -0
  81. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Lib/FFmpeg/util.py +0 -0
  82. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Lib/M3U8/__init__.py +0 -0
  83. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Lib/M3U8/decryptor.py +0 -0
  84. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Lib/M3U8/estimator.py +0 -0
  85. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Lib/M3U8/parser.py +0 -0
  86. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Lib/M3U8/url_fixer.py +0 -0
  87. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Lib/TMBD/__init__.py +0 -0
  88. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Lib/TMBD/obj_tmbd.py +0 -0
  89. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Lib/TMBD/tmdb.py +0 -0
  90. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/TelegramHelp/__init__.py +0 -0
  91. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/TelegramHelp/telegram_bot.py +0 -0
  92. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Util/color.py +0 -0
  93. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Util/config_json.py +0 -0
  94. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Util/ffmpeg_installer.py +0 -0
  95. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Util/headers.py +0 -0
  96. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Util/logger.py +0 -0
  97. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Util/message.py +0 -0
  98. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/Util/table.py +0 -0
  99. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity/__init__.py +0 -0
  100. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity.egg-info/dependency_links.txt +0 -0
  101. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity.egg-info/entry_points.txt +0 -0
  102. {streamingcommunity-3.0.1 → streamingcommunity-3.0.3}/StreamingCommunity.egg-info/top_level.txt +0 -0
  103. {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.1
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('"', '')
@@ -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
@@ -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}, livesearch error: {e}")
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:
@@ -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(site_constant.FULL_URL, headers=get_headers())
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
@@ -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 = 4
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.name)
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']