StreamingCommunity 2.9.3__py3-none-any.whl → 2.9.5__py3-none-any.whl
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/Api/Player/Helper/Vixcloud/util.py +40 -38
- StreamingCommunity/Api/Player/maxstream.py +3 -11
- StreamingCommunity/Api/Site/1337xx/__init__.py +26 -12
- StreamingCommunity/Api/Site/1337xx/site.py +3 -10
- StreamingCommunity/Api/Site/altadefinizione/__init__.py +108 -0
- StreamingCommunity/Api/Site/altadefinizione/film.py +128 -0
- StreamingCommunity/Api/Site/altadefinizione/series.py +209 -0
- StreamingCommunity/Api/Site/altadefinizione/site.py +93 -0
- StreamingCommunity/Api/Site/altadefinizione/util/ScrapeSerie.py +72 -0
- StreamingCommunity/Api/Site/animeunity/__init__.py +53 -32
- StreamingCommunity/Api/Site/animeunity/film_serie.py +6 -2
- StreamingCommunity/Api/Site/animeunity/site.py +1 -11
- StreamingCommunity/Api/Site/cb01new/__init__.py +26 -14
- StreamingCommunity/Api/Site/cb01new/site.py +7 -16
- StreamingCommunity/Api/Site/ddlstreamitaly/__init__.py +26 -15
- StreamingCommunity/Api/Site/ddlstreamitaly/site.py +1 -9
- StreamingCommunity/Api/Site/guardaserie/__init__.py +23 -11
- StreamingCommunity/Api/Site/guardaserie/site.py +3 -10
- StreamingCommunity/Api/Site/mostraguarda/__init__.py +27 -7
- StreamingCommunity/Api/Site/streamingcommunity/__init__.py +50 -27
- StreamingCommunity/Api/Site/streamingcommunity/series.py +34 -12
- StreamingCommunity/Api/Site/streamingcommunity/site.py +14 -10
- StreamingCommunity/Api/Site/streamingcommunity/util/ScrapeSerie.py +38 -17
- StreamingCommunity/Api/Template/Class/SearchType.py +1 -1
- StreamingCommunity/Api/Template/Util/__init__.py +0 -1
- StreamingCommunity/Api/Template/Util/manage_ep.py +1 -0
- StreamingCommunity/Api/Template/config_loader.py +0 -4
- StreamingCommunity/Lib/Downloader/HLS/downloader.py +2 -2
- StreamingCommunity/Lib/Downloader/HLS/segments.py +1 -1
- StreamingCommunity/Lib/Downloader/MP4/downloader.py +8 -6
- StreamingCommunity/Lib/M3U8/estimator.py +3 -3
- StreamingCommunity/Upload/version.py +1 -1
- StreamingCommunity/Util/config_json.py +2 -11
- StreamingCommunity/Util/table.py +12 -2
- StreamingCommunity/__init__.py +6 -0
- StreamingCommunity/global_search.py +315 -0
- StreamingCommunity/run.py +27 -3
- {StreamingCommunity-2.9.3.dist-info → streamingcommunity-2.9.5.dist-info}/METADATA +128 -16
- streamingcommunity-2.9.5.dist-info/RECORD +80 -0
- {StreamingCommunity-2.9.3.dist-info → streamingcommunity-2.9.5.dist-info}/WHEEL +1 -1
- StreamingCommunity/Api/Template/Util/get_domain.py +0 -100
- StreamingCommunity-2.9.3.dist-info/RECORD +0 -75
- {StreamingCommunity-2.9.3.dist-info → streamingcommunity-2.9.5.dist-info}/LICENSE +0 -0
- {StreamingCommunity-2.9.3.dist-info → streamingcommunity-2.9.5.dist-info}/entry_points.txt +0 -0
- {StreamingCommunity-2.9.3.dist-info → streamingcommunity-2.9.5.dist-info}/top_level.txt +0 -0
|
@@ -11,6 +11,7 @@ class Episode:
|
|
|
11
11
|
self.number: int = data.get('number', 1)
|
|
12
12
|
self.name: str = data.get('name', '')
|
|
13
13
|
self.duration: int = data.get('duration', 0)
|
|
14
|
+
self.url: str = data.get('url', '')
|
|
14
15
|
|
|
15
16
|
def __str__(self):
|
|
16
17
|
return f"Episode(id={self.id}, number={self.number}, name='{self.name}', duration={self.duration} sec)"
|
|
@@ -35,69 +36,70 @@ class EpisodeManager:
|
|
|
35
36
|
|
|
36
37
|
Parameters:
|
|
37
38
|
- index (int): The zero-based index of the episode to retrieve.
|
|
38
|
-
|
|
39
|
-
Returns:
|
|
40
|
-
Episode: The Episode object at the specified index.
|
|
41
39
|
"""
|
|
42
40
|
return self.episodes[index]
|
|
43
41
|
|
|
44
|
-
def length(self) -> int:
|
|
45
|
-
"""
|
|
46
|
-
Get the number of episodes in the manager.
|
|
47
|
-
|
|
48
|
-
Returns:
|
|
49
|
-
int: Number of episodes.
|
|
50
|
-
"""
|
|
51
|
-
return len(self.episodes)
|
|
52
|
-
|
|
53
42
|
def clear(self) -> None:
|
|
54
43
|
"""
|
|
55
44
|
This method clears the episodes list.
|
|
56
|
-
|
|
57
|
-
Parameters:
|
|
58
|
-
- self: The object instance.
|
|
59
45
|
"""
|
|
60
46
|
self.episodes.clear()
|
|
61
47
|
|
|
48
|
+
def __len__(self) -> int:
|
|
49
|
+
"""
|
|
50
|
+
Get the number of episodes in the manager.
|
|
51
|
+
"""
|
|
52
|
+
return len(self.episodes)
|
|
53
|
+
|
|
62
54
|
def __str__(self):
|
|
63
55
|
return f"EpisodeManager(num_episodes={len(self.episodes)})"
|
|
64
56
|
|
|
65
57
|
|
|
66
|
-
class
|
|
58
|
+
class Season:
|
|
67
59
|
def __init__(self, data: Dict[str, Any]):
|
|
68
60
|
self.id: int = data.get('id', 0)
|
|
69
61
|
self.number: int = data.get('number', 0)
|
|
62
|
+
self.name: str = data.get('name', '')
|
|
63
|
+
self.slug: str = data.get('slug', '')
|
|
64
|
+
self.type: str = data.get('type', '')
|
|
65
|
+
self.episodes: EpisodeManager = EpisodeManager()
|
|
70
66
|
|
|
71
67
|
def __str__(self):
|
|
72
|
-
return f"
|
|
68
|
+
return f"Season(id={self.id}, number={self.number}, name='{self.name}', episodes={self.episodes.length()})"
|
|
69
|
+
|
|
73
70
|
|
|
74
71
|
class SeasonManager:
|
|
75
72
|
def __init__(self):
|
|
76
|
-
self.seasons: List[
|
|
73
|
+
self.seasons: List[Season] = []
|
|
77
74
|
|
|
78
|
-
def add_season(self, season_data):
|
|
79
|
-
|
|
75
|
+
def add_season(self, season_data: Dict[str, Any]) -> Season:
|
|
76
|
+
"""
|
|
77
|
+
Add a new season to the manager and return it.
|
|
78
|
+
|
|
79
|
+
Parameters:
|
|
80
|
+
- season_data (Dict[str, Any]): A dictionary containing data for the new season.
|
|
81
|
+
"""
|
|
82
|
+
season = Season(season_data)
|
|
80
83
|
self.seasons.append(season)
|
|
84
|
+
return season
|
|
81
85
|
|
|
82
|
-
def get_season_by_number(self, number: int) -> Optional[
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
class Season:
|
|
86
|
-
def __init__(self, season_data: Dict[str, Union[int, str, None]]):
|
|
87
|
-
self.season_data = season_data
|
|
88
|
-
|
|
89
|
-
self.id: int = season_data.get('id', 0)
|
|
90
|
-
self.number: int = season_data.get('number', 0)
|
|
91
|
-
self.name: str = season_data.get('name', '')
|
|
92
|
-
self.slug: str = season_data.get('slug', '')
|
|
93
|
-
self.type: str = season_data.get('type', '')
|
|
94
|
-
self.seasons_count: int = season_data.get('seasons_count', 0)
|
|
86
|
+
def get_season_by_number(self, number: int) -> Optional[Season]:
|
|
87
|
+
"""
|
|
88
|
+
Get a season by its number.
|
|
95
89
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
for
|
|
100
|
-
|
|
90
|
+
Parameters:
|
|
91
|
+
- number (int): The season number (1-based index)
|
|
92
|
+
"""
|
|
93
|
+
for season in self.seasons:
|
|
94
|
+
if season.number == number:
|
|
95
|
+
return season
|
|
96
|
+
return None
|
|
97
|
+
|
|
98
|
+
def __len__(self) -> int:
|
|
99
|
+
"""
|
|
100
|
+
Return the number of seasons managed.
|
|
101
|
+
"""
|
|
102
|
+
return len(self.seasons)
|
|
101
103
|
|
|
102
104
|
|
|
103
105
|
class Stream:
|
|
@@ -48,11 +48,7 @@ class VideoSource:
|
|
|
48
48
|
|
|
49
49
|
return self.redirect_url
|
|
50
50
|
|
|
51
|
-
except
|
|
52
|
-
logging.error(f"Error during the initial request: {e}")
|
|
53
|
-
raise
|
|
54
|
-
|
|
55
|
-
except AttributeError as e:
|
|
51
|
+
except Exception as e:
|
|
56
52
|
logging.error(f"Error parsing HTML: {e}")
|
|
57
53
|
raise
|
|
58
54
|
|
|
@@ -98,12 +94,8 @@ class VideoSource:
|
|
|
98
94
|
|
|
99
95
|
return self.maxstream_url
|
|
100
96
|
|
|
101
|
-
except
|
|
102
|
-
logging.error(f"Error during the request
|
|
103
|
-
raise
|
|
104
|
-
|
|
105
|
-
except AttributeError as e:
|
|
106
|
-
logging.error(f"Error parsing HTML: {e}")
|
|
97
|
+
except Exception as e:
|
|
98
|
+
logging.error(f"Error during the request: {e}")
|
|
107
99
|
raise
|
|
108
100
|
|
|
109
101
|
def get_m3u8_url(self):
|
|
@@ -10,10 +10,11 @@ from rich.prompt import Prompt
|
|
|
10
10
|
|
|
11
11
|
# Internal utilities
|
|
12
12
|
from StreamingCommunity.Api.Template import get_select_title
|
|
13
|
+
from StreamingCommunity.Api.Template.config_loader import site_constant
|
|
14
|
+
from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
|
|
13
15
|
|
|
14
16
|
|
|
15
17
|
# Logic class
|
|
16
|
-
from StreamingCommunity.Api.Template.config_loader import site_constant
|
|
17
18
|
from .site import title_search, media_search_manager, table_show_manager
|
|
18
19
|
from .title import download_title
|
|
19
20
|
|
|
@@ -29,30 +30,43 @@ console = Console()
|
|
|
29
30
|
msg = Prompt()
|
|
30
31
|
|
|
31
32
|
|
|
32
|
-
|
|
33
|
+
|
|
34
|
+
def process_search_result(select_title):
|
|
35
|
+
"""
|
|
36
|
+
Handles the search result and initiates the download for either a film or series.
|
|
37
|
+
"""
|
|
38
|
+
download_title(select_title)
|
|
39
|
+
|
|
40
|
+
def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_item: dict = None):
|
|
33
41
|
"""
|
|
34
|
-
Main function of the application for film and
|
|
42
|
+
Main function of the application for search film, series and anime.
|
|
43
|
+
|
|
44
|
+
Parameters:
|
|
45
|
+
string_to_search (str, optional): String to search for
|
|
46
|
+
get_onylDatabase (bool, optional): If True, return only the database object
|
|
47
|
+
direct_item (dict, optional): Direct item to process (bypass search)
|
|
35
48
|
"""
|
|
49
|
+
if direct_item:
|
|
50
|
+
select_title = MediaItem(**direct_item)
|
|
51
|
+
process_search_result(select_title)
|
|
52
|
+
return
|
|
53
|
+
|
|
36
54
|
if string_to_search is None:
|
|
37
55
|
string_to_search = msg.ask(f"\n[purple]Insert word to search in [green]{site_constant.SITE_NAME}").strip()
|
|
38
56
|
|
|
39
|
-
#
|
|
57
|
+
# Perform the database search
|
|
40
58
|
len_database = title_search(quote_plus(string_to_search))
|
|
41
59
|
|
|
42
|
-
#
|
|
43
|
-
if
|
|
60
|
+
# If only the database is needed, return the manager
|
|
61
|
+
if get_onlyDatabase:
|
|
44
62
|
return media_search_manager
|
|
45
63
|
|
|
46
64
|
if len_database > 0:
|
|
47
|
-
|
|
48
|
-
# Select title from list
|
|
49
65
|
select_title = get_select_title(table_show_manager, media_search_manager)
|
|
50
|
-
|
|
51
|
-
# Download title
|
|
52
66
|
download_title(select_title)
|
|
53
67
|
|
|
54
68
|
else:
|
|
55
|
-
console.print(f"\n[red]Nothing matching was found for[white]: [purple]{string_to_search}")
|
|
56
69
|
|
|
57
|
-
#
|
|
70
|
+
# If no results are found, ask again
|
|
71
|
+
console.print(f"\n[red]Nothing matching was found for[white]: [purple]{string_to_search}")
|
|
58
72
|
search()
|
|
@@ -16,7 +16,6 @@ from StreamingCommunity.Util.table import TVShowManager
|
|
|
16
16
|
|
|
17
17
|
# Logic class
|
|
18
18
|
from StreamingCommunity.Api.Template.config_loader import site_constant
|
|
19
|
-
from StreamingCommunity.Api.Template.Util import search_domain
|
|
20
19
|
from StreamingCommunity.Api.Template.Class.SearchType import MediaManager
|
|
21
20
|
|
|
22
21
|
|
|
@@ -40,14 +39,6 @@ def title_search(word_to_search: str) -> int:
|
|
|
40
39
|
media_search_manager.clear()
|
|
41
40
|
table_show_manager.clear()
|
|
42
41
|
|
|
43
|
-
# Check if domain is working
|
|
44
|
-
domain_to_use, base_url = search_domain(site_constant.FULL_URL)
|
|
45
|
-
|
|
46
|
-
if domain_to_use is None or base_url is None:
|
|
47
|
-
console.log("[bold red]Error: Unable to determine valid domain or base URL.[/bold red]")
|
|
48
|
-
console.print("[yellow]The service might be temporarily unavailable or the domain may have changed.[/yellow]")
|
|
49
|
-
sys.exit(1)
|
|
50
|
-
|
|
51
42
|
search_url = f"{site_constant.FULL_URL}/search/{word_to_search}/1/"
|
|
52
43
|
console.print(f"[cyan]Search url: [yellow]{search_url}")
|
|
53
44
|
|
|
@@ -57,6 +48,7 @@ def title_search(word_to_search: str) -> int:
|
|
|
57
48
|
|
|
58
49
|
except Exception as e:
|
|
59
50
|
console.print(f"Site: {site_constant.SITE_NAME}, request search error: {e}")
|
|
51
|
+
return 0
|
|
60
52
|
|
|
61
53
|
# Create soup and find table
|
|
62
54
|
soup = BeautifulSoup(response.text, "html.parser")
|
|
@@ -70,7 +62,8 @@ def title_search(word_to_search: str) -> int:
|
|
|
70
62
|
'seader': tr.find_all("td")[-5].get_text(strip=True),
|
|
71
63
|
'leacher': tr.find_all("td")[-4].get_text(strip=True),
|
|
72
64
|
'date': tr.find_all("td")[-3].get_text(strip=True).replace("'", ""),
|
|
73
|
-
'size': tr.find_all("td")[-2].get_text(strip=True)
|
|
65
|
+
'size': tr.find_all("td")[-2].get_text(strip=True),
|
|
66
|
+
'type': 'torrent'
|
|
74
67
|
}
|
|
75
68
|
media_search_manager.add_media(title_info)
|
|
76
69
|
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# 16.03.25
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
import subprocess
|
|
5
|
+
from urllib.parse import quote_plus
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# External library
|
|
9
|
+
from rich.console import Console
|
|
10
|
+
from rich.prompt import Prompt
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# Internal utilities
|
|
14
|
+
from StreamingCommunity.Api.Template import get_select_title
|
|
15
|
+
from StreamingCommunity.Api.Template.config_loader import site_constant
|
|
16
|
+
from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
|
|
17
|
+
from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
# Logic class
|
|
21
|
+
from .site import title_search, table_show_manager, media_search_manager
|
|
22
|
+
from .film import download_film
|
|
23
|
+
from .series import download_series
|
|
24
|
+
|
|
25
|
+
# Variable
|
|
26
|
+
indice = 2
|
|
27
|
+
_useFor = "film_serie"
|
|
28
|
+
_deprecate = False
|
|
29
|
+
_priority = 1
|
|
30
|
+
_engineDownload = "hls"
|
|
31
|
+
|
|
32
|
+
msg = Prompt()
|
|
33
|
+
console = Console()
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def get_user_input(string_to_search: str = None):
|
|
37
|
+
"""
|
|
38
|
+
Asks the user to input a search term.
|
|
39
|
+
Handles both Telegram bot input and direct input.
|
|
40
|
+
"""
|
|
41
|
+
if string_to_search is None:
|
|
42
|
+
if site_constant.TELEGRAM_BOT:
|
|
43
|
+
bot = get_bot_instance()
|
|
44
|
+
string_to_search = bot.ask(
|
|
45
|
+
"key_search",
|
|
46
|
+
f"Enter the search term\nor type 'back' to return to the menu: ",
|
|
47
|
+
None
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
if string_to_search == 'back':
|
|
51
|
+
|
|
52
|
+
# Restart the script
|
|
53
|
+
subprocess.Popen([sys.executable] + sys.argv)
|
|
54
|
+
sys.exit()
|
|
55
|
+
else:
|
|
56
|
+
string_to_search = msg.ask(f"\n[purple]Insert a word to search in [green]{site_constant.SITE_NAME}").strip()
|
|
57
|
+
|
|
58
|
+
return string_to_search
|
|
59
|
+
|
|
60
|
+
def process_search_result(select_title):
|
|
61
|
+
"""
|
|
62
|
+
Handles the search result and initiates the download for either a film or series.
|
|
63
|
+
"""
|
|
64
|
+
if select_title.type == 'tv':
|
|
65
|
+
download_series(select_title)
|
|
66
|
+
else:
|
|
67
|
+
download_film(select_title)
|
|
68
|
+
|
|
69
|
+
def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_item: dict = None):
|
|
70
|
+
"""
|
|
71
|
+
Main function of the application for search film, series and anime.
|
|
72
|
+
|
|
73
|
+
Parameters:
|
|
74
|
+
string_to_search (str, optional): String to search for
|
|
75
|
+
get_onylDatabase (bool, optional): If True, return only the database object
|
|
76
|
+
direct_item (dict, optional): Direct item to process (bypass search)
|
|
77
|
+
"""
|
|
78
|
+
if direct_item:
|
|
79
|
+
select_title = MediaItem(**direct_item)
|
|
80
|
+
process_search_result(select_title)
|
|
81
|
+
return
|
|
82
|
+
|
|
83
|
+
# Get the user input for the search term
|
|
84
|
+
string_to_search = get_user_input(string_to_search)
|
|
85
|
+
|
|
86
|
+
# Perform the database search
|
|
87
|
+
len_database = title_search(quote_plus(string_to_search))
|
|
88
|
+
|
|
89
|
+
# If only the database is needed, return the manager
|
|
90
|
+
if get_onlyDatabase:
|
|
91
|
+
return media_search_manager
|
|
92
|
+
|
|
93
|
+
if site_constant.TELEGRAM_BOT:
|
|
94
|
+
bot = get_bot_instance()
|
|
95
|
+
|
|
96
|
+
if len_database > 0:
|
|
97
|
+
select_title = get_select_title(table_show_manager, media_search_manager)
|
|
98
|
+
process_search_result(select_title)
|
|
99
|
+
|
|
100
|
+
else:
|
|
101
|
+
console.print(f"\n[red]Nothing matching was found for[white]: [purple]{string_to_search}")
|
|
102
|
+
|
|
103
|
+
if site_constant.TELEGRAM_BOT:
|
|
104
|
+
bot.send_message(f"No results found, please try again", None)
|
|
105
|
+
|
|
106
|
+
# If no results are found, ask again
|
|
107
|
+
string_to_search = get_user_input()
|
|
108
|
+
search()
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# 16.03.25
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
# External library
|
|
7
|
+
import httpx
|
|
8
|
+
from bs4 import BeautifulSoup
|
|
9
|
+
from rich.console import Console
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# Internal utilities
|
|
13
|
+
from StreamingCommunity.Util.os import os_manager
|
|
14
|
+
from StreamingCommunity.Util.message import start_message
|
|
15
|
+
from StreamingCommunity.Util.headers import get_headers
|
|
16
|
+
from StreamingCommunity.Util.config_json import config_manager
|
|
17
|
+
from StreamingCommunity.Lib.Downloader import HLS_Downloader
|
|
18
|
+
from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance, TelegramSession
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# Logic class
|
|
22
|
+
from StreamingCommunity.Api.Template.config_loader import site_constant
|
|
23
|
+
from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
# Player
|
|
27
|
+
from StreamingCommunity.Api.Player.supervideo import VideoSource
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# Variable
|
|
31
|
+
console = Console()
|
|
32
|
+
max_timeout = config_manager.get_int("REQUESTS", "timeout")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def download_film(select_title: MediaItem) -> str:
|
|
36
|
+
"""
|
|
37
|
+
Downloads a film using the provided film ID, title name, and domain.
|
|
38
|
+
|
|
39
|
+
Parameters:
|
|
40
|
+
- select_title (MediaItem): The selected media item.
|
|
41
|
+
|
|
42
|
+
Return:
|
|
43
|
+
- str: output path if successful, otherwise None
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
if site_constant.TELEGRAM_BOT:
|
|
47
|
+
bot = get_bot_instance()
|
|
48
|
+
bot.send_message(f"Download in corso:\n{select_title.name}", None)
|
|
49
|
+
|
|
50
|
+
# Viene usato per lo screen
|
|
51
|
+
console.print(f"## Download: [red]{select_title.name} ##")
|
|
52
|
+
|
|
53
|
+
# Get script_id
|
|
54
|
+
script_id = TelegramSession.get_session()
|
|
55
|
+
if script_id != "unknown":
|
|
56
|
+
TelegramSession.updateScriptId(script_id, select_title.name)
|
|
57
|
+
|
|
58
|
+
start_message()
|
|
59
|
+
console.print(f"[yellow]Download: [red]{select_title.name} \n")
|
|
60
|
+
|
|
61
|
+
# Extract mostraguarda link
|
|
62
|
+
try:
|
|
63
|
+
response = httpx.get(select_title.url, headers=get_headers(), timeout=10)
|
|
64
|
+
response.raise_for_status()
|
|
65
|
+
|
|
66
|
+
except Exception as e:
|
|
67
|
+
console.print(f"[red]Error fetching the page: {e}")
|
|
68
|
+
|
|
69
|
+
if site_constant.TELEGRAM_BOT:
|
|
70
|
+
bot.send_message(f"ERRORE\n\nErrore durante il recupero della pagina.\n\n{e}", None)
|
|
71
|
+
return None
|
|
72
|
+
|
|
73
|
+
# Create mostraguarda url
|
|
74
|
+
soup = BeautifulSoup(response.text, "html.parser")
|
|
75
|
+
iframe_tag = soup.find_all("iframe")
|
|
76
|
+
url_mostraGuarda = iframe_tag[0].get('data-src')
|
|
77
|
+
if not url_mostraGuarda:
|
|
78
|
+
console.print("Error: data-src attribute not found in iframe.")
|
|
79
|
+
if site_constant.TELEGRAM_BOT:
|
|
80
|
+
bot.send_message(f"ERRORE\n\nErrore: attributo data-src non trovato nell'iframe", None)
|
|
81
|
+
|
|
82
|
+
# Extract supervideo URL
|
|
83
|
+
try:
|
|
84
|
+
response = httpx.get(url_mostraGuarda, headers=get_headers(), timeout=10)
|
|
85
|
+
response.raise_for_status()
|
|
86
|
+
|
|
87
|
+
except Exception as e:
|
|
88
|
+
console.print(f"[red]Error fetching mostraguarda link: {e}")
|
|
89
|
+
console.print("[yellow]Missing access credentials. This part of the code is still under development.")
|
|
90
|
+
if site_constant.TELEGRAM_BOT:
|
|
91
|
+
bot.send_message(f"ERRORE\n\nErrore durante il recupero del link mostra/guarda.\n\n{e}", None)
|
|
92
|
+
bot.send_message(f"ERRORE\n\nCredenziali di accesso mancanti.\nQuesta parte del codice è ancora in fase di sviluppo.", None)
|
|
93
|
+
return None
|
|
94
|
+
|
|
95
|
+
# Create supervio URL
|
|
96
|
+
soup = BeautifulSoup(response.text, "html.parser")
|
|
97
|
+
player_links = soup.find("ul", class_="_player-mirrors")
|
|
98
|
+
player_items = player_links.find_all("li")
|
|
99
|
+
supervideo_url = "https:" + player_items[0].get("data-link")
|
|
100
|
+
if not supervideo_url:
|
|
101
|
+
return None
|
|
102
|
+
|
|
103
|
+
# Init class
|
|
104
|
+
video_source = VideoSource(url=supervideo_url)
|
|
105
|
+
master_playlist = video_source.get_playlist()
|
|
106
|
+
|
|
107
|
+
# Define the filename and path for the downloaded film
|
|
108
|
+
title_name = os_manager.get_sanitize_file(select_title.name) + ".mp4"
|
|
109
|
+
mp4_path = os.path.join(site_constant.MOVIE_FOLDER, title_name.replace(".mp4", ""))
|
|
110
|
+
|
|
111
|
+
# Download the film using the m3u8 playlist, and output filename
|
|
112
|
+
r_proc = HLS_Downloader(
|
|
113
|
+
m3u8_url=master_playlist,
|
|
114
|
+
output_path=os.path.join(mp4_path, title_name)
|
|
115
|
+
).start()
|
|
116
|
+
|
|
117
|
+
if site_constant.TELEGRAM_BOT:
|
|
118
|
+
|
|
119
|
+
# Delete script_id
|
|
120
|
+
script_id = TelegramSession.get_session()
|
|
121
|
+
if script_id != "unknown":
|
|
122
|
+
TelegramSession.deleteScriptId(script_id)
|
|
123
|
+
|
|
124
|
+
if r_proc['error'] is not None:
|
|
125
|
+
try: os.remove(r_proc['path'])
|
|
126
|
+
except: pass
|
|
127
|
+
|
|
128
|
+
return r_proc['path']
|