StreamingCommunity 2.9.4__py3-none-any.whl → 2.9.6__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/sweetpixel.py +49 -0
- StreamingCommunity/Api/Site/1337xx/__init__.py +26 -12
- StreamingCommunity/Api/Site/1337xx/site.py +5 -4
- StreamingCommunity/Api/Site/1337xx/title.py +4 -6
- StreamingCommunity/Api/Site/altadefinizione/__init__.py +64 -17
- StreamingCommunity/Api/Site/altadefinizione/film.py +32 -2
- StreamingCommunity/Api/Site/altadefinizione/series.py +54 -10
- StreamingCommunity/Api/Site/altadefinizione/site.py +25 -7
- StreamingCommunity/Api/Site/altadefinizione/util/ScrapeSerie.py +2 -2
- StreamingCommunity/Api/Site/animeunity/__init__.py +53 -32
- StreamingCommunity/Api/Site/animeunity/film_serie.py +8 -5
- StreamingCommunity/Api/Site/animeunity/site.py +4 -6
- StreamingCommunity/Api/Site/animeworld/__init__.py +71 -0
- StreamingCommunity/Api/Site/animeworld/serie.py +107 -0
- StreamingCommunity/Api/Site/animeworld/site.py +111 -0
- StreamingCommunity/Api/Site/animeworld/util/ScrapeSerie.py +79 -0
- StreamingCommunity/Api/Site/cb01new/__init__.py +26 -14
- StreamingCommunity/Api/Site/cb01new/film.py +1 -1
- StreamingCommunity/Api/Site/cb01new/site.py +9 -7
- StreamingCommunity/Api/Site/ddlstreamitaly/__init__.py +26 -15
- StreamingCommunity/Api/Site/ddlstreamitaly/series.py +2 -2
- StreamingCommunity/Api/Site/ddlstreamitaly/site.py +3 -3
- StreamingCommunity/Api/Site/guardaserie/__init__.py +23 -11
- StreamingCommunity/Api/Site/guardaserie/series.py +1 -1
- StreamingCommunity/Api/Site/guardaserie/site.py +5 -4
- StreamingCommunity/Api/Site/mostraguarda/__init__.py +27 -7
- StreamingCommunity/Api/Site/mostraguarda/film.py +1 -1
- StreamingCommunity/Api/Site/streamingcommunity/__init__.py +50 -27
- StreamingCommunity/Api/Site/streamingcommunity/film.py +1 -1
- StreamingCommunity/Api/Site/streamingcommunity/series.py +6 -3
- StreamingCommunity/Api/Site/streamingcommunity/site.py +7 -3
- StreamingCommunity/Lib/Downloader/HLS/segments.py +2 -4
- StreamingCommunity/Lib/Downloader/MP4/downloader.py +7 -6
- StreamingCommunity/Lib/Downloader/TOR/downloader.py +397 -227
- StreamingCommunity/Lib/FFmpeg/util.py +12 -0
- StreamingCommunity/Lib/M3U8/estimator.py +5 -8
- StreamingCommunity/Upload/version.py +1 -1
- StreamingCommunity/Util/config_json.py +2 -8
- StreamingCommunity/Util/table.py +12 -2
- StreamingCommunity/global_search.py +315 -0
- StreamingCommunity/run.py +39 -5
- {streamingcommunity-2.9.4.dist-info → streamingcommunity-2.9.6.dist-info}/METADATA +42 -15
- streamingcommunity-2.9.6.dist-info/RECORD +85 -0
- {streamingcommunity-2.9.4.dist-info → streamingcommunity-2.9.6.dist-info}/WHEEL +1 -1
- streamingcommunity-2.9.4.dist-info/RECORD +0 -79
- {streamingcommunity-2.9.4.dist-info → streamingcommunity-2.9.6.dist-info}/entry_points.txt +0 -0
- {streamingcommunity-2.9.4.dist-info → streamingcommunity-2.9.6.dist-info/licenses}/LICENSE +0 -0
- {streamingcommunity-2.9.4.dist-info → streamingcommunity-2.9.6.dist-info}/top_level.txt +0 -0
|
@@ -27,12 +27,12 @@ table_show_manager = TVShowManager()
|
|
|
27
27
|
max_timeout = config_manager.get_int("REQUESTS", "timeout")
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
def title_search(
|
|
30
|
+
def title_search(query: str) -> int:
|
|
31
31
|
"""
|
|
32
32
|
Search for titles based on a search query.
|
|
33
33
|
|
|
34
34
|
Parameters:
|
|
35
|
-
-
|
|
35
|
+
- query (str): The query to search for.
|
|
36
36
|
|
|
37
37
|
Returns:
|
|
38
38
|
- int: The number of titles found.
|
|
@@ -40,7 +40,7 @@ def title_search(word_to_search: str) -> int:
|
|
|
40
40
|
media_search_manager.clear()
|
|
41
41
|
table_show_manager.clear()
|
|
42
42
|
|
|
43
|
-
search_url = f"{site_constant.FULL_URL}/?
|
|
43
|
+
search_url = f"{site_constant.FULL_URL}/?s={query}"
|
|
44
44
|
console.print(f"[cyan]Search url: [yellow]{search_url}")
|
|
45
45
|
|
|
46
46
|
try:
|
|
@@ -54,14 +54,16 @@ def title_search(word_to_search: str) -> int:
|
|
|
54
54
|
# Create soup and find table
|
|
55
55
|
soup = BeautifulSoup(response.text, "html.parser")
|
|
56
56
|
|
|
57
|
-
for
|
|
57
|
+
for card in soup.find_all("div", class_=["card", "mp-post", "horizontal"]):
|
|
58
58
|
try:
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
title_tag = card.find("h3", class_="card-title").find("a")
|
|
60
|
+
url = title_tag.get("href")
|
|
61
|
+
title = title_tag.get_text(strip=True)
|
|
61
62
|
|
|
62
63
|
title_info = {
|
|
63
64
|
'name': title,
|
|
64
|
-
'url': url
|
|
65
|
+
'url': url,
|
|
66
|
+
'type': 'film'
|
|
65
67
|
}
|
|
66
68
|
|
|
67
69
|
media_search_manager.add_media(title_info)
|
|
@@ -12,6 +12,7 @@ from rich.prompt import Prompt
|
|
|
12
12
|
# Internal utilities
|
|
13
13
|
from StreamingCommunity.Api.Template import get_select_title
|
|
14
14
|
from StreamingCommunity.Api.Template.config_loader import site_constant
|
|
15
|
+
from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
# Logic class
|
|
@@ -30,10 +31,28 @@ msg = Prompt()
|
|
|
30
31
|
console = Console()
|
|
31
32
|
|
|
32
33
|
|
|
33
|
-
def
|
|
34
|
+
def process_search_result(select_title):
|
|
34
35
|
"""
|
|
35
|
-
|
|
36
|
+
Handles the search result and initiates the download for either a film or series.
|
|
36
37
|
"""
|
|
38
|
+
if "Serie TV" in str(select_title.type):
|
|
39
|
+
download_thread(select_title)
|
|
40
|
+
else:
|
|
41
|
+
logging.error(f"Not supported: {select_title.type}")
|
|
42
|
+
|
|
43
|
+
def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_item: dict = None):
|
|
44
|
+
"""
|
|
45
|
+
Main function of the application for search film, series and anime.
|
|
46
|
+
|
|
47
|
+
Parameters:
|
|
48
|
+
string_to_search (str, optional): String to search for
|
|
49
|
+
get_onylDatabase (bool, optional): If True, return only the database object
|
|
50
|
+
direct_item (dict, optional): Direct item to process (bypass search)
|
|
51
|
+
"""
|
|
52
|
+
if direct_item:
|
|
53
|
+
select_title = MediaItem(**direct_item)
|
|
54
|
+
process_search_result(select_title)
|
|
55
|
+
return
|
|
37
56
|
|
|
38
57
|
if string_to_search is None:
|
|
39
58
|
string_to_search = msg.ask(f"\n[purple]Insert word to search in [green]{site_constant.SITE_NAME}").strip()
|
|
@@ -41,24 +60,16 @@ def search(string_to_search: str = None, get_onylDatabase: bool = False):
|
|
|
41
60
|
# Search on database
|
|
42
61
|
len_database = title_search(quote_plus(string_to_search))
|
|
43
62
|
|
|
44
|
-
#
|
|
45
|
-
if
|
|
63
|
+
# If only the database is needed, return the manager
|
|
64
|
+
if get_onlyDatabase:
|
|
46
65
|
return media_search_manager
|
|
47
66
|
|
|
48
67
|
if len_database > 0:
|
|
49
|
-
|
|
50
|
-
# Select title from list
|
|
51
68
|
select_title = get_select_title(table_show_manager, media_search_manager)
|
|
52
|
-
|
|
53
|
-
# Download only film
|
|
54
|
-
if "Serie TV" in str(select_title.type):
|
|
55
|
-
download_thread(select_title)
|
|
56
|
-
|
|
57
|
-
else:
|
|
58
|
-
logging.error(f"Not supported: {select_title.type}")
|
|
69
|
+
process_search_result(select_title)
|
|
59
70
|
|
|
60
71
|
else:
|
|
72
|
+
|
|
73
|
+
# If no results are found, ask again
|
|
61
74
|
console.print(f"\n[red]Nothing matching was found for[white]: [purple]{string_to_search}")
|
|
62
|
-
|
|
63
|
-
# Retry
|
|
64
75
|
search()
|
|
@@ -51,8 +51,8 @@ def download_video(index_episode_selected: int, scape_info_serie: GetSerieInfo,
|
|
|
51
51
|
|
|
52
52
|
# Get info about episode
|
|
53
53
|
obj_episode = scape_info_serie.list_episodes[index_episode_selected - 1]
|
|
54
|
-
console.print(f"[yellow]Download: [red]{obj_episode.get('name')}\n")
|
|
55
|
-
|
|
54
|
+
console.print(f"[bold yellow]Download:[/bold yellow] [red]{site_constant.SITE_NAME}[/red] → [bold magenta]{obj_episode.get('name')}[/bold magenta] ([cyan]E{index_episode_selected}[/cyan]) \n")
|
|
55
|
+
|
|
56
56
|
# Define filename and path for the downloaded video
|
|
57
57
|
title_name = os_manager.get_sanitize_file(
|
|
58
58
|
f"{map_episode_title(scape_info_serie.tv_name, None, index_episode_selected, obj_episode.get('name'))}.mp4"
|
|
@@ -28,12 +28,12 @@ table_show_manager = TVShowManager()
|
|
|
28
28
|
max_timeout = config_manager.get_int("REQUESTS", "timeout")
|
|
29
29
|
|
|
30
30
|
|
|
31
|
-
def title_search(
|
|
31
|
+
def title_search(query: str) -> int:
|
|
32
32
|
"""
|
|
33
33
|
Search for titles based on a search query.
|
|
34
34
|
|
|
35
35
|
Parameters:
|
|
36
|
-
-
|
|
36
|
+
- query (str): The query to search for.
|
|
37
37
|
|
|
38
38
|
Returns:
|
|
39
39
|
- int: The number of titles found.
|
|
@@ -41,7 +41,7 @@ def title_search(word_to_search: str) -> int:
|
|
|
41
41
|
media_search_manager.clear()
|
|
42
42
|
table_show_manager.clear()
|
|
43
43
|
|
|
44
|
-
search_url = f"{site_constant.FULL_URL}/search/?&q={
|
|
44
|
+
search_url = f"{site_constant.FULL_URL}/search/?&q={query}&quick=1&type=videobox_video&nodes=11"
|
|
45
45
|
console.print(f"[cyan]Search url: [yellow]{search_url}")
|
|
46
46
|
|
|
47
47
|
try:
|
|
@@ -11,6 +11,7 @@ from rich.prompt import Prompt
|
|
|
11
11
|
# Internal utilities
|
|
12
12
|
from StreamingCommunity.Api.Template import get_select_title
|
|
13
13
|
from StreamingCommunity.Api.Template.config_loader import site_constant
|
|
14
|
+
from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
# Logic class
|
|
@@ -29,10 +30,25 @@ msg = Prompt()
|
|
|
29
30
|
console = Console()
|
|
30
31
|
|
|
31
32
|
|
|
32
|
-
def
|
|
33
|
+
def process_search_result(select_title):
|
|
33
34
|
"""
|
|
34
|
-
|
|
35
|
+
Handles the search result and initiates the download for either a film or series.
|
|
35
36
|
"""
|
|
37
|
+
download_series(select_title)
|
|
38
|
+
|
|
39
|
+
def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_item: dict = None):
|
|
40
|
+
"""
|
|
41
|
+
Main function of the application for search film, series and anime.
|
|
42
|
+
|
|
43
|
+
Parameters:
|
|
44
|
+
string_to_search (str, optional): String to search for
|
|
45
|
+
get_onylDatabase (bool, optional): If True, return only the database object
|
|
46
|
+
direct_item (dict, optional): Direct item to process (bypass search)
|
|
47
|
+
"""
|
|
48
|
+
if direct_item:
|
|
49
|
+
select_title = MediaItem(**direct_item)
|
|
50
|
+
process_search_result(select_title)
|
|
51
|
+
return
|
|
36
52
|
|
|
37
53
|
if string_to_search is None:
|
|
38
54
|
string_to_search = msg.ask(f"\n[purple]Insert word to search in [green]{site_constant.SITE_NAME}").strip()
|
|
@@ -40,20 +56,16 @@ def search(string_to_search: str = None, get_onylDatabase: bool = False):
|
|
|
40
56
|
# Search on database
|
|
41
57
|
len_database = title_search(quote_plus(string_to_search))
|
|
42
58
|
|
|
43
|
-
#
|
|
44
|
-
if
|
|
59
|
+
# If only the database is needed, return the manager
|
|
60
|
+
if get_onlyDatabase:
|
|
45
61
|
return media_search_manager
|
|
46
62
|
|
|
47
63
|
if len_database > 0:
|
|
48
|
-
|
|
49
|
-
# Select title from list
|
|
50
64
|
select_title = get_select_title(table_show_manager, media_search_manager)
|
|
51
|
-
|
|
52
|
-
# Download only film
|
|
53
|
-
download_series(select_title)
|
|
65
|
+
process_search_result(select_title)
|
|
54
66
|
|
|
55
67
|
else:
|
|
56
|
-
console.print(f"\n[red]Nothing matching was found for[white]: [purple]{string_to_search}")
|
|
57
68
|
|
|
58
|
-
#
|
|
69
|
+
# If no results are found, ask again
|
|
70
|
+
console.print(f"\n[red]Nothing matching was found for[white]: [purple]{string_to_search}")
|
|
59
71
|
search()
|
|
@@ -55,7 +55,7 @@ def download_video(index_season_selected: int, index_episode_selected: int, scap
|
|
|
55
55
|
|
|
56
56
|
# Get info about episode
|
|
57
57
|
obj_episode = scape_info_serie.list_episodes[index_episode_selected - 1]
|
|
58
|
-
console.print(f"[yellow]Download: [red]{
|
|
58
|
+
console.print(f"[bold yellow]Download:[/bold yellow] [red]{site_constant.SITE_NAME}[/red] → [bold magenta]{obj_episode.get('name')}[/bold magenta] ([cyan]S{index_season_selected}E{index_episode_selected}[/cyan]) \n")
|
|
59
59
|
|
|
60
60
|
# Define filename and path for the downloaded video
|
|
61
61
|
mp4_name = f"{map_episode_title(scape_info_serie.tv_name, index_season_selected, index_episode_selected, obj_episode.get('name'))}.mp4"
|
|
@@ -27,12 +27,12 @@ max_timeout = config_manager.get_int("REQUESTS", "timeout")
|
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
def title_search(
|
|
30
|
+
def title_search(query: str) -> int:
|
|
31
31
|
"""
|
|
32
32
|
Search for titles based on a search query.
|
|
33
33
|
|
|
34
34
|
Parameters:
|
|
35
|
-
-
|
|
35
|
+
- query (str): The query to search for.
|
|
36
36
|
|
|
37
37
|
Returns:
|
|
38
38
|
- int: The number of titles found.
|
|
@@ -40,7 +40,7 @@ def title_search(word_to_search: str) -> int:
|
|
|
40
40
|
media_search_manager.clear()
|
|
41
41
|
table_show_manager.clear()
|
|
42
42
|
|
|
43
|
-
search_url = f"{site_constant.FULL_URL}/?story={
|
|
43
|
+
search_url = f"{site_constant.FULL_URL}/?story={query}&do=search&subaction=search"
|
|
44
44
|
console.print(f"[cyan]Search url: [yellow]{search_url}")
|
|
45
45
|
|
|
46
46
|
try:
|
|
@@ -63,7 +63,8 @@ def title_search(word_to_search: str) -> int:
|
|
|
63
63
|
|
|
64
64
|
serie_info = {
|
|
65
65
|
'name': title,
|
|
66
|
-
'url': link
|
|
66
|
+
'url': link,
|
|
67
|
+
'type': 'tv'
|
|
67
68
|
}
|
|
68
69
|
|
|
69
70
|
media_search_manager.add_media(serie_info)
|
|
@@ -5,12 +5,16 @@ from urllib.parse import quote_plus
|
|
|
5
5
|
|
|
6
6
|
# External library
|
|
7
7
|
from rich.console import Console
|
|
8
|
-
from rich.prompt import Prompt
|
|
8
|
+
from rich.prompt import Prompt
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
#
|
|
11
|
+
# Internal utilities
|
|
12
12
|
from StreamingCommunity.Api.Template.config_loader import site_constant
|
|
13
|
+
from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
|
|
13
14
|
from StreamingCommunity.Lib.TMBD import tmdb, Json_film
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# Logic class
|
|
14
18
|
from .film import download_film
|
|
15
19
|
|
|
16
20
|
|
|
@@ -25,16 +29,32 @@ msg = Prompt()
|
|
|
25
29
|
console = Console()
|
|
26
30
|
|
|
27
31
|
|
|
28
|
-
def
|
|
32
|
+
def process_search_result(select_title):
|
|
29
33
|
"""
|
|
30
|
-
|
|
34
|
+
Handles the search result and initiates the download for either a film or series.
|
|
31
35
|
"""
|
|
36
|
+
download_film(select_title)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_item: dict = None):
|
|
40
|
+
"""
|
|
41
|
+
Main function of the application for search film, series and anime.
|
|
42
|
+
|
|
43
|
+
Parameters:
|
|
44
|
+
string_to_search (str, optional): String to search for
|
|
45
|
+
get_onylDatabase (bool, optional): If True, return only the database object
|
|
46
|
+
direct_item (dict, optional): Direct item to process (bypass search)
|
|
47
|
+
"""
|
|
48
|
+
if direct_item:
|
|
49
|
+
select_title = MediaItem(**direct_item)
|
|
50
|
+
process_search_result(select_title)
|
|
51
|
+
return
|
|
32
52
|
|
|
33
53
|
if string_to_search is None:
|
|
34
54
|
string_to_search = msg.ask(f"\n[purple]Insert word to search in [green]{site_constant.SITE_NAME}").strip()
|
|
35
55
|
|
|
36
56
|
# Not available for the moment
|
|
37
|
-
if
|
|
57
|
+
if get_onlyDatabase:
|
|
38
58
|
return 0
|
|
39
59
|
|
|
40
60
|
# Search on database
|
|
@@ -47,7 +67,7 @@ def search(string_to_search: str = None, get_onylDatabase: bool = False):
|
|
|
47
67
|
download_film(movie_details)
|
|
48
68
|
|
|
49
69
|
else:
|
|
50
|
-
console.print(f"\n[red]Nothing matching was found for[white]: [purple]{string_to_search}")
|
|
51
70
|
|
|
52
|
-
#
|
|
71
|
+
# If no results are found, ask again
|
|
72
|
+
console.print(f"\n[red]Nothing matching was found for[white]: [purple]{string_to_search}")
|
|
53
73
|
search()
|
|
@@ -44,7 +44,7 @@ def download_film(movie_details: Json_film) -> str:
|
|
|
44
44
|
|
|
45
45
|
# Start message and display film information
|
|
46
46
|
start_message()
|
|
47
|
-
console.print(f"[yellow]Download:
|
|
47
|
+
console.print(f"[bold yellow]Download:[/bold yellow] [red]{site_constant.SITE_NAME}[/red] → [cyan]{movie_details.title}[/cyan] \n")
|
|
48
48
|
|
|
49
49
|
# Make request to main site
|
|
50
50
|
try:
|
|
@@ -12,11 +12,12 @@ from rich.prompt import Prompt
|
|
|
12
12
|
|
|
13
13
|
# Internal utilities
|
|
14
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
|
|
15
17
|
from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance
|
|
16
18
|
|
|
17
19
|
|
|
18
20
|
# Logic class
|
|
19
|
-
from StreamingCommunity.Api.Template.config_loader import site_constant
|
|
20
21
|
from .site import title_search, table_show_manager, media_search_manager
|
|
21
22
|
from .film import download_film
|
|
22
23
|
from .series import download_series
|
|
@@ -33,54 +34,76 @@ msg = Prompt()
|
|
|
33
34
|
console = Console()
|
|
34
35
|
|
|
35
36
|
|
|
36
|
-
def
|
|
37
|
+
def get_user_input(string_to_search: str = None):
|
|
37
38
|
"""
|
|
38
|
-
|
|
39
|
+
Asks the user to input a search term.
|
|
40
|
+
Handles both Telegram bot input and direct input.
|
|
39
41
|
"""
|
|
40
|
-
if
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if string_to_search is None:
|
|
44
|
-
|
|
45
|
-
# Chiedi la scelta all'utente con il bot Telegram
|
|
42
|
+
if string_to_search is None:
|
|
43
|
+
if site_constant.TELEGRAM_BOT:
|
|
44
|
+
bot = get_bot_instance()
|
|
46
45
|
string_to_search = bot.ask(
|
|
47
46
|
"key_search",
|
|
48
|
-
f"
|
|
47
|
+
f"Enter the search term\nor type 'back' to return to the menu: ",
|
|
49
48
|
None
|
|
50
49
|
)
|
|
51
50
|
|
|
52
51
|
if string_to_search == 'back':
|
|
53
|
-
|
|
54
|
-
#
|
|
52
|
+
|
|
53
|
+
# Restart the script
|
|
55
54
|
subprocess.Popen([sys.executable] + sys.argv)
|
|
56
55
|
sys.exit()
|
|
57
|
-
|
|
56
|
+
else:
|
|
57
|
+
string_to_search = msg.ask(f"\n[purple]Insert a word to search in [green]{site_constant.SITE_NAME}").strip()
|
|
58
|
+
|
|
59
|
+
return string_to_search
|
|
60
|
+
|
|
61
|
+
def process_search_result(select_title):
|
|
62
|
+
"""
|
|
63
|
+
Handles the search result and initiates the download for either a film or series.
|
|
64
|
+
"""
|
|
65
|
+
if select_title.type == 'tv':
|
|
66
|
+
download_series(select_title)
|
|
58
67
|
else:
|
|
59
|
-
|
|
60
|
-
string_to_search = msg.ask(f"\n[purple]Insert word to search in [green]{site_constant.SITE_NAME}").strip()
|
|
68
|
+
download_film(select_title)
|
|
61
69
|
|
|
70
|
+
def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_item: dict = None):
|
|
71
|
+
"""
|
|
72
|
+
Main function of the application for search film, series and anime.
|
|
73
|
+
|
|
74
|
+
Parameters:
|
|
75
|
+
string_to_search (str, optional): String to search for
|
|
76
|
+
get_onylDatabase (bool, optional): If True, return only the database object
|
|
77
|
+
direct_item (dict, optional): Direct item to process (bypass search)
|
|
78
|
+
"""
|
|
79
|
+
if direct_item:
|
|
80
|
+
select_title = MediaItem(**direct_item)
|
|
81
|
+
process_search_result(select_title)
|
|
82
|
+
return
|
|
83
|
+
|
|
84
|
+
# Get the user input for the search term
|
|
85
|
+
string_to_search = get_user_input(string_to_search)
|
|
86
|
+
|
|
87
|
+
# Perform the database search
|
|
62
88
|
len_database = title_search(quote_plus(string_to_search))
|
|
63
89
|
|
|
64
|
-
#
|
|
65
|
-
if
|
|
90
|
+
# If only the database is needed, return the manager
|
|
91
|
+
if get_onlyDatabase:
|
|
66
92
|
return media_search_manager
|
|
67
93
|
|
|
94
|
+
if site_constant.TELEGRAM_BOT:
|
|
95
|
+
bot = get_bot_instance()
|
|
96
|
+
|
|
68
97
|
if len_database > 0:
|
|
69
|
-
|
|
70
|
-
# Select title from list
|
|
71
98
|
select_title = get_select_title(table_show_manager, media_search_manager)
|
|
72
|
-
|
|
73
|
-
if select_title.type == 'tv':
|
|
74
|
-
download_series(select_title)
|
|
75
|
-
|
|
76
|
-
else:
|
|
77
|
-
download_film(select_title)
|
|
99
|
+
process_search_result(select_title)
|
|
78
100
|
|
|
79
101
|
else:
|
|
80
102
|
console.print(f"\n[red]Nothing matching was found for[white]: [purple]{string_to_search}")
|
|
81
103
|
|
|
82
104
|
if site_constant.TELEGRAM_BOT:
|
|
83
|
-
bot.send_message(f"
|
|
105
|
+
bot.send_message(f"No results found, please try again", None)
|
|
84
106
|
|
|
85
|
-
#
|
|
107
|
+
# If no results are found, ask again
|
|
108
|
+
string_to_search = get_user_input()
|
|
86
109
|
search()
|
|
@@ -52,7 +52,7 @@ def download_film(select_title: MediaItem) -> str:
|
|
|
52
52
|
|
|
53
53
|
# Start message and display film information
|
|
54
54
|
start_message()
|
|
55
|
-
console.print(f"[yellow]Download: [red]{select_title.name} \n")
|
|
55
|
+
console.print(f"[bold yellow]Download:[/bold yellow] [red]{site_constant.SITE_NAME}[/red] → [cyan]{select_title.name}[/cyan] \n")
|
|
56
56
|
|
|
57
57
|
# Init class
|
|
58
58
|
video_source = VideoSource(site_constant.FULL_URL, False)
|
|
@@ -61,8 +61,7 @@ def download_video(index_season_selected: int, index_episode_selected: int, scra
|
|
|
61
61
|
|
|
62
62
|
# Get info about episode
|
|
63
63
|
obj_episode = season.episodes.get(index_episode_selected - 1)
|
|
64
|
-
console.print(f"[yellow]Download: [red]{
|
|
65
|
-
print()
|
|
64
|
+
console.print(f"[bold yellow]Download:[/bold yellow] [red]{site_constant.SITE_NAME}[/red] → [bold magenta]{obj_episode.name}[/bold magenta] ([cyan]S{index_season_selected}E{index_episode_selected}[/cyan]) \n")
|
|
66
65
|
|
|
67
66
|
if site_constant.TELEGRAM_BOT:
|
|
68
67
|
bot = get_bot_instance()
|
|
@@ -185,7 +184,11 @@ def download_series(select_season: MediaItem) -> None:
|
|
|
185
184
|
|
|
186
185
|
index_season_selected = bot.ask(
|
|
187
186
|
"select_title_episode",
|
|
188
|
-
"
|
|
187
|
+
"Menu di selezione delle stagioni\n\n"
|
|
188
|
+
"- Inserisci il numero della stagione (ad esempio, 1)\n"
|
|
189
|
+
"- Inserisci * per scaricare tutte le stagioni\n"
|
|
190
|
+
"- Inserisci un intervallo di stagioni (ad esempio, 1-2) per scaricare da una stagione all'altra\n"
|
|
191
|
+
"- Inserisci (ad esempio, 3-*) per scaricare dalla stagione specificata fino alla fine della serie",
|
|
189
192
|
None
|
|
190
193
|
)
|
|
191
194
|
|
|
@@ -27,12 +27,12 @@ table_show_manager = TVShowManager()
|
|
|
27
27
|
max_timeout = config_manager.get_int("REQUESTS", "timeout")
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
def title_search(
|
|
30
|
+
def title_search(query: str) -> int:
|
|
31
31
|
"""
|
|
32
32
|
Search for titles based on a search query.
|
|
33
33
|
|
|
34
34
|
Parameters:
|
|
35
|
-
-
|
|
35
|
+
- query (str): The query to search for.
|
|
36
36
|
|
|
37
37
|
Returns:
|
|
38
38
|
int: The number of titles found.
|
|
@@ -43,7 +43,7 @@ def title_search(title_search: str) -> int:
|
|
|
43
43
|
media_search_manager.clear()
|
|
44
44
|
table_show_manager.clear()
|
|
45
45
|
|
|
46
|
-
search_url = f"{site_constant.FULL_URL}/api/search?q={
|
|
46
|
+
search_url = f"{site_constant.FULL_URL}/api/search?q={query}"
|
|
47
47
|
console.print(f"[cyan]Search url: [yellow]{search_url}")
|
|
48
48
|
|
|
49
49
|
try:
|
|
@@ -52,6 +52,8 @@ def title_search(title_search: str) -> int:
|
|
|
52
52
|
|
|
53
53
|
except Exception as e:
|
|
54
54
|
console.print(f"Site: {site_constant.SITE_NAME}, request search error: {e}")
|
|
55
|
+
if site_constant.TELEGRAM_BOT:
|
|
56
|
+
bot.send_message(f"ERRORE\n\nErrore nella richiesta di ricerca:\n\n{e}", None)
|
|
55
57
|
return 0
|
|
56
58
|
|
|
57
59
|
# Prepara le scelte per l'utente
|
|
@@ -82,6 +84,8 @@ def title_search(title_search: str) -> int:
|
|
|
82
84
|
|
|
83
85
|
except Exception as e:
|
|
84
86
|
print(f"Error parsing a film entry: {e}")
|
|
87
|
+
if site_constant.TELEGRAM_BOT:
|
|
88
|
+
bot.send_message(f"ERRORE\n\nErrore nell'analisi del film:\n\n{e}", None)
|
|
85
89
|
|
|
86
90
|
if site_constant.TELEGRAM_BOT:
|
|
87
91
|
if choices:
|
|
@@ -37,7 +37,7 @@ from ...M3U8 import (
|
|
|
37
37
|
# Config
|
|
38
38
|
TQDM_DELAY_WORKER = config_manager.get_float('M3U8_DOWNLOAD', 'tqdm_delay')
|
|
39
39
|
REQUEST_MAX_RETRY = config_manager.get_int('REQUESTS', 'max_retry')
|
|
40
|
-
REQUEST_VERIFY = config_manager.
|
|
40
|
+
REQUEST_VERIFY = config_manager.get_bool('REQUESTS', 'verify')
|
|
41
41
|
DEFAULT_VIDEO_WORKERS = config_manager.get_int('M3U8_DOWNLOAD', 'default_video_workser')
|
|
42
42
|
DEFAULT_AUDIO_WORKERS = config_manager.get_int('M3U8_DOWNLOAD', 'default_audio_workser')
|
|
43
43
|
MAX_TIMEOOUT = config_manager.get_int("REQUESTS", "timeout")
|
|
@@ -223,14 +223,12 @@ class M3U8_Segments:
|
|
|
223
223
|
|
|
224
224
|
try:
|
|
225
225
|
with self._get_http_client() as client:
|
|
226
|
-
start_time = time.time()
|
|
227
226
|
response = client.get(ts_url)
|
|
228
227
|
|
|
229
228
|
# Validate response and content
|
|
230
229
|
response.raise_for_status()
|
|
231
230
|
segment_content = response.content
|
|
232
231
|
content_size = len(segment_content)
|
|
233
|
-
duration = time.time() - start_time
|
|
234
232
|
|
|
235
233
|
# Decrypt if needed and verify decrypted content
|
|
236
234
|
if self.decryption is not None:
|
|
@@ -243,7 +241,7 @@ class M3U8_Segments:
|
|
|
243
241
|
self.stop_event.set() # Trigger the stopping event for all threads
|
|
244
242
|
break # Stop the current task immediately
|
|
245
243
|
|
|
246
|
-
self.class_ts_estimator.update_progress_bar(content_size,
|
|
244
|
+
self.class_ts_estimator.update_progress_bar(content_size, progress_bar)
|
|
247
245
|
self.queue.put((index, segment_content))
|
|
248
246
|
self.downloaded_segments.add(index)
|
|
249
247
|
progress_bar.update(1)
|
|
@@ -31,7 +31,6 @@ from ...FFmpeg import print_duration_table
|
|
|
31
31
|
|
|
32
32
|
# Config
|
|
33
33
|
REQUEST_VERIFY = config_manager.get_bool('REQUESTS', 'verify')
|
|
34
|
-
REQUEST_HTTP2 = config_manager.get_bool('REQUESTS', 'http2')
|
|
35
34
|
GET_ONLY_LINK = config_manager.get_bool('M3U8_PARSER', 'get_only_link')
|
|
36
35
|
REQUEST_TIMEOUT = config_manager.get_float('REQUESTS', 'timeout')
|
|
37
36
|
TELEGRAM_BOT = config_manager.get_bool('DEFAULT', 'telegram_bot')
|
|
@@ -111,11 +110,12 @@ def MP4_downloader(url: str, path: str, referer: str = None, headers_: dict = No
|
|
|
111
110
|
interrupt_handler = InterruptHandler()
|
|
112
111
|
original_handler = signal.signal(signal.SIGINT, partial(signal_handler, interrupt_handler=interrupt_handler, original_handler=signal.getsignal(signal.SIGINT)))
|
|
113
112
|
|
|
113
|
+
# Ensure the output directory exists
|
|
114
|
+
os.makedirs(os.path.dirname(path), exist_ok=True)
|
|
115
|
+
|
|
114
116
|
try:
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
with httpx.Client(transport=transport, timeout=httpx.Timeout(60)) as client:
|
|
118
|
-
with client.stream("GET", url, headers=headers, timeout=REQUEST_TIMEOUT) as response:
|
|
117
|
+
with httpx.Client() as client:
|
|
118
|
+
with client.stream("GET", url, headers=headers) as response:
|
|
119
119
|
response.raise_for_status()
|
|
120
120
|
total = int(response.headers.get('content-length', 0))
|
|
121
121
|
|
|
@@ -123,6 +123,7 @@ def MP4_downloader(url: str, path: str, referer: str = None, headers_: dict = No
|
|
|
123
123
|
console.print("[bold red]No video stream found.[/bold red]")
|
|
124
124
|
return None, False
|
|
125
125
|
|
|
126
|
+
# Create a fancy progress bar
|
|
126
127
|
progress_bar = tqdm(
|
|
127
128
|
total=total,
|
|
128
129
|
ascii='░▒█',
|
|
@@ -135,7 +136,7 @@ def MP4_downloader(url: str, path: str, referer: str = None, headers_: dict = No
|
|
|
135
136
|
unit_scale=True,
|
|
136
137
|
desc='Downloading',
|
|
137
138
|
mininterval=0.05,
|
|
138
|
-
file=sys.stdout # Using file=sys.stdout to force in-place updates because sys.stderr may not support carriage returns in this environment.
|
|
139
|
+
file=sys.stdout # Using file=sys.stdout to force in-place updates because sys.stderr may not support carriage returns in this environment.
|
|
139
140
|
)
|
|
140
141
|
|
|
141
142
|
downloaded = 0
|