- handle season,episode overwrite for song,movie

- Make folder for each type of title
- Fix bug for discord downloader
This commit is contained in:
2026-03-30 11:46:33 +07:00
parent c2fafcd406
commit e9ca391575
7 changed files with 32 additions and 25 deletions

1
.gitignore vendored
View File

@@ -245,3 +245,4 @@ Logs/
Cookies/ Cookies/
Cache/ Cache/
Temp/ Temp/
bot_logs/

Submodule Unshackle-Service-SeFree updated: 2d97c3d34a...fb12e9444f

View File

@@ -2476,6 +2476,13 @@ class dl:
final_filename = title.get_filename(media_info, show_service=not no_source,season_overwrite=int(season_overwrite) if season_overwrite else None,episode_overwrite=int(episode_overwrite) if episode_overwrite else None) final_filename = title.get_filename(media_info, show_service=not no_source,season_overwrite=int(season_overwrite) if season_overwrite else None,episode_overwrite=int(episode_overwrite) if episode_overwrite else None)
audio_codec_suffix = muxed_audio_codecs.get(muxed_path) audio_codec_suffix = muxed_audio_codecs.get(muxed_path)
if isinstance(title, Movie):
final_dir = Path.joinpath(Path(final_dir),"Movie")
elif isinstance(title, Episode):
final_dir = Path.joinpath(Path(final_dir),"Series")
elif isinstance(title, Song):
final_dir = Path.joinpath(Path(final_dir),"Song")
if not no_folder and isinstance(title, (Episode, Song)): if not no_folder and isinstance(title, (Episode, Song)):
final_dir /= title.get_filename(media_info, show_service=not no_source, folder=True,season_overwrite=int(season_overwrite) if season_overwrite else None) final_dir /= title.get_filename(media_info, show_service=not no_source, folder=True,season_overwrite=int(season_overwrite) if season_overwrite else None)
final_dir.mkdir(parents=True, exist_ok=True) final_dir.mkdir(parents=True, exist_ok=True)

View File

@@ -57,7 +57,7 @@ class Movie(Title):
return f"{self.name} ({self.year})" return f"{self.name} ({self.year})"
return self.name return self.name
def get_filename(self, media_info: MediaInfo, folder: bool = False, show_service: bool = True) -> str: def get_filename(self, media_info: MediaInfo, folder: bool = False, show_service: bool = True,season_overwrite=None,episode_overwrite=None) -> str:
if folder: if folder:
name = f"{self.name}" name = f"{self.name}"
if self.year: if self.year:

View File

@@ -92,7 +92,7 @@ class Song(Title):
context["disc"] = f"{self.disc:02}" if self.disc > 1 else "" context["disc"] = f"{self.disc:02}" if self.disc > 1 else ""
return context return context
def get_filename(self, media_info: MediaInfo, folder: bool = False, show_service: bool = True) -> str: def get_filename(self, media_info: MediaInfo, folder: bool = False, show_service: bool = True,season_overwrite=None,episode_overwrite=None) -> str:
if folder: if folder:
name = f"{self.artist} - {self.album}" name = f"{self.artist} - {self.album}"
if self.year: if self.year:

View File

@@ -175,7 +175,7 @@ class Title:
return context return context
@abstractmethod @abstractmethod
def get_filename(self, media_info: MediaInfo, folder: bool = False, show_service: bool = True) -> str: def get_filename(self, media_info: MediaInfo, folder: bool = False, show_service: bool = True,season_overwrite=None,episode_overwrite=None) -> str:
""" """
Get a Filename for this Title with the provided Media Info. Get a Filename for this Title with the provided Media Info.
All filenames should be sanitized with the sanitize_filename() utility function. All filenames should be sanitized with the sanitize_filename() utility function.

View File

@@ -202,7 +202,7 @@ async def download_command(
url: str, url: str,
keys: Optional[str] = 'False', keys: Optional[str] = 'False',
quality: Optional[str] = '1080', quality: Optional[str] = '1080',
codec: Optional[str] = "h265", codec: Optional[str] = "h.265",
range_: Optional[str] = "SDR", range_: Optional[str] = "SDR",
bitrate: Optional[str] = "Max", bitrate: Optional[str] = "Max",
start_season: Optional[int] = None, start_season: Optional[int] = None,
@@ -344,7 +344,7 @@ async def process_download(entry):
bot.save_data() bot.save_data()
channel = bot.get_channel(entry['channel_id']) channel = bot.get_channel(entry['channel_id'])
cmd=['/root/unshackle/.venv/bin/unshackle','dl'] cmd=['/root/unshackle-SeFree/.venv/bin/unshackle','dl']
if entry['proxy'] and entry['service'] not in ['HIDI']: if entry['proxy'] and entry['service'] not in ['HIDI']:
cmd += ['--proxy', entry['proxy']] cmd += ['--proxy', entry['proxy']]
@@ -468,8 +468,8 @@ async def process_download(entry):
if entry['original_language']: if entry['original_language']:
cmd += ['--original_lang', entry['original_language']] cmd += ['--original_lang', entry['original_language']]
if entry['android'] and entry['android'].lower() == 'true': # if entry['android'] and entry['android'].lower() == 'true':
cmd += ['--android'] # cmd += ['--android']
if entry['service'] == 'TVN': if entry['service'] == 'TVN':
if entry['original_language']: if entry['original_language']:
@@ -485,10 +485,9 @@ async def process_download(entry):
await channel.send(embed=embed) await channel.send(embed=embed)
result = await asyncio.to_thread(subprocess.run, cmd, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE) result = await asyncio.to_thread(subprocess.run, cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
try: try:
if '[E]' in result.stderr.decode() or "Processed all titles" not in result.stderr.decode(): if '[E]' in result.stdout.decode() or "Processed all titles" not in result.stdout.decode():
embed = discord.Embed( embed = discord.Embed(
title="❌ Download Failed", title="❌ Download Failed",
description="Download request has been failed.", description="Download request has been failed.",
@@ -509,9 +508,9 @@ async def process_download(entry):
embed.add_field(name="📅 Timestamp", value=entry['timestamp'], inline=False) embed.add_field(name="📅 Timestamp", value=entry['timestamp'], inline=False)
embed.set_footer(text=f"Requested by {entry['user']}") embed.set_footer(text=f"Requested by {entry['user']}")
print(result.stderr.decode()) print(result.stdout.decode())
print(f"Error downloading {entry['url']}: ") print(f"Error downloading {entry['url']}: ")
entry['error'] = result.stderr.decode() entry['error'] = result.stdout.decode()
entry['status'] = 'failed' entry['status'] = 'failed'
await channel.send(embed=embed) await channel.send(embed=embed)
@@ -583,8 +582,8 @@ async def process_download(entry):
app_commands.Choice(name="BiliBili", value="BLBL"), app_commands.Choice(name="BiliBili", value="BLBL"),
]) ])
@app_commands.choices(codec=[ @app_commands.choices(codec=[
app_commands.Choice(name="H264", value="H264"), app_commands.Choice(name="H264", value="H.264"),
app_commands.Choice(name="H265", value="H265"), app_commands.Choice(name="H265", value="H.265"),
app_commands.Choice(name="AV1", value="AV1"), app_commands.Choice(name="AV1", value="AV1"),
app_commands.Choice(name="VP9", value="VP9"), app_commands.Choice(name="VP9", value="VP9"),
]) ])
@@ -642,7 +641,7 @@ async def clear_temp_command(
await interaction.response.send_message(embed=embed) await interaction.response.send_message(embed=embed)
# Check if H265 codec is available for the given URL # Check if H265 codec is available for the given URL
os.removedirs("/root/unshackle/Temp") os.removedirs("/root/unshackle-SeFree/Temp")
embed = discord.Embed( embed = discord.Embed(
title="🛠 Temporary Files Cleared", title="🛠 Temporary Files Cleared",
description="Temporary files have been successfully cleared.", description="Temporary files have been successfully cleared.",
@@ -661,7 +660,7 @@ def check_codec_support(url: str, codec: str, service: str, range_: str):
vp9_alias=['vp9', 'VP9', 'VP9.0', 'vp9.0'] vp9_alias=['vp9', 'VP9', 'VP9.0', 'vp9.0']
cmd = ['/root/unshackle/.venv/bin/unshackle','dl', '--list', cmd = ['/root/unshackle-SeFree/.venv/bin/unshackle','dl', '--list',
'--wanted','s01e01', '--wanted','s01e01',
'--vcodec', codec, '--range', range_] '--vcodec', codec, '--range', range_]
@@ -675,26 +674,26 @@ def check_codec_support(url: str, codec: str, service: str, range_: str):
result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if ("Processed all titles" not in result.stderr.decode() or any(alias in result.stderr.decode() for alias in error_alias)): if ("Processed all titles" not in result.stdout.decode() or any(alias in result.stdout.decode() for alias in error_alias)):
print(f"Error checking codec support for {url}: {result.stderr.decode()}") print(f"Error checking codec support for {url}: {result.stdout.decode()}")
return ' '.join(cmd),'error','error' return ' '.join(cmd),'error','error'
# codec check # codec check
codec_available = False codec_available = False
if codec.lower() in h264_alias: if codec.lower() in h264_alias:
if any(alias in result.stderr.decode() for alias in h264_alias): if any(alias in result.stdout.decode() for alias in h264_alias):
codec_available = True codec_available = True
elif codec.lower() in h265_alias: elif codec.lower() in h265_alias:
if any(alias in result.stderr.decode() for alias in h265_alias): if any(alias in result.stdout.decode() for alias in h265_alias):
codec_available = True codec_available = True
elif codec.lower() in av1_alias: elif codec.lower() in av1_alias:
if any(alias in result.stderr.decode() for alias in av1_alias): if any(alias in result.stdout.decode() for alias in av1_alias):
codec_available = True codec_available = True
elif codec.lower() in vp9_alias: elif codec.lower() in vp9_alias:
if any(alias in result.stderr.decode() for alias in vp9_alias): if any(alias in result.stdout.decode() for alias in vp9_alias):
codec_available = True codec_available = True
if not codec_available: if not codec_available:
@@ -707,7 +706,7 @@ def check_codec_support(url: str, codec: str, service: str, range_: str):
range_available = False range_available = False
print(f"Checking {range_} support for {url}") print(f"Checking {range_} support for {url}")
if range_ not in result.stderr.decode(): if range_ not in result.stdout.decode():
print(f"HDR support not available for {url}") print(f"HDR support not available for {url}")
else: else:
print(f"{range_} support available for {url}") print(f"{range_} support available for {url}")