From 59d818b6a1ebfa4d596f59e6aa65426cec8ad54f Mon Sep 17 00:00:00 2001 From: tangyoha <39958403+tangyoha@users.noreply.github.com> Date: Wed, 7 Dec 2022 22:21:42 +0800 Subject: [PATCH] Revert "refactor:provide save path option (#13)" (#14) This reverts commit 4f8b788a05305ddcdfc884fdf11e5dcb46c3daa5. --- .github/FUNDING.yml | 2 + .../documentation-improvement.md | 2 +- CONTRIBUTING.md | 10 +- README.md | 107 ++++------- README_CN.md | 179 ------------------ config.yaml | 36 ++-- media_downloader.py | 76 ++++---- module/app.py | 45 +---- requirements.txt | 2 +- setup.py | 12 +- tests/test_app/test_app.py | 16 +- tests/test_media_downloader.py | 36 ++-- tests/utils/test_updates.py | 6 +- utils/__init__.py | 4 +- 14 files changed, 137 insertions(+), 396 deletions(-) create mode 100644 .github/FUNDING.yml delete mode 100644 README_CN.md diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..891c6f87 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,2 @@ +github: Dineshkarthik +custom: ["https://www.buymeacoffee.com/dkraveendran"] diff --git a/.github/ISSUE_TEMPLATE/documentation-improvement.md b/.github/ISSUE_TEMPLATE/documentation-improvement.md index f035739b..64fd284b 100644 --- a/.github/ISSUE_TEMPLATE/documentation-improvement.md +++ b/.github/ISSUE_TEMPLATE/documentation-improvement.md @@ -9,7 +9,7 @@ assignees: '' #### Location of the documentation -[this should provide the location of the documentation, e.g. "CONTRIBUTION.md" or the URL of the documentation, e.g. "https://github.com/tangyoha/telegram_media_downloader/blob/master/CONTRIBUTING.md"] +[this should provide the location of the documentation, e.g. "CONTRIBUTION.md" or the URL of the documentation, e.g. "https://github.com/Dineshkarthik/telegram_media_downloader/blob/master/CONTRIBUTING.md"] #### Documentation problem diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4cc2c7e4..5b03fa21 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,9 +5,9 @@ Please take a moment to review this document in order to make the contribution p ### Where do I go from here? -If you've noticed a bug or have a feature request, [make one](https://github.com/tangyoha/telegram_media_downloader/issues)! It's generally best if you get confirmation of your bug or approval for your feature request this way before starting to code. +If you've noticed a bug or have a feature request, [make one](https://github.com/Dineshkarthik/telegram_media_downloader/issues)! It's generally best if you get confirmation of your bug or approval for your feature request this way before starting to code. -If you have a general question about telegram-media-downloader, you can ask it on [Discussion](https://github.com/tangyoha/telegram_media_downloader/discussions) under `Q&A` category and any ideas/suggestions goes under `Ideas` category, the issue tracker is only for bugs and feature requests. +If you have a general question about telegram-media-downloader, you can ask it on [Discussion](https://github.com/Dineshkarthik/telegram_media_downloader/discussions) under `Q&A` category and any ideas/suggestions goes under `Ideas` category, the issue tracker is only for bugs and feature requests. ### Fork & create a branch @@ -66,13 +66,13 @@ Please follow these coding standards when writing code for inclusion in telegram Telegram-media-downloader follows the [PEP8](https://www.python.org/dev/peps/pep-0008/) standard and uses [Black](https://black.readthedocs.io/en/stable/) and [Pylint](https://pylint.pycqa.org/en/latest/) to ensure a consistent code format throughout the project. -[Continuous Integration](https://github.com/tangyoha/telegram_media_downloader/actions) using GitHub Actions will run those tools and report any stylistic errors in your code. Therefore, it is helpful before submitting code to run the check yourself: +[Continuous Integration](https://github.com/Dineshkarthik/telegram_media_downloader/actions) using GitHub Actions will run those tools and report any stylistic errors in your code. Therefore, it is helpful before submitting code to run the check yourself: ```sh black media_downloader.py utils ``` to auto-format your code. Additionally, many editors have plugins that will apply `black` as you edit files. -Writing good code is not just about what you write. It is also about _how_ you write it. During [Continuous Integration](https://github.com/tangyoha/telegram_media_downloader/actions) testing, several tools will be run to check your code for stylistic errors. Generating any warnings will cause the test to fail. Thus, good style is a requirement for submitting code to telegram-media-downloader. +Writing good code is not just about what you write. It is also about _how_ you write it. During [Continuous Integration](https://github.com/Dineshkarthik/telegram_media_downloader/actions) testing, several tools will be run to check your code for stylistic errors. Generating any warnings will cause the test to fail. Thus, good style is a requirement for submitting code to telegram-media-downloader. This is already added in the repo to help contributors verify their changes before contributing them to the project: ```sh @@ -196,4 +196,4 @@ Explain the motivation for the change in the commit message body. This commit me ### Code of Conduct -As a contributor, you can help us keep the community open and inclusive. Please read and follow our [Code of Conduct](https://github.com/tangyoha/telegram_media_downloader/blob/master/CODE_OF_CONDUCT.md). +As a contributor, you can help us keep the community open and inclusive. Please read and follow our [Code of Conduct](https://github.com/Dineshkarthik/telegram_media_downloader/blob/master/CODE_OF_CONDUCT.md). diff --git a/README.md b/README.md index 82ef0388..c7d0e7a2 100644 --- a/README.md +++ b/README.md @@ -2,55 +2,48 @@

Telegram Media Downloader

-Unittest +Unittest Coverage Status -License: MIT +License: MIT Code style: black

- 中文 · - Feature request + Feature request · - Report a bug + Report a bug · - Support: Discussions + Support: Discussions & Telegram Community

-### Overview - +### Overview: Download all media files from a conversation or a channel that you are a part of from telegram. A meta of last read/downloaded message is stored in the config file so that in such a way it won't download the same media file again. -### Support - +### Support: | Category | Support | |--|--| -|Language | `Python 3.7` and above| +|Language | `Python 3.7 ` and above| |Download media types| audio, document, photo, video, video_note, voice| -### ToDo - +### ToDo: - Add support for multiple channels/chats. ### Installation For *nix os distributions with `make` availability - ```sh -git clone https://github.com/tangyoha/telegram_media_downloader.git -cd telegram_media_downloader -make install +$ git clone https://github.com/Dineshkarthik/telegram_media_downloader.git +$ cd telegram_media_downloader +$ make install ``` - For Windows which doesn't have `make` inbuilt - ```sh -git clone https://github.com/tangyoha/telegram_media_downloader.git -cd telegram_media_downloader -pip3 install -r requirements.txt +$ git clone https://github.com/Dineshkarthik/telegram_media_downloader.git +$ cd telegram_media_downloader +$ pip3 install -r requirements.txt ``` ## Configuration @@ -59,33 +52,31 @@ All the configurations are passed to the Telegram Media Downloader via `config. **Getting your API Keys:** The very first step requires you to obtain a valid Telegram API key (API id/hash pair): +1. Visit [https://my.telegram.org/apps](https://my.telegram.org/apps) and log in with your Telegram Account. +2. Fill out the form to register a new Telegram application. +3. Done! The API key consists of two parts: **api_id** and **api_hash**. -1. Visit [https://my.telegram.org/apps](https://my.telegram.org/apps) and log in with your Telegram Account. -2. Fill out the form to register a new Telegram application. -3. Done! The API key consists of two parts: **api_id** and **api_hash**. **Getting chat id:** **1. Using web telegram:** - -1. Open - +1. Open https://web.telegram.org/?legacy=1#/im 2. Now go to the chat/channel and you will see the URL as something like - - `https://web.telegram.org/?legacy=1#/im?p=u853521067_2449618633394` here `853521067` is the chat id. - - `https://web.telegram.org/?legacy=1#/im?p=@somename` here `somename` is the chat id. - - `https://web.telegram.org/?legacy=1#/im?p=s1301254321_6925449697188775560` here take `1301254321` and add `-100` to the start of the id => `-1001301254321`. - - `https://web.telegram.org/?legacy=1#/im?p=c1301254321_6925449697188775560` here take `1301254321` and add `-100` to the start of the id => `-1001301254321`. + - `https://web.telegram.org/?legacy=1#/im?p=u853521067_2449618633394` here `853521067` is the chat id. + - `https://web.telegram.org/?legacy=1#/im?p=@somename` here `somename` is the chat id. + - `https://web.telegram.org/?legacy=1#/im?p=s1301254321_6925449697188775560` here take `1301254321` and add `-100` to the start of the id => `-1001301254321`. + - `https://web.telegram.org/?legacy=1#/im?p=c1301254321_6925449697188775560` here take `1301254321` and add `-100` to the start of the id => `-1001301254321`. -**2. Using bot:** +**2. Using bot:** 1. Use [@username_to_id_bot](https://t.me/username_to_id_bot) to get the chat_id of - almost any telegram user: send username to the bot or just forward their message to the bot - any chat: send chat username or copy and send its joinchat link to the bot - public or private channel: same as chats, just copy and send to the bot - id of any telegram bot -### config.yaml +### config.yaml ```yaml api_hash: your_api_hash api_id: your_api_id @@ -107,42 +98,27 @@ file_formats: video: - mp4 save_path: D:\telegram_media_downloader -file_path_prefix: -- chat_title -- media_datetime disable_syslog: - INFO ``` -- **api_hash** - The api_hash you got from telegram apps -- **api_id** - The api_id you got from telegram apps -- **chat_id** - The id of the chat/channel you want to download media. Which you get from the above-mentioned steps. -- **last_read_message_id** - If it is the first time you are going to read the channel let it be `0` or if you have already used this script to download media it will have some numbers which are auto-updated after the scripts successful execution. Don't change it. -- **ids_to_retry** - `Leave it as it is.` This is used by the downloader script to keep track of all skipped downloads so that it can be downloaded during the next execution of the script. -- **media_types** - Type of media to download, you can update which type of media you want to download it can be one or any of the available types. -- **file_formats** - File types to download for supported media types which are `audio`, `document` and `video`. Default format is `all`, downloads all files. -- **save_path** - The root directory where you want to store downloaded files. -- **file_path_prefix** - Store file subfolders, the order of the list is not fixed, can be randomly combined. - - `chat_title` - channel or group title, it will be chat id if not exist title. - - `media_datetime` - media date, also see pyrogram.types.Message.date.strftime("%Y_%m"). - - `meida_type` - meida type, also see `media_types`. -- **disable_syslog** - You can choose which types of logs to disable,see `logging._nameToLevel`. - +- api_hash - The api_hash you got from telegram apps +- api_id - The api_id you got from telegram apps +- chat_id - The id of the chat/channel you want to download media. Which you get from the above-mentioned steps. +- last_read_message_id - If it is the first time you are going to read the channel let it be `0` or if you have already used this script to download media it will have some numbers which are auto-updated after the scripts successful execution. Don't change it. +- ids_to_retry - `Leave it as it is.` This is used by the downloader script to keep track of all skipped downloads so that it can be downloaded during the next execution of the script. +- media_types - Type of media to download, you can update which type of media you want to download it can be one or any of the available types. +- file_formats - File types to download for supported media types which are `audio`, `document` and `video`. Default format is `all`, downloads all files. +- save_path - Where you want to storge download file +- disable_syslog - You can choose which types of logs to disable,see `logging._nameToLevel` ## Execution - ```sh -python3 media_downloader.py +$ python3 media_downloader.py ``` -All downloaded media will be stored at the root of `save_path`. -The specific location reference is as follows: - -The complete directory of video download is: `save_path`/`chat_title`/`media_datetime`/`meida_type`. -The order of the list is not fixed and can be randomly combined. -If the configuration is empty, all files are saved under `save_path`. +All the downloaded media will be stored inside `save_path`, and floder names include channel id or chat id.All files are rented by `month`. ## Proxy - `socks4, socks5, http` proxies are supported in this project currently. To use it, add the following to the bottom of your `config.yaml` file ```yaml @@ -153,19 +129,14 @@ proxy: username: your_username password: your_password ``` - If your proxy doesn’t require authorization you can omit username and password. Then the proxy will automatically be enabled. ## Contributing - ### Contributing Guidelines - -Read through our [contributing guidelines](https://github.com/tangyoha/telegram_media_downloader/blob/master/CONTRIBUTING.md) to learn about our submission process, coding rules and more. +Read through our [contributing guidelines](https://github.com/Dineshkarthik/telegram_media_downloader/blob/master/CONTRIBUTING.md) to learn about our submission process, coding rules and more. ### Want to Help? - -Want to file a bug, contribute some code, or improve documentation? Excellent! Read up on our guidelines for [contributing](https://github.com/tangyoha/telegram_media_downloader/blob/master/CONTRIBUTING.md). +Want to file a bug, contribute some code, or improve documentation? Excellent! Read up on our guidelines for [contributing](https://github.com/Dineshkarthik/telegram_media_downloader/blob/master/CONTRIBUTING.md). ### Code of Conduct - -Help us keep Telegram Media Downloader open and inclusive. Please read and follow our [Code of Conduct](https://github.com/tangyoha/telegram_media_downloader/blob/master/CODE_OF_CONDUCT.md). +Help us keep Telegram Media Downloader open and inclusive. Please read and follow our [Code of Conduct](https://github.com/Dineshkarthik/telegram_media_downloader/blob/master/CODE_OF_CONDUCT.md). diff --git a/README_CN.md b/README_CN.md deleted file mode 100644 index 2fb9b7cd..00000000 --- a/README_CN.md +++ /dev/null @@ -1,179 +0,0 @@ - -

电报资源下载

- -

-Unittest -Coverage Status -License: MIT -Code style: black -

- -

- English · - 新功能请求 - · - 报告bug - · - 帮助: 讨论 - & - 电报讨论群 -

- -### 概述 - -从您所属的电报对话或频道下载所有媒体文件。 -最后读取/下载消息的元数据存储在配置文件中,这样它就不会再次下载相同的媒体文件。 - -### 支持 - -| 类别 | 支持 | -| ------------ | ---------------------------------------- | -| 语言 | `Python 3.7` 及以上 | -| 下载媒体类型 | 音频、文档、照片、视频、video_note、语音 | - -### 待做 - -- 添加对多个频道/聊天的支持。 - -### 安装 - -对于具有 `make` 可用性的 *nix 操作系统发行版 - -```sh -git clone https://github.com/tangyoha/telegram_media_downloader.git -cd telegram_media_downloader -make install -``` - -对于没有内置 `make` 的 Windows - -```sh -git clone https://github.com/tangyoha/telegram_media_downloader.git -cd telegram_media_downloader -pip3 install -r requirements.txt -``` - -## 配置 - -所有配置都通过 config.yaml 文件传递​​给 `Telegram Media Downloader`。 - -**获取您的 API 密钥:** -第一步需要您获得有效的 Telegram API 密钥(API id/hash pair): - -1. 访问 [https://my.telegram.org/apps](https://my.telegram.org/apps) 并使用您的 Telegram 帐户登录。 -2. 填写表格以注册新的 Telegram 应用程序。 -3. 完成! API 密钥由两部分组成:**api_id** 和**api_hash**。 - -**获取聊天ID:** -> 如果你需要下载收藏夹的内容请填`me` - -**1。使用网络电报:** - -1. 打开 -2. 现在转到聊天/频道,您将看到 URL 类似 - -- `https://web.telegram.org/?legacy=1#/im?p=u853521067_2449618633394` 这里 `853521067` 是聊天 ID。 -- `https://web.telegram.org/?legacy=1#/im?p=@somename` 这里的 `somename` 是聊天 ID。 -- `https://web.telegram.org/?legacy=1#/im?p=s1301254321_6925449697188775560` 此处取 `1301254321` 并将 `-100` 添加到 id => `-1001301254321` 的开头。 -- `https://web.telegram.org/?legacy=1#/im?p=c1301254321_6925449697188775560` 此处取 `1301254321` 并将 `-100` 添加到 id => `-1001301254321` 的开头。 - -**2。使用机器人:** -1.使用[@username_to_id_bot](https://t.me/username_to_id_bot)获取chat_id - - 几乎所有电报用户:将用户名发送给机器人或将他们的消息转发给机器人 - - 任何聊天:发送聊天用户名或复制并发送其加入聊天链接到机器人 - - 公共或私人频道:与聊天相同,只需复制并发送给机器人 - - 任何电报机器人的 ID - -### 配置文件 - -```yaml -api_hash: your_api_hash -api_id: your_api_id -chat_id: telegram_chat_id -last_read_message_id: 0 -ids_to_retry: [] -media_types: -- audio -- document -- photo -- video -- voice -file_formats: - audio: - - all - document: - - pdf - - epub - video: - - mp4 -save_path: D:\telegram_media_downloader -group_by_media_type: true -file_path_prefix: -- chat_title -- media_datetime -disable_syslog: -- INFO -``` - -- **api_hash** - 你从电报应用程序获得的 api_hash -- **api_id** - 您从电报应用程序获得的 api_id -- **chat_id** - 您要下载媒体的聊天/频道的 ID。你从上述步骤中得到的。 -- **last_read_message_id** - 如果这是您第一次阅读频道,请将其设置为“0”,或者如果您已经使用此脚本下载媒体,它将有一些数字,这些数字会在脚本成功执行后自动更新。不要改变它。如果你需要下载收藏夹的内容,请填`me`。 -- **ids_to_retry** - `保持原样。`下载器脚本使用它来跟踪所有跳过的下载,以便在下次执行脚本时可以下载它。 -- **media_types** - 要下载的媒体类型,您可以更新要下载的媒体类型,它可以是一种或任何可用类型。 -- **file_formats** - 为支持的媒体类型(“音频”、“文档”和“视频”)下载的文件类型。默认格式为“all”,下载所有文件。 -- **save_path** - 你想存储下载文件的根目录 -- **file_path_prefix** - 存储文件子文件夹,列表的顺序不定,可以随机组合 - - `chat_title` - 聊天频道或者群组标题, 如果找不到标题则为配置文件中的`chat_id` - - `media_datetime` - 资源的发布时间 - - `meida_type` - 资源类型,类型查阅 `media_types` -- **disable_syslog** - 您可以选择要禁用的日志类型,请参阅 `logging._nameToLevel` - -## 执行 - -```sh -python3 media_downloader.py -``` - -所有下载的媒体都将存储在`save_path`根目录下。 -具体位置参考如下: - -```yaml -file_path_prefix: - - chat_title - - media_datetime - - meida_type -``` - -视频下载完整目录为:`save_path`/`chat_title`/`media_datetime`/`meida_type`。 -列表的顺序不定,可以随机组合。 -如果配置为空,则所有文件保存在`save_path`下。 - -## 代理 - -该项目目前支持 socks4、socks5、http 代理。要使用它,请将以下内容添加到`config.yaml`文件的底部 - -```yaml -代理人: - 方案:socks5 - 主机名:11.22.33.44 - 端口:1234 - 用户名:你的用户名 - 密码:你的密码 -``` - -如果您的代理不需要授权,您可以省略用户名和密码。然后代理将自动启用。 - -## 贡献 - -### 贡献指南 - -通读我们的[贡献指南](./CONTRIBUTING.md),了解我们的提交流程、编码规则等。 - -### 想帮忙? - -想要提交错误、贡献一些代码或改进文档?出色的!阅读我们的 [贡献] 指南 (./CONTRIBUTING.md)。 - -### 行为守则 - -帮助我们保持 Telegram Media Downloader 的开放性和包容性。请阅读并遵守我们的[行为准则](./CODE_OF_CONDUCT.md)。 diff --git a/config.yaml b/config.yaml index b1143a1f..2f8bd867 100644 --- a/config.yaml +++ b/config.yaml @@ -1,22 +1,8 @@ -api_hash: f689e50c58309525f591e53dbf20b325 -api_id: 10502402 -bot_token: 5331758252:AAG05jKtjEQFjnNlMeeArefFxilAMDZddt8 -chat_id: me -disable_syslog: -- INFO -file_formats: - audio: - - all - document: - - all - video: - - all -file_path_prefix: -- chat_title -- media_datetime - -ids_to_retry: [] +api_hash: your_api_hash +api_id: your_api_id +chat_id: telegram_chat_id last_read_message_id: 0 +ids_to_retry: [] media_types: - audio - photo @@ -24,8 +10,12 @@ media_types: - document - voice - video_note -proxy: - hostname: 127.0.0.1 - port: 10808 - scheme: socks5 -save_path: E:\github\telegram_media_downloader +file_formats: + audio: + - all + document: + - all + video: + - all +disable_syslog: +- INFO \ No newline at end of file diff --git a/media_downloader.py b/media_downloader.py index f93d9f0e..585086e6 100644 --- a/media_downloader.py +++ b/media_downloader.py @@ -54,15 +54,16 @@ def _check_download_finish(media_size: Any, download_path: str, message_id: int) if media_size is not None: download_size = os.path.getsize(download_path) if media_size == download_size: - logger.log(CUSTOM_LOG, "Media downloaded - %s", download_path) + logger.log(CUSTOM_LOG, + "Media downloaded - %s", download_path) app.downloaded_ids.append(message_id) app.total_download_task += 1 else: - logger.log( - CUSTOM_LOG, "Media downloaded with wrong size - %s", download_path - ) + logger.log(CUSTOM_LOG, + 'Media downloaded with wrong size - %s', download_path) os.remove(download_path) - raise TypeError("Media downloaded with wrong size") + raise TypeError( + 'Media downloaded with wrong size') def _validate_title(title: str): @@ -145,13 +146,14 @@ async def _get_media_meta( """ if _type in ["audio", "document", "video"]: # pylint: disable = C0301 - file_format: Optional[str] = media_obj.mime_type.split("/")[-1] # type: ignore + file_format: Optional[str] = media_obj.mime_type.split( # type: ignore + "/")[-1] else: file_format = None - dirname = _validate_title(f"{app.chat_id}") - if message.chat and message.chat.title: - dirname = _validate_title(f"{message.chat.title}") + dirname = _validate_title(f'{app.chat_id}') + if message.chat: + dirname = _validate_title(f'{message.chat.title}') if message.date: datetime_dir_name = message.date.strftime("%Y_%m") @@ -161,10 +163,8 @@ async def _get_media_meta( if _type in ["voice", "video_note"]: # pylint: disable = C0209 file_format = media_obj.mime_type.split("/")[-1] # type: ignore - file_save_path = app.get_file_save_path(_type, dirname, datetime_dir_name) - file_name: str = os.path.join( - file_save_path, + app.save_path, dirname, datetime_dir_name, "{} - {}_{}.{}".format( message.id, _type, @@ -180,8 +180,8 @@ async def _get_media_meta( file_format = "jpg" file_name = f"{file_name}.{file_format}" - file_save_path = app.get_file_save_path(_type, dirname, datetime_dir_name) - file_name = os.path.join(file_save_path, f"{message.id} - {file_name}") + file_name = os.path.join( + app.save_path, dirname, datetime_dir_name, f"{message.id} - {file_name}") return file_name, file_format @@ -239,11 +239,8 @@ async def download_media( # if media_size is not None and file_size != media_size: # FIXME: if exist and not empty file skip - logger.log( - CUSTOM_LOG, - "%s alreay download,download skipped.\n", - file_name, - ) + logger.log(CUSTOM_LOG, + "%s alreay download,download skipped.\n", file_name) break download_path = await client.download_media( @@ -251,9 +248,10 @@ async def download_media( ) if download_path and isinstance(download_path, str): - media_size = getattr(_media, "file_size") + media_size = getattr(_media, 'file_size') # TODO: if not exist file size or media - _check_download_finish(media_size, download_path, message.id) + _check_download_finish( + media_size, download_path, message.id) app.downloaded_ids.append(message.id) break @@ -364,8 +362,6 @@ async def begin_import(pagination_limit: int): proxy=app.proxy, ) await client.start() - print("Successfully started (Press Ctrl+C to stop)") - last_read_message_id: int = app.last_read_message_id messages_iter = client.get_chat_history( app.chat_id, offset_id=app.last_read_message_id, reverse=True @@ -395,9 +391,7 @@ async def begin_import(pagination_limit: int): app.update_config() async for message in messages_iter: # type: ignore - if pagination_count != pagination_limit and not app.need_skip_message( - message.id - ): + if pagination_count != pagination_limit and not app.need_skip_message(message.id): pagination_count += 1 messages_list.append(message) else: @@ -427,30 +421,26 @@ async def begin_import(pagination_limit: int): def main(): """Main function of the downloader.""" try: - asyncio.get_event_loop().run_until_complete(begin_import(pagination_limit=100)) + asyncio.get_event_loop().run_until_complete( + begin_import(pagination_limit=100) + ) if app.failed_ids: - logger.log( - CUSTOM_LOG, - "Downloading of %d files failed. " - "Failed message ids are added to config file.\n" - "These files will be downloaded on the next run.", - len(set(app.failed_ids)), - ) + logger.log(CUSTOM_LOG, + "Downloading of %d files failed. " + "Failed message ids are added to config file.\n" + "These files will be downloaded on the next run.", + len(set(app.failed_ids)), + ) + app.update_config() check_for_updates() - except KeyboardInterrupt: - logger.log(CUSTOM_LOG, "Stopped!") except Exception as e: logger.exception("%s", e) - finally: - logger.log(CUSTOM_LOG, "update config......") app.update_config() if __name__ == "__main__": print_meta(logger) main() - logger.log( - CUSTOM_LOG, - "Updated last read message_id to config file, total download %s", - app.total_download_task, - ) + logger.log(CUSTOM_LOG, + "Updated last read message_id to config file, total download %s", + app.total_download_task) diff --git a/module/app.py b/module/app.py index d785ec2f..898e3a75 100644 --- a/module/app.py +++ b/module/app.py @@ -1,7 +1,6 @@ """Application module""" import os from typing import List - import yaml # pylint: disable = R0902 @@ -24,7 +23,7 @@ def __init__(self, config_file: str): self.reset() try: - with open(os.path.join(os.path.abspath("."), self.config_file)) as f: + with open(os.path.join(os.path.abspath('.'), self.config_file)) as f: self.config = yaml.safe_load(f) self.load_config(self.config) except Exception: @@ -37,7 +36,7 @@ def reset(self): self.downloaded_ids: list = [] self.failed_ids: list = [] self.disable_syslog: list = [] - self.save_path = os.path.abspath(".") + self.save_path = os.path.abspath('.') self.ids_to_retry: list = [] self.api_id: str = "" self.api_hash: str = "" @@ -48,7 +47,6 @@ def reset(self): self.last_read_message_id = 0 self.restart_program = False self.config: dict = {} - self.file_path_prefix: List[str] = ["chat_title", "media_datetime"] def load_config(self, _config: dict) -> bool: """load config from str. @@ -89,41 +87,8 @@ def load_config(self, _config: dict) -> bool: self.proxy = _config["proxy"] if _config.get("restart_program"): self.restart_program = _config["restart_program"] - if _config.get("file_path_prefix"): - self.file_path_prefix = _config["file_path_prefix"] - return True - - def get_file_save_path( - self, media_type: str, chat_title: str, media_datetime: str - ) -> str: - """Get file save path prefix. - - Parameters - ---------- - media_type: str - see config.yaml media_types - - chat_title: str - see channel or group title - media_datetime: str - media datatime - - Returns - ------- - str - file save path prefix - """ - - res: str = self.save_path - for iter in self.file_path_prefix: - if iter == "chat_title": - res = os.path.join(res, chat_title) - elif iter == "media_datetime": - res = os.path.join(res, media_datetime) - elif iter == "media_type": - res = os.path.join(res, media_type) - return res + return True def need_skip_message(self, message_id: int) -> bool: """if need skip download message. @@ -150,14 +115,14 @@ def update_config(self, immediate: bool = True): # pylint: disable = W0201 self.ids_to_retry = ( - list(set(self.ids_to_retry) - set(self.downloaded_ids)) + self.failed_ids + list(set(self.ids_to_retry) - + set(self.downloaded_ids)) + self.failed_ids ) self.config["last_read_message_id"] = self.last_read_message_id self.config["ids_to_retry"] = self.ids_to_retry self.config["disable_syslog"] = self.disable_syslog self.config["save_path"] = self.save_path - self.config["file_path_prefix"] = self.file_path_prefix if immediate: with open(self.config_file, "w") as yaml_file: diff --git a/requirements.txt b/requirements.txt index 31b7eb90..7cad49df 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -https://github.com/tangyoha/pyrogram/archive/refs/heads/master.zip +https://github.com/Dineshkarthik/pyrogram/archive/refs/heads/master.zip PyYAML==6.0 rich==12.5.1 TgCrypto==1.2.3 diff --git a/setup.py b/setup.py index ffcec245..717a3bbc 100644 --- a/setup.py +++ b/setup.py @@ -5,11 +5,11 @@ setup( name="telegram-media-downloader", version=__version__, - author="tangyoha", - author_email="tangyoha@outlook.com", + author="Dineshkarthik Raveendran", + author_email="hello@dineshkarthik.me", description="A simple script to download media from telegram", - url="https://github.com/tangyoha/telegram_media_downloader", - download_url="https://github.com/tangyoha/telegram_media_downloader/releases/latest", + url="https://github.com/Dineshkarthik/telegram_media_downloader", + download_url="https://github.com/Dineshkarthik/telegram_media_downloader/releases/latest", py_modules=["media_downloader"], classifiers=[ "Development Status :: 5 - Production/Stable", @@ -34,9 +34,9 @@ "Topic :: Software Development :: Libraries :: Python Modules", ], project_urls={ - "Tracker": "https://github.com/tangyoha/telegram_media_downloader/issues", + "Tracker": "https://github.com/Dineshkarthik/telegram_media_downloader/issues", "Community": "https://t.me/tgmdnews", - "Source": "https://github.com/tangyoha/telegram_media_downloader", + "Source": "https://github.com/Dineshkarthik/telegram_media_downloader", }, python_requires="~=3.7", ) diff --git a/tests/test_app/test_app.py b/tests/test_app/test_app.py index a35bbda4..abbe42af 100644 --- a/tests/test_app/test_app.py +++ b/tests/test_app/test_app.py @@ -1,11 +1,13 @@ +from module.app import Application import os import sys import unittest from unittest import mock - import mock -from module.app import Application +from module.app import ( + Application +) sys.path.append("..") # Adds higher directory to python modules path. @@ -13,13 +15,13 @@ class AppTestCase(unittest.TestCase): @classmethod def tearDownClass(cls): - config_test = os.path.join(os.path.abspath("."), "config_test.yaml") + config_test = os.path.join(os.path.abspath('.'), "config_test.yaml") if os.path.exists(config_test): os.remove(config_test) def test_app(self): app = Application("") - self.assertEqual(app.save_path, os.path.abspath(".")) + self.assertEqual(app.save_path, os.path.abspath('.')) self.assertEqual(app.proxy, {}) self.assertEqual(app.restart_program, False) @@ -29,7 +31,8 @@ def test_app(self): app.update_config(False) - self.assertEqual(app.last_read_message_id, app.config["last_read_message_id"]) + self.assertEqual(app.last_read_message_id, + app.config["last_read_message_id"]) self.assertEqual(app.ids_to_retry, app.config["ids_to_retry"]) @mock.patch("__main__.__builtins__.open", new_callable=mock.mock_open) @@ -40,6 +43,5 @@ def test_update_config(self, mock_yaml, mock_open): app.update_config() mock_open.assert_called_with("config_test.yaml", "w") mock_yaml.dump.assert_called_with( - app.config, mock.ANY, default_flow_style=False - ) + app.config, mock.ANY, default_flow_style=False) mock_open.assert_called_with("config_test.yaml", "w") diff --git a/tests/test_media_downloader.py b/tests/test_media_downloader.py index b10471c2..43652c31 100644 --- a/tests/test_media_downloader.py +++ b/tests/test_media_downloader.py @@ -12,11 +12,11 @@ _can_download, _get_media_meta, _is_exist, - app, begin_import, download_media, main, process_messages, + app, ) MOCK_DIR: str = "/root/project" @@ -30,7 +30,7 @@ "ids_to_retry": [1, 2], "media_types": ["audio", "voice"], "file_formats": {"audio": ["all"], "voice": ["all"]}, - "save_path": MOCK_DIR, + "save_path": MOCK_DIR } @@ -98,9 +98,8 @@ def __init__(self, **kwargs): self.voice = kwargs.get("voice", None) self.video_note = kwargs.get("video_note", None) if kwargs.get("dis_chat") == None: - self.chat = Chat( - kwargs.get("chat_id", None), kwargs.get("chat_title", None) - ) + self.chat = Chat(kwargs.get("chat_id", None), + kwargs.get("chat_title", None)) else: self.chat = None self.date: datetime = None @@ -294,7 +293,7 @@ async def get_messages(self, *args, **kwargs): file_name="sample_video2.mov", mime_type="video/mov", ), - ), + ) ] return [] @@ -349,16 +348,16 @@ def test_get_media_meta(self): media=True, date=datetime(2019, 8, 5, 14, 35, 12), chat_title="test2", - photo=MockPhoto( - date=datetime(2019, 8, 5, 14, 35, 12), file_unique_id="ADAVKJYIFV" - ), + photo=MockPhoto(date=datetime(2019, 8, 5, 14, 35, + 12), file_unique_id="ADAVKJYIFV"), ) result = self.loop.run_until_complete( async_get_media_meta(message, message.photo, "photo") ) self.assertEqual( ( - platform_generic_path("/root/project/test2/2019_08/2 - ADAVKJYIFV.jpg"), + platform_generic_path( + "/root/project/test2/2019_08/2 - ADAVKJYIFV.jpg"), "jpg", ), result, @@ -379,7 +378,8 @@ def test_get_media_meta(self): ) self.assertEqual( ( - platform_generic_path("/root/project/test2/0/3 - sample_document.pdf"), + platform_generic_path( + "/root/project/test2/0/3 - sample_document.pdf"), "pdf", ), result, @@ -402,8 +402,7 @@ def test_get_media_meta(self): self.assertEqual( ( platform_generic_path( - "/root/project/test2/2021_08/4 - sample_audio.mp3" - ), + "/root/project/test2/2021_08/4 - sample_audio.mp3"), "mp3", ), result, @@ -424,7 +423,8 @@ def test_get_media_meta(self): ) self.assertEqual( ( - platform_generic_path("/root/project/test2/2022_08/5 - None.mp4"), + platform_generic_path( + "/root/project/test2/2022_08/5 - None.mp4"), "mp4", ), result, @@ -446,7 +446,8 @@ def test_get_media_meta(self): ) self.assertEqual( ( - platform_generic_path("/root/project/test2/2022_08/5 - test.mp4"), + platform_generic_path( + "/root/project/test2/2022_08/5 - test.mp4"), "mp4", ), result, @@ -470,7 +471,8 @@ def test_get_media_meta(self): print(app.chat_id) self.assertEqual( ( - platform_generic_path("/root/project/8654123/2022_08/5 - test.mp4"), + platform_generic_path( + "/root/project/8654123/2022_08/5 - test.mp4"), "mp4", ), result, @@ -721,7 +723,7 @@ def test_issues_311(self): ), ) - media_size = getattr(message.video, "file_size") + media_size = getattr(message.video, 'file_size') self.assertEqual(media_size, 1024) self.loop.run_until_complete( diff --git a/tests/utils/test_updates.py b/tests/utils/test_updates.py index 1df354b0..d04c2d30 100644 --- a/tests/utils/test_updates.py +++ b/tests/utils/test_updates.py @@ -27,7 +27,7 @@ def __init__(self, status): def read(self): if self.status == 200: - return b'{"name":"v0.0.0 2022-03-02","tag_name":"v0.0.0", "html_url":"https://github.com/tangyoha/telegram_media_downloader/releases/tag/v0.0.0"}' + return b'{"name":"v0.0.0 2022-03-02","tag_name":"v0.0.0", "html_url":"https://github.com/Dineshkarthik/telegram_media_downloader/releases/tag/v0.0.0"}' else: return b"{error}" @@ -43,9 +43,7 @@ class UpdatesTestCase(unittest.TestCase): def test_update(self, mock_markdown, mock_console): check_for_updates() name: str = "v0.0.0 2022-03-02" - html_url: str = ( - "https://github.com/tangyoha/telegram_media_downloader/releases/tag/v0.0.0" - ) + html_url: str = "https://github.com/Dineshkarthik/telegram_media_downloader/releases/tag/v0.0.0" expected_message: str = ( f"## New version of Telegram-Media-Downloader is available - {name}\n" "You are using an outdated version v0.0.1 please pull in the changes using `git pull` or download the latest release.\n\n" diff --git a/utils/__init__.py b/utils/__init__.py index 5d3115a1..400808d9 100644 --- a/utils/__init__.py +++ b/utils/__init__.py @@ -1,5 +1,5 @@ """Init namespace""" -__version__ = "2.1.0" +__version__ = "2.0.2" __license__ = "MIT License" -__copyright__ = "Copyright (C) 2022 tangyoha " +__copyright__ = "Copyright (C) 2019 Dineshkarthik "