├── .gitignore
├── License
├── Procfile
├── README.md
├── app.json
├── bot.py
├── config.py
├── helper
├── botHelper.py
├── botMessages.py
├── downloader
│ ├── downloader.py
│ └── urlDL.py
├── importCommon.py
└── uploader.py
├── plugins
├── broadcast.py
├── premiumMembership.py
├── start_help.py
└── uploadRequest.py
└── requirements.txt
/.gitignore:
--------------------------------------------------------------------------------
1 | #Cache Files
2 | __pycache__/
3 |
4 | #Session File
5 | URL_Uploader.session
6 |
7 | #Test File
8 | testexp/
9 |
10 |
--------------------------------------------------------------------------------
/License:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
--------------------------------------------------------------------------------
/Procfile:
--------------------------------------------------------------------------------
1 | worker: python3 bot.py
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Repo Stats
2 | 
3 | 
4 | 
5 | [](https://t.me/URL_UploaderAJ_Bot)
6 | 
7 | [](https://t.me/AJPyroVerseGroup)
8 | [](https://t.me/AJPyroVerse)
9 | 
10 |
11 | # URL Uploader Bot
12 |
13 | This is the source code of [URL Uploader Bot](https://t.me/URL_UploaderAJ_Bot).
14 | And the developer of this bot is [AJTimePyro](https://t.me/AJTimePyro), His Telegram [Channel](http://t.me/AJPyroVerse) & [Group](http://t.me/AJPyroVerseGroup).
15 |
16 | You can use this source code in any way but you need to **give credit** to its
17 | Developer AJTimePyro.
18 |
19 | **Don't Forget to give a Star.**
20 |
21 | ## Requirement
22 | * API ID & API Hash - Get both from https://my.telegram.org
23 | * Bot Token - Get easily from [Bot Father](https://t.me/BotFather)
24 |
25 | ## Direct Deploy
26 | Click Below Button to Deploy your Bot.
27 |
28 | [](https://heroku.com/deploy?template=https://github.com/AJTimePyro/URL_Uploader_Bot)
29 |
30 | ## Support Telegram Group and Channel
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name" : "URL Uploader Bot",
3 | "description" : "This bot can accept direct downloading url and then return file as telegram file.",
4 | "keywords" : [
5 | "telegram",
6 | "bot",
7 | "heroku",
8 | "python",
9 | "telethon",
10 | "app.json",
11 | "app",
12 | "url",
13 | "uploader"
14 | ],
15 | "repository" : "https://github.com/AJTimePyro/URL_Uploader_Bot",
16 | "success_url" : "https://t.me/URL_UploaderAJ_Bot",
17 | "env" : {
18 | "BOT_TOKEN" : {
19 | "description" : "Get From https://t.me/BotFather"
20 | },
21 | "API_ID" : {
22 | "description" : "Get From https://my.telegram.org"
23 | },
24 | "API_HASH" : {
25 | "description" : "Get From https://my.telegram.org"
26 | },
27 | "MONGO_STR" : {
28 | "description" : "Get from MongoDB Atlas."
29 | },
30 | "OWNER_ID" : {
31 | "description" : "Your(owner's) telegram id"
32 | }
33 | },
34 | "stack" : "heroku-20",
35 | "buildpacks" : [
36 | {
37 | "url" : "heroku/python"
38 | }
39 | ],
40 | "formation" : {
41 | "worker" : {
42 | "quantity" : 1,
43 | "size" : "free"
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/bot.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 |
4 | """Importing"""
5 | # Importing External Packages
6 | from pyrogram import Client, idle
7 |
8 | # Importing Inbuilt Packages
9 | import logging
10 | from os import path, makedirs, remove
11 |
12 | # Importing Credentials & Required Data
13 | try:
14 | from testexp.config import Config
15 | except ModuleNotFoundError:
16 | from config import Config
17 |
18 |
19 | '''For Displaying Errors&Warnings Better'''
20 | logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
21 | logger = logging.getLogger(__name__)
22 | logging.getLogger("pyrogram").setLevel(logging.WARNING)
23 |
24 | # No task on staring bot
25 | try:
26 | remove('task.txt')
27 | except FileNotFoundError:
28 | pass
29 |
30 | """Starting Bot"""
31 | if __name__ == "__main__" :
32 | # Creating download directories, if they does not exists
33 | if not path.isdir(Config.DOWNLOAD_LOCATION):
34 | makedirs(Config.DOWNLOAD_LOCATION)
35 | plugins = dict(
36 | root="plugins"
37 | )
38 | app = Client(
39 | "URL_Uploader",
40 | bot_token=Config.TG_BOT_TOKEN,
41 | api_id=Config.APP_ID,
42 | api_hash=Config.API_HASH,
43 | plugins=plugins
44 | )
45 | print('Bot is Started!')
46 | app.run()
47 |
--------------------------------------------------------------------------------
/config.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | class Config(object):
4 | TG_BOT_TOKEN = os.environ.get("BOT_TOKEN", "") # Make a bot from https://t.me/BotFather and enter the token here
5 |
6 | APP_ID = int(os.environ.get("API_ID", 12345)) # Get this value from https://my.telegram.org/apps
7 |
8 | API_HASH = os.environ.get("API_HASH", "") # Get this value from https://my.telegram.org/apps
9 |
10 | OWNER_ID = int(os.environ.get("OWNER_ID", None)) # Your(owner's) telegram id
11 |
12 | MONGO_STR = os.environ.get("MONGO_STR", "") # Get from MongoDB Atlas
13 |
14 | DOWNLOAD_LOCATION = "app//DOWNLOADS//" # The download location for users. (Don't change anything in this field!)
--------------------------------------------------------------------------------
/helper/botHelper.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 |
4 | """Importing"""
5 | # Importing External Packages
6 | from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
7 | from pyrogram.errors import exceptions, UserNotParticipant
8 | from pymongo import MongoClient
9 | from requests import head
10 |
11 | # Importing Inbuilt Packages
12 | import __main__
13 | from os import path
14 | from inspect import currentframe
15 | from datetime import date
16 |
17 | # Importing Credentials & Required Data
18 | from helper.botMessages import BotMessage
19 | try:
20 | from testexp.config import Config
21 | except ModuleNotFoundError:
22 | from config import Config
23 | finally:
24 | mongoSTR = Config.MONGO_STR
25 |
26 | fileName = 'botHelper'
27 |
28 | '''Connecting To Database'''
29 | if mongoSTR:
30 | mongo_client = MongoClient(mongoSTR)
31 | db_user = mongo_client['URL_Uploader']
32 | collection_user = db_user['members']
33 |
34 | '''Defining Some Functions'''
35 | #Function to find error in which file and in which line
36 | def line_number(fileName, e):
37 | cf = currentframe()
38 | return f'In {fileName}.py at line {cf.f_back.f_lineno} {e}'
39 |
40 | #Checking User whether he joined channel and group or not joined.
41 | async def search_user_in_community(bot, update):
42 | try:
43 | await bot.get_chat_member('@AJPyroVerse', update.chat.id)
44 | await bot.get_chat_member('@AJPyroVerseGroup', update.chat.id)
45 | except UserNotParticipant:
46 | await update.reply_text(BotMessage.not_joined_community, parse_mode = 'html',reply_markup=InlineKeyboardMarkup([
47 | [InlineKeyboardButton('Join our Channel.',url = 'https://t.me/AJPyroVerse')],
48 | [InlineKeyboardButton('Join our Group.',url = 'https://t.me/AJPyroVerseGroup')]
49 | ]))
50 | return
51 | except exceptions.bad_request_400.ChatAdminRequired:
52 | return True
53 | except Exception as e:
54 | await bot.send_message(Config.OWNER_ID, line_number(fileName, e))
55 | return True
56 | else:
57 | return True
58 |
59 | #Finding user in database, if not found then adding him
60 | def checking_user_in_db(userid):
61 | if mongoSTR:
62 | document = {'userid' : userid}
63 | if collection_user.find_one(document):
64 | return True
65 | collection_user.insert_one(document)
66 | return
67 |
68 | #it will check the length of file
69 | async def length_of_file(bot, url, userid):
70 | try:
71 | h = head(url, allow_redirects=True)
72 | header = h.headers
73 | content_length = int(header.get('content-length'))
74 | file_length = int(content_length/1048576) #Getting Length of File
75 | except TypeError:
76 | return 'Not Valid'
77 | except Exception as e: #File is not Exist in Given URL
78 | await bot.send_message(Config.OWNER_ID, line_number(fileName, e))
79 | return 'Not Valid'
80 | else:
81 | if content_length > 2097152000: #File`s Size is more than Telegram Limit
82 | return 'Telegram Limit'
83 | return 'Valid'
84 |
85 |
--------------------------------------------------------------------------------
/helper/botMessages.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 |
4 | # Bot defined Messages
5 | class BotMessage(object):
6 | common_text = "\n\nIf you are facing any problem, so report at @AJPyroVerseGroup"
7 | help_msg = f"To use me, Just Send me any direct downloading link, and I will send you the file as telegram file.{common_text}"
8 | start_msg = f"Hi, I am URL_UploaderBot Created by @AJPyroVerse and My Developer is @AJTimePyro.\n{help_msg}"
9 | not_joined_community = f"To use this bot, you need to Join our Channel and Group.{common_text}"
10 | broadcast_failed = "Broadcasting Message can`t be empty"
11 | processing_url = "Please wait while I am Processing File"
12 | starting_to_download = "Starting to Upload the file.... Have Some Patience!!!"
13 | unsuccessful_upload = f'Uploading went Unsuccessful, Something Went Wrong{common_text}'
14 | uploading_msg = "File successfully downloaded to server, Now uploading to Telegram."
15 | youtube_url = "Currently I do not support youtube videos."
16 | telegramLimit = f"It is more than limit of telegram."
17 |
--------------------------------------------------------------------------------
/helper/downloader/downloader.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 |
4 | """Importing"""
5 | # Importing External Packages
6 | from requests import get
7 | from bs4 import BeautifulSoup
8 |
9 | # Importing Inbuilt Packages
10 | from re import match
11 | from json import loads
12 |
13 | # Importing Developer defined Module
14 | from helper.downloader.urlDL import *
15 |
16 |
17 | class Downloader:
18 |
19 | def __init__(self, update, url, bot):
20 | self.update = update
21 | self.url = url
22 | self.bot = bot
23 |
24 | @classmethod
25 | async def start(cls, update, url, bot):
26 | self = cls(update, url, bot)
27 | self.process_msg = await update.reply_text(BotMessage.processing_url, parse_mode = 'html')
28 | if match('^(https://)?(www.)?youtu(.)?be(.com)?/(.*)', url):
29 | await update.reply_text(BotMessage.youtube_url, parse_mode = 'html')
30 | elif match('^(http(s)?://)?(www.)?(cofilink.com|pdisk1.net|pdisk.net|pdisks.com)/share-video\?videoid=(.*)', url):
31 | await self.pdiskRawLinkExtract()
32 | else: #Normal Url
33 | await self.rawLinkDownloader()
34 | return self
35 |
36 | async def rawLinkDownloader(self, customFileName = None):
37 | urldownOBJ = URLDL(self.update, self.process_msg, self.bot, self.url, customFileName)
38 | await urldownOBJ.start()
39 | if urldownOBJ.filename:
40 | self.n_msg = urldownOBJ.n_msg
41 | self.filename = urldownOBJ.filename
42 | self.downloadFolder = urldownOBJ.Downloadfolder
43 |
44 | async def pdiskRawLinkExtract(self):
45 | res = get(self.url)
46 | page = BeautifulSoup(res.content, 'html5lib')
47 | try:
48 | scriptValue = str(page.find_all('script')[2]).split('')[0]
49 | jsonDoc = loads(scriptValue)
50 | self.url = jsonDoc['infoData']['defaultUrl']
51 | except Exception as e:
52 | await self.bot.send_message(Config.OWNER_ID, f'{line_number(fileName, e)}\n\n{self.url}')
53 | await self.bot.edit_message_text(self.userid, self.process_msg.message_id, BotMessage.unsuccessful_upload, parse_mode = 'html')
54 | return
55 | else:
56 | try:
57 | customFileName = str(page.find('p', {"class" : 'title text-ellipsis'}).contents[0])
58 | except Exception as e:
59 | customFileName = None
60 | else:
61 | customFileName += '.mp4'
62 | finally:
63 | await self.rawLinkDownloader(customFileName)
64 |
65 |
--------------------------------------------------------------------------------
/helper/downloader/urlDL.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 |
4 | """Importing"""
5 | # Importing External Packages
6 | from pySmartDL import SmartDL
7 | from pyrogram.errors import exceptions
8 |
9 | # Importing Common Files
10 | from helper.importCommon import *
11 |
12 | # Importing Inbuilt Packages
13 | from shutil import rmtree
14 | from time import sleep
15 | from os import makedirs, rename
16 | from uuid import uuid4
17 |
18 |
19 | class URLDL:
20 |
21 | def __init__(self, update, process_msg, bot, url, customFileName):
22 | self.update = update
23 | self.process_msg_id = process_msg.message_id
24 | self.bot = bot
25 | self.url = url
26 | self.customFileName = customFileName
27 | self.Downloadfolder = f'{Config.DOWNLOAD_LOCATION}{str(uuid4())}//'
28 | makedirs(self.Downloadfolder)
29 |
30 | async def start(self):
31 |
32 | self.userid = self.update.chat.id
33 | len_file = await length_of_file(self.bot, self.url, self.userid)
34 | if len_file == 'Valid':
35 | msg = await self.bot.edit_message_text(self.userid, self.process_msg_id, BotMessage.starting_to_download, parse_mode = 'html')
36 |
37 | downObj = SmartDL(self.url, dest = self.Downloadfolder)
38 | downObj.start(blocking = False)
39 | while not downObj.isFinished():
40 | progress_bar = downObj.get_progress_bar().replace('#', '■').replace('-', '□')
41 | completed = downObj.get_dl_size(human=True)
42 | speed = downObj.get_speed(human=True)
43 | remaining = downObj.get_eta(human=True)
44 | percentage = int(downObj.get_progress()*100)
45 | try:
46 | msg = await self.bot.edit_message_text(self.userid, msg.message_id, f"Downloading... !! Keep patience...\n {progress_bar}\n📊Percentage: {percentage} %\n✅Completed: {completed}\n🚀Speed: {speed}\n⌚️Remaining Time: {remaining}", parse_mode = 'html')
47 | sleep(2)
48 | except exceptions.bad_request_400.MessageNotModified:
49 | pass
50 | try:
51 | filename = downObj.get_dest()
52 | except Exception as e:
53 | await self.bot.send_message(Config.OWNER_ID, line_number(fileName, e))
54 | await self.bot.edit_message_text(self.userid, msg.message_id, BotMessage.unsuccessful_upload, parse_mode = 'html')
55 | else:
56 | if downObj.isSuccessful():
57 | if self.customFileName: # To use custom File names
58 | self.customFileName = f'{self.Downloadfolder}{self.customFileName}'
59 | rename(filename, self.customFileName)
60 | filename = self.customFileName
61 | n_msg = await self.bot.edit_message_text(self.userid, msg.message_id, BotMessage.uploading_msg, parse_mode = 'html')
62 | self.n_msg, self.filename = n_msg, filename
63 | return True
64 | else:
65 | try:
66 | rmtree(f'{self.Downloadfolder}')
67 | except Exception as e:
68 | await self.bot.send_message(Config.OWNER_ID, line_number(fileName, e))
69 | await self.bot.delete_messages(self.userid, msg.message_id)
70 | await self.bot.send_message(self.userid, BotMessage.unsuccessful_upload, parse_mode = 'html')
71 | finally:
72 | for e in downObj.get_errors():
73 | await self.bot.send_message(Config.OWNER_ID, line_number(fileName, e))
74 | elif len_file == 'Telegram Limit':
75 | await self.bot.edit_message_text(self.userid, self.process_msg_id, BotMessage.telegramLimit, parse_mode = 'html')
76 | elif len_file == 'Not Valid':
77 | await self.bot.edit_message_text(self.userid, self.process_msg_id, BotMessage.unsuccessful_upload, parse_mode = 'html')
78 |
79 | self.filename = None
80 | return
81 |
--------------------------------------------------------------------------------
/helper/importCommon.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 |
4 | """Importing"""
5 | # Importing External Packages
6 | from pyrogram import Client, filters
7 |
8 | # Importing Developer defined Module
9 | from helper.botHelper import *
10 |
11 |
--------------------------------------------------------------------------------
/helper/uploader.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 |
4 | """Importing"""
5 | # Importing External Packages
6 | from pyrogram.errors import exceptions
7 |
8 | # Importing Common Files
9 | from helper.importCommon import *
10 |
11 | # Importing Inbuilt Packages
12 | from shutil import rmtree
13 | from time import time, sleep
14 |
15 |
16 | class Upload:
17 |
18 | def __init__(self, bot, update, old_msg, filename, downloadFolder):
19 | self.bot = bot
20 | self.userid = update.chat.id
21 | self.msg_id = update.message_id
22 | self.old_msg = old_msg
23 | self.filename = filename
24 | self.downloadFolder = downloadFolder
25 |
26 | async def start(self):
27 | fileName = 'uploader.py'
28 |
29 | async def editMessage(progress_bar, percentage, completed, speed, remaining):
30 | try:
31 | self.old_msg = await self.bot.edit_message_text(self.userid, self.old_msg.message_id, f"Now Uploading... !! Have patience... ⌛\n [{progress_bar}]\n📊Percentage: {percentage} %\n✅Completed: {completed} MB\n🚀Speed: {speed} MB/s\n⌚️Remaining Time: {remaining} seconds", parse_mode = 'html')
32 | except exceptions.bad_request_400.MessageNotModified:
33 | pass
34 |
35 | def uploadingProgress(current, total):
36 | percentFraction = current/total
37 | progress = int(18*percentFraction)
38 | progress_bar = '■' * progress + '□' * (18 - progress)
39 | percentage = int((percentFraction)*100)
40 | currentMB = (current/1024)/1024
41 | completed = int(currentMB)
42 | speed = round(currentMB/(time() - t1), 2)
43 | if not speed:
44 | speed = 0.01
45 | remaining = int((((total - current)/1024)/1024)/speed)
46 | print(f"{current} {total} [{progress_bar}] {percentage} % {completed} MB {speed} MB/s {remaining} seconds")
47 | self.bot.loop.create_task(editMessage(progress_bar, percentage, completed, speed, remaining))
48 | sleep(3)
49 |
50 | try:
51 | global t1
52 | t1 = time()
53 | # await self.bot.send_document(self.userid , document = self.filename, reply_to_message_id = self.msg_id, progress = uploadingProgress)
54 | await self.bot.send_document(self.userid , document = self.filename, reply_to_message_id = self.msg_id)
55 | except Exception as e:
56 | await self.bot.delete_messages(self.userid, self.old_msg.message_id)
57 | await self.bot.send_message(self.userid, BotMessage.unsuccessful_upload, reply_to_message_id = self.msg_id)
58 | await self.bot.send_message(Config.OWNER_ID, line_number(fileName, e))
59 | else:
60 | await self.bot.delete_messages(self.userid, self.old_msg.message_id)
61 | finally:
62 | rmtree(self.downloadFolder)
63 |
64 |
--------------------------------------------------------------------------------
/plugins/broadcast.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 |
4 | """Importing"""
5 | # Importing External Packages
6 | from pyrogram.errors import exceptions
7 |
8 | # Importing Common Files
9 | from helper.importCommon import *
10 |
11 |
12 | # Current Filename
13 | fileName = 'broadcast'
14 |
15 |
16 | #For Owner of Bot Only, Sent message to all Bot Users
17 | @Client.on_message(filters.chat(Config.OWNER_ID) & filters.regex("^/broadcast(.+)"))
18 | async def broadcast_handler(bot, update):
19 | try:
20 | #Extracting Broadcasting Message
21 | message = update.text.split('/broadcast ')[1]
22 | except IndexError:
23 | await update.reply_text(BotMessage.broadcast_failed, parse_mode = 'html')
24 | except Exception as e:
25 | await bot.send_message(Config.OWNER_ID, line_number(fileName, e))
26 | else:
27 | #Getting User`s Id from Database
28 | for userid in [document['userid'] for document in collection_user.find()]:
29 | try:
30 | #Sending Message One By One
31 | await bot.send_message(userid, message)
32 | except exceptions.bad_request_400.UserIsBlocked:
33 | #User Blocked the bot
34 | collection_user.delete_one({'userid' : userid})
35 | except Exception as e:
36 | await bot.send_message(Config.OWNER_ID, line_number(fileName, e))
37 | return
38 |
39 |
--------------------------------------------------------------------------------
/plugins/premiumMembership.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 |
4 | """Importing"""
5 | # Importing Common Files
6 | from helper.importCommon import *
7 |
8 |
9 | #For Owner of Bot Only, Sent message to all Bot Users
10 | @Client.on_message(filters.chat(Config.OWNER_ID) & filters.regex("^/add(.+)"))
11 | async def broadcast_handler(bot, update):
12 | try:
13 | #Extracting userid
14 | userid = str(update.text.split('/add ')[1])
15 | except IndexError:
16 | await update.reply_text(BotMessage.addcommandinvaild, parse_mode = 'html')
17 | except Exception as e:
18 | await bot.send_message(Config.OWNER_ID, line_number(fileName, e))
19 | else:
20 | if userid.isdigit():
21 | if addingPremiumUser(userid):
22 | await update.reply_text(BotMessage.successfullyadded, parse_mode = 'html')
23 | else:
24 | await update.reply_text(BotMessage.addingWentWrong, parse_mode = 'html')
25 | else:
26 | await update.reply_text(BotMessage.addcommandinvaild, parse_mode = 'html')
27 |
28 |
--------------------------------------------------------------------------------
/plugins/start_help.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 |
4 | """Importing"""
5 | # Importing Common Files
6 | from helper.importCommon import *
7 |
8 |
9 | """Start Handler"""
10 | @Client.on_message(filters.private & filters.command("start"))
11 | async def start_handler(bot, update):
12 | if await search_user_in_community(bot, update):
13 | await update.reply_text(BotMessage.start_msg, parse_mode = 'html')
14 | return checking_user_in_db(update.chat.id)
15 |
16 |
17 | """Help Handler"""
18 | @Client.on_message(filters.private & filters.command("help"))
19 | async def help_handler(bot, update):
20 | if await search_user_in_community(bot, update):
21 | await update.reply_text(BotMessage.help_msg, parse_mode = 'html')
22 | return
23 |
24 |
--------------------------------------------------------------------------------
/plugins/uploadRequest.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 |
4 | """Importing"""
5 | # Importing Common Files
6 | from helper.importCommon import *
7 |
8 | # Importing Developer defined Module
9 | from helper.downloader.downloader import Downloader
10 | from helper.uploader import *
11 |
12 |
13 | # Current File Name
14 | fileName = 'uploadRequest'
15 |
16 |
17 | # Some Global Variable
18 | listTask = ['']
19 | global counter
20 | counter = 0
21 |
22 |
23 | @Client.on_message(filters.private & filters.regex("^http(s)?:(.*)"))
24 | async def upload_handler(bot, update):
25 | if await search_user_in_community(bot, update):
26 | global counter
27 | counter += 1
28 | listTask.append(Multitask(bot, update))
29 | bot.loop.create_task(listTask[counter].start())
30 | return
31 |
32 | class Multitask:
33 |
34 | def __init__(self, bot, update):
35 | self.bot = bot
36 | self.update = update
37 |
38 | async def start(self):
39 | url = self.update.text
40 | downloader = await Downloader.start(self.update, url, self.bot)
41 | filename = downloader.filename
42 |
43 | if filename: #Sending file to user
44 | msg = downloader.n_msg
45 | uploader = Upload(self.bot, self.update, msg, filename, downloader.downloadFolder)
46 | await uploader.start()
47 |
48 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | pyrogram
2 | tgcrypto
3 | dnspython
4 | pymongo
5 | requests
6 | pySmartDL
7 | bs4
8 | html5lib
--------------------------------------------------------------------------------