Skip to content

Commit

Permalink
fix: Issue where thumbnails were removed after a restart and more.
Browse files Browse the repository at this point in the history
## Summary by Sourcery

Refactor torrent search functionality to use qBittorrent search plugins, removing the dependency on an external search API. Update archive handling during extraction to delete split archive files after successful extraction. Embed thumbnails into video files using ffmpeg.

Bug Fixes:

- Fixed case sensitivity issue in document type extension checks.
- Fixed channel-related issues for mirror and leech operations.
- Addressed the issue where thumbnails were removed after a restart.
  • Loading branch information
5hojib authored Jan 22, 2025
1 parent 1b8d3a7 commit e023f38
Show file tree
Hide file tree
Showing 19 changed files with 221 additions and 352 deletions.
11 changes: 3 additions & 8 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
config.py
*.pyc
data*
.vscode
.idea
*.json
*.pickle
token.pickle
rclone.conf
.netrc
log.txt
accounts/*
Expand All @@ -16,6 +12,5 @@ tokens/*
list_drives.txt
shorteners.txt
cookies.txt
downloads
downloads/*
bot.session*
rclone.conf
20 changes: 19 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,24 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## v2.0.2 - 2025-01-22

### Fixed

- Resolved case sensitivity issue in document type extension checks.
- Fixed channel-related issues for mirror and leech operations.
- Addressed the issue where thumbnails were removed after a restart.

## v2.0.1 - 2025-01-20

### Fixed

- Token generation issues caused by the command suffix.

### Removed

- The "refresh status" and "overview status" buttons, simplifying the status interface.

## v2.0.0 - 2025-01-18

### Breaking Changes
Expand All @@ -21,4 +39,4 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

### Removed

- Removed certain limit-related variables such as `MIRROR LIMIT` and `LEECH LIMIT`.
- Removed certain limit-related variables such as `MIRROR LIMIT` and `LEECH LIMIT`.
3 changes: 0 additions & 3 deletions bot/core/config_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,6 @@ class Config:
RSS_CHAT = ""
RSS_DELAY = 600
RSS_SIZE_LIMIT = 0
SEARCH_API_LINK = ""
SEARCH_LIMIT = 0
SEARCH_PLUGINS: ClassVar[list[str]] = []
STOP_DUPLICATE = False
STREAMWISH_API = ""
SUDO_USERS = ""
Expand Down
2 changes: 2 additions & 0 deletions bot/core/startup.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ def update_aria2_options():


async def load_settings():
if await aiopath.exists("Thumbnails"):
await rmtree("Thumbnails", ignore_errors=True)
if not Config.DATABASE_URL:
return
await database.connect()
Expand Down
5 changes: 3 additions & 2 deletions bot/helper/aeon_utils/access_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@

async def error_check(message):
msg, button = [], None
user_id = message.from_user.id
user = message.from_user or message.sender_chat
user_id = user.id
token_timeout = Config.TOKEN_TIMEOUT

if message.chat.type != message.chat.type.BOT:
Expand Down Expand Up @@ -67,7 +68,7 @@ async def error_check(message):

if user_id not in {
Config.OWNER_ID,
1781717085,
Config.RSS_CHAT,
user_data.get(user_id, {}).get("is_sudo"),
}:
token_msg, button = await token_check(user_id, button)
Expand Down
26 changes: 9 additions & 17 deletions bot/helper/aeon_utils/metadata_editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,8 @@ async def get_metadata_cmd(file_path, key):


# later
async def add_attachment(file, attachment_path):
LOGGER.info(f"Adding photo attachment to file: {file}")

async def get_embed_thumb_cmd(file, attachment_path):
temp_file = f"{file}.temp.mkv"

attachment_ext = attachment_path.split(".")[-1].lower()
mime_type = "application/octet-stream"
if attachment_ext in ["jpg", "jpeg"]:
Expand All @@ -173,7 +170,11 @@ async def add_attachment(file, attachment_path):

cmd = [
"xtra",
"-y",
"-hide_banner",
"-loglevel",
"error",
"-progress",
"pipe:1",
"-i",
file,
"-attach",
Expand All @@ -184,18 +185,9 @@ async def add_attachment(file, attachment_path):
"copy",
"-map",
"0",
"-threads",
f"{max(1, os.cpu_count() // 2)}",
temp_file,
]

process = await create_subprocess_exec(*cmd, stderr=PIPE, stdout=PIPE)
stdout, stderr = await process.communicate()

if process.returncode != 0:
err = stderr.decode().strip()
LOGGER.error(err)
LOGGER.error(f"Error adding photo attachment to file: {file}")
return

os.replace(temp_file, file)
LOGGER.info(f"Photo attachment added successfully to file: {file}")
return
return cmd, temp_file
83 changes: 73 additions & 10 deletions bot/helper/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@
)
from bot.core.aeon_client import TgClient
from bot.core.config_manager import Config
from bot.helper.aeon_utils.metadata_editor import get_metadata_cmd, get_watermark_cmd
from bot.helper.aeon_utils.metadata_editor import (
get_embed_thumb_cmd,
get_metadata_cmd,
get_watermark_cmd,
)

from .ext_utils.bot_utils import get_size_bytes, new_task, sync_to_async
from .ext_utils.bulk_links import extract_bulk_links
Expand Down Expand Up @@ -601,18 +605,14 @@ async def proceed_extract(self, dl_path, gid):
if not self.is_file:
self.subname = file_
code = await sevenz.extract(f_path, t_path, pswd)
if code == 0:
if code == 0:
for file_ in files:
if is_archive_split(file_) or is_archive(file_):
del_path = ospath.join(dirpath, file_)
try:
await remove(f_path)
await remove(del_path)
except Exception:
self.is_cancelled = True
for file_ in files:
if is_archive_split(file_):
del_path = ospath.join(dirpath, file_)
try:
await remove(del_path)
except Exception:
self.is_cancelled = True
return t_path if self.is_file and code == 0 else dl_path

async def proceed_ffmpeg(self, dl_path, gid):
Expand Down Expand Up @@ -1198,3 +1198,66 @@ async def proceed_watermark(self, dl_path, gid):
if checked:
cpu_eater_lock.release()
return dl_path

async def proceed_embed_thumb(self, dl_path, gid):
thumb = self.e_thumb
ffmpeg = FFMpeg(self)
checked = False
if self.is_file:
if is_mkv(dl_path):
cmd, temp_file = await get_embed_thumb_cmd(dl_path, thumb)
if cmd:
if not checked:
checked = True
async with task_dict_lock:
task_dict[self.mid] = FFmpegStatus(
self,
ffmpeg,
gid,
"E_thumb",
)
self.progress = False
await cpu_eater_lock.acquire()
self.progress = True
self.subsize = self.size
res = await ffmpeg.metadata_watermark_cmds(cmd, dl_path)
if res:
os.replace(temp_file, dl_path)
else:
for dirpath, _, files in await sync_to_async(
walk,
dl_path,
topdown=False,
):
for file_ in files:
file_path = ospath.join(dirpath, file_)
if self.is_cancelled:
cpu_eater_lock.release()
return ""
if is_mkv(file_path):
cmd, temp_file = await get_embed_thumb_cmd(file_path, thumb)
if cmd:
if not checked:
checked = True
async with task_dict_lock:
task_dict[self.mid] = FFmpegStatus(
self,
ffmpeg,
gid,
"E_thumb",
)
self.progress = False
await cpu_eater_lock.acquire()
self.progress = True
LOGGER.info(f"Running cmd for: {file_path}")
self.subsize = await aiopath.getsize(file_path)
self.subname = file_
res = await ffmpeg.metadata_watermark_cmds(
cmd,
file_path,
)
if res:
os.replace(temp_file, file_path)
if checked:
cpu_eater_lock.release()
return dl_path
10 changes: 5 additions & 5 deletions bot/helper/ext_utils/files_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,11 @@
".crc64",
]

FIRST_SPLIT_REGEX = r"(\.|_)part0*1\.rar$|(\.|_)7z\.0*1$|(\.|_)zip\.0*1$|^(?!.*(\.|_)part\d+\.rar$).*\.rar$"
FIRST_SPLIT_REGEX = (
r"\.part0*1\.rar$|\.7z\.0*1$|\.zip\.0*1$|^(?!.*\.part\d+\.rar$).*\.rar$"
)

SPLIT_REGEX = r"\.r\d+$|\.7z\.\d+$|\.z\d+$|\.zip\.\d+$"
SPLIT_REGEX = r"\.r\d+$|\.7z\.\d+$|\.z\d+$|\.zip\.\d+$|\.part\d+\.rar$"


def is_first_archive_split(file):
Expand Down Expand Up @@ -144,8 +146,6 @@ def clean_all():
try:
LOGGER.info("Cleaning Download Directory")
rmtree(Config.DOWNLOAD_DIR, ignore_errors=True)
if ospath.exists("Thumbnails"):
rmtree("Thumbnails", ignore_errors=True)
except Exception:
pass
makedirs(Config.DOWNLOAD_DIR, exist_ok=True)
Expand Down Expand Up @@ -324,7 +324,7 @@ async def _sevenz_progress(self):
or self._listener.subproc.stdout.at_eof()
):
try:
line = await wait_for(self._listener.subproc.stdout.readline(), 5)
line = await wait_for(self._listener.subproc.stdout.readline(), 2)
except Exception:
break
line = line.decode().strip()
Expand Down
44 changes: 5 additions & 39 deletions bot/helper/ext_utils/media_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from bot.core.config_manager import Config

from .bot_utils import cmd_exec, sync_to_async
from .files_utils import ARCH_EXT, get_mime_type
from .files_utils import get_mime_type, is_archive, is_archive_split
from .status_utils import time_to_seconds


Expand All @@ -34,41 +34,6 @@ async def create_thumb(msg, _id=""):
return output


async def is_multi_streams(path):
try:
result = await cmd_exec(
[
"ffprobe",
"-hide_banner",
"-loglevel",
"error",
"-print_format",
"json",
"-show_streams",
path,
],
)
except Exception as e:
LOGGER.error(
f"Get Video Streams: {e}. Mostly File not found! - File: {path}",
)
return False
if result[0] and result[2] == 0:
fields = eval(result[0]).get("streams")
if fields is None:
LOGGER.error(f"get_video_streams: {result}")
return False
videos = 0
audios = 0
for stream in fields:
if stream.get("codec_type") == "video":
videos += 1
elif stream.get("codec_type") == "audio":
audios += 1
return videos > 1 or audios > 1
return False


async def get_media_info(path):
try:
result = await cmd_exec(
Expand Down Expand Up @@ -101,9 +66,10 @@ async def get_media_info(path):

async def get_document_type(path):
is_video, is_audio, is_image = False, False, False
if path.endswith(tuple(ARCH_EXT)) or re_search(
r".+(\.|_)(rar|7z|zip|bin)(\.0*\d+)?$",
path,
if (
is_archive(path)
or is_archive_split(path)
or re_search(r".+(\.|_)(rar|7z|zip|bin)(\.0*\d+)?$", path)
):
return is_video, is_audio, is_image
mime_type = await sync_to_async(get_mime_type, path)
Expand Down
5 changes: 3 additions & 2 deletions bot/helper/ext_utils/status_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class MirrorStatus:
STATUS_FFMPEG = "FFmpeg"
STATUS_METADATA = "Metadata"
STATUS_WATERMARK = "Watermark"
STATUS_ETHUMB = "Embed Thumb"


STATUSES = {
Expand Down Expand Up @@ -199,9 +200,9 @@ async def get_readable_message(sid, is_user, page_no=1, status="All", page_step=
):
tstatus = await sync_to_async(task.status) if status == "All" else status
if task.listener.is_super_chat:
msg += f"<b>{index + start_position}.<a href='{task.listener.message.link}'>{tstatus}</a>: </b>"
msg += f"<b>{index + start_position}. <a href='{task.listener.message.link}'>{tstatus}</a>: </b>"
else:
msg += f"<b>{index + start_position}.{tstatus}: </b>"
msg += f"<b>{index + start_position}. {tstatus}: </b>"
msg += f"<code>{escape(f'{task.name()}')}</code>"
if task.listener.subname:
msg += f"\n<i>{task.listener.subname}</i>"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from pyrogram.errors import FloodPremiumWait, FloodWait

from bot import LOGGER, task_dict, task_dict_lock
from bot.core.aeon_client import TgClient
from bot.helper.ext_utils.task_manager import (
check_running_tasks,
stop_duplicate_check,
Expand Down Expand Up @@ -94,11 +93,10 @@ async def _download(self, message, path):

async def add_download(self, message, path, session):
self.session = session
if self.session != TgClient.bot:
message = await self.session.get_messages(
chat_id=message.chat.id,
message_ids=message.id,
)
message = await self.session.get_messages(
chat_id=message.chat.id,
message_ids=message.id,
)

media = (
message.document
Expand Down
2 changes: 2 additions & 0 deletions bot/helper/mirror_leech_utils/status_utils/ffmpeg_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ def status(self):
return MirrorStatus.STATUS_METADATA
if self._cstatus == "Watermark":
return MirrorStatus.STATUS_WATERMARK
if self._cstatus == "E_thumb":
return MirrorStatus.STATUS_ETHUMB
return MirrorStatus.STATUS_FFMPEG

def task(self):
Expand Down
Loading

0 comments on commit e023f38

Please sign in to comment.