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
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
# 16.03.25
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from typing import Tuple
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# External library
|
|
8
|
+
from rich.console import Console
|
|
9
|
+
from rich.prompt import Prompt
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# Internal utilities
|
|
13
|
+
from StreamingCommunity.Util.message import start_message
|
|
14
|
+
from StreamingCommunity.Lib.Downloader import HLS_Downloader
|
|
15
|
+
from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance, TelegramSession
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# Logic class
|
|
19
|
+
from .util.ScrapeSerie import GetSerieInfo
|
|
20
|
+
from StreamingCommunity.Api.Template.Util import (
|
|
21
|
+
manage_selection,
|
|
22
|
+
map_episode_title,
|
|
23
|
+
dynamic_format_number,
|
|
24
|
+
validate_selection,
|
|
25
|
+
validate_episode_selection,
|
|
26
|
+
display_episodes_list
|
|
27
|
+
)
|
|
28
|
+
from StreamingCommunity.Api.Template.config_loader import site_constant
|
|
29
|
+
from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# Player
|
|
33
|
+
from StreamingCommunity.Api.Player.supervideo import VideoSource
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
# Variable
|
|
37
|
+
msg = Prompt()
|
|
38
|
+
console = Console()
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def download_video(index_season_selected: int, index_episode_selected: int, scrape_serie: GetSerieInfo) -> Tuple[str,bool]:
|
|
42
|
+
"""
|
|
43
|
+
Download a single episode video.
|
|
44
|
+
|
|
45
|
+
Parameters:
|
|
46
|
+
- index_season_selected (int): Index of the selected season.
|
|
47
|
+
- index_episode_selected (int): Index of the selected episode.
|
|
48
|
+
|
|
49
|
+
Return:
|
|
50
|
+
- str: output path
|
|
51
|
+
- bool: kill handler status
|
|
52
|
+
"""
|
|
53
|
+
start_message()
|
|
54
|
+
index_season_selected = dynamic_format_number(str(index_season_selected))
|
|
55
|
+
|
|
56
|
+
# Get info about episode
|
|
57
|
+
obj_episode = scrape_serie.seasons_manager.get_season_by_number(int(index_season_selected)).episodes.get(index_episode_selected-1)
|
|
58
|
+
console.print(f"[yellow]Download: [red]{index_season_selected}:{index_episode_selected} {obj_episode.name}")
|
|
59
|
+
print()
|
|
60
|
+
|
|
61
|
+
if site_constant.TELEGRAM_BOT:
|
|
62
|
+
bot = get_bot_instance()
|
|
63
|
+
|
|
64
|
+
# Invio a telegram
|
|
65
|
+
bot.send_message(
|
|
66
|
+
f"Download in corso\nSerie: {scrape_serie.series_name}\nStagione: {index_season_selected}\nEpisodio: {index_episode_selected}\nTitolo: {obj_episode.name}",
|
|
67
|
+
None
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
# Get script_id and update it
|
|
71
|
+
script_id = TelegramSession.get_session()
|
|
72
|
+
if script_id != "unknown":
|
|
73
|
+
TelegramSession.updateScriptId(script_id, f"{scrape_serie.series_name} - S{index_season_selected} - E{index_episode_selected} - {obj_episode.name}")
|
|
74
|
+
|
|
75
|
+
# Define filename and path for the downloaded video
|
|
76
|
+
mp4_name = f"{map_episode_title(scrape_serie.series_name, index_season_selected, index_episode_selected, obj_episode.name)}.mp4"
|
|
77
|
+
mp4_path = os.path.join(site_constant.SERIES_FOLDER, scrape_serie.series_name, f"S{index_season_selected}")
|
|
78
|
+
|
|
79
|
+
# Retrieve scws and if available master playlist
|
|
80
|
+
video_source = VideoSource(obj_episode.url)
|
|
81
|
+
video_source.make_request(obj_episode.url)
|
|
82
|
+
master_playlist = video_source.get_playlist()
|
|
83
|
+
|
|
84
|
+
# Download the episode
|
|
85
|
+
r_proc = HLS_Downloader(
|
|
86
|
+
m3u8_url=master_playlist,
|
|
87
|
+
output_path=os.path.join(mp4_path, mp4_name)
|
|
88
|
+
).start()
|
|
89
|
+
|
|
90
|
+
if r_proc['error'] is not None:
|
|
91
|
+
try: os.remove(r_proc['path'])
|
|
92
|
+
except: pass
|
|
93
|
+
|
|
94
|
+
return r_proc['path'], r_proc['stopped']
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def download_episode(index_season_selected: int, scrape_serie: GetSerieInfo, download_all: bool = False) -> None:
|
|
98
|
+
"""
|
|
99
|
+
Download episodes of a selected season.
|
|
100
|
+
|
|
101
|
+
Parameters:
|
|
102
|
+
- index_season_selected (int): Index of the selected season.
|
|
103
|
+
- download_all (bool): Download all episodes in the season.
|
|
104
|
+
"""
|
|
105
|
+
start_message()
|
|
106
|
+
obj_episodes = scrape_serie.seasons_manager.get_season_by_number(index_season_selected).episodes
|
|
107
|
+
episodes_count = len(obj_episodes.episodes)
|
|
108
|
+
|
|
109
|
+
if download_all:
|
|
110
|
+
|
|
111
|
+
# Download all episodes without asking
|
|
112
|
+
for i_episode in range(1, episodes_count + 1):
|
|
113
|
+
path, stopped = download_video(index_season_selected, i_episode, scrape_serie)
|
|
114
|
+
|
|
115
|
+
if stopped:
|
|
116
|
+
break
|
|
117
|
+
|
|
118
|
+
console.print(f"\n[red]End downloaded [yellow]season: [red]{index_season_selected}.")
|
|
119
|
+
|
|
120
|
+
else:
|
|
121
|
+
|
|
122
|
+
# Display episodes list and manage user selection
|
|
123
|
+
last_command = display_episodes_list(obj_episodes.episodes)
|
|
124
|
+
list_episode_select = manage_selection(last_command, episodes_count)
|
|
125
|
+
|
|
126
|
+
try:
|
|
127
|
+
list_episode_select = validate_episode_selection(list_episode_select, episodes_count)
|
|
128
|
+
except ValueError as e:
|
|
129
|
+
console.print(f"[red]{str(e)}")
|
|
130
|
+
return
|
|
131
|
+
|
|
132
|
+
# Download selected episodes if not stopped
|
|
133
|
+
for i_episode in list_episode_select:
|
|
134
|
+
path, stopped = download_video(index_season_selected, i_episode, scrape_serie)
|
|
135
|
+
|
|
136
|
+
if stopped:
|
|
137
|
+
break
|
|
138
|
+
|
|
139
|
+
def download_series(select_season: MediaItem) -> None:
|
|
140
|
+
"""
|
|
141
|
+
Download episodes of a TV series based on user selection.
|
|
142
|
+
|
|
143
|
+
Parameters:
|
|
144
|
+
- select_season (MediaItem): Selected media item (TV series).
|
|
145
|
+
"""
|
|
146
|
+
if site_constant.TELEGRAM_BOT:
|
|
147
|
+
bot = get_bot_instance()
|
|
148
|
+
|
|
149
|
+
start_message()
|
|
150
|
+
|
|
151
|
+
# Init class
|
|
152
|
+
scrape_serie = GetSerieInfo(select_season.url)
|
|
153
|
+
|
|
154
|
+
# Collect information about seasons
|
|
155
|
+
scrape_serie.collect_season()
|
|
156
|
+
seasons_count = len(scrape_serie.seasons_manager)
|
|
157
|
+
|
|
158
|
+
# Prompt user for season selection and download episodes
|
|
159
|
+
console.print(f"\n[green]Seasons found: [red]{seasons_count}")
|
|
160
|
+
|
|
161
|
+
if site_constant.TELEGRAM_BOT:
|
|
162
|
+
console.print("\n[cyan]Insert season number [yellow](e.g., 1), [red]* [cyan]to download all seasons, "
|
|
163
|
+
"[yellow](e.g., 1-2) [cyan]for a range of seasons, or [yellow](e.g., 3-*) [cyan]to download from a specific season to the end")
|
|
164
|
+
|
|
165
|
+
bot.send_message(f"Stagioni trovate: {seasons_count}", None)
|
|
166
|
+
|
|
167
|
+
index_season_selected = bot.ask(
|
|
168
|
+
"select_title_episode",
|
|
169
|
+
"Menu di selezione delle stagioni\n\n"
|
|
170
|
+
"- Inserisci il numero della stagione (ad esempio, 1)\n"
|
|
171
|
+
"- Inserisci * per scaricare tutte le stagioni\n"
|
|
172
|
+
"- Inserisci un intervallo di stagioni (ad esempio, 1-2) per scaricare da una stagione all'altra\n"
|
|
173
|
+
"- Inserisci (ad esempio, 3-*) per scaricare dalla stagione specificata fino alla fine della serie",
|
|
174
|
+
None
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
else:
|
|
178
|
+
index_season_selected = msg.ask(
|
|
179
|
+
"\n[cyan]Insert season number [yellow](e.g., 1), [red]* [cyan]to download all seasons, "
|
|
180
|
+
"[yellow](e.g., 1-2) [cyan]for a range of seasons, or [yellow](e.g., 3-*) [cyan]to download from a specific season to the end"
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
# Manage and validate the selection
|
|
184
|
+
list_season_select = manage_selection(index_season_selected, seasons_count)
|
|
185
|
+
|
|
186
|
+
try:
|
|
187
|
+
list_season_select = validate_selection(list_season_select, seasons_count)
|
|
188
|
+
except ValueError as e:
|
|
189
|
+
console.print(f"[red]{str(e)}")
|
|
190
|
+
return
|
|
191
|
+
|
|
192
|
+
# Loop through the selected seasons and download episodes
|
|
193
|
+
for i_season in list_season_select:
|
|
194
|
+
if len(list_season_select) > 1 or index_season_selected == "*":
|
|
195
|
+
|
|
196
|
+
# Download all episodes if multiple seasons are selected or if '*' is used
|
|
197
|
+
download_episode(i_season, scrape_serie, download_all=True)
|
|
198
|
+
else:
|
|
199
|
+
|
|
200
|
+
# Otherwise, let the user select specific episodes for the single season
|
|
201
|
+
download_episode(i_season, scrape_serie, download_all=False)
|
|
202
|
+
|
|
203
|
+
if site_constant.TELEGRAM_BOT:
|
|
204
|
+
bot.send_message(f"Finito di scaricare tutte le serie e episodi", None)
|
|
205
|
+
|
|
206
|
+
# Get script_id
|
|
207
|
+
script_id = TelegramSession.get_session()
|
|
208
|
+
if script_id != "unknown":
|
|
209
|
+
TelegramSession.deleteScriptId(script_id)
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# 16.03.25
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
# External libraries
|
|
5
|
+
import httpx
|
|
6
|
+
from bs4 import BeautifulSoup
|
|
7
|
+
from rich.console import Console
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# Internal utilities
|
|
11
|
+
from StreamingCommunity.Util.config_json import config_manager
|
|
12
|
+
from StreamingCommunity.Util.headers import get_userAgent
|
|
13
|
+
from StreamingCommunity.Util.table import TVShowManager
|
|
14
|
+
from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# Logic class
|
|
18
|
+
from StreamingCommunity.Api.Template.config_loader import site_constant
|
|
19
|
+
from StreamingCommunity.Api.Template.Class.SearchType import MediaManager
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# Variable
|
|
23
|
+
console = Console()
|
|
24
|
+
media_search_manager = MediaManager()
|
|
25
|
+
table_show_manager = TVShowManager()
|
|
26
|
+
max_timeout = config_manager.get_int("REQUESTS", "timeout")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def title_search(title_search: str) -> int:
|
|
30
|
+
"""
|
|
31
|
+
Search for titles based on a search query.
|
|
32
|
+
|
|
33
|
+
Parameters:
|
|
34
|
+
- title_search (str): The title to search for.
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
int: The number of titles found.
|
|
38
|
+
"""
|
|
39
|
+
if site_constant.TELEGRAM_BOT:
|
|
40
|
+
bot = get_bot_instance()
|
|
41
|
+
|
|
42
|
+
media_search_manager.clear()
|
|
43
|
+
table_show_manager.clear()
|
|
44
|
+
|
|
45
|
+
search_url = f"{site_constant.FULL_URL}/?story={title_search}&do=search&subaction=search"
|
|
46
|
+
console.print(f"[cyan]Search url: [yellow]{search_url}")
|
|
47
|
+
|
|
48
|
+
try:
|
|
49
|
+
response = httpx.post(search_url, headers={'user-agent': get_userAgent()}, timeout=max_timeout, follow_redirects=True)
|
|
50
|
+
response.raise_for_status()
|
|
51
|
+
|
|
52
|
+
except Exception as e:
|
|
53
|
+
console.print(f"Site: {site_constant.SITE_NAME}, request search error: {e}")
|
|
54
|
+
if site_constant.TELEGRAM_BOT:
|
|
55
|
+
bot.send_message(f"ERRORE\n\nErrore nella richiesta di ricerca:\n\n{e}", None)
|
|
56
|
+
return 0
|
|
57
|
+
|
|
58
|
+
# Prepara le scelte per l'utente
|
|
59
|
+
if site_constant.TELEGRAM_BOT:
|
|
60
|
+
choices = []
|
|
61
|
+
|
|
62
|
+
# Create soup istance
|
|
63
|
+
soup = BeautifulSoup(response.text, "html.parser")
|
|
64
|
+
|
|
65
|
+
# Collect data from soup
|
|
66
|
+
for i, movie_div in enumerate(soup.find_all("div", class_="movie")):
|
|
67
|
+
|
|
68
|
+
title_tag = movie_div.find("h2", class_="movie-title")
|
|
69
|
+
title = title_tag.find("a").get_text(strip=True)
|
|
70
|
+
url = title_tag.find("a").get("href")
|
|
71
|
+
|
|
72
|
+
# Define typo
|
|
73
|
+
if "/serie-tv/" in url:
|
|
74
|
+
tipo = "tv"
|
|
75
|
+
else:
|
|
76
|
+
tipo = "film"
|
|
77
|
+
|
|
78
|
+
media_search_manager.add_media({
|
|
79
|
+
'url': url,
|
|
80
|
+
'name': title,
|
|
81
|
+
'type': tipo
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
if site_constant.TELEGRAM_BOT:
|
|
85
|
+
choice_text = f"{i} - {title} ({tipo})"
|
|
86
|
+
choices.append(choice_text)
|
|
87
|
+
|
|
88
|
+
if site_constant.TELEGRAM_BOT:
|
|
89
|
+
if choices:
|
|
90
|
+
bot.send_message(f"Lista dei risultati:", choices)
|
|
91
|
+
|
|
92
|
+
# Return the number of titles found
|
|
93
|
+
return media_search_manager.get_length()
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# 16.03.25
|
|
2
|
+
|
|
3
|
+
# External libraries
|
|
4
|
+
import httpx
|
|
5
|
+
from bs4 import BeautifulSoup
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# Internal utilities
|
|
9
|
+
from StreamingCommunity.Util.headers import get_userAgent
|
|
10
|
+
from StreamingCommunity.Util.config_json import config_manager
|
|
11
|
+
from StreamingCommunity.Api.Player.Helper.Vixcloud.util import SeasonManager
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# Variable
|
|
15
|
+
max_timeout = config_manager.get_int("REQUESTS", "timeout")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class GetSerieInfo:
|
|
20
|
+
def __init__(self, url):
|
|
21
|
+
"""
|
|
22
|
+
Initialize the GetSerieInfo class for scraping TV series information.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
- url (str): The URL of the streaming site.
|
|
26
|
+
"""
|
|
27
|
+
self.headers = {'user-agent': get_userAgent()}
|
|
28
|
+
self.url = url
|
|
29
|
+
self.seasons_manager = SeasonManager()
|
|
30
|
+
|
|
31
|
+
def collect_season(self) -> None:
|
|
32
|
+
"""
|
|
33
|
+
Retrieve all episodes for all seasons
|
|
34
|
+
"""
|
|
35
|
+
response = httpx.get(self.url, headers=self.headers)
|
|
36
|
+
soup = BeautifulSoup(response.text, "html.parser")
|
|
37
|
+
self.series_name = soup.find("title").get_text(strip=True).split(" - ")[0]
|
|
38
|
+
|
|
39
|
+
# Process all seasons
|
|
40
|
+
season_items = soup.find_all('div', class_='accordion-item')
|
|
41
|
+
|
|
42
|
+
for season_idx, season_item in enumerate(season_items, 1):
|
|
43
|
+
season_header = season_item.find('div', class_='accordion-header')
|
|
44
|
+
if not season_header:
|
|
45
|
+
continue
|
|
46
|
+
|
|
47
|
+
season_name = season_header.get_text(strip=True)
|
|
48
|
+
|
|
49
|
+
# Create a new season and get a reference to it
|
|
50
|
+
current_season = self.seasons_manager.add_season({
|
|
51
|
+
'number': season_idx,
|
|
52
|
+
'name': season_name
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
# Find episodes for this season
|
|
56
|
+
episode_divs = season_item.find_all('div', class_='down-episode')
|
|
57
|
+
for ep_idx, ep_div in enumerate(episode_divs, 1):
|
|
58
|
+
episode_name_tag = ep_div.find('b')
|
|
59
|
+
if not episode_name_tag:
|
|
60
|
+
continue
|
|
61
|
+
|
|
62
|
+
episode_name = episode_name_tag.get_text(strip=True)
|
|
63
|
+
link_tag = ep_div.find('a', string=lambda text: text and "Supervideo" in text)
|
|
64
|
+
episode_url = link_tag['href'] if link_tag else None
|
|
65
|
+
|
|
66
|
+
# Add episode to the season
|
|
67
|
+
if current_season:
|
|
68
|
+
current_season.episodes.add({
|
|
69
|
+
'number': ep_idx,
|
|
70
|
+
'name': episode_name,
|
|
71
|
+
'url': episode_url
|
|
72
|
+
})
|
|
@@ -11,11 +11,12 @@ from rich.prompt import Prompt
|
|
|
11
11
|
|
|
12
12
|
# Internal utilities
|
|
13
13
|
from StreamingCommunity.Api.Template import get_select_title
|
|
14
|
+
from StreamingCommunity.Api.Template.config_loader import site_constant
|
|
15
|
+
from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
|
|
14
16
|
from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance
|
|
15
17
|
|
|
16
18
|
|
|
17
19
|
# Logic class
|
|
18
|
-
from StreamingCommunity.Api.Template.config_loader import site_constant
|
|
19
20
|
from .site import title_search, media_search_manager, table_show_manager
|
|
20
21
|
from .film_serie import download_film, download_series
|
|
21
22
|
|
|
@@ -31,53 +32,73 @@ msg = Prompt()
|
|
|
31
32
|
console = Console()
|
|
32
33
|
|
|
33
34
|
|
|
34
|
-
def
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
35
|
+
def get_user_input(string_to_search: str = None):
|
|
36
|
+
"""
|
|
37
|
+
Asks the user to input a search term.
|
|
38
|
+
Handles both Telegram bot input and direct input.
|
|
39
|
+
"""
|
|
40
|
+
if string_to_search is None:
|
|
41
|
+
if site_constant.TELEGRAM_BOT:
|
|
42
|
+
bot = get_bot_instance()
|
|
42
43
|
string_to_search = bot.ask(
|
|
43
44
|
"key_search",
|
|
44
|
-
f"
|
|
45
|
+
f"Enter the search term\nor type 'back' to return to the menu: ",
|
|
45
46
|
None
|
|
46
47
|
)
|
|
47
48
|
|
|
48
49
|
if string_to_search == 'back':
|
|
49
|
-
|
|
50
|
-
#
|
|
50
|
+
|
|
51
|
+
# Restart the script
|
|
51
52
|
subprocess.Popen([sys.executable] + sys.argv)
|
|
52
53
|
sys.exit()
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
else:
|
|
55
|
+
string_to_search = msg.ask(f"\n[purple]Insert a word to search in [green]{site_constant.SITE_NAME}").strip()
|
|
56
|
+
|
|
57
|
+
return string_to_search
|
|
58
|
+
|
|
59
|
+
def process_search_result(select_title):
|
|
60
|
+
"""
|
|
61
|
+
Handles the search result and initiates the download for either a film or series.
|
|
62
|
+
"""
|
|
63
|
+
download_series(select_title)
|
|
64
|
+
|
|
65
|
+
def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_item: dict = None):
|
|
66
|
+
"""
|
|
67
|
+
Main function of the application for search film, series and anime.
|
|
68
|
+
|
|
69
|
+
Parameters:
|
|
70
|
+
string_to_search (str, optional): String to search for
|
|
71
|
+
get_onlyDatabase (bool, optional): If True, return only the database object
|
|
72
|
+
direct_item (dict, optional): Direct item to process (bypass search)
|
|
73
|
+
"""
|
|
74
|
+
if direct_item:
|
|
75
|
+
select_title = MediaItem(**direct_item)
|
|
76
|
+
process_search_result(select_title)
|
|
77
|
+
return
|
|
78
|
+
|
|
79
|
+
# Get the user input for the search term
|
|
80
|
+
string_to_search = get_user_input(string_to_search)
|
|
81
|
+
|
|
82
|
+
# Perform the database search
|
|
59
83
|
len_database = title_search(string_to_search)
|
|
60
84
|
|
|
61
|
-
|
|
62
|
-
if
|
|
85
|
+
##If only the database is needed, return the manager
|
|
86
|
+
if get_onlyDatabase:
|
|
63
87
|
return media_search_manager
|
|
88
|
+
|
|
89
|
+
if site_constant.TELEGRAM_BOT:
|
|
90
|
+
bot = get_bot_instance()
|
|
64
91
|
|
|
65
92
|
if len_database > 0:
|
|
66
|
-
|
|
67
|
-
# Select title from list (type: TV \ Movie \ OVA)
|
|
68
93
|
select_title = get_select_title(table_show_manager, media_search_manager)
|
|
94
|
+
process_search_result(select_title)
|
|
69
95
|
|
|
70
|
-
if select_title.type == 'Movie' or select_title.type == 'OVA':
|
|
71
|
-
download_film(select_title)
|
|
72
|
-
|
|
73
|
-
else:
|
|
74
|
-
download_series(select_title)
|
|
75
|
-
|
|
76
96
|
else:
|
|
77
|
-
if site_constant.TELEGRAM_BOT:
|
|
78
|
-
bot.send_message(f"Nessun risultato trovato riprova", None)
|
|
79
|
-
|
|
80
97
|
console.print(f"\n[red]Nothing matching was found for[white]: [purple]{string_to_search}")
|
|
81
98
|
|
|
82
|
-
|
|
99
|
+
if site_constant.TELEGRAM_BOT:
|
|
100
|
+
bot.send_message(f"No results found, please try again", None)
|
|
101
|
+
|
|
102
|
+
# If no results are found, ask again
|
|
103
|
+
string_to_search = get_user_input()
|
|
83
104
|
search()
|
|
@@ -123,7 +123,11 @@ def download_series(select_title: MediaItem):
|
|
|
123
123
|
|
|
124
124
|
last_command = bot.ask(
|
|
125
125
|
"select_title",
|
|
126
|
-
|
|
126
|
+
"Menu di selezione degli episodi: \n\n"
|
|
127
|
+
"- Inserisci il numero dell'episodio (ad esempio, 1)\n"
|
|
128
|
+
"- Inserisci * per scaricare tutti gli episodi\n"
|
|
129
|
+
"- Inserisci un intervallo di episodi (ad esempio, 1-2) per scaricare da un episodio all'altro\n"
|
|
130
|
+
"- Inserisci (ad esempio, 3-*) per scaricare dall'episodio specificato fino alla fine della serie",
|
|
127
131
|
None
|
|
128
132
|
)
|
|
129
133
|
|
|
@@ -137,7 +141,7 @@ def download_series(select_title: MediaItem):
|
|
|
137
141
|
|
|
138
142
|
# Download selected episodes
|
|
139
143
|
if len(list_episode_select) == 1 and last_command != "*":
|
|
140
|
-
path, _ = download_episode(list_episode_select[0]-1, scrape_serie, video_source)
|
|
144
|
+
path, _ = download_episode(list_episode_select[0]-1, scrape_serie, video_source)
|
|
141
145
|
return path
|
|
142
146
|
|
|
143
147
|
# Download all other episodes selecter
|
|
@@ -19,7 +19,6 @@ from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance
|
|
|
19
19
|
|
|
20
20
|
# Logic class
|
|
21
21
|
from StreamingCommunity.Api.Template.config_loader import site_constant
|
|
22
|
-
from StreamingCommunity.Api.Template.Util import search_domain
|
|
23
22
|
from StreamingCommunity.Api.Template.Class.SearchType import MediaManager
|
|
24
23
|
|
|
25
24
|
|
|
@@ -78,10 +77,8 @@ def get_real_title(record):
|
|
|
78
77
|
"""
|
|
79
78
|
if record['title_eng'] is not None:
|
|
80
79
|
return record['title_eng']
|
|
81
|
-
|
|
82
80
|
elif record['title'] is not None:
|
|
83
81
|
return record['title']
|
|
84
|
-
|
|
85
82
|
else:
|
|
86
83
|
return record['title_it']
|
|
87
84
|
|
|
@@ -102,14 +99,6 @@ def title_search(title: str) -> int:
|
|
|
102
99
|
media_search_manager.clear()
|
|
103
100
|
table_show_manager.clear()
|
|
104
101
|
|
|
105
|
-
# Check if domain is working
|
|
106
|
-
domain_to_use, base_url = search_domain(site_constant.FULL_URL)
|
|
107
|
-
|
|
108
|
-
if domain_to_use is None or base_url is None:
|
|
109
|
-
console.print("[bold red]Error: Unable to determine valid domain or base URL.[/bold red]")
|
|
110
|
-
console.print("[yellow]The service might be temporarily unavailable or the domain may have changed.[/yellow]")
|
|
111
|
-
sys.exit(1)
|
|
112
|
-
|
|
113
102
|
# Create parameter for request
|
|
114
103
|
data = get_token()
|
|
115
104
|
cookies = {'animeunity_session': data.get('animeunity_session')}
|
|
@@ -132,6 +121,7 @@ def title_search(title: str) -> int:
|
|
|
132
121
|
|
|
133
122
|
except Exception as e:
|
|
134
123
|
console.print(f"Site: {site_constant.SITE_NAME}, request search error: {e}")
|
|
124
|
+
return 0
|
|
135
125
|
|
|
136
126
|
# Inizializza la lista delle scelte
|
|
137
127
|
if site_constant.TELEGRAM_BOT:
|
|
@@ -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 .film import download_film
|
|
19
20
|
|
|
@@ -29,10 +30,26 @@ msg = Prompt()
|
|
|
29
30
|
console = Console()
|
|
30
31
|
|
|
31
32
|
|
|
32
|
-
def
|
|
33
|
+
def process_search_result(select_title):
|
|
34
|
+
"""
|
|
35
|
+
Handles the search result and initiates the download for either a film or series.
|
|
36
|
+
"""
|
|
37
|
+
# !!! ADD TYPE DONT WORK FOR SERIE
|
|
38
|
+
download_film(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
|
|
36
53
|
|
|
37
54
|
if string_to_search is None:
|
|
38
55
|
string_to_search = msg.ask(f"\n[purple]Insert word to search in [green]{site_constant.SITE_NAME}").strip()
|
|
@@ -40,21 +57,16 @@ def search(string_to_search: str = None, get_onylDatabase: bool = False):
|
|
|
40
57
|
# Search on database
|
|
41
58
|
len_database = title_search(quote_plus(string_to_search))
|
|
42
59
|
|
|
43
|
-
|
|
44
|
-
if
|
|
60
|
+
## If only the database is needed, return the manager
|
|
61
|
+
if get_onlyDatabase:
|
|
45
62
|
return media_search_manager
|
|
46
63
|
|
|
47
64
|
if len_database > 0:
|
|
48
|
-
|
|
49
|
-
# Select title from list
|
|
50
65
|
select_title = get_select_title(table_show_manager, media_search_manager)
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
download_film(select_title)
|
|
54
|
-
|
|
55
|
-
|
|
66
|
+
process_search_result(select_title)
|
|
67
|
+
|
|
56
68
|
else:
|
|
57
|
-
console.print(f"\n[red]Nothing matching was found for[white]: [purple]{string_to_search}")
|
|
58
69
|
|
|
59
|
-
#
|
|
70
|
+
# If no results are found, ask again
|
|
71
|
+
console.print(f"\n[red]Nothing matching was found for[white]: [purple]{string_to_search}")
|
|
60
72
|
search()
|
|
@@ -17,7 +17,6 @@ from StreamingCommunity.Util.table import TVShowManager
|
|
|
17
17
|
|
|
18
18
|
# Logic class
|
|
19
19
|
from StreamingCommunity.Api.Template.config_loader import site_constant
|
|
20
|
-
from StreamingCommunity.Api.Template.Util import search_domain
|
|
21
20
|
from StreamingCommunity.Api.Template.Class.SearchType import MediaManager
|
|
22
21
|
|
|
23
22
|
|
|
@@ -41,14 +40,6 @@ def title_search(word_to_search: str) -> int:
|
|
|
41
40
|
media_search_manager.clear()
|
|
42
41
|
table_show_manager.clear()
|
|
43
42
|
|
|
44
|
-
# Check if domain is working
|
|
45
|
-
domain_to_use, base_url = search_domain(site_constant.FULL_URL)
|
|
46
|
-
|
|
47
|
-
if domain_to_use is None or base_url is None:
|
|
48
|
-
console.print("[bold red]Error: Unable to determine valid domain or base URL.[/bold red]")
|
|
49
|
-
console.print("[yellow]The service might be temporarily unavailable or the domain may have changed.[/yellow]")
|
|
50
|
-
sys.exit(1)
|
|
51
|
-
|
|
52
43
|
search_url = f"{site_constant.FULL_URL}/?s={word_to_search}"
|
|
53
44
|
console.print(f"[cyan]Search url: [yellow]{search_url}")
|
|
54
45
|
|
|
@@ -58,21 +49,21 @@ def title_search(word_to_search: str) -> int:
|
|
|
58
49
|
|
|
59
50
|
except Exception as e:
|
|
60
51
|
console.print(f"Site: {site_constant.SITE_NAME}, request search error: {e}")
|
|
52
|
+
return 0
|
|
61
53
|
|
|
62
54
|
# Create soup and find table
|
|
63
55
|
soup = BeautifulSoup(response.text, "html.parser")
|
|
64
56
|
|
|
65
|
-
for
|
|
57
|
+
for card in soup.find_all("div", class_=["card", "mp-post", "horizontal"]):
|
|
66
58
|
try:
|
|
67
|
-
|
|
68
|
-
url =
|
|
69
|
-
title =
|
|
70
|
-
desc = div.find("p").find("strong").text
|
|
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)
|
|
71
62
|
|
|
72
63
|
title_info = {
|
|
73
64
|
'name': title,
|
|
74
|
-
'
|
|
75
|
-
'
|
|
65
|
+
'url': url,
|
|
66
|
+
'type': 'film'
|
|
76
67
|
}
|
|
77
68
|
|
|
78
69
|
media_search_manager.add_media(title_info)
|