StreamingCommunity 3.0.7__tar.gz → 3.0.9__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 (104) hide show
  1. {streamingcommunity-3.0.7/StreamingCommunity.egg-info → streamingcommunity-3.0.9}/PKG-INFO +2 -2
  2. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/README.md +1 -1
  3. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/animeworld/util/ScrapeSerie.py +2 -1
  4. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/raiplay/__init__.py +1 -1
  5. streamingcommunity-3.0.9/StreamingCommunity/Api/Site/raiplay/site.py +105 -0
  6. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/raiplay/util/ScrapeSerie.py +37 -17
  7. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/streamingcommunity/__init__.py +6 -4
  8. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Upload/version.py +1 -1
  9. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Util/config_json.py +16 -21
  10. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Util/os.py +49 -31
  11. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/run.py +14 -3
  12. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9/StreamingCommunity.egg-info}/PKG-INFO +2 -2
  13. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/setup.py +1 -1
  14. streamingcommunity-3.0.7/StreamingCommunity/Api/Site/raiplay/site.py +0 -173
  15. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/LICENSE +0 -0
  16. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/MANIFEST.in +0 -0
  17. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Player/Helper/Vixcloud/js_parser.py +0 -0
  18. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Player/Helper/Vixcloud/util.py +0 -0
  19. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Player/ddl.py +0 -0
  20. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Player/hdplayer.py +0 -0
  21. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Player/maxstream.py +0 -0
  22. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Player/mediapolisvod.py +0 -0
  23. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Player/mixdrop.py +0 -0
  24. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Player/supervideo.py +0 -0
  25. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Player/sweetpixel.py +0 -0
  26. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Player/vixcloud.py +0 -0
  27. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/1337xx/__init__.py +0 -0
  28. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/1337xx/site.py +0 -0
  29. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/1337xx/title.py +0 -0
  30. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/altadefinizione/__init__.py +0 -0
  31. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/altadefinizione/film.py +0 -0
  32. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/altadefinizione/series.py +0 -0
  33. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/altadefinizione/site.py +0 -0
  34. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/altadefinizione/util/ScrapeSerie.py +0 -0
  35. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/animeunity/__init__.py +0 -0
  36. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/animeunity/film.py +0 -0
  37. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/animeunity/serie.py +0 -0
  38. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/animeunity/site.py +0 -0
  39. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/animeunity/util/ScrapeSerie.py +0 -0
  40. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/animeworld/__init__.py +0 -0
  41. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/animeworld/film.py +0 -0
  42. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/animeworld/serie.py +0 -0
  43. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/animeworld/site.py +0 -0
  44. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/cb01new/__init__.py +0 -0
  45. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/cb01new/film.py +0 -0
  46. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/cb01new/site.py +0 -0
  47. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/guardaserie/__init__.py +0 -0
  48. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/guardaserie/series.py +0 -0
  49. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/guardaserie/site.py +0 -0
  50. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/guardaserie/util/ScrapeSerie.py +0 -0
  51. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/raiplay/film.py +0 -0
  52. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/raiplay/series.py +0 -0
  53. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/streamingcommunity/film.py +0 -0
  54. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/streamingcommunity/series.py +0 -0
  55. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/streamingcommunity/site.py +0 -0
  56. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/streamingcommunity/util/ScrapeSerie.py +0 -0
  57. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/streamingwatch/__init__.py +0 -0
  58. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/streamingwatch/film.py +0 -0
  59. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/streamingwatch/series.py +0 -0
  60. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/streamingwatch/site.py +0 -0
  61. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Site/streamingwatch/util/ScrapeSerie.py +0 -0
  62. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Template/Class/SearchType.py +0 -0
  63. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Template/Util/__init__.py +0 -0
  64. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Template/Util/manage_ep.py +0 -0
  65. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Template/__init__.py +0 -0
  66. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Template/config_loader.py +0 -0
  67. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Api/Template/site.py +0 -0
  68. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Lib/Downloader/HLS/downloader.py +0 -0
  69. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Lib/Downloader/HLS/segments.py +0 -0
  70. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Lib/Downloader/MP4/downloader.py +0 -0
  71. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Lib/Downloader/TOR/downloader.py +0 -0
  72. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Lib/Downloader/__init__.py +0 -0
  73. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Lib/FFmpeg/__init__.py +0 -0
  74. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Lib/FFmpeg/capture.py +0 -0
  75. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Lib/FFmpeg/command.py +0 -0
  76. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Lib/FFmpeg/util.py +0 -0
  77. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Lib/M3U8/__init__.py +0 -0
  78. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Lib/M3U8/decryptor.py +0 -0
  79. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Lib/M3U8/estimator.py +0 -0
  80. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Lib/M3U8/parser.py +0 -0
  81. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Lib/M3U8/url_fixer.py +0 -0
  82. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Lib/Proxies/proxy.py +0 -0
  83. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Lib/TMBD/__init__.py +0 -0
  84. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Lib/TMBD/obj_tmbd.py +0 -0
  85. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Lib/TMBD/tmdb.py +0 -0
  86. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/TelegramHelp/__init__.py +0 -0
  87. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/TelegramHelp/config.json +0 -0
  88. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/TelegramHelp/telegram_bot.py +0 -0
  89. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Upload/update.py +0 -0
  90. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Util/color.py +0 -0
  91. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Util/ffmpeg_installer.py +0 -0
  92. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Util/headers.py +0 -0
  93. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Util/logger.py +0 -0
  94. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Util/message.py +0 -0
  95. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/Util/table.py +0 -0
  96. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/__init__.py +0 -0
  97. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity/global_search.py +0 -0
  98. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity.egg-info/SOURCES.txt +0 -0
  99. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity.egg-info/dependency_links.txt +0 -0
  100. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity.egg-info/entry_points.txt +0 -0
  101. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity.egg-info/requires.txt +0 -0
  102. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/StreamingCommunity.egg-info/top_level.txt +0 -0
  103. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/requirements.txt +0 -0
  104. {streamingcommunity-3.0.7 → streamingcommunity-3.0.9}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: StreamingCommunity
3
- Version: 3.0.7
3
+ Version: 3.0.9
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
@@ -35,7 +35,7 @@ Dynamic: requires-dist
35
35
  Dynamic: requires-python
36
36
 
37
37
  <p align="center">
38
- <img src="https://i.ibb.co/v6RnT0wY/s2.jpg" alt="Project Logo" width="600"/>
38
+ <img src="https://i.ibb.co/v6RnT0wY/s2.jpg" alt="Project Logo" width="450"/>
39
39
  </p>
40
40
 
41
41
  <p align="center">
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <img src="https://i.ibb.co/v6RnT0wY/s2.jpg" alt="Project Logo" width="600"/>
2
+ <img src="https://i.ibb.co/v6RnT0wY/s2.jpg" alt="Project Logo" width="450"/>
3
3
  </p>
4
4
 
5
5
  <p align="center">
@@ -31,7 +31,8 @@ class ScrapSerie:
31
31
  self.client = httpx.Client(
32
32
  cookies={"sessionId": self.session_id},
33
33
  headers={"User-Agent": get_userAgent(), "csrf-token": self.csrf_token},
34
- base_url=full_url
34
+ base_url=full_url,
35
+ verify=False
35
36
  )
36
37
 
37
38
  try:
@@ -21,7 +21,7 @@ from .film import download_film
21
21
  # Variable
22
22
  indice = 5
23
23
  _useFor = "Film_&_Serie"
24
- _priority = 1 # NOTE: Site search need the use of tmbd obj
24
+ _priority = 0
25
25
  _engineDownload = "hls"
26
26
  _deprecate = False
27
27
 
@@ -0,0 +1,105 @@
1
+ # 21.05.24
2
+
3
+ # External libraries
4
+ import httpx
5
+ from rich.console import Console
6
+
7
+
8
+ # Internal utilities
9
+ from StreamingCommunity.Util.config_json import config_manager
10
+ from StreamingCommunity.Util.headers import get_userAgent
11
+ from StreamingCommunity.Util.table import TVShowManager
12
+ from StreamingCommunity.Api.Template.config_loader import site_constant
13
+ from StreamingCommunity.Api.Template.Class.SearchType import MediaManager
14
+ from .util.ScrapeSerie import GetSerieInfo
15
+
16
+
17
+ # Variable
18
+ console = Console()
19
+ media_search_manager = MediaManager()
20
+ table_show_manager = TVShowManager()
21
+ max_timeout = config_manager.get_int("REQUESTS", "timeout")
22
+
23
+
24
+ def determine_media_type(item):
25
+ """
26
+ Determine if the item is a film or TV series by checking actual seasons count
27
+ using GetSerieInfo.
28
+ """
29
+ try:
30
+ # Extract program name from path_id
31
+ program_name = None
32
+ if item.get('path_id'):
33
+ parts = item['path_id'].strip('/').split('/')
34
+ if len(parts) >= 2:
35
+ program_name = parts[-1].split('.')[0]
36
+
37
+ if not program_name:
38
+ return "film"
39
+
40
+ scraper = GetSerieInfo(program_name)
41
+ scraper.collect_info_title()
42
+ return "tv" if scraper.getNumberSeason() > 0 else "film"
43
+
44
+ except Exception as e:
45
+ console.print(f"[red]Error determining media type: {e}[/red]")
46
+ return "film"
47
+
48
+
49
+ def title_search(query: str) -> int:
50
+ """
51
+ Search for titles based on a search query.
52
+
53
+ Parameters:
54
+ - query (str): The query to search for.
55
+
56
+ Returns:
57
+ int: The number of titles found.
58
+ """
59
+ media_search_manager.clear()
60
+ table_show_manager.clear()
61
+
62
+ search_url = f"https://www.raiplay.it/atomatic/raiplay-search-service/api/v1/msearch"
63
+ console.print(f"[cyan]Search url: [yellow]{search_url}")
64
+
65
+ json_data = {
66
+ 'templateIn': '6470a982e4e0301afe1f81f1',
67
+ 'templateOut': '6516ac5d40da6c377b151642',
68
+ 'params': {
69
+ 'param': query,
70
+ 'from': None,
71
+ 'sort': 'relevance',
72
+ 'onlyVideoQuery': False,
73
+ },
74
+ }
75
+
76
+ try:
77
+ response = httpx.post(
78
+ search_url,
79
+ headers={'user-agent': get_userAgent()},
80
+ json=json_data,
81
+ timeout=max_timeout,
82
+ follow_redirects=True
83
+ )
84
+ response.raise_for_status()
85
+
86
+ except Exception as e:
87
+ console.print(f"[red]Site: {site_constant.SITE_NAME}, request search error: {e}")
88
+ return 0
89
+
90
+ # Limit to only 15 results for performance
91
+ data = response.json().get('agg').get('titoli').get('cards')
92
+ data = data[:15] if len(data) > 15 else data
93
+
94
+ # Process each item and add to media manager
95
+ for item in data:
96
+ media_search_manager.add_media({
97
+ 'id': item.get('id', ''),
98
+ 'name': item.get('titolo', ''),
99
+ 'type': determine_media_type(item),
100
+ 'path_id': item.get('path_id', ''),
101
+ 'url': f"https://www.raiplay.it{item.get('url', '')}",
102
+ 'image': f"https://www.raiplay.it{item.get('immagine', '')}",
103
+ })
104
+
105
+ return media_search_manager.get_length()
@@ -30,28 +30,48 @@ class GetSerieInfo:
30
30
  try:
31
31
  program_url = f"{self.base_url}/programmi/{self.program_name}.json"
32
32
  response = httpx.get(url=program_url, headers=get_headers(), timeout=max_timeout)
33
+
34
+ # If 404, content is not yet available
35
+ if response.status_code == 404:
36
+ logging.info(f"Content not yet available: {self.program_name}")
37
+ return
38
+
33
39
  response.raise_for_status()
34
-
35
40
  json_data = response.json()
36
41
 
37
42
  # Look for seasons in the 'blocks' property
38
- for block in json_data.get('blocks'):
39
- if block.get('type') == 'RaiPlay Multimedia Block' and block.get('name', '').lower() == 'episodi':
40
- self.publishing_block_id = block.get('id')
41
-
42
- # Extract seasons from sets array
43
- for season_set in block.get('sets', []):
44
- if 'stagione' in season_set.get('name', '').lower():
45
- self.seasons_manager.add_season({
46
- 'id': season_set.get('id', ''),
47
- 'number': len(self.seasons_manager.seasons) + 1,
48
- 'name': season_set.get('name', ''),
49
- 'path': season_set.get('path_id', ''),
50
- 'episodes_count': season_set.get('episode_size', {}).get('number', 0)
51
- })
52
-
53
- except Exception as e:
43
+ for block in json_data.get('blocks', []):
44
+
45
+ # Check if block is a season block or episodi block
46
+ if block.get('type') == 'RaiPlay Multimedia Block':
47
+ if block.get('name', '').lower() == 'episodi':
48
+ self.publishing_block_id = block.get('id')
49
+
50
+ # Extract seasons from sets array
51
+ for season_set in block.get('sets', []):
52
+ if 'stagione' in season_set.get('name', '').lower():
53
+ self._add_season(season_set, block.get('id'))
54
+
55
+ elif 'stagione' in block.get('name', '').lower():
56
+ self.publishing_block_id = block.get('id')
57
+
58
+ # Extract season directly from block's sets
59
+ for season_set in block.get('sets', []):
60
+ self._add_season(season_set, block.get('id'))
61
+
62
+ except httpx.HTTPError as e:
54
63
  logging.error(f"Error collecting series info: {e}")
64
+ except Exception as e:
65
+ logging.error(f"Unexpected error collecting series info: {e}")
66
+
67
+ def _add_season(self, season_set: dict, block_id: str):
68
+ self.seasons_manager.add_season({
69
+ 'id': season_set.get('id', ''),
70
+ 'number': len(self.seasons_manager.seasons) + 1,
71
+ 'name': season_set.get('name', ''),
72
+ 'path': season_set.get('path_id', ''),
73
+ 'episodes_count': season_set.get('episode_size', {}).get('number', 0)
74
+ })
55
75
 
56
76
  def collect_info_season(self, number_season: int) -> None:
57
77
  """Get episodes for a specific season."""
@@ -121,14 +121,16 @@ def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_
121
121
  if site_constant.TELEGRAM_BOT:
122
122
  bot = get_bot_instance()
123
123
 
124
+ # Check proxy if not already set
125
+ finder = ProxyFinder(site_constant.FULL_URL)
126
+ proxy = finder.find_fast_proxy()
127
+
124
128
  if direct_item:
125
129
  select_title_obj = MediaItem(**direct_item)
126
130
  process_search_result(select_title_obj, selections, proxy)
127
131
  return
128
132
 
129
- # Check proxy if not already set
130
- finder = ProxyFinder(site_constant.FULL_URL)
131
- proxy = finder.find_fast_proxy()
133
+
132
134
 
133
135
  actual_search_query = get_user_input(string_to_search)
134
136
 
@@ -142,7 +144,7 @@ def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_
142
144
  # Perform search on the database using the obtained query
143
145
  finder = ProxyFinder(site_constant.FULL_URL)
144
146
  proxy = finder.find_fast_proxy()
145
- len_database = title_search(string_to_search, proxy)
147
+ len_database = title_search(actual_search_query, proxy)
146
148
 
147
149
  # If only the database object (media_search_manager populated by title_search) is needed
148
150
  if get_onlyDatabase:
@@ -1,5 +1,5 @@
1
1
  __title__ = 'StreamingCommunity'
2
- __version__ = '3.0.7'
2
+ __version__ = '3.0.9'
3
3
  __author__ = 'Arrowar'
4
4
  __description__ = 'A command-line program to download film'
5
5
  __copyright__ = 'Copyright 2024'
@@ -39,9 +39,6 @@ class ConfigManager:
39
39
 
40
40
  # Get the actual path of the module file
41
41
  current_file_path = os.path.abspath(__file__)
42
- # Navigate upwards to find the project root
43
- # Assuming this file is in a package structure like StreamingCommunity/Util/config_json.py
44
- # We need to go up 2 levels to reach the project root
45
42
  base_path = os.path.dirname(os.path.dirname(os.path.dirname(current_file_path)))
46
43
 
47
44
  # Initialize file paths
@@ -271,33 +268,32 @@ class ConfigManager:
271
268
  self._load_site_data_from_file()
272
269
 
273
270
  def _load_site_data_from_api(self) -> None:
274
- """Load site data from API."""
271
+ """Load site data from GitHub."""
272
+ domains_github_url = "https://raw.githubusercontent.com/Arrowar/StreamingCommunity/refs/heads/main/.github/.domain/domains.json"
275
273
  headers = {
276
- "apikey": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inp2Zm5ncG94d3Jnc3duenl0YWRoIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NDAxNTIxNjMsImV4cCI6MjA1NTcyODE2M30.FNTCCMwi0QaKjOu8gtZsT5yQttUW8QiDDGXmzkn89QE",
277
- "Authorization": f"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inp2Zm5ncG94d3Jnc3duenl0YWRoIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NDAxNTIxNjMsImV4cCI6MjA1NTcyODE2M30.FNTCCMwi0QaKjOu8gtZsT5yQttUW8QiDDGXmzkn89QE",
278
- "Content-Type": "application/json",
279
- "User-Agent": get_userAgent()
274
+ "User-Agent": get_userAgent()
280
275
  }
281
276
 
282
277
  try:
283
- console.print("[bold cyan]Retrieving site data from API...[/bold cyan]")
284
- response = requests.get("https://zvfngpoxwrgswnzytadh.supabase.co/rest/v1/public", timeout=8, headers=headers)
278
+ console.print(f"[bold cyan]Retrieving site data from GitHub:[/bold cyan] [green]{domains_github_url}[/green]")
279
+ response = requests.get(domains_github_url, timeout=8, headers=headers)
285
280
 
286
281
  if response.ok:
287
- data = response.json()
288
- if data and len(data) > 0:
289
- self.configSite = data[0]['data']
290
-
291
- site_count = len(self.configSite) if isinstance(self.configSite, dict) else 0
292
-
293
- else:
294
- console.print("[bold yellow]API returned an empty data set[/bold yellow]")
282
+ self.configSite = response.json()
283
+
284
+ site_count = len(self.configSite) if isinstance(self.configSite, dict) else 0
285
+ console.print(f"[bold green]Site data loaded from GitHub:[/bold green] {site_count} streaming services found.")
286
+
295
287
  else:
296
- console.print(f"[bold red]API request failed:[/bold red] HTTP {response.status_code}, {response.text[:100]}")
288
+ console.print(f"[bold red]GitHub request failed:[/bold red] HTTP {response.status_code}, {response.text[:100]}")
297
289
  self._handle_site_data_fallback()
298
290
 
291
+ except json.JSONDecodeError as e:
292
+ console.print(f"[bold red]Error parsing JSON from GitHub:[/bold red] {str(e)}")
293
+ self._handle_site_data_fallback()
294
+
299
295
  except Exception as e:
300
- console.print(f"[bold red]API connection error:[/bold red] {str(e)}")
296
+ console.print(f"[bold red]GitHub connection error:[/bold red] {str(e)}")
301
297
  self._handle_site_data_fallback()
302
298
 
303
299
  def _load_site_data_from_file(self) -> None:
@@ -562,7 +558,6 @@ class ConfigManager:
562
558
  return section in config_source
563
559
 
564
560
 
565
- # Helper function to check the platform
566
561
  def get_use_large_bar():
567
562
  """
568
563
  Determine if the large bar feature should be enabled.
@@ -12,7 +12,7 @@ import inspect
12
12
  import subprocess
13
13
  import contextlib
14
14
  import importlib.metadata
15
-
15
+ import socket
16
16
 
17
17
  # External library
18
18
  from unidecode import unidecode
@@ -283,44 +283,62 @@ class InternManager():
283
283
  else:
284
284
  return f"{bytes / (1024 * 1024):.2f} MB/s"
285
285
 
286
- def check_dns_provider(self):
286
+ # def check_dns_provider(self):
287
+ # """
288
+ # Check if the system's current DNS server matches any known DNS providers.
289
+
290
+ # Returns:
291
+ # bool: True if the current DNS server matches a known provider,
292
+ # False if no match is found or in case of errors
293
+ # """
294
+ # dns_providers = {
295
+ # "Cloudflare": ["1.1.1.1", "1.0.0.1"],
296
+ # "Google": ["8.8.8.8", "8.8.4.4"],
297
+ # "OpenDNS": ["208.67.222.222", "208.67.220.220"],
298
+ # "Quad9": ["9.9.9.9", "149.112.112.112"],
299
+ # "AdGuard": ["94.140.14.14", "94.140.15.15"],
300
+ # "Comodo": ["8.26.56.26", "8.20.247.20"],
301
+ # "Level3": ["209.244.0.3", "209.244.0.4"],
302
+ # "Norton": ["199.85.126.10", "199.85.127.10"],
303
+ # "CleanBrowsing": ["185.228.168.9", "185.228.169.9"],
304
+ # "Yandex": ["77.88.8.8", "77.88.8.1"]
305
+ # }
306
+
307
+ # try:
308
+ # resolver = dns.resolver.Resolver()
309
+ # nameservers = resolver.nameservers
310
+
311
+ # if not nameservers:
312
+ # return False
313
+
314
+ # for server in nameservers:
315
+ # for provider, ips in dns_providers.items():
316
+ # if server in ips:
317
+ # return True
318
+ # return False
319
+
320
+ # except Exception:
321
+ # return False
322
+
323
+ def check_dns_resolve(self):
287
324
  """
288
- Check if the system's current DNS server matches any known DNS providers.
325
+ Check if the system's current DNS server can resolve a domain name.
326
+ Works on both Windows and Unix-like systems.
289
327
 
290
328
  Returns:
291
- bool: True if the current DNS server matches a known provider,
292
- False if no match is found or in case of errors
329
+ bool: True if the current DNS server can resolve a domain name,
330
+ False if can't resolve or in case of errors
293
331
  """
294
- dns_providers = {
295
- "Cloudflare": ["1.1.1.1", "1.0.0.1"],
296
- "Google": ["8.8.8.8", "8.8.4.4"],
297
- "OpenDNS": ["208.67.222.222", "208.67.220.220"],
298
- "Quad9": ["9.9.9.9", "149.112.112.112"],
299
- "AdGuard": ["94.140.14.14", "94.140.15.15"],
300
- "Comodo": ["8.26.56.26", "8.20.247.20"],
301
- "Level3": ["209.244.0.3", "209.244.0.4"],
302
- "Norton": ["199.85.126.10", "199.85.127.10"],
303
- "CleanBrowsing": ["185.228.168.9", "185.228.169.9"],
304
- "Yandex": ["77.88.8.8", "77.88.8.1"]
305
- }
332
+ test_domains = ["github.com", "google.com", "microsoft.com", "amazon.com"]
306
333
 
307
334
  try:
308
- resolver = dns.resolver.Resolver()
309
- nameservers = resolver.nameservers
310
-
311
- if not nameservers:
312
- return False
313
-
314
- for server in nameservers:
315
- for provider, ips in dns_providers.items():
316
- if server in ips:
317
- return True
318
- return False
319
-
320
- except Exception:
335
+ for domain in test_domains:
336
+ # socket.gethostbyname() works consistently across all platforms
337
+ socket.gethostbyname(domain)
338
+ return True
339
+ except (socket.gaierror, socket.error):
321
340
  return False
322
341
 
323
-
324
342
  class OsSummary:
325
343
  def __init__(self):
326
344
  self.ffmpeg_path = None
@@ -210,7 +210,19 @@ def main(script_id = 0):
210
210
  log_not = Logger()
211
211
  initialize()
212
212
 
213
- if not internet_manager.check_dns_provider():
213
+ # if not internet_manager.check_dns_provider():
214
+ # print()
215
+ # console.print("[red]❌ ERROR: DNS configuration is required!")
216
+ # console.print("[red]The program cannot function correctly without proper DNS settings.")
217
+ # console.print("[yellow]Please configure one of these DNS servers:")
218
+ # console.print("[blue]• Cloudflare (1.1.1.1) 'https://developers.cloudflare.com/1.1.1.1/setup/windows/'")
219
+ # console.print("[blue]• Quad9 (9.9.9.9) 'https://docs.quad9.net/Setup_Guides/Windows/Windows_10/'")
220
+ # console.print("\n[yellow]⚠️ The program will not work until you configure your DNS settings.")
221
+
222
+ # time.sleep(2)
223
+ # msg.ask("[yellow]Press Enter to continue ...")
224
+
225
+ if not internet_manager.check_dns_resolve():
214
226
  print()
215
227
  console.print("[red]❌ ERROR: DNS configuration is required!")
216
228
  console.print("[red]The program cannot function correctly without proper DNS settings.")
@@ -219,8 +231,7 @@ def main(script_id = 0):
219
231
  console.print("[blue]• Quad9 (9.9.9.9) 'https://docs.quad9.net/Setup_Guides/Windows/Windows_10/'")
220
232
  console.print("\n[yellow]⚠️ The program will not work until you configure your DNS settings.")
221
233
 
222
- time.sleep(2)
223
- msg.ask("[yellow]Press Enter to continue ...")
234
+ os._exit(0)
224
235
 
225
236
  # Load search functions
226
237
  search_functions = load_search_functions()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: StreamingCommunity
3
- Version: 3.0.7
3
+ Version: 3.0.9
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
@@ -35,7 +35,7 @@ Dynamic: requires-dist
35
35
  Dynamic: requires-python
36
36
 
37
37
  <p align="center">
38
- <img src="https://i.ibb.co/v6RnT0wY/s2.jpg" alt="Project Logo" width="600"/>
38
+ <img src="https://i.ibb.co/v6RnT0wY/s2.jpg" alt="Project Logo" width="450"/>
39
39
  </p>
40
40
 
41
41
  <p align="center">
@@ -10,7 +10,7 @@ with open(os.path.join(os.path.dirname(__file__), "requirements.txt"), "r", enco
10
10
 
11
11
  setup(
12
12
  name="StreamingCommunity",
13
- version="3.0.7",
13
+ version="3.0.9",
14
14
  long_description=read_readme(),
15
15
  long_description_content_type="text/markdown",
16
16
  author="Lovi-0",
@@ -1,173 +0,0 @@
1
- # 21.05.24
2
-
3
- import threading
4
- import queue
5
-
6
-
7
- # External libraries
8
- import httpx
9
- from rich.console import Console
10
-
11
-
12
- # Internal utilities
13
- from StreamingCommunity.Util.config_json import config_manager
14
- from StreamingCommunity.Util.headers import get_userAgent
15
- from StreamingCommunity.Util.table import TVShowManager
16
- from StreamingCommunity.Lib.TMBD.tmdb import tmdb
17
-
18
-
19
- # Logic class
20
- from StreamingCommunity.Api.Template.config_loader import site_constant
21
- from StreamingCommunity.Api.Template.Class.SearchType import MediaManager
22
-
23
-
24
- # Variable
25
- console = Console()
26
- media_search_manager = MediaManager()
27
- table_show_manager = TVShowManager()
28
- max_timeout = config_manager.get_int("REQUESTS", "timeout")
29
- MAX_THREADS = 12
30
-
31
-
32
- def determine_media_type(title):
33
- """
34
- Use TMDB to determine if a title is a movie or TV show.
35
- """
36
- try:
37
- # First search as a movie
38
- movie_results = tmdb._make_request("search/movie", {"query": title})
39
- movie_count = len(movie_results.get("results", []))
40
-
41
- # Then search as a TV show
42
- tv_results = tmdb._make_request("search/tv", {"query": title})
43
- tv_count = len(tv_results.get("results", []))
44
-
45
- # If results found in only one category, use that
46
- if movie_count > 0 and tv_count == 0:
47
- return "film"
48
- elif tv_count > 0 and movie_count == 0:
49
- return "tv"
50
-
51
- # If both have results, compare popularity
52
- if movie_count > 0 and tv_count > 0:
53
- top_movie = movie_results["results"][0]
54
- top_tv = tv_results["results"][0]
55
-
56
- return "film" if top_movie.get("popularity", 0) > top_tv.get("popularity", 0) else "tv"
57
-
58
- return "film"
59
-
60
- except Exception as e:
61
- console.log(f"Error determining media type with TMDB: {e}")
62
- return "film"
63
-
64
-
65
- def worker_determine_type(work_queue, result_dict, worker_id):
66
- """
67
- Worker function to process items from queue and determine media types.
68
-
69
- Parameters:
70
- - work_queue: Queue containing items to process
71
- - result_dict: Dictionary to store results
72
- - worker_id: ID of the worker thread
73
- """
74
- while not work_queue.empty():
75
- try:
76
- index, item = work_queue.get(block=False)
77
- title = item.get('titolo', '')
78
- media_type = determine_media_type(title)
79
-
80
- result_dict[index] = {
81
- 'id': item.get('id', ''),
82
- 'name': title,
83
- 'type': media_type,
84
- 'path_id': item.get('path_id', ''),
85
- 'url': f"https://www.raiplay.it{item.get('url', '')}",
86
- 'image': f"https://www.raiplay.it{item.get('immagine', '')}",
87
- }
88
-
89
- work_queue.task_done()
90
-
91
- except queue.Empty:
92
- break
93
-
94
- except Exception as e:
95
- console.log(f"Worker {worker_id} error: {e}")
96
- work_queue.task_done()
97
-
98
-
99
- def title_search(query: str) -> int:
100
- """
101
- Search for titles based on a search query.
102
-
103
- Parameters:
104
- - query (str): The query to search for.
105
-
106
- Returns:
107
- int: The number of titles found.
108
- """
109
- media_search_manager.clear()
110
- table_show_manager.clear()
111
-
112
- search_url = f"https://www.raiplay.it/atomatic/raiplay-search-service/api/v1/msearch"
113
- console.print(f"[cyan]Search url: [yellow]{search_url}")
114
-
115
- json_data = {
116
- 'templateIn': '6470a982e4e0301afe1f81f1',
117
- 'templateOut': '6516ac5d40da6c377b151642',
118
- 'params': {
119
- 'param': query,
120
- 'from': None,
121
- 'sort': 'relevance',
122
- 'onlyVideoQuery': False,
123
- },
124
- }
125
-
126
- try:
127
- response = httpx.post(
128
- search_url,
129
- headers={'user-agent': get_userAgent()},
130
- json=json_data,
131
- timeout=max_timeout,
132
- follow_redirects=True
133
- )
134
- response.raise_for_status()
135
-
136
- except Exception as e:
137
- console.print(f"[red]Site: {site_constant.SITE_NAME}, request search error: {e}")
138
- return 0
139
-
140
- # Limit to only 15 results for performance
141
- data = response.json().get('agg').get('titoli').get('cards')
142
- data = data[:15] if len(data) > 15 else data
143
-
144
- # Use multithreading to determine media types in parallel
145
- work_queue = queue.Queue()
146
- result_dict = {}
147
-
148
- # Add items to the work queue
149
- for i, item in enumerate(data):
150
- work_queue.put((i, item))
151
-
152
- # Create and start worker threads
153
- threads = []
154
- for i in range(min(MAX_THREADS, len(data))):
155
- thread = threading.Thread(
156
- target=worker_determine_type,
157
- args=(work_queue, result_dict, i),
158
- daemon=True
159
- )
160
- threads.append(thread)
161
- thread.start()
162
-
163
- # Wait for all threads to complete
164
- for thread in threads:
165
- thread.join()
166
-
167
- # Add all results to media manager in correct order
168
- for i in range(len(data)):
169
- if i in result_dict:
170
- media_search_manager.add_media(result_dict[i])
171
-
172
- # Return the number of titles found
173
- return media_search_manager.get_length()