BinaryONe commited on
Commit
e566133
·
1 Parent(s): 282455b

APP -sparkdrive

Browse files
Files changed (46) hide show
  1. Dockerfile +20 -0
  2. FileStream/.gitignore +162 -0
  3. FileStream/Database/__init__.py +1 -0
  4. FileStream/Database/database.py +382 -0
  5. FileStream/TMDB/Endpoint.py +37 -0
  6. FileStream/TMDB/__init__.py +14 -0
  7. FileStream/Tools/__init__.py +1 -0
  8. FileStream/Tools/cleanup.py +51 -0
  9. FileStream/Tools/file.py +11 -0
  10. FileStream/Tools/progress.py +87 -0
  11. FileStream/Tools/tool.py +25 -0
  12. FileStream/__init__.py +6 -0
  13. FileStream/__main__.py +94 -0
  14. FileStream/bot/__init__.py +28 -0
  15. FileStream/bot/clients.py +59 -0
  16. FileStream/bot/plugins/Admin/admin.py +197 -0
  17. FileStream/bot/plugins/FileHandlers/callback.py +584 -0
  18. FileStream/bot/plugins/FileHandlers/files.py +171 -0
  19. FileStream/bot/plugins/FileHandlers/stream.py +238 -0
  20. FileStream/bot/plugins/startup.py +134 -0
  21. FileStream/config.py +50 -0
  22. FileStream/server/Functions/downloader.py +98 -0
  23. FileStream/server/__init__.py +19 -0
  24. FileStream/server/exceptions.py +5 -0
  25. FileStream/server/render_template.py +40 -0
  26. FileStream/server/routes_api.py +179 -0
  27. FileStream/server/routes_app.py +41 -0
  28. FileStream/server/routes_main.py +34 -0
  29. FileStream/server/template/dl.html +44 -0
  30. FileStream/server/template/owner.js +317 -0
  31. FileStream/server/template/play.html +171 -0
  32. FileStream/server/template/upload.html +40 -0
  33. FileStream/utils/FileProcessors/__init__.py +3 -0
  34. FileStream/utils/FileProcessors/bot_utils.py +350 -0
  35. FileStream/utils/FileProcessors/broadcast_helper.py +19 -0
  36. FileStream/utils/FileProcessors/custom_dl.py +208 -0
  37. FileStream/utils/FileProcessors/custom_mix.py +385 -0
  38. FileStream/utils/FileProcessors/custom_ul.py +256 -0
  39. FileStream/utils/FileProcessors/file_properties.py +221 -0
  40. FileStream/utils/FileProcessors/human_readable.py +10 -0
  41. FileStream/utils/FileProcessors/time_format.py +26 -0
  42. FileStream/utils/FileProcessors/translation.py +120 -0
  43. FileStream/utils/__init__.py +3 -0
  44. app.json +117 -0
  45. requirement.txt +29 -0
  46. streambot.log +407 -0
Dockerfile ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.11
2
+ RUN useradd -ms /bin/bash admin
3
+ RUN rm -rf /app/*
4
+ WORKDIR /app
5
+ COPY . /app
6
+ COPY requirement.txt ./requirements.txt
7
+ RUN apt-get update -y && apt-get upgrade -y \
8
+ && apt-get install \
9
+ && apt-get clean \
10
+ && rm -rf /var/lib/apt/lists/*
11
+
12
+ RUN pip3 install --no-cache-dir --upgrade --requirement requirements.txt
13
+ RUN chown -R admin:admin /app
14
+ RUN chmod 777 /app
15
+ #RUN chmod 664 /app
16
+ USER admin
17
+ EXPOSE 7860
18
+ #CMD ["uvicorn", "live:app", "--host", "0.0.0.0", "--port", "7860"]
19
+ #CMD ["bash", "start"]
20
+ CMD ["python","-u", "-m", "FileStream"]
FileStream/.gitignore ADDED
@@ -0,0 +1,162 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py,cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ #Pipfile.lock
96
+
97
+ # poetry
98
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
102
+ #poetry.lock
103
+
104
+ # pdm
105
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
106
+ #pdm.lock
107
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
108
+ # in version control.
109
+ # https://pdm.fming.dev/latest/usage/project/#working-with-version-control
110
+ .pdm.toml
111
+ .pdm-python
112
+ .pdm-build/
113
+
114
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
115
+ __pypackages__/
116
+
117
+ # Celery stuff
118
+ celerybeat-schedule
119
+ celerybeat.pid
120
+
121
+ # SageMath parsed files
122
+ *.sage.py
123
+
124
+ # Environments
125
+ .env
126
+ .venv
127
+ env/
128
+ venv/
129
+ ENV/
130
+ env.bak/
131
+ venv.bak/
132
+
133
+ # Spyder project settings
134
+ .spyderproject
135
+ .spyproject
136
+
137
+ # Rope project settings
138
+ .ropeproject
139
+
140
+ # mkdocs documentation
141
+ /site
142
+
143
+ # mypy
144
+ .mypy_cache/
145
+ .dmypy.json
146
+ dmypy.json
147
+
148
+ # Pyre type checker
149
+ .pyre/
150
+
151
+ # pytype static type analyzer
152
+ .pytype/
153
+
154
+ # Cython debug symbols
155
+ cython_debug/
156
+
157
+ # PyCharm
158
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
159
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
160
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
161
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
162
+ #.idea/
FileStream/Database/__init__.py ADDED
@@ -0,0 +1 @@
 
 
1
+ from .database import Database
FileStream/Database/database.py ADDED
@@ -0,0 +1,382 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import re
2
+ import time
3
+ import pymongo
4
+ import motor.motor_asyncio
5
+ from bson.objectid import ObjectId
6
+ from bson.errors import InvalidId
7
+ from bson.json_util import dumps
8
+
9
+ #----------------------Local Imports-----------------------#
10
+ from FileStream.server.exceptions import FIleNotFound
11
+ from FileStream.Tools import Time_ISTKolNow
12
+
13
+
14
+ class Database:
15
+
16
+ def __init__(self, uri, database_name):
17
+ self._client = motor.motor_asyncio.AsyncIOMotorClient(uri)
18
+ self.db = self._client[database_name]
19
+ self.users = self.db.Users
20
+ self.files = self.db.Public_Files
21
+ self.pfile = self.db.Private_Files
22
+ self.web_upload = self.db.Web_Files
23
+
24
+ #---------------------[ SCHEMAS ]------------------------------#
25
+ #---------------------[ NEW USER ]---------------------#
26
+
27
+ def new_user(self, id):
28
+ return dict(
29
+ telegram_id=id,
30
+ access="USER",
31
+ tele_status={
32
+ "status": "ACTIVE",
33
+ "activity": None,
34
+ "joined": Time_ISTKolNow()
35
+ },
36
+ file={
37
+ "links": 0,
38
+ "private_files": 0,
39
+ "public_files": 0,
40
+ },
41
+ site_id="None",
42
+ site_status={
43
+ "status": None,
44
+ "activity": None,
45
+ "password": None,
46
+ "links": 0,
47
+ "joined": "None"
48
+ },
49
+ )
50
+ #------------------------------------------------
51
+
52
+ def NewTG_Files(self, details):
53
+ return {
54
+ "user_id":
55
+ details['user_id'] if details['user_id'] else None,
56
+ "user_type":
57
+ details['user_type'] if details['user_type'] else None,
58
+ "message_id":
59
+ details['message_id'] if details['message_id'] else None,
60
+ "location":
61
+ details['location'] if details['location'] else None,
62
+ "file": {
63
+ "file_id":
64
+ details['file']['file_id'] if details['file']['file_id'] else None,
65
+ "file_unique_id":
66
+ details['file']['file_unique_id']
67
+ if details['file']['file_unique_id'] else None,
68
+ "file_name":
69
+ details['file']['file_name']
70
+ if details['file']['file_name'] else None,
71
+ "file_size":
72
+ details['file']['file_size']
73
+ if details['file']['file_size'] else None,
74
+ "mime_type":
75
+ details['file']['mime_type']
76
+ if details['file']['mime_type'] else None,
77
+ "taged_users": {}
78
+ },
79
+ "time":
80
+ details['time'] if details['time'] else None,
81
+ "privacy_type":
82
+ details['privacy_type'] if details['privacy_type'] else None,
83
+ }
84
+
85
+ # ---------------------[ ADD USER ]---------------------#
86
+
87
+ async def add_user(self, id):
88
+ user = self.new_user(id)
89
+ await self.users.insert_one(user)
90
+
91
+ async def add_admin(self, id):
92
+ user= await self.get_user(id)
93
+ if user:
94
+ await self.users.update_one({"_id": user['_id']}, {"$set": {"access":"ADMIN" }})
95
+ else:
96
+ user = self.new_user(id)
97
+ user['access']="ADMIN"
98
+ await self.users.insert_one(user)
99
+
100
+ # ---------------------[ GET USER ]---------------------#
101
+
102
+ async def get_user(self, id):
103
+ user = await self.users.find_one({'telegram_id': int(id)})
104
+ return user
105
+
106
+ # ---------------------[ CHECK USER ]---------------------#
107
+
108
+ async def total_users_count(self):
109
+ count = await self.users.count_documents({})
110
+ return count
111
+
112
+ async def get_all_users(self):
113
+ all_users = self.users.find({})
114
+ return all_users
115
+
116
+ async def is_admin(self, user_id):
117
+ user = await self.users.find_one({'telegram_id': int(user_id)})
118
+ return True if user['access'] == "ADMIN" else False
119
+
120
+ # ---------------------[ REMOVE USER ]---------------------#
121
+
122
+ async def delete_user(self, user_id):
123
+ await self.users.delete_many({'telegram_id': int(user_id)})
124
+
125
+ # ---------------------[ BAN, UNBAN USER ]---------------------#
126
+
127
+ async def ban_user(self, id):
128
+ await self.users.update_one({"_id": ObjectId(_id)}, {
129
+ "$set": {
130
+ "tele_status": {
131
+ "status": "BANNED",
132
+ "activity": Time_ISTKolNow()
133
+ },
134
+ }
135
+ })
136
+
137
+ async def unban_user(self, id):
138
+ await self.users.update_one({"_id": ObjectId(_id)}, {
139
+ "$set": {
140
+ "tele_status": {
141
+ "status": "ACTIVE",
142
+ "activity": Time_ISTKolNow(),
143
+ }
144
+ }
145
+ })
146
+
147
+ async def is_user_banned(self, id):
148
+ if await self.users.find_one({'telegram_id': int(id)}):
149
+ return True
150
+ else:
151
+ return False
152
+
153
+ # ---------------------[ ADD FILE TO DB ]---------------------#
154
+ async def add_file(self, file_info):
155
+ file_info["time"] = Time_ISTKolNow()
156
+ fetch_old = await self.get_file_by_fileuniqueid(file_info["user_id"], file_info['file']["file_unique_id"])
157
+ if fetch_old:
158
+ return fetch_old["_id"]
159
+ await self.count_links(file_info["user_id"], "+")
160
+ return (await self.files.insert_one(file_info)).inserted_id
161
+
162
+ # ---------------------[ FIND FILE IN DB for Bot and APIs]---------------------#
163
+ async def get_file(self, _id):
164
+ try:
165
+ file_info = await self.files.find_one({"_id": ObjectId(_id)})
166
+ if not file_info:
167
+ print('file not found')
168
+ #raise FIleNotFound
169
+ return file_info
170
+ except InvalidId:
171
+ raise FIleNotFound
172
+
173
+ async def get_all_files_api(self,range=None):
174
+ #files = self.files.find({})
175
+ files= await self.files.find().to_list(length=None)
176
+ #json_result = dumps(cursor)[row for row in files]
177
+ print("\n get_all_files_api : Return Type : ", type(files))
178
+ return files
179
+
180
+ async def get_all_files(self,range=None):
181
+ user_files = self.files.find({})
182
+ if range :
183
+ user_files.skip(range[0] - 1)
184
+ user_files.limit(range[1] - range[0] + 1)
185
+ user_files.sort('_id', pymongo.DESCENDING)
186
+ return user_files
187
+
188
+ async def find_files(self, user_id, range):
189
+ user_files = self.files.find(
190
+ {f"file.tagged_users.{user_id}": {
191
+ "$exists": True
192
+ }})
193
+ user_files.skip(range[0] - 1)
194
+ user_files.limit(range[1] - range[0] + 1)
195
+ user_files.sort('_id', pymongo.DESCENDING)
196
+ total_files = await self.files.count_documents(
197
+ {f"file.tagged_users.{user_id}": {
198
+ "$exists": True
199
+ }})
200
+ return user_files, total_files
201
+
202
+ async def find_all_public_files(self, range):
203
+ user_files = self.files.find({"privacy_type": "PUBLIC"})
204
+ user_files.skip(range[0] - 1)
205
+ user_files.limit(range[1] - range[0] + 1)
206
+ user_files.sort('_id', pymongo.DESCENDING)
207
+ total_files = await self.files.count_documents({"privacy_type": "PUBLIC"})
208
+ return user_files, total_files
209
+
210
+ async def find_all_files(self, range):
211
+ user_files = self.files.find({})
212
+ user_files.skip(range[0] - 1)
213
+ user_files.limit(range[1] - range[0] + 1)
214
+ user_files.sort('_id', pymongo.DESCENDING)
215
+ total_files = await self.files.count_documents({})
216
+ return user_files, total_files
217
+
218
+ async def find_private_files(self, user_id, range):
219
+ #search_string = "file.tagged_user." + str(user_id)
220
+ user_files = self.files.find({f"file.tagged_users.{user_id}": "PRIVATE"})
221
+ user_files.skip(range[0] - 1)
222
+ user_files.limit(range[1] - range[0] + 1)
223
+ user_files.sort('_id', pymongo.DESCENDING)
224
+ total_files = await self.files.count_documents(
225
+ {"file.tagged_users." + str(user_id): "PRIVATE"})
226
+ return user_files, total_files
227
+
228
+ async def get_file_by_fileuniqueid_only(self, file_unique_id):
229
+ return await self.files.find_one({"file.file_unique_id": file_unique_id})
230
+
231
+ async def get_file_by_fileuniqueid(self, id, file_unique_id):
232
+ count = await self.files.count_documents({"user_id":id,"file.file_unique_id":file_unique_id})
233
+ if count == 0:
234
+ return False
235
+ elif count == 1:
236
+ return await self.files.find_one({"user_id": id,"file.file_unique_id": file_unique_id})
237
+ else:
238
+ return self.files.find({"user_id": id,"file.file_unique_id": file_unique_id})
239
+
240
+ # ---------------------[ UPDATE FILE IN DB ]---------------------#
241
+
242
+ async def update_privacy(self, file_details: dict):
243
+ file = await self.get_file_by_fileuniqueid_only(file_details['file']['file_unique_id'])
244
+ # Merge the tagged_user dictionaries
245
+ updated_tagged_users = file['file']['tagged_users'].copy()
246
+ updated_tagged_users.update(file_details['file']['tagged_users'])
247
+ #for value in updated_tagged_users.values():
248
+ # if value == "PRIVATE":
249
+ # file_details['privacy_type']=="PRIVATE"
250
+ file_details['privacy_type'] = "PRIVATE" if any(value == "PRIVATE" for value in updated_tagged_users.values()) else file_details['privacy_type']
251
+ await self.files.update_one({"_id": file['_id']}, {
252
+ "$set": {
253
+ "privacy_type": file_details['privacy_type'],
254
+ "file.tagged_users": updated_tagged_users
255
+ }
256
+ })
257
+ return await self.get_file_by_fileuniqueid_only(file_details['file']['file_unique_id'])
258
+
259
+ async def update_file_ids(self, _id, file_ids: dict):
260
+ await self.files.update_one({"_id": ObjectId(_id)},
261
+ {"$set": {
262
+ "file_ids": file_ids
263
+ }})
264
+
265
+ async def update_file_info(self, _id, file_info: dict):
266
+ await self.files.update_one({"_id": ObjectId(_id)}, {
267
+ "$set": {
268
+ "message_id": file_info['message_id'],
269
+ "location": file_info['location'],
270
+ "file": file_info['file']
271
+ }
272
+ })
273
+
274
+
275
+ #--------------------------PrivateFiles-------------------
276
+ async def get_private_file(self, _id):
277
+ try:
278
+ file_info = await self.pfile.find_one({"_id": ObjectId(_id)})
279
+ if not file_info:
280
+ raise FIleNotFound
281
+ return file_info
282
+ except InvalidId:
283
+ raise FIleNotFound
284
+
285
+ async def add_private_file(self, file_info):
286
+ file_info["time"] = Time_ISTKolNow()
287
+ fetch_old = await self.get_private_file_by_fileuniqueid_only(file_info['file']["file_unique_id"])
288
+ if fetch_old:
289
+ return fetch_old["_id"]
290
+ return (await self.pfile.insert_one(file_info))
291
+
292
+ async def get_private_file_by_fileuniqueid_only(self, file_unique_id):
293
+ return await self.pfile.find_one({"file.file_unique_id": file_unique_id})
294
+
295
+ async def update_private_file_ids(self, _id, file_ids: dict):
296
+ await self.pfile.update_one({"_id": ObjectId(_id)},
297
+ {"$set": {
298
+ "file_ids": file_ids
299
+ }})
300
+
301
+ async def update_private_privacy(self, file_details: dict, instruction: dict):
302
+ file = await self.get_file_by_fileuniqueid_only(file_details['file']['file_unique_id'])
303
+ await self.pfile.insert_one(file_details)
304
+
305
+ #####################-------search for inline query ------------###############
306
+
307
+ async def get_search_results(self,query=None, file_type=None, max_results=10, offset=0):
308
+
309
+ regex = re.compile(re.escape(query), re.IGNORECASE)
310
+ filter = {'$or': [{'file.file_name': {"$regex": regex}}, {'file.caption': {"$regex": regex}}]}
311
+
312
+ if file_type:
313
+ filter['mime_type'] = file_type
314
+
315
+ total_results = await self.files.count_documents(filter)
316
+ next_offset = offset + max_results
317
+
318
+ if next_offset > total_results:
319
+ next_offset = ''
320
+
321
+ cursor = self.files.find(filter)
322
+ # Sort by recent
323
+ cursor.sort('$natural', -1)
324
+ # Slice files according to offset and max results
325
+ cursor.skip(offset).limit(max_results)
326
+ # Get list of files
327
+ files = await cursor.to_list(length=max_results)
328
+ return files, next_offset
329
+
330
+ # ---------------------[ TOTAL FILES ]---------------------#
331
+ async def total_files(self, id=None):
332
+ if id:
333
+ return await self.files.count_documents({"user_id": id})
334
+ return await self.files.count_documents({})
335
+
336
+ async def total_privfiles(self, id=None):
337
+ if id:
338
+ return await self.pfile.count_documents({"user_id": id})
339
+ return await self.pfile.count_documents({})
340
+
341
+ # ---------------------[ DELETE FILES ]---------------------#
342
+
343
+ async def delete_one_file(self, _id):
344
+ await self.files.delete_one({'_id': ObjectId(_id)})
345
+
346
+
347
+ # ---------------------[ PAID SYS ]---------------------#
348
+ # async def link_available(self, id):
349
+ # user = await self.col.find_one({"id": id})
350
+ # if user.get("Plan") == "Plus":
351
+ # return "Plus"
352
+ # elif user.get("Plan") == "Free":
353
+ # files = await self.file.count_documents({"user_id": id})
354
+ # if files < 11:
355
+ # return True
356
+ # return False
357
+
358
+ async def count_links(self, id, operation: str):
359
+ if operation == "-":
360
+ await self.users.update_one({"id": id}, {"$inc": {"file.links": -1}})
361
+ elif operation == "+":
362
+ await self.users.update_one({"id": id}, {"$inc": {"file.links": 1}})
363
+
364
+ #------------------------------For Web Files -----------------------------------------#
365
+ async def add_webfile(self, upload_info):
366
+ fetch_old = await self.get_web_file(upload_info["dropzone_id"])
367
+ if fetch_old:
368
+ return fetch_old
369
+ else:
370
+ await self.web_upload.insert_one(upload_info)
371
+ return await self.get_web_file(upload_info["dropzone_id"])
372
+
373
+ #async def update_web_file(self, dropzone_id):
374
+
375
+ async def get_web_file(self, upload_id):
376
+ file_info = await self.web_upload.find_one({"dropzone_id": upload_id})
377
+ if not file_info:
378
+ return None
379
+ return file_info
380
+
381
+ async def uploaded_web_file(self, upload_id):
382
+ await self.web_upload.delete_one({"dropzone_id": upload_id})
FileStream/TMDB/Endpoint.py ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from FileStream.TMDB.__init__ import tmdb,search,movie,tv
2
+ import urllib3
3
+ from FileStream.Tools.cleanup import Get_Title_Year
4
+
5
+
6
+ def get_tvshows(tv_show_id):
7
+ return tv.details(tv_show_id).__dict__
8
+
9
+ def search_tmdb(name):
10
+ # Search for the title in TMDb
11
+ title, year = Get_Title_Year(name)
12
+ print("*", title, year,"\n Name :", name)
13
+ if title is None :
14
+ return None
15
+ search_results = search.multi(title)
16
+ # Filter results by year
17
+ try:
18
+ for result in search_results:
19
+ #if not isinstance(result, dict):
20
+ #print(result)
21
+ #result = result
22
+ #release_date = result.release_date if result.release_date else result.first_air_date
23
+ if result.media_type == "tv":
24
+ release_date=result.release_date or result.first_air_date or result.get("release_date") or result.get("first_air_date")
25
+ if release_date and int(release_date.split('-')[0]) == year:
26
+ return get_tvshows( result.id or result.get("id") )
27
+
28
+ if result.media_type == "movie":
29
+ release_date=result.release_date or result.get("release_date") or result.get("first_air_date")
30
+ if release_date and int(release_date.split('-')[0]) == year:
31
+ return result
32
+
33
+ except Exception as e :
34
+ #print("* Error at Endpoint", e, result)
35
+ return None
36
+
37
+ return None
FileStream/TMDB/__init__.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import re
2
+ from tmdbv3api import TMDb, Search, Movie,TV
3
+ from FileStream.config import TMDB
4
+
5
+ # Initialize the TMDb API
6
+ tmdb = TMDb()
7
+ tmdb.api_key = TMDB.API # Replace with your actual TMDb API key
8
+
9
+ # Initialize the Search class
10
+ search = Search()
11
+ movie=Movie()
12
+ tv=TV()
13
+
14
+
FileStream/Tools/__init__.py ADDED
@@ -0,0 +1 @@
 
 
1
+ from .tool import Time_ISTKolNow, mime_identifier
FileStream/Tools/cleanup.py ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import re
2
+
3
+ #words_to_remove = ["FC","HEVC","ɴᴀᴍᴇ:","-","BuLMoviee" ,"𝗝𝗼𝗶𝗻 𝗨𝘀 𝗢𝗻 𝗧𝗲𝗹𝗲𝗴𝗿𝗮�","SIDHUU 591","𝑱𝒐𝒊𝒏 𝑼𝒔 𝑶ɴ 𝑻ᴇʟᴇɢʀᴀᴍ","Tɪᴛʟᴇ :"]
4
+
5
+ def remove_words(text, words_to_remove):
6
+ # Join the words to remove into a single regex pattern
7
+ pattern = r'\b(?:' + '|'.join(map(re.escape, words_to_remove)) + r')\b'
8
+ # Use re.sub() to replace the pattern with an empty string
9
+ cleaned_text = re.sub(pattern, '', text)
10
+ # Remove extra spaces that might have been left after removing the words
11
+ cleaned_text = re.sub(r'\s+', ' ', cleaned_text).strip()
12
+ return cleaned_text
13
+
14
+ def convert_special_to_normal(text):
15
+ # Unescape HTML entities
16
+ text = html.unescape(text)
17
+ # Normalize Unicode characters
18
+ text = unicodedata.normalize('NFKD', text).encode('ascii', 'ignore').decode('utf-8')
19
+ # Remove special characters
20
+ text = re.sub(r'[^A-Za-z0-9 ]+', '', text)
21
+ return text
22
+
23
+ def clean_text(input_text):
24
+ # Remove new line characters
25
+ text = input_text.replace('\n', '').replace('@', '')
26
+ emoji_pattern = re.compile(
27
+ "["
28
+ "\U0001F600-\U0001F64F" # emoticons
29
+ "\U0001F300-\U0001F5FF" # symbols & pictographs
30
+ "\U0001F680-\U0001F6FF" # transport & map symbols
31
+ "\U0001F700-\U0001F77F" # alchemical symbols
32
+ "\U00002600-\U000026FF" # Miscellaneous Symbols
33
+ "\U00002700-\U000027BF" # Dingbats
34
+ "\U0001F900-\U0001F9FF" # Supplemental Symbols and Pictographs
35
+ "\U0001FA70-\U0001FAFF" # Symbols and Pictographs Extended-A
36
+ "\U0001F1E0-\U0001F1FF" # Flags (iOS)
37
+ "]+",
38
+ flags=re.UNICODE)
39
+ output_text = emoji_pattern.sub(r'', text)
40
+ return output_text
41
+
42
+
43
+
44
+ def Get_Title_Year(name):
45
+ # Regex to match title and year
46
+ words_to_remove = ["FC", "HEVC","ɴᴀᴍᴇ:","-","BuLMoviee" ,"𝗝𝗼𝗶𝗻 𝗨𝘀 𝗢𝗻 𝗧𝗲𝗹𝗲𝗴𝗿𝗮�","𝗝𝗼𝗶𝗻 𝗨𝘀 𝗢𝗻 𝗧𝗲𝗹𝗲𝗴𝗿𝗮𝗺","SIDHUU 591","𝑱𝒐𝒊𝒏 𝑼𝒔 𝑶ɴ 𝑻ᴇʟᴇɢʀᴀᴍ","Tɪᴛʟᴇ :"]
47
+ name=remove_words(name, words_to_remove)
48
+ match = re.search(r'(?P<title>.+?)[\s\.\(\)]*(?P<year>\d{4})',name )
49
+ if match:
50
+ return match.group('title').strip(), int(match.group('year'))
51
+ return None, None
FileStream/Tools/file.py ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ def humanbytes(size):
3
+ if not size:
4
+ return ""
5
+ power = 2**10
6
+ n = 0
7
+ Dic_powerN = {0: ' ', 1: 'Ki', 2: 'Mi', 3: 'Gi', 4: 'Ti'}
8
+ while size > power:
9
+ size /= power
10
+ n += 1
11
+ return str(round(size, 2)) + " " + Dic_powerN[n] + 'B'
FileStream/Tools/progress.py ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import random
2
+ import urllib3
3
+ import logging
4
+ import asyncio
5
+ import traceback
6
+ import mimetypes
7
+ import time, math
8
+ from datetime import datetime
9
+ from typing import Dict, Union
10
+ from typing import Union, BinaryIO, List, Optional, Callable
11
+
12
+ from pyrogram import raw
13
+ from pyrogram import types
14
+ from pyrogram import filters, Client
15
+ from pyrogram import utils as pgutils
16
+ from pyrogram import StopTransmission, enums
17
+ from pyrogram import Client, utils, raw
18
+
19
+ from pyrogram.file_id import FileType
20
+ from pyrogram.session import Session, Auth
21
+ from pyrogram.errors import FilePartMissing,AuthBytesInvalid,FloodWait
22
+ from pyrogram.file_id import FileId, FileType, ThumbnailSource
23
+ from pyrogram.enums import ParseMode, ChatType
24
+ from pyrogram.enums.parse_mode import ParseMode
25
+ from pyrogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton
26
+
27
+
28
+ #--------------------------Local Imports-------------#
29
+
30
+ from FileStream.bot import FileStream, multi_clients, work_loads
31
+ from FileStream.Database import Database
32
+ from FileStream.config import Telegram, Server
33
+ from FileStream.Tools.tool import TimeFormatter
34
+
35
+ from FileStream.utils.FileProcessors.bot_utils import is_user_banned, is_user_exist, is_user_joined, gen_link, is_channel_banned, is_channel_exist, is_user_authorized, upload_type_func
36
+ from FileStream.utils.FileProcessors.custom_dl import ByteStreamer
37
+ from FileStream.utils.FileProcessors.custom_ul import TeleUploader
38
+ from FileStream.utils.FileProcessors.custom_mix import TGFileController
39
+ from FileStream.utils.FileProcessors.translation import LANG, BUTTON
40
+ from FileStream.utils.FileProcessors.human_readable import humanbytes
41
+ from FileStream.utils.FileProcessors.file_properties import get_file_ids,get_file_info
42
+
43
+
44
+
45
+
46
+
47
+ async def progress(current, total, progress_args):
48
+ progress_text = LANG.BASIC_PRIV_FILE.format(
49
+ progress_args[1], humanbytes(progress_args[2]))
50
+ #print(f"{current * 100 / total:.1f}%")
51
+ now = time.time()
52
+ diff = now - progress_args[3]
53
+ if round(diff % 10.00) == 0 or current == total:
54
+ percentage = current * 100 / total
55
+ speed = current / diff
56
+ elapsed_time = round(diff) * 1000
57
+ time_to_completion = round((total - current) / speed) * 1000
58
+ estimated_total_time = elapsed_time + time_to_completion
59
+
60
+ elapsed_time = TimeFormatter(milliseconds=elapsed_time)
61
+ estimated_total_time = TimeFormatter(
62
+ milliseconds=estimated_total_time)
63
+
64
+ progress = "{0}{1}".format(
65
+ ''.join(["●" for i in range(math.floor(percentage / 5))]),
66
+ ''.join(["○" for i in range(20 - math.floor(percentage / 5))
67
+ ]) # This line is modified
68
+ )
69
+ tmp = progress_text + '\n' + progress + LANG.PROGRESS_BAR.format(
70
+ percentage=round(percentage, 2),
71
+ current=humanbytes(current),
72
+ total=humanbytes(total),
73
+ speed=humanbytes(speed),
74
+ est_time=estimated_total_time
75
+ if estimated_total_time != '' else "0 s")
76
+ try:
77
+ await progress_args[0].edit_text(
78
+ text=tmp,
79
+ parse_mode=ParseMode.HTML,
80
+ disable_web_page_preview=True,
81
+ )
82
+
83
+ except FloodWait as w:
84
+ print(f"Sleeping for {str(w.wait_time)}s")
85
+ await asyncio.sleep(w.wait_time)
86
+ except Exception as e:
87
+ print(e)
FileStream/Tools/tool.py ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ def Time_ISTKolNow():
2
+ from datetime import datetime
3
+ import pytz
4
+ IST = datetime.now(pytz.timezone("Asia/Kolkata")).strftime("%c")
5
+ return IST
6
+
7
+
8
+ def mime_identifier(filename):
9
+ import mimetypes
10
+ mime_type, encoding = mimetypes.guess_type(filename)
11
+
12
+ return mime_type
13
+
14
+
15
+ def TimeFormatter(milliseconds: int) -> str:
16
+ seconds, milliseconds = divmod(int(milliseconds), 1000)
17
+ minutes, seconds = divmod(seconds, 60)
18
+ hours, minutes = divmod(minutes, 60)
19
+ days, hours = divmod(hours, 24)
20
+ tmp = ((str(days) + "d, ") if days else "") + \
21
+ ((str(hours) + "h, ") if hours else "") + \
22
+ ((str(minutes) + "m, ") if minutes else "") + \
23
+ ((str(seconds) + "s, ") if seconds else "") + \
24
+ ((str(milliseconds) + "ms, ") if milliseconds else "")
25
+ return tmp[:-2]
FileStream/__init__.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ from FileStream.Tools import Time_ISTKolNow
2
+
3
+ __version__ = "1.1.0"
4
+ StartTime = Time_ISTKolNow()
5
+ print("** Program starting at Indian Standard Time :", Time_ISTKolNow())
6
+
FileStream/__main__.py ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sys
2
+ import asyncio
3
+ import logging
4
+ import traceback
5
+ import logging.handlers as handlers
6
+ from FileStream.config import Telegram, Server
7
+ from aiohttp import web
8
+ from pyrogram import idle
9
+
10
+ from FileStream.bot import FileStream
11
+ from FileStream.Tools import Time_ISTKolNow
12
+ from FileStream.server import web_server
13
+ from FileStream.bot.clients import initialize_clients
14
+
15
+ logging.basicConfig(
16
+ level=logging.INFO,
17
+ datefmt="%d/%m/%Y %H:%M:%S",
18
+ format=
19
+ '[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s',
20
+ handlers=[
21
+ logging.StreamHandler(stream=sys.stdout),
22
+ handlers.RotatingFileHandler("streambot.log",
23
+ mode="a",
24
+ maxBytes=104857600,
25
+ backupCount=2,
26
+ encoding="utf-8")
27
+ ],
28
+ )
29
+
30
+ logging.getLogger("aiohttp").setLevel(logging.ERROR)
31
+ logging.getLogger("pyrogram").setLevel(logging.ERROR)
32
+ logging.getLogger("aiohttp.web").setLevel(logging.ERROR)
33
+
34
+ server = web.AppRunner(web_server())
35
+
36
+ loop = asyncio.get_event_loop()
37
+
38
+
39
+ async def start_services():
40
+ print()
41
+ if Telegram.SECONDARY:
42
+ print("------------------ Starting as Secondary Server ------------------")
43
+ else:
44
+ print("------------------- Starting as Primary Server -------------------")
45
+ print()
46
+ print("-------------------- Initializing Telegram Bot --------------------")
47
+
48
+ await FileStream.start()
49
+ bot_info = await FileStream.get_me()
50
+ FileStream.id = bot_info.id
51
+ FileStream.username = bot_info.username
52
+ FileStream.fname = bot_info.first_name
53
+ print("------------------------------ DONE ------------------------------")
54
+ print()
55
+ print("---------------------- Initializing Clients ----------------------")
56
+ await initialize_clients()
57
+ print("------------------------------ DONE ------------------------------")
58
+ print()
59
+ print("--------------------- Initializing Web Server ---------------------")
60
+ await server.setup()
61
+ await web.TCPSite(server, Server.BIND_ADDRESS, Server.PORT).start()
62
+ print("------------------------------ DONE ------------------------------")
63
+ print()
64
+ print("------------------------- Service Started -------------------------")
65
+ print("Bot =>> {}".format(bot_info.first_name))
66
+ if bot_info.dc_id:
67
+ print("DC ID =>> {}".format(str(bot_info.dc_id)))
68
+ print(" URL =>> {}".format(Server.URL))
69
+ print("------------------------------------------------------------------")
70
+ """
71
+ all_sources = [
72
+ Telegram.ULOG_GROUP, Telegram.FLOG_CHANNEL, Telegram.PFLOG_CHANNEL
73
+ ]
74
+ for source in all_sources:
75
+ await FileStream.send_message(chat_id=source,
76
+ text=f"Hi, I am Online @{ISTKolNow()}",
77
+ disable_web_page_preview=True)
78
+ """
79
+ await idle()
80
+
81
+
82
+ async def cleanup():
83
+ await server.cleanup()
84
+ await FileStream.stop()
85
+
86
+
87
+ if __name__ == "__main__":
88
+ try:
89
+ loop.run_until_complete(start_services())
90
+ except KeyboardInterrupt:
91
+ loop.stop()
92
+ print("------------------------ Stopped Services ------------------------")
93
+ except Exception as err:
94
+ logging.error(traceback.format_exc())
FileStream/bot/__init__.py ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from ..config import Telegram
2
+ from pyrogram import Client
3
+
4
+ if Telegram.SECONDARY:
5
+ plugins = None
6
+ no_updates = True
7
+ else:
8
+ plugins = dict(root="FileStream/bot/plugins")
9
+ no_updates = None
10
+
11
+ FileStream = Client(name="FileStream",
12
+ api_id=Telegram.API_ID,
13
+ api_hash=Telegram.API_HASH,
14
+ workdir="FileStream",
15
+ plugins=plugins,
16
+ bot_token=Telegram.BOT_TOKEN,
17
+ sleep_threshold=Telegram.SLEEP_THRESHOLD,
18
+ workers=Telegram.WORKERS,
19
+ no_updates=no_updates)
20
+
21
+ multi_clients = {}
22
+ work_loads = {}
23
+
24
+ async def req_client():
25
+ index = min(work_loads, key=work_loads.get)
26
+ faster_client = multi_clients[index]
27
+ response = dict(index=index, client=faster_client)
28
+ return response
FileStream/bot/clients.py ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import asyncio
2
+ import logging
3
+ from os import environ
4
+ from ..config import Telegram
5
+ from pyrogram import Client
6
+ from . import multi_clients, work_loads, FileStream
7
+
8
+
9
+ async def initialize_clients():
10
+ all_tokens = dict(
11
+ (c + 1, t)
12
+ for c, (_, t) in enumerate(
13
+ filter(
14
+ lambda n: n[0].startswith("MULTI_TOKEN"), sorted(environ.items())
15
+ )
16
+ )
17
+ )
18
+ if not all_tokens:
19
+ multi_clients[0] = FileStream
20
+ work_loads[0] = 0
21
+ print("No additional clients found, using default client")
22
+ return
23
+
24
+ async def start_client(client_id, token):
25
+ try:
26
+ if len(token) >= 100:
27
+ session_string=token
28
+ bot_token=None
29
+ print(f'Starting Client - {client_id} Using Session String')
30
+ else:
31
+ session_string=None
32
+ bot_token=token
33
+ print(f'Starting Client - {client_id} Using Bot Token')
34
+ if client_id == len(all_tokens):
35
+ await asyncio.sleep(2)
36
+ print("This will take some time, please wait...")
37
+ client = await Client(
38
+ name=str(client_id),
39
+ api_id=Telegram.API_ID,
40
+ api_hash=Telegram.API_HASH,
41
+ bot_token=bot_token,
42
+ sleep_threshold=Telegram.SLEEP_THRESHOLD,
43
+ no_updates=True,
44
+ session_string=session_string,
45
+ in_memory=True,
46
+ ).start()
47
+ client.id = (await client.get_me()).id
48
+ work_loads[client_id] = 0
49
+ return client_id, client
50
+ except Exception:
51
+ logging.error(f"Failed starting Client - {client_id} Error:", exc_info=True)
52
+
53
+ clients = await asyncio.gather(*[start_client(i, token) for i, token in all_tokens.items()])
54
+ multi_clients.update(dict(clients))
55
+ if len(multi_clients) != 1:
56
+ Telegram.MULTI_CLIENT = True
57
+ print("Multi-Client Mode Enabled")
58
+ else:
59
+ print("No additional clients were initialized, using default client")
FileStream/bot/plugins/Admin/admin.py ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import time
3
+ import string
4
+ import random
5
+ import asyncio
6
+ import aiofiles
7
+ import datetime
8
+
9
+ from FileStream.utils.FileProcessors.broadcast_helper import send_msg
10
+ from FileStream.Database import Database
11
+ from FileStream.bot import FileStream
12
+ from FileStream.server.exceptions import FIleNotFound
13
+ from FileStream.config import Telegram, Server
14
+ from pyrogram import filters, Client
15
+ from pyrogram.types import Message
16
+ from pyrogram.enums.parse_mode import ParseMode
17
+
18
+ db = Database(Telegram.DATABASE_URL, Telegram.SESSION_NAME)
19
+ broadcast_ids = {}
20
+
21
+
22
+ #Authorize User to Use the Services
23
+ @FileStream.on_message(filters.command("auth") & filters.private & filters.user(Telegram.OWNER_ID))
24
+ async def sts(c: Client, m: Message):
25
+ await m.reply_text(
26
+ text=f"""**Total Users in DB:** `{await db.total_users_count()}`
27
+ **Banned Users in DB:** `{await db.total_banned_users_count()}`
28
+ **Total Links Generated: ** `{await db.total_files()}`""",
29
+ parse_mode=ParseMode.MARKDOWN,
30
+ quote=True)
31
+
32
+ @FileStream.on_message(filters.command("add_user") & filters.private )
33
+ async def add_user(c: Client, m: Message):
34
+ if await db.is_admin(m.from_user.id):
35
+ if len(m.command) == 1:
36
+ return await m.reply_text("**Usage:**\n /add_user <user_id>")
37
+ try:
38
+ user_id = int(m.command[1])
39
+ except ValueError or UnboundLocalError:
40
+ return await m.reply_text(f"**Usage:**\n <code> /add_admin <{user_id}> </code> ")
41
+ await db.add_user(user_id)
42
+ await m.reply_text(f"**User[{m.from_user.first_name} {m.from_user.last_name}] \n User ID : {user_id} Added Successfully**")
43
+ else:
44
+ await m.reply_text(f"** Sorry Sir {user_id} You are not Admin **")
45
+
46
+ @FileStream.on_message(filters.command("add_admin") & filters.user(Telegram.OWNER_ID) )
47
+ async def add_user(c: Client, m: Message):
48
+ if await db.is_admin(m.from_user.id):
49
+ if len(m.command) == 1:
50
+ return await m.reply_text(f"**Usage:**\n <code> /add_admin <user_id> </code>")
51
+ try:
52
+ user_id = int(m.command[1])
53
+ except ValueError or UnboundLocalError:
54
+ return await m.reply_text(f"**Usage:**\n <code> /add_admin <{user_id}> </code>")
55
+ await db.add_admin(user_id)
56
+ await m.reply_text(f"**Admin [{m.from_user.first_name} {m.from_user.last_name}]\n {user_id} Added Successfully**")
57
+ else:
58
+ await m.reply_text(f"** Sorry Sir [{m.from_user.first_name} {m.from_user.last_name}] {user_id} You are not Admin **")
59
+
60
+
61
+ @FileStream.on_message(filters.command("status") & filters.private & filters.user(Telegram.OWNER_ID))
62
+ async def sts(c: Client, m: Message):
63
+ await m.reply_text(
64
+ text=f"""**Total Users in DB:** `{await db.total_users_count()}`
65
+ **Banned Users in DB:** `{await db.total_banned_users_count()}`
66
+ **Total Links Generated: ** `{await db.total_files()}`""",
67
+ parse_mode=ParseMode.MARKDOWN,
68
+ quote=True)
69
+
70
+
71
+ @FileStream.on_message(filters.command("ban") & filters.private & filters.user(Telegram.OWNER_ID))
72
+ async def sts(b, m: Message):
73
+ id = m.text.split("/ban ")[-1]
74
+ if not await db.is_user_banned(int(id)):
75
+ try:
76
+ await db.ban_user(int(id))
77
+ await db.delete_user(int(id))
78
+ await m.reply_text(text=f"`{id}`** is Banned** ",
79
+ parse_mode=ParseMode.MARKDOWN,
80
+ quote=True)
81
+ if not str(id).startswith('-100'):
82
+ await b.send_message(chat_id=id,
83
+ text="**Your Banned to Use The Bot**",
84
+ parse_mode=ParseMode.MARKDOWN,
85
+ disable_web_page_preview=True)
86
+ except Exception as e:
87
+ await m.reply_text(text=f"**something went wrong: {e}** ",
88
+ parse_mode=ParseMode.MARKDOWN,
89
+ quote=True)
90
+ else:
91
+ await m.reply_text(text=f"`{id}`** is Already Banned** ",
92
+ parse_mode=ParseMode.MARKDOWN,
93
+ quote=True)
94
+
95
+
96
+ @FileStream.on_message(filters.command("unban") & filters.private & filters.user(Telegram.OWNER_ID))
97
+ async def sts(b, m: Message):
98
+ id = m.text.split("/unban ")[-1]
99
+ if await db.is_user_banned(int(id)):
100
+ try:
101
+ await db.unban_user(int(id))
102
+ await m.reply_text(text=f"`{id}`** is Unbanned** ",
103
+ parse_mode=ParseMode.MARKDOWN,
104
+ quote=True)
105
+ if not str(id).startswith('-100'):
106
+ await b.send_message(chat_id=id,
107
+ text="**Your Unbanned now Use can use The Bot**",
108
+ parse_mode=ParseMode.MARKDOWN,
109
+ disable_web_page_preview=True)
110
+ except Exception as e:
111
+ await m.reply_text(text=f"** something went wrong: {e}**",
112
+ parse_mode=ParseMode.MARKDOWN,
113
+ quote=True)
114
+ else:
115
+ await m.reply_text(text=f"`{id}`** is not Banned** ",
116
+ parse_mode=ParseMode.MARKDOWN,
117
+ quote=True)
118
+
119
+
120
+ @FileStream.on_message(
121
+ filters.command("broadcast") & filters.private
122
+ & filters.user(Telegram.OWNER_ID) & filters.reply)
123
+ async def broadcast_(c, m):
124
+ all_users = await db.get_all_users()
125
+ broadcast_msg = m.reply_to_message
126
+ while True:
127
+ broadcast_id = ''.join(
128
+ [random.choice(string.ascii_letters) for i in range(3)])
129
+ if not broadcast_ids.get(broadcast_id):
130
+ break
131
+ out = await m.reply_text(
132
+ text=
133
+ f"Broadcast initiated! You will be notified with log file when all the users are notified."
134
+ )
135
+ start_time = time.time()
136
+ total_users = await db.total_users_count()
137
+ done = 0
138
+ failed = 0
139
+ success = 0
140
+ broadcast_ids[broadcast_id] = dict(total=total_users,
141
+ current=done,
142
+ failed=failed,
143
+ success=success)
144
+ async with aiofiles.open('broadcast.txt', 'w') as broadcast_log_file:
145
+ async for user in all_users:
146
+ sts, msg = await send_msg(user_id=int(user['id']), message=broadcast_msg)
147
+ if msg is not None:
148
+ await broadcast_log_file.write(msg)
149
+ if sts == 200:
150
+ success += 1
151
+ else:
152
+ failed += 1
153
+ if sts == 400:
154
+ await db.delete_user(user['id'])
155
+ done += 1
156
+ if broadcast_ids.get(broadcast_id) is None:
157
+ break
158
+ else:
159
+ broadcast_ids[broadcast_id].update(
160
+ dict(current=done, failed=failed, success=success))
161
+ try:
162
+ await out.edit_text(
163
+ f"Broadcast Status\n\ncurrent: {done}\nfailed:{failed}\nsuccess: {success}"
164
+ )
165
+ except:
166
+ pass
167
+ if broadcast_ids.get(broadcast_id):
168
+ broadcast_ids.pop(broadcast_id)
169
+ completed_in = datetime.timedelta(seconds=int(time.time() - start_time))
170
+ await asyncio.sleep(3)
171
+ await out.delete()
172
+ if failed == 0:
173
+ await m.reply_text(
174
+ text=
175
+ f"broadcast completed in `{completed_in}`\n\nTotal users {total_users}.\nTotal done {done}, {success} success and {failed} failed.",
176
+ quote=True)
177
+ else:
178
+ await m.reply_document(
179
+ document='broadcast.txt',
180
+ caption=
181
+ f"broadcast completed in `{completed_in}`\n\nTotal users {total_users}.\nTotal done {done}, {success} success and {failed} failed.",
182
+ quote=True)
183
+ os.remove('broadcast.txt')
184
+
185
+
186
+ @FileStream.on_message(
187
+ filters.command("del") & filters.private & filters.user(Telegram.OWNER_ID))
188
+ async def sts(c: Client, m: Message):
189
+ file_id = m.text.split(" ")[-1]
190
+ try:
191
+ file_info = await db.get_file(file_id)
192
+ except FIleNotFound:
193
+ await m.reply_text(text=f"**File Already Deleted**", quote=True)
194
+ return
195
+ await db.delete_one_file(file_info['_id'])
196
+ await db.count_links(file_info['user_id'], "-")
197
+ await m.reply_text(text=f"**Fɪʟᴇ Dᴇʟᴇᴛᴇᴅ Sᴜᴄᴄᴇssғᴜʟʟʏ !** ", quote=True)
FileStream/bot/plugins/FileHandlers/callback.py ADDED
@@ -0,0 +1,584 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import math
2
+ import asyncio
3
+ import datetime
4
+
5
+ from pyrogram import filters, Client
6
+ from pyrogram.errors import FloodWait
7
+ from pyrogram.enums.parse_mode import ParseMode
8
+ from pyrogram.file_id import FileId, FileType, PHOTO_TYPES
9
+ from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery, WebAppInfo
10
+ from pyrogram.raw.types import KeyboardButtonSimpleWebView
11
+ #-------------------------Local Imports -----------------------------------#
12
+ from FileStream import __version__
13
+ from FileStream.Database import Database
14
+ from FileStream.config import Telegram, Server
15
+ from FileStream.bot import FileStream, multi_clients
16
+ from FileStream.server.exceptions import FIleNotFound
17
+ from FileStream.utils.FileProcessors.translation import LANG, BUTTON
18
+ from FileStream.utils.FileProcessors.human_readable import humanbytes
19
+ from FileStream.bot.plugins.FileHandlers.stream import private_receive_handler
20
+ from FileStream.utils.FileProcessors.file_properties import get_file_ids, get_file_info
21
+ from FileStream.utils.FileProcessors.bot_utils import gen_link, priv_func, gen_priv_file_link
22
+ #-----------------Starting Point --------------------------#
23
+
24
+ db = Database(Telegram.DATABASE_URL, Telegram.SESSION_NAME)
25
+
26
+
27
+ #---------------------[ START CMD ]---------------------#
28
+ @FileStream.on_callback_query()
29
+ async def cb_data(bot: Client, update: CallbackQuery):
30
+ usr_cmd = update.data.split("_")
31
+ if usr_cmd[0] == "home":
32
+ await update.message.edit_text(text=LANG.START_TEXT.format(
33
+ update.from_user.mention, FileStream.username),
34
+ disable_web_page_preview=True,
35
+ reply_markup=BUTTON.START_BUTTONS)
36
+ elif usr_cmd[0] == "help":
37
+ await update.message.edit_text(text=LANG.HELP_TEXT.format(
38
+ Telegram.OWNER_ID),
39
+ disable_web_page_preview=True,
40
+ reply_markup=BUTTON.HELP_BUTTONS)
41
+ elif usr_cmd[0] == "about":
42
+ await update.message.edit_text(text=LANG.ABOUT_TEXT.format(
43
+ FileStream.fname, __version__),
44
+ disable_web_page_preview=True,
45
+ reply_markup=BUTTON.ABOUT_BUTTONS)
46
+
47
+ #---------------------[ MY FILES CMD ]---------------------#
48
+
49
+ elif usr_cmd[0] == "N/A":
50
+ await update.answer("N/A", True)
51
+ elif usr_cmd[0] == "close":
52
+ await update.message.delete()
53
+ elif usr_cmd[0] == "back":
54
+ try:
55
+ user_id = str(usr_cmd[1])
56
+ message_id = int(usr_cmd[2])
57
+ print(user_id, message_id)
58
+ message = await FileStream.get_messages(user_id, message_id)
59
+ await private_receive_handler(FileStream, message)
60
+ except FloodWait as e:
61
+ print(f"Sleeping for {str(e.value)}s")
62
+ await asyncio.sleep(e.value)
63
+ await FileStream.send_message(
64
+ chat_id=Telegram.ULOG_GROUP,
65
+ text=
66
+ f"Gᴏᴛ FʟᴏᴏᴅWᴀɪᴛ ᴏғ {str(e.value)}s ғʀᴏᴍ [{message.from_user.first_name}](tg://user?id={message.from_user.id})\n\n**ᴜsᴇʀ ɪᴅ :** `{str(message.from_user.id)}`",
67
+ disable_web_page_preview=True,
68
+ parse_mode=ParseMode.MARKDOWN)
69
+
70
+ elif usr_cmd[0] == "msgdelete":
71
+ await update.message.edit_caption(
72
+ caption="**Cᴏɴғɪʀᴍ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴅᴇʟᴇᴛᴇ ᴛʜᴇ Fɪʟᴇ**\n\n",
73
+ reply_markup=InlineKeyboardMarkup([[
74
+ InlineKeyboardButton(
75
+ "ʏᴇs", callback_data=f"msgdelyes_{usr_cmd[1]}_{usr_cmd[2]}"),
76
+ InlineKeyboardButton(
77
+ "ɴᴏ", callback_data=f"myfile_{usr_cmd[1]}_{usr_cmd[2]}")
78
+ ]]))
79
+ elif usr_cmd[0] == "msgdelyes":
80
+ await delete_user_file(usr_cmd[1], int(usr_cmd[2]), update)
81
+ return
82
+ elif usr_cmd[0] == "msgdelpvt":
83
+ await update.message.edit_caption(
84
+ caption="**Cᴏɴғɪʀᴍ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴅᴇʟᴇᴛᴇ ᴛʜᴇ Fɪʟᴇ**\n\n",
85
+ reply_markup=InlineKeyboardMarkup([[
86
+ InlineKeyboardButton("ʏᴇs",
87
+ callback_data=f"msgdelpvtyes_{usr_cmd[1]}"),
88
+ InlineKeyboardButton("ɴᴏ",
89
+ callback_data=f"mainstream_{usr_cmd[1]}")
90
+ ]]))
91
+ elif usr_cmd[0] == "msgdelpvtyes":
92
+ await delete_user_filex(usr_cmd[1], update)
93
+ return
94
+
95
+ elif usr_cmd[0] == "mainstream":
96
+ _id = usr_cmd[1]
97
+ reply_markup, stream_text = await gen_link(_id=_id)
98
+ await update.message.edit_text(
99
+ text=stream_text,
100
+ parse_mode=ParseMode.HTML,
101
+ disable_web_page_preview=True,
102
+ reply_markup=reply_markup,
103
+ )
104
+ elif usr_cmd[0] == "pubup":
105
+ try:
106
+ user_id = str(usr_cmd[1])
107
+ message_id = int(usr_cmd[2])
108
+ message = await FileStream.get_messages(user_id, message_id)
109
+ instruction = {
110
+ "privacy_type": "PUBLIC",
111
+ "user_id": user_id,
112
+ "user_type": "TELEGRAM"
113
+ }
114
+ file_info = get_file_info(message, instruction)
115
+ # Here we are Adding the File Into the database First
116
+ inserted_id = await db.add_file(file_info)
117
+ await get_file_ids(False, inserted_id, message)
118
+ #All the Time Get_file_ids should be called before update privacy or else tagged_users will be {}
119
+ await db.update_privacy(file_info)
120
+ reply_markup, stream_text = await gen_link(_id=inserted_id)
121
+ await update.message.edit_text(
122
+ text=stream_text,
123
+ parse_mode=ParseMode.HTML,
124
+ disable_web_page_preview=True,
125
+ reply_markup=reply_markup,
126
+ )
127
+ except FloodWait as e:
128
+ print(f"Sleeping for {str(e.value)}s")
129
+ await asyncio.sleep(e.value)
130
+ await FileStream.send_message(
131
+ chat_id=Telegram.ULOG_GROUP,
132
+ text=
133
+ f"Gᴏᴛ FʟᴏᴏᴅWᴀɪᴛ ᴏғ {str(e.value)}s ғʀᴏᴍ [{message.from_user.first_name}](tg://user?id={message.from_user.id})\n\n**ᴜsᴇʀ ɪᴅ :** `{str(message.from_user.id)}`",
134
+ disable_web_page_preview=True,
135
+ parse_mode=ParseMode.MARKDOWN)
136
+
137
+ elif usr_cmd[0] == "privup":
138
+ try:
139
+ user_id = str(usr_cmd[1])
140
+ message_id = int(usr_cmd[2])
141
+ message = await FileStream.get_messages(user_id, message_id)
142
+ instruction = {
143
+ "privacy_type": "PRIVATE",
144
+ "user_id": user_id,
145
+ "user_type": "TELEGRAM"
146
+ }
147
+ file_info = get_file_info(message, instruction)
148
+ # Here we are Adding the File Into the database First
149
+ db_id = await db.add_file(file_info)
150
+ await get_file_ids(False, db_id, message)
151
+
152
+ if True:
153
+ file_info = await db.get_file(db_id)
154
+ reply_markup, stream_text = await priv_func(file_info['file']['file_name'], file_info['file']['file_size'])
155
+
156
+ await update.message.edit_text(
157
+ text=stream_text,
158
+ parse_mode=ParseMode.HTML,
159
+ disable_web_page_preview=True,
160
+ reply_markup=reply_markup,
161
+ )
162
+ except FloodWait as e:
163
+ print(f"Sleeping for {str(e.value)}s")
164
+ await asyncio.sleep(e.value)
165
+ await FileStream.send_message(
166
+ chat_id=Telegram.ULOG_GROUP,
167
+ text=
168
+ f"Gᴏᴛ FʟᴏᴏᴅWᴀɪᴛ ᴏғ {str(e.value)}s ғʀᴏᴍ [{message.from_user.first_name}](tg://user?id={message.from_user.id})\n\n**ᴜsᴇʀ ɪᴅ :** `{str(message.from_user.id)}`",
169
+ disable_web_page_preview=True,
170
+ parse_mode=ParseMode.MARKDOWN)
171
+
172
+ elif usr_cmd[0] == "userfiles":
173
+ file_list, total_files = await gen_file_list_button(int(usr_cmd[1]), update.from_user.id)
174
+ await update.message.edit_caption(
175
+ caption="Total files: {}".format(total_files),
176
+ reply_markup=InlineKeyboardMarkup(file_list))
177
+
178
+ elif usr_cmd[0] == "userprivfiles":
179
+ file_list, total_files = await gen_privfile_list_button(
180
+ int(usr_cmd[1]), update.from_user.id)
181
+ await update.message.edit_caption(
182
+ caption="Total files: {}".format(total_files),
183
+ reply_markup=InlineKeyboardMarkup(file_list))
184
+
185
+ elif usr_cmd[0] == "userallfiles":
186
+ file_list, total_files = await gen_allfile_list_button(
187
+ int(usr_cmd[1]), update.from_user.id)
188
+ await update.message.edit_caption(
189
+ caption="Total files: {}".format(total_files),
190
+ reply_markup=InlineKeyboardMarkup(file_list))
191
+
192
+ elif usr_cmd[0] == "myfile":
193
+ await gen_file_menu(usr_cmd[1], usr_cmd[2], update)
194
+ return
195
+ elif usr_cmd[0] == "allfile":
196
+ await gen_allfile_menu(usr_cmd[1], usr_cmd[2], update)
197
+ return
198
+ elif usr_cmd[0] == "myprivfile":
199
+ await gen_privfile_menu(usr_cmd[1], usr_cmd[2], update)
200
+ return
201
+ elif usr_cmd[0] == "sendfile":
202
+ myfile = await db.get_file(usr_cmd[1])
203
+ file_name = myfile['file']['file_name']
204
+ await update.answer(f"Sending File {file_name}")
205
+ await update.message.reply_cached_media(myfile['file']['file_id'],caption=f'**{file_name}**')
206
+ else:
207
+ await update.message.delete()
208
+
209
+ #---------------------[ MY FILES FUNC ]---------------------#
210
+
211
+
212
+ async def gen_file_list_button(file_list_no: int, user_id: int):
213
+
214
+ file_range = [file_list_no * 10 - 10 + 1, file_list_no * 10]
215
+ user_files, total_files = await db.find_files(user_id, file_range)
216
+
217
+ file_list = []
218
+ async for x in user_files:
219
+ file_list.append([
220
+ InlineKeyboardButton(f"📦 {x['file']['caption']}",
221
+ callback_data=f"myfile_{x['_id']}_{file_list_no}")
222
+ ])
223
+ if total_files > 10:
224
+ file_list.append([
225
+ InlineKeyboardButton(
226
+ "◄",
227
+ callback_data="{}".format("userfiles_" +
228
+ str(file_list_no -
229
+ 1) if file_list_no > 1 else 'N/A')),
230
+ InlineKeyboardButton(f"{file_list_no}/{math.ceil(total_files/10)}",
231
+ callback_data="N/A"),
232
+ InlineKeyboardButton(
233
+ "►",
234
+ callback_data="{}".format("userfiles_" +
235
+ str(file_list_no +
236
+ 1) if total_files > file_list_no *
237
+ 10 else 'N/A'))
238
+ ])
239
+ if not file_list:
240
+ file_list.append([InlineKeyboardButton("ᴇᴍᴘᴛʏ", callback_data="N/A")])
241
+ file_list.append([InlineKeyboardButton("ᴄʟᴏsᴇ", callback_data="close")])
242
+ return file_list, total_files
243
+
244
+
245
+ async def gen_file_menu(_id, file_list_no, update: CallbackQuery):
246
+ try:
247
+ myfile_info = await db.get_file(_id)
248
+ except FIleNotFound:
249
+ await update.answer("File Not Found")
250
+ return
251
+
252
+ file_id = FileId.decode(myfile_info['file']['file_id'])
253
+
254
+ if file_id.file_type in PHOTO_TYPES:
255
+ file_type = "Image"
256
+ elif file_id.file_type == FileType.VOICE:
257
+ file_type = "Voice"
258
+ elif file_id.file_type in (FileType.VIDEO, FileType.ANIMATION,
259
+ FileType.VIDEO_NOTE):
260
+ file_type = "Video"
261
+ elif file_id.file_type == FileType.DOCUMENT:
262
+ file_type = "Document"
263
+ elif file_id.file_type == FileType.STICKER:
264
+ file_type = "Sticker"
265
+ elif file_id.file_type == FileType.AUDIO:
266
+ file_type = "Audio"
267
+ else:
268
+ file_type = "Unknown"
269
+
270
+ page_link = f"{Server.URL}app/watch/{myfile_info['_id']}"
271
+ stream_link = f"{Server.URL}api/dl/{myfile_info['_id']}"
272
+ if "video" in file_type.lower():
273
+ MYFILES_BUTTONS = InlineKeyboardMarkup([
274
+ [
275
+ InlineKeyboardButton("sᴛʀᴇᴀᴍ", url=page_link),
276
+ InlineKeyboardButton("ᴅᴏᴡɴʟᴏᴀᴅ", url=stream_link)
277
+ ],
278
+ [
279
+ InlineKeyboardButton(
280
+ "ɢᴇᴛ ғɪʟᴇ", callback_data=f"sendfile_{myfile_info['_id']}"),
281
+ InlineKeyboardButton(
282
+ "ʀᴇᴠᴏᴋᴇ ғɪʟᴇ",
283
+ callback_data=f"msgdelete_{myfile_info['_id']}_{file_list_no}")
284
+ ],
285
+ [
286
+ InlineKeyboardButton(
287
+ "ʙᴀᴄᴋ", callback_data="userfiles_{}".format(file_list_no))
288
+ ]
289
+ ])
290
+ else:
291
+ MYFILES_BUTTONS = InlineKeyboardMarkup([
292
+ [InlineKeyboardButton("ᴅᴏᴡɴʟᴏᴀᴅ", url=stream_link)],
293
+ [
294
+ InlineKeyboardButton(
295
+ "ɢᴇᴛ ғɪʟᴇ", callback_data=f"sendfile_{myfile_info['_id']}"),
296
+ InlineKeyboardButton(
297
+ "ʀᴇᴠᴏᴋᴇ ғɪʟᴇ",
298
+ callback_data=f"msgdelete_{myfile_info['_id']}_{file_list_no}")
299
+ ],
300
+ [
301
+ InlineKeyboardButton(
302
+ "ʙᴀᴄᴋ", callback_data="userfiles_{}".format(file_list_no))
303
+ ]
304
+ ])
305
+
306
+ TiMe = myfile_info['time']
307
+ if type(TiMe) == float:
308
+ date = datetime.datetime.fromtimestamp(TiMe)
309
+ await update.edit_message_caption(
310
+ caption="**File Name :** `{}`\n**File Size :** `{}`\n**File Type :** `{}`\n**Created On :** `{}`"
311
+ .format(myfile_info['file']['file_name'],
312
+ humanbytes(int(myfile_info['file']['file_size'])), file_type,
313
+ TiMe if isinstance(TiMe, str) else date.date()), reply_markup=MYFILES_BUTTONS)
314
+
315
+
316
+ #################------ private file list
317
+ async def gen_privfile_list_button(file_list_no: int, user_id: int):
318
+
319
+ file_range = [file_list_no * 10 - 10 + 1, file_list_no * 10]
320
+ user_files, total_files = await db.find_privfiles(user_id, file_range)
321
+
322
+ file_list = []
323
+ async for x in user_files:
324
+ file_list.append([
325
+ InlineKeyboardButton(
326
+ f"📦 {x['file']['caption']}",
327
+ callback_data=f"myprivfile_{x['_id']}_{file_list_no}")
328
+ ])
329
+ if total_files > 10:
330
+ file_list.append([
331
+ InlineKeyboardButton(
332
+ "◄",
333
+ callback_data="{}".format("userprivfiles_" +
334
+ str(file_list_no -
335
+ 1) if file_list_no > 1 else 'N/A')),
336
+ InlineKeyboardButton(f"{file_list_no}/{math.ceil(total_files/10)}",
337
+ callback_data="N/A"),
338
+ InlineKeyboardButton(
339
+ "►",
340
+ callback_data="{}".format("userprivfiles_" +
341
+ str(file_list_no +
342
+ 1) if total_files > file_list_no *
343
+ 10 else 'N/A'))
344
+ ])
345
+ if not file_list:
346
+ file_list.append([InlineKeyboardButton("ᴇᴍᴘᴛʏ", callback_data="N/A")])
347
+ file_list.append([InlineKeyboardButton("ᴄʟᴏsᴇ", callback_data="close")])
348
+ return file_list, total_files
349
+
350
+
351
+ async def gen_privfile_menu(_id, file_list_no, update: CallbackQuery):
352
+ try:
353
+ myfile_info = await db.get_privfile(_id)
354
+ except FIleNotFound:
355
+ await update.answer("File Not Found")
356
+ return
357
+
358
+ file_id = FileId.decode(myfile_info['file']['file_id'])
359
+
360
+ if file_id.file_type in PHOTO_TYPES:
361
+ file_type = "Image"
362
+ elif file_id.file_type == FileType.VOICE:
363
+ file_type = "Voice"
364
+ elif file_id.file_type in (FileType.VIDEO, FileType.ANIMATION,
365
+ FileType.VIDEO_NOTE):
366
+ file_type = "Video"
367
+ elif file_id.file_type == FileType.DOCUMENT:
368
+ file_type = "Document"
369
+ elif file_id.file_type == FileType.STICKER:
370
+ file_type = "Sticker"
371
+ elif file_id.file_type == FileType.AUDIO:
372
+ file_type = "Audio"
373
+ else:
374
+ file_type = "Unknown"
375
+
376
+ page_link = f"{Server.URL}app/watch/{myfile_info['_id']}"
377
+ stream_link = f"{Server.URL}api/dl/{myfile_info['_id']}"
378
+ if "video" in file_type.lower():
379
+ MYFILES_BUTTONS = InlineKeyboardMarkup([
380
+ [
381
+ InlineKeyboardButton("sᴛʀᴇᴀᴍ", url=page_link),
382
+ InlineKeyboardButton("ᴅᴏᴡɴʟᴏᴀᴅ", url=stream_link)
383
+ ],
384
+ [
385
+ InlineKeyboardButton(
386
+ "ɢᴇᴛ ғɪʟᴇ", callback_data=f"sendfile_{myfile_info['_id']}"),
387
+ InlineKeyboardButton(
388
+ "ʀᴇᴠᴏᴋᴇ ғɪʟᴇ",
389
+ callback_data=f"msgdelete_{myfile_info['_id']}_{file_list_no}")
390
+ ],
391
+ [
392
+ InlineKeyboardButton(
393
+ "ʙᴀᴄᴋ", callback_data="userfiles_{}".format(file_list_no))
394
+ ]
395
+ ])
396
+ else:
397
+ MYFILES_BUTTONS = InlineKeyboardMarkup([
398
+ [InlineKeyboardButton("ᴅᴏᴡɴʟᴏᴀᴅ", url=stream_link)],
399
+ [
400
+ InlineKeyboardButton(
401
+ "ɢᴇᴛ ғɪʟᴇ", callback_data=f"sendfile_{myfile_info['_id']}"),
402
+ InlineKeyboardButton(
403
+ "ʀᴇᴠᴏᴋᴇ ғɪʟᴇ",
404
+ callback_data=f"msgdelete_{myfile_info['_id']}_{file_list_no}")
405
+ ],
406
+ [
407
+ InlineKeyboardButton(
408
+ "ʙᴀᴄᴋ", callback_data="userfiles_{}".format(file_list_no))
409
+ ]
410
+ ])
411
+
412
+ TiMe = myfile_info['time']
413
+ if type(TiMe) == float:
414
+ date = datetime.datetime.fromtimestamp(TiMe)
415
+ await update.edit_message_caption(
416
+ caption=
417
+ "**File Name :** `{}`\n**File Size :** `{}`\n**File Type :** `{}`\n**Created On :** `{}`"
418
+ .format(myfile_info['file_name'],
419
+ humanbytes(int(myfile_info['file']['file_size'])), file_type,
420
+ TiMe if isinstance(TiMe, str) else date.date()),
421
+ reply_markup=MYFILES_BUTTONS)
422
+
423
+
424
+ ##################---- all file function-----##################
425
+ async def gen_allfile_list_button(file_list_no: int, user_id: int):
426
+
427
+ file_range = [file_list_no * 10 - 10 + 1, file_list_no * 10]
428
+ user_files, total_files = await db.find_all_files(file_range)
429
+
430
+ file_list = []
431
+ async for x in user_files:
432
+ file_list.append([
433
+ InlineKeyboardButton(
434
+ f"📦 {x['file']['caption']}",
435
+ callback_data=f"allfile_{x['_id']}_{file_list_no}")
436
+ ])
437
+ if total_files > 10:
438
+ file_list.append([
439
+ InlineKeyboardButton(
440
+ "◄",
441
+ callback_data="{}".format("userallfiles_" +
442
+ str(file_list_no -
443
+ 1) if file_list_no > 1 else 'N/A')),
444
+ InlineKeyboardButton(f"{file_list_no}/{math.ceil(total_files/10)}",
445
+ callback_data="N/A"),
446
+ InlineKeyboardButton(
447
+ "►",
448
+ callback_data="{}".format("userallfiles_" +
449
+ str(file_list_no +
450
+ 1) if total_files > file_list_no *
451
+ 10 else 'N/A'))
452
+ ])
453
+ if not file_list:
454
+ file_list.append([InlineKeyboardButton("ᴇᴍᴘᴛʏ", callback_data="N/A")])
455
+ file_list.append([InlineKeyboardButton("ᴄʟᴏsᴇ", callback_data="close")])
456
+ return file_list, total_files
457
+
458
+
459
+ async def gen_allfile_menu(_id, file_list_no, update: CallbackQuery):
460
+ try:
461
+ myfile_info = await db.get_file(_id)
462
+ except FIleNotFound:
463
+ await update.answer("File Not Found")
464
+ return
465
+
466
+ file_id = FileId.decode(myfile_info['file']['file_id'])
467
+
468
+ if file_id.file_type in PHOTO_TYPES:
469
+ file_type = "Image"
470
+ elif file_id.file_type == FileType.VOICE:
471
+ file_type = "Voice"
472
+ elif file_id.file_type in (FileType.VIDEO, FileType.ANIMATION,
473
+ FileType.VIDEO_NOTE):
474
+ file_type = "Video"
475
+ elif file_id.file_type == FileType.DOCUMENT:
476
+ file_type = "Document"
477
+ elif file_id.file_type == FileType.STICKER:
478
+ file_type = "Sticker"
479
+ elif file_id.file_type == FileType.AUDIO:
480
+ file_type = "Audio"
481
+ else:
482
+ file_type = "Unknown"
483
+
484
+ page_link = f"{Server.URL}app/watch/{myfile_info['_id']}"
485
+ stream_link = f"{Server.URL}api/dl/{myfile_info['_id']}"
486
+ if "video" in file_type.lower():
487
+ MYFILES_BUTTONS = InlineKeyboardMarkup([
488
+ [
489
+ InlineKeyboardButton("sᴛʀᴇᴀᴍ", url=page_link),
490
+ InlineKeyboardButton("ᴅᴏᴡɴʟᴏᴀᴅ", url=stream_link)
491
+ ],
492
+ [
493
+ InlineKeyboardButton(
494
+ "ɢᴇᴛ ғɪʟᴇ", callback_data=f"sendfile_{myfile_info['_id']}"),
495
+ InlineKeyboardButton(
496
+ "ʀᴇᴠᴏᴋᴇ ғɪʟᴇ",
497
+ callback_data=f"msgdelete_{myfile_info['_id']}_{file_list_no}")
498
+ ],
499
+ [
500
+ InlineKeyboardButton(
501
+ "ʙᴀᴄᴋ", callback_data="userfiles_{}".format(file_list_no))
502
+ ]
503
+ ])
504
+ else:
505
+ MYFILES_BUTTONS = InlineKeyboardMarkup([
506
+ [InlineKeyboardButton("ᴅᴏᴡɴʟᴏᴀᴅ", url=stream_link)],
507
+ [
508
+ InlineKeyboardButton(
509
+ "ɢᴇᴛ ғɪʟᴇ", callback_data=f"sendfile_{myfile_info['_id']}"),
510
+ InlineKeyboardButton(
511
+ "ʀᴇᴠᴏᴋᴇ ғɪʟᴇ",
512
+ callback_data=f"msgdelete_{myfile_info['_id']}_{file_list_no}")
513
+ ],
514
+ [
515
+ InlineKeyboardButton(
516
+ "ʙᴀᴄᴋ", callback_data="userfiles_{}".format(file_list_no))
517
+ ]
518
+ ])
519
+
520
+ TiMe = myfile_info['time']
521
+ if type(TiMe) == float:
522
+ date = datetime.datetime.fromtimestamp(TiMe)
523
+ await update.edit_message_caption(
524
+ caption=
525
+ "**File Name :** `{}`\n**File Size :** `{}`\n**File Type :** `{}`\n**Created On :** `{}`"
526
+ .format(myfile_info['file']['file_name'],
527
+ humanbytes(int(myfile_info['file']['file_size'])), file_type,
528
+ TiMe if isinstance(TiMe, str) else date.date()),
529
+ reply_markup=MYFILES_BUTTONS)
530
+
531
+
532
+ async def delete_user_file(_id, file_list_no: int, update: CallbackQuery):
533
+
534
+ try:
535
+ myfile_info = await db.get_file(_id)
536
+ if not myfile_info:
537
+
538
+ myfile_info = await db.get_privfile(db_id)
539
+ await db.delete_one_privfile(myfile_info['_id'])
540
+ #await db.count_links(update.from_user.id, "-")
541
+ await update.message.edit_caption(
542
+ caption="**Fɪʟᴇ Dᴇʟᴇᴛᴇᴅ Sᴜᴄᴄᴇssғᴜʟʟʏ !**" +
543
+ update.message.caption.replace("Cᴏɴғɪʀᴍ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴅᴇʟᴇᴛᴇ ᴛʜᴇ Fɪʟᴇ",
544
+ ""),
545
+ reply_markup=InlineKeyboardMarkup(
546
+ [[InlineKeyboardButton("ʙᴀᴄᴋ", callback_data=f"userfiles_1")]]))
547
+ else:
548
+ await db.delete_one_file(myfile_info['_id'])
549
+ await db.count_links(update.from_user.id, "-")
550
+ await update.message.edit_caption(
551
+ caption="**Fɪʟᴇ Dᴇʟᴇᴛᴇᴅ Sᴜᴄᴄᴇssғᴜʟʟʏ !**" +
552
+ update.message.caption.replace("Cᴏɴғɪʀᴍ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴅᴇʟᴇᴛᴇ ᴛʜᴇ Fɪʟᴇ",
553
+ ""),
554
+ reply_markup=InlineKeyboardMarkup(
555
+ [[InlineKeyboardButton("ʙᴀᴄᴋ", callback_data=f"userfiles_1")]]))
556
+
557
+ except FIleNotFound:
558
+ await update.answer("File Already Deleted")
559
+ return
560
+
561
+
562
+ async def delete_user_filex(_id, update: CallbackQuery):
563
+
564
+ try:
565
+ myfile_info = await db.get_file(_id)
566
+ if not myfile_info:
567
+
568
+ myfile_info = await db.get_privfile(_id)
569
+ await db.delete_one_privfile(myfile_info['_id'])
570
+ await update.message.edit_caption(
571
+ caption="**Fɪʟᴇ Dᴇʟᴇᴛᴇᴅ Sᴜᴄᴄᴇssғᴜʟʟʏ !**\n\n",
572
+ reply_markup=InlineKeyboardMarkup(
573
+ [[InlineKeyboardButton("ᴄʟᴏsᴇ", callback_data=f"close")]]))
574
+ else:
575
+ await db.delete_one_file(myfile_info['_id'])
576
+ await db.count_links(update.from_user.id, "-")
577
+ await update.message.edit_caption(
578
+ caption="**Fɪʟᴇ Dᴇʟᴇᴛᴇᴅ Sᴜᴄᴄᴇssғᴜʟʟʏ !**\n\n",
579
+ reply_markup=InlineKeyboardMarkup(
580
+ [[InlineKeyboardButton("ᴄʟᴏsᴇ", callback_data=f"close")]]))
581
+
582
+ except FIleNotFound:
583
+ await update.answer("File Already Deleted")
584
+ return
FileStream/bot/plugins/FileHandlers/files.py ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import math
2
+ import asyncio
3
+ import logging
4
+ from pyrogram import filters, Client
5
+ from pyrogram.types import BotCommand
6
+ from pyrogram.enums.parse_mode import ParseMode
7
+ from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, ReplyKeyboardMarkup, KeyboardButton, Message, InlineQueryResultArticle, InputTextMessageContent, InlineQueryResultPhoto
8
+ from pyrogram.types import InlineQueryResultVideo, InlineQueryResultAudio, InlineQueryResultCachedDocument,WebAppInfo
9
+ #----------------------------Local Imports ---------------------#
10
+ from FileStream import __version__
11
+ from FileStream.bot import FileStream
12
+ from FileStream.config import Telegram
13
+ from FileStream.Database import Database
14
+ from FileStream.server.exceptions import FIleNotFound
15
+ from FileStream.utils.FileProcessors.human_readable import humanbytes
16
+ from FileStream.utils.FileProcessors.bot_utils import gen_linkx, verify_user, verify_users
17
+ from FileStream.utils.FileProcessors.translation import LANG, BUTTON
18
+
19
+ # Set new commands
20
+
21
+ db = Database(Telegram.DATABASE_URL, Telegram.SESSION_NAME)
22
+
23
+
24
+ #----------------------------search Commands ---------------------#
25
+ @FileStream.on_message((filters.command('search') & filters.private) | (filters.regex("ꜱᴇᴀʀᴄʜ") & filters.private))
26
+ @verify_users
27
+ async def search_files(bot: Client, message: Message, response):
28
+
29
+ await message.reply(text="ꜱᴇᴀʀᴄʜ ɪɴ ᴘᴜʙʟɪᴄ ꜰɪʟᴇꜱ",
30
+ reply_markup=InlineKeyboardMarkup([[
31
+ InlineKeyboardButton(
32
+ 'Search', switch_inline_query_current_chat='')
33
+ ]]))
34
+
35
+ @FileStream.on_message(filters.command("webview"))
36
+ @verify_users
37
+ async def send_webview_button(bot: Client, message: Message, response):
38
+ # Define the inline keyboard with a button that opens a web page
39
+ webapp_button = InlineKeyboardMarkup(
40
+ [
41
+ [InlineKeyboardButton("Open WebApp", web_app=WebAppInfo(url="https://youtube.com"))]
42
+ ]
43
+ )
44
+
45
+ await message.reply_text(
46
+ "Click the button below to open the WebApp:",
47
+ reply_markup=webapp_button
48
+
49
+ )
50
+ #-------------------------Files---------------------------------#
51
+ @FileStream.on_message((filters.command('files') & filters.private) | (filters.regex("ᴍʏ ᴘᴜʙʟɪᴄ ꜰɪʟᴇꜱ") & filters.private))
52
+ @verify_users
53
+ async def my_files(bot: Client, message: Message, response):
54
+
55
+ user_files, total_files = await db.find_files(message.from_user.id, [1, 10])
56
+
57
+ file_list = []
58
+ async for x in user_files:
59
+ file_list.append([
60
+ InlineKeyboardButton(f"📦 {x['file']['caption']}",
61
+ callback_data=f"myfile_{x['_id']}_{1}")
62
+ ])
63
+ if total_files > 10:
64
+ file_list.append([
65
+ InlineKeyboardButton("◄", callback_data="N/A"),
66
+ InlineKeyboardButton(f"1/{math.ceil(total_files / 10)}",
67
+ callback_data="N/A"),
68
+ InlineKeyboardButton("►", callback_data="userfiles_2")
69
+ ], )
70
+ if not file_list:
71
+ file_list.append([InlineKeyboardButton("ᴇᴍᴘᴛʏ", callback_data="N/A")], )
72
+ file_list.append([InlineKeyboardButton("ᴄʟᴏsᴇ", callback_data="close")])
73
+ await message.reply_photo(photo=Telegram.FILE_PIC,
74
+ caption="Total files: {}".format(total_files),
75
+ reply_markup=InlineKeyboardMarkup(file_list))
76
+
77
+
78
+ # -----------------------------Bot Private Files Command -----------------------------------------------#
79
+ @FileStream.on_message((filters.command('myfiles') & filters.private) | (filters.regex("ᴘʀɪᴠᴀᴛᴇ ꜱᴘᴀᴄᴇ") & filters.private))
80
+ @verify_users
81
+ async def my_privfiles(bot: Client, message: Message, response):
82
+ user_files, total_files = await db.find_private_files(
83
+ message.from_user.id, [1, 10])
84
+
85
+ file_list = []
86
+ async for x in user_files:
87
+ file_list.append([
88
+ InlineKeyboardButton(f" 📦 {x['file']['caption']}",callback_data=f"myprivfile_{x['_id']}_{1}")
89
+ ])
90
+ if total_files > 10:
91
+ file_list.append([
92
+ InlineKeyboardButton("◄", callback_data="N/A"),
93
+ InlineKeyboardButton(f"1/{math.ceil(total_files / 10)}",
94
+ callback_data="N/A"),
95
+ InlineKeyboardButton("►", callback_data="userfiles_2")
96
+ ], )
97
+ if not file_list:
98
+ file_list.append([InlineKeyboardButton("ᴇᴍᴘᴛʏ", callback_data="N/A")], )
99
+ file_list.append([InlineKeyboardButton("ᴄʟᴏsᴇ", callback_data="close")])
100
+ await message.reply_photo(photo=Telegram.FILE_PIC,
101
+ caption="Total files: {}".format(total_files),
102
+ reply_markup=InlineKeyboardMarkup(file_list))
103
+
104
+
105
+ # -----------------------------Bot All Available Files Command ----------------------------------------#
106
+ @FileStream.on_message((filters.command('filebank') & filters.private) | (filters.regex("ꜰɪʟᴇ ʙᴀɴᴋ") & filters.private))
107
+ @verify_users
108
+ async def my_filebank(bot: Client, message: Message, response):
109
+
110
+ if await db.is_admin(message.from_user.id):
111
+ user_files, total_files = await db.find_all_files([1, 10])
112
+ else:
113
+ user_files, total_files = await db.find_all_public_files([1, 10])
114
+
115
+ file_list = []
116
+ async for x in user_files:
117
+ file_list.append([
118
+ InlineKeyboardButton(f"📦 {x['file']['caption']}",callback_data=f"allfile_{x['_id']}_{1}")])
119
+ if total_files > 10:
120
+ file_list.append([
121
+ InlineKeyboardButton("◄", callback_data="N/A"),
122
+ InlineKeyboardButton(f"1/{math.ceil(total_files / 10)}",
123
+ callback_data="N/A"),
124
+ InlineKeyboardButton("►", callback_data="userallfiles_2")
125
+ ], )
126
+ if not file_list:
127
+ file_list.append([InlineKeyboardButton("ᴇᴍᴘᴛʏ", callback_data="N/A")], )
128
+ file_list.append([InlineKeyboardButton("ᴄʟᴏsᴇ", callback_data="close")])
129
+
130
+ await message.reply_photo(photo=Telegram.FILE_PIC,
131
+ caption="Total files: {}".format(total_files),
132
+ reply_markup=InlineKeyboardMarkup(file_list))
133
+
134
+
135
+ @FileStream.on_inline_query()
136
+ async def handle_inline_query(client, query):
137
+ results = []
138
+ if '|' in query.query:
139
+ text, file_type = query.query.split('|', maxsplit=1)
140
+ text = text.strip()
141
+ file_type = file_type.strip().lower()
142
+ else:
143
+ text = query.query.strip()
144
+ file_type = None
145
+ offset = int(query.offset or 0)
146
+ files, next_offset = await db.get_search_results(text,file_type=file_type,max_results=10,offset=offset)
147
+ for file in files:
148
+ results.append(
149
+ InlineQueryResultCachedDocument(
150
+ title=file['file']['file_name'],
151
+ document_file_id=file['file']['file_id'],
152
+ caption=file['file']['file_name'] or "",
153
+ description=
154
+ f" Size: {humanbytes(file['file']['file_size'])}\nType:{file['file']['mime_type']} ",
155
+ reply_markup=InlineKeyboardMarkup([[
156
+ InlineKeyboardButton('Search',
157
+ switch_inline_query_current_chat='')
158
+ ]])))
159
+ if results:
160
+ switch_pm_text = f"Results"
161
+ if text:
162
+ switch_pm_text += f" for {text}"
163
+
164
+ await query.answer(results=results, cache_time=300, switch_pm_text=str(switch_pm_text), switch_pm_parameter="start", next_offset=str(next_offset) )
165
+ else:
166
+ switch_pm_text = f'No results'
167
+ if text:
168
+ switch_pm_text += f' for "{text}"'
169
+
170
+ await query.answer(results=[],cache_time=300,switch_pm_text=switch_pm_text,switch_pm_parameter="okay")
171
+ #await inline_query.answer(results=result)
FileStream/bot/plugins/FileHandlers/stream.py ADDED
@@ -0,0 +1,238 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ import random
4
+ import urllib3
5
+ import logging
6
+ import asyncio
7
+ import traceback
8
+ import mimetypes
9
+ import time, math
10
+ from datetime import datetime
11
+ from typing import Dict, Union
12
+ from typing import Union, BinaryIO, List, Optional, Callable
13
+
14
+ from pyrogram import raw
15
+ from pyrogram import types
16
+ from pyrogram import filters, Client
17
+ from pyrogram import utils as pgutils
18
+ from pyrogram import StopTransmission, enums
19
+ from pyrogram import Client, utils, raw
20
+
21
+ from pyrogram.file_id import FileType
22
+ from pyrogram.session import Session, Auth
23
+ from pyrogram.enums import ParseMode, ChatType
24
+ from pyrogram.enums.parse_mode import ParseMode
25
+ from pyrogram.file_id import FileId, FileType, ThumbnailSource
26
+ from pyrogram.errors import FilePartMissing, AuthBytesInvalid, FloodWait
27
+ from pyrogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton
28
+
29
+ #--------------------------Local Imports-------------#
30
+
31
+ from FileStream.Database import Database
32
+ from FileStream.config import Telegram, Server
33
+ from FileStream.Tools.tool import TimeFormatter
34
+ from FileStream.Tools.progress import progress
35
+ from FileStream.bot import FileStream, multi_clients, work_loads, req_client
36
+ from FileStream.utils.FileProcessors.bot_utils import is_user_banned, is_user_exist, is_user_joined, gen_link, is_channel_banned, is_channel_exist, is_user_authorized, upload_type_func
37
+ from FileStream.utils.FileProcessors.custom_dl import ByteStreamer
38
+ from FileStream.utils.FileProcessors.custom_ul import TeleUploader
39
+ from FileStream.utils.FileProcessors.custom_mix import TGFileController
40
+ from FileStream.utils.FileProcessors.translation import LANG, BUTTON
41
+ from FileStream.utils.FileProcessors.human_readable import humanbytes
42
+ from FileStream.utils.FileProcessors.file_properties import get_file_ids, get_file_info, get_private_file_ids
43
+
44
+ db = Database(Telegram.DATABASE_URL, Telegram.SESSION_NAME)
45
+
46
+
47
+ @FileStream.on_message(filters.private & (filters.document | filters.video | filters.video_note | filters.audio | filters.voice | filters.animation | filters.photo), group=4,)
48
+ async def private_receive_handler(bot: Client, message: Message):
49
+
50
+ try:
51
+ """
52
+ //All Values Generated Here is Decided in get_file_info () so No Need of this Block
53
+ message_id = message.id
54
+ if message.chat.type == ChatType.PRIVATE:
55
+ user_idx = message.from_user.id
56
+ else:
57
+ user_idx = message.chat.id
58
+ """
59
+ #For First Set All Files PUBLIC
60
+ instruction = {
61
+ "privacy_type":"PUBLIC",
62
+ "user_id":message.from_user.id if (message.chat.type == ChatType.PRIVATE) else message.chat.id,
63
+ "user_type": "TELEGRAM"
64
+ }
65
+ reply_markup, stream_text = await upload_type_func(get_file_info(message, instruction))
66
+ await message.reply_text(text=stream_text,
67
+ parse_mode=ParseMode.HTML,
68
+ disable_web_page_preview=True,
69
+ reply_markup=reply_markup,
70
+ quote=True)
71
+ except FloodWait as e:
72
+ print(f"Sleeping for {str(e.value)}s")
73
+ await asyncio.sleep(e.value)
74
+ await bot.send_message(
75
+ chat_id=Telegram.ULOG_CHANNEL,
76
+ text=
77
+ f"Gᴏᴛ FʟᴏᴏᴅWᴀɪᴛ ᴏғ {str(e.value)}s ғʀᴏᴍ [{message.from_user.first_name}](tg://user?id={message.from_user.id})\n\n**ᴜsᴇʀ ɪᴅ :** `{str(message.from_user.id)}`",
78
+ disable_web_page_preview=True,
79
+ parse_mode=ParseMode.MARKDOWN)
80
+
81
+
82
+ @FileStream.on_message(filters.channel & ~filters.forwarded & ~filters.media_group & (filters.document | filters.video | filters.video_note | filters.audio | filters.voice | filters.photo))
83
+ async def channel_receive_handler(bot: Client, message: Message):
84
+ if await is_channel_banned(bot, message):
85
+ return
86
+ await is_channel_exist(bot, message)
87
+
88
+ try:
89
+ inserted_id = await db.add_file(get_file_info(message))
90
+ await get_file_ids(False, inserted_id, multi_clients, message)
91
+ reply_markup, stream_link = await gen_link(_id=inserted_id)
92
+ await bot.edit_message_reply_markup(
93
+ chat_id=message.chat.id,
94
+ message_id=message.id,
95
+ reply_markup=InlineKeyboardMarkup([[
96
+ InlineKeyboardButton(
97
+ "Dᴏᴡɴʟᴏᴀᴅ ʟɪɴᴋ 📥",
98
+ url=
99
+ f"https://t.me/{FileStream.username}?start=stream_{str(inserted_id)}"
100
+ )
101
+ ]]))
102
+
103
+ except FloodWait as w:
104
+ print(f"Sleeping for {str(w.x)}s")
105
+ await asyncio.sleep(w.x)
106
+ await bot.send_message(
107
+ chat_id=Telegram.ULOG_GROUP,
108
+ text=
109
+ f"ɢᴏᴛ ғʟᴏᴏᴅᴡᴀɪᴛ ᴏғ {str(w.x)}s ғʀᴏᴍ {message.chat.title}\n\n**ᴄʜᴀɴɴᴇʟ ɪᴅ :** `{str(message.chat.id)}`",
110
+ disable_web_page_preview=True)
111
+ except Exception as e:
112
+ exc_type, exc_obj, exc_tb = sys.exc_info()
113
+ await bot.send_message(chat_id=Telegram.ULOG_GROUP,
114
+ text=f"**#EʀʀᴏʀTʀᴀᴄᴋᴇʙᴀᴄᴋ:** `{e} {exc_type, fname, exc_tb.tb_lineno}`",
115
+ disable_web_page_preview=True)
116
+ print(
117
+ f"Cᴀɴ'ᴛ Eᴅɪᴛ Bʀᴏᴀᴅᴄᴀsᴛ Mᴇssᴀɢᴇ!\nEʀʀᴏʀ: **Gɪᴠᴇ ᴍᴇ ᴇᴅɪᴛ ᴘᴇʀᴍɪssɪᴏɴ ɪɴ ᴜᴘᴅᴀᴛᴇs ᴀɴᴅ ʙɪɴ Cʜᴀɴɴᴇʟ!{e}**"
118
+ )
119
+
120
+
121
+ @FileStream.on_message(filters.reply)
122
+ async def reply_handler(
123
+ bot: Client,
124
+ message: Message,
125
+ thumb: Union[str, BinaryIO] = None,
126
+ ):
127
+
128
+ replied_message = message.reply_to_message
129
+ resp = ["n", "no", "not"]
130
+ if replied_message.empty:
131
+ return
132
+ if replied_message.media:
133
+ return
134
+ text = message.text
135
+ try:
136
+ main_message = replied_message.reply_to_message
137
+ instruction = {
138
+ "privacy_type":"PRIVATE",
139
+ "user_id":message.from_user.id if (message.chat.type == ChatType.PRIVATE) else message.chat.id,
140
+ "user_type":"TELEGRAM"
141
+ }
142
+ #file_infos = get_file_info(main_message, instruction)
143
+ #All the Time Get_file_ids should be called before update privacy or else tagged_users will be {}
144
+ file_info = await db.update_privacy(get_file_info(main_message, instruction))
145
+
146
+ #file_info = await db.get_file_by_fileuniqueid_only(
147
+ # file_infos['file']['file_unique_id'])
148
+ mime_type = file_info['file']['mime_type']
149
+ file_id = file_info['file']['file_id']
150
+ file_size = file_info['file']['file_size']
151
+ message_id = replied_message.id
152
+ user_idx = message.from_user.id if (message.chat.type == ChatType.PRIVATE) else message.chat.id
153
+
154
+ if text.lower() not in resp:
155
+ ext = mimetypes.guess_extension(mime_type)
156
+ file_info['file']['file_name'] = f"{message.text}{ext}"
157
+
158
+ #index = min(work_loads, key=work_loads.get)
159
+ #faster_client = multi_clients[index]
160
+ client=await req_client()
161
+ print(f"Using {client['index']} for {file_info['file']['file_name']}")
162
+ logging.info(f"Client {client['index']} is now serving {request.headers.get('X-FORWARDED-FOR',request.remote)}")
163
+
164
+
165
+ tg_connect = TGFileController(client['client'])
166
+ req_file_id = await tg_connect.get_file_properties(file_info['_id'], multi_clients)
167
+
168
+ start_time = time.time()
169
+ file = await tg_connect.upload_file(
170
+ index=client['index'],
171
+ file_id=req_file_id,
172
+ file_name=file_info['file']['file_name'],
173
+ file_size=file_info['file']['file_size'],
174
+ progress=progress,
175
+ progress_args=(replied_message, file_info['file']['file_name'],
176
+ file_info['file']['file_size'], start_time))
177
+
178
+ success_text = LANG.SUCCESS_PRIV_FILE.format(
179
+ file_info['file']['file_name'], humanbytes(file_size))
180
+ await replied_message.edit_text(
181
+ text=success_text,
182
+ parse_mode=ParseMode.HTML,
183
+ disable_web_page_preview=True,
184
+ )
185
+
186
+ media = raw.types.InputMediaUploadedDocument(
187
+ mime_type=mime_type,
188
+ file=file,
189
+ force_file=False,
190
+ thumb=thumb,
191
+ attributes=[
192
+ raw.types.DocumentAttributeFilename(
193
+ file_name=file_info['file']['file_name'])
194
+ ])
195
+ message_txt = f"* File Name: { file_info['file']['file_name']} \n* File Size :{humanbytes(file_info['file']['file_size'])} \n\n🔔 ᴛʜɪꜱ ꜰɪʟᴇ ɪꜱ ᴜᴘʟᴏᴀᴅᴇᴅ ᴛᴏ ᴘʀɪᴠᴀᴛᴇ ꜱᴘᴀᴄᴇ ʙʏ @ꜱᴘᴀʀᴋᴅʀɪᴠᴇ_ʙᴏᴛ"
196
+
197
+ send_file = await tg_connect.send(media=media,
198
+ caption=message_txt,
199
+ reply_to_msg_id=None,
200
+ chat_id=Telegram.PFLOG_CHANNEL)
201
+
202
+ reply_markup, stream_text = await gen_link(_id=file_info['_id'])
203
+ await replied_message.edit_text(
204
+ text=f"{message_txt}\n{stream_text}",
205
+ parse_mode=ParseMode.HTML,
206
+ disable_web_page_preview=True,
207
+ reply_markup=reply_markup,
208
+ )
209
+ instruction = {
210
+ "privacy_type":"PRIVATE",
211
+ "user_id":message.from_user.id if(message.chat.type == ChatType.PRIVATE) else message.chat.id,
212
+ "user_type":"TELEGRAM",
213
+ "REUPLOADED":"True"
214
+ }
215
+ file_info = get_file_info(send_file, instruction)
216
+ file_info['reupload']="True"
217
+ # Here we are Adding the File Into the database First
218
+ await db.add_private_file(file_info)
219
+ #await get_private_file_ids(False, inserted_id, message)
220
+ #All the Time Get_file_ids should be called before update privacy or else tagged_users will be {}
221
+ #await db.update_privacy(file_info)
222
+
223
+ except FloodWait as w:
224
+ print(f"Sleeping for {str(w.wait_time)}s")
225
+ await asyncio.sleep(w.wait_time)
226
+ await bot.send_message(
227
+ chat_id=Telegram.ULOG_GROUP,
228
+ text=
229
+ f"ɢᴏᴛ ғʟᴏᴏᴅᴡᴀɪᴛ ᴏғ {str(w.x)}s ғʀᴏᴍ {message.chat.title}\n\n**ᴄʜᴀɴɴᴇʟ ɪᴅ :** `{str(message.chat.id)}`",
230
+ disable_web_page_preview=True)
231
+
232
+ except Exception as e:
233
+ exc_type, exc_obj, exc_tb = sys.exc_info()
234
+ await bot.send_message(chat_id=Telegram.ULOG_GROUP,
235
+ text=f"**#EʀʀᴏʀTʀᴀᴄᴋᴇʙᴀᴄᴋ:** `{e} {exc_type, fname, exc_tb.tb_lineno}`",
236
+ disable_web_page_preview=True)
237
+ print(f"Cᴀɴ'ᴛ Eᴅɪᴛ Bʀᴏᴀᴅᴄᴀsᴛ Mᴇssᴀɢᴇ!\nEʀʀᴏʀ: **Gɪᴠᴇ ᴍᴇ ᴇᴅɪᴛ ᴘᴇʀᴍɪssɪᴏɴ ɪɴ ᴜᴘᴅᴀᴛᴇs ᴀɴᴅ ʙɪɴ Cʜᴀɴɴᴇʟ!{traceback.print_exc()} (upload_file)**")
238
+ #await db.delete_one_privfile(inserted_id)
FileStream/bot/plugins/startup.py ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import math
2
+ import logging
3
+ import asyncio
4
+ import traceback
5
+ from pyrogram import filters, Client
6
+ from pyrogram.enums.parse_mode import ParseMode
7
+ from pyrogram.types import BotCommand, Message, ReplyKeyboardMarkup, InlineKeyboardMarkup, InlineKeyboardButton
8
+
9
+ from FileStream import __version__
10
+ from FileStream.bot import FileStream
11
+ from FileStream.server.exceptions import FIleNotFound
12
+ from FileStream.utils.FileProcessors.bot_utils import gen_linkx, verify_user, verify_users
13
+ from FileStream.config import Telegram
14
+ from FileStream.Database import Database
15
+ from FileStream.utils.FileProcessors.translation import LANG, BUTTON
16
+
17
+ db = Database(Telegram.DATABASE_URL, Telegram.SESSION_NAME)
18
+
19
+
20
+ async def menu(bot, message):
21
+ await bot.send_message(
22
+ chat_id=message.from_user.id,
23
+ text="ꜱᴇʟᴇᴄᴛ ꜰʀᴏᴍ ᴍᴇɴᴜ",
24
+ reply_markup=ReplyKeyboardMarkup(
25
+ [[("ꜰɪʟᴇ ʙᴀɴᴋ"),("ꜱᴇᴀʀᴄʜ")], [("ᴍʏ ᴘʀɪᴠᴀᴛᴇ ꜱᴘᴀᴄᴇ"), ("ᴍʏ ᴘᴜʙʟɪᴄ ꜰɪʟᴇꜱ")]],
26
+ one_time_keyboard=False,
27
+ resize_keyboard=True,
28
+ placeholder="🄼🄰🄸🄽 🄼🄴🄽🅄 👉"))
29
+
30
+
31
+ @FileStream.on_message(filters.command('start') & filters.private)
32
+ @verify_users
33
+ async def start(bot: Client, message: Message, response):
34
+ if response['status'] == "AUTHORIZED":
35
+ usr_cmd = message.text.split("_")[-1]
36
+ if usr_cmd == "/start":
37
+ await bot.set_bot_commands([
38
+ BotCommand("start", "ꜱᴛᴀʀᴛ ᴛʜᴇ ʙᴏᴛ"),
39
+ BotCommand("help", "ʙᴏᴛ ꜱᴇᴛᴛɪɴɢꜱ"),
40
+ BotCommand("about", "ᴀʙᴏᴜᴛ ᴛʜᴇ ʙᴏᴛ"),
41
+ BotCommand("search", "ꜱᴇᴀʀᴄʜ ɪɴ ᴘᴜʙʟɪᴄ ꜰɪʟᴇꜱ"),
42
+ BotCommand("filebank", "ꜰɪʟᴇ ʙᴀɴᴋ"),
43
+ BotCommand("files", "ᴍʏ ᴘᴜʙʟɪᴄ ꜰɪʟᴇꜱ"),
44
+ BotCommand("myfiles", "ᴍʏ ᴘʀɪᴠᴀᴛᴇ ꜱᴘᴀᴄᴇ"),
45
+ ])
46
+ await menu(bot, message)
47
+ if Telegram.START_PIC:
48
+ await message.reply_photo(photo=Telegram.START_PIC,
49
+ caption=LANG.START_TEXT.format(
50
+ message.from_user.mention,
51
+ FileStream.username),
52
+ parse_mode=ParseMode.HTML,
53
+ reply_markup=BUTTON.START_BUTTONS)
54
+ else:
55
+ await message.reply_text(text=LANG.START_TEXT.format(
56
+ message.from_user.mention, FileStream.username),
57
+ parse_mode=ParseMode.HTML,
58
+ disable_web_page_preview=True,
59
+ reply_markup=BUTTON.START_BUTTONS)
60
+ else:
61
+ if "stream_" in message.text:
62
+ try:
63
+ file_check = await db.get_file(usr_cmd)
64
+ file_id = str(file_check['_id'])
65
+ if file_id == usr_cmd:
66
+ reply_markup, stream_text = await gen_linkx(
67
+ m=message,
68
+ _id=file_id,
69
+ name=[FileStream.username, FileStream.fname])
70
+ await message.reply_text(text=stream_text,
71
+ parse_mode=ParseMode.HTML,
72
+ disable_web_page_preview=True,
73
+ reply_markup=reply_markup,
74
+ quote=True)
75
+
76
+ except FIleNotFound as e:
77
+ await message.reply_text("File Not Found")
78
+ except Exception as e:
79
+ await message.reply_text("Something Went Wrong")
80
+ logging.error(e)
81
+
82
+ elif "file_" in message.text:
83
+ try:
84
+ file_check = await db.get_file(usr_cmd)
85
+ db_id = str(file_check['_id'])
86
+ file_id = file_check['file']['file_id']
87
+ file_name = file_check['file']['file_name']
88
+ if db_id == usr_cmd:
89
+ filex = await message.reply_cached_media(
90
+ file_id=file_id, caption=f'**{file_name}**')
91
+ await asyncio.sleep(3600)
92
+ try:
93
+ await filex.delete()
94
+ await message.delete()
95
+ except Exception:
96
+ pass
97
+
98
+ except FIleNotFound as e:
99
+ await message.reply_text("**File Not Found**")
100
+ except Exception as e:
101
+ await message.reply_text("Something Went Wrong")
102
+ logging.error(e)
103
+
104
+ else:
105
+ await message.reply_text(f"**Invalid Command**")
106
+
107
+
108
+ @FileStream.on_message(filters.private & filters.command(["about"]))
109
+ async def about_handler(bot, message):
110
+ if Telegram.START_PIC:
111
+ await message.reply_photo(photo=Telegram.START_PIC,
112
+ caption=LANG.ABOUT_TEXT.format(
113
+ FileStream.fname, __version__),
114
+ parse_mode=ParseMode.HTML,
115
+ reply_markup=BUTTON.ABOUT_BUTTONS)
116
+ else:
117
+ await message.reply_text(text=LANG.ABOUT_TEXT.format(
118
+ FileStream.fname, __version__),
119
+ disable_web_page_preview=True,
120
+ reply_markup=BUTTON.ABOUT_BUTTONS)
121
+
122
+
123
+ @FileStream.on_message((filters.command('help')) & filters.private)
124
+ async def help_handler(bot, message):
125
+ if Telegram.START_PIC:
126
+ await message.reply_photo(photo=Telegram.START_PIC,
127
+ caption=LANG.HELP_TEXT.format(Telegram.OWNER_ID),
128
+ parse_mode=ParseMode.HTML,
129
+ reply_markup=BUTTON.HELP_BUTTONS)
130
+ else:
131
+ await message.reply_text(text=LANG.HELP_TEXT.format(Telegram.OWNER_ID),
132
+ parse_mode=ParseMode.HTML,
133
+ disable_web_page_preview=True,
134
+ reply_markup=BUTTON.HELP_BUTTONS)
FileStream/config.py ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from os import environ as env
2
+ from dotenv import load_dotenv
3
+
4
+ load_dotenv()
5
+
6
+
7
+ class Telegram:
8
+ API_ID = int(env.get("API_ID"))
9
+ API_HASH = str(env.get("API_HASH"))
10
+ BOT_TOKEN = str(env.get("BOT_TOKEN"))
11
+ OWNER_ID = int(env.get('OWNER_ID', ''))
12
+ WORKERS = int(env.get("WORKERS", "6")) # 6 workers = 6 commands at once
13
+ DATABASE_URL = str(env.get('DATABASE_URL'))
14
+ UPDATES_CHANNEL = str(env.get('UPDATES_CHANNEL', "SparkyForum"))
15
+ SESSION_NAME = str(env.get('SESSION_NAME', 'FileStream'))
16
+ FORCE_SUB_ID = env.get('FORCE_SUB_ID', None)
17
+ FORCE_SUB = env.get('FORCE_UPDATES_CHANNEL', False)
18
+ FORCE_SUB = True if str(FORCE_SUB).lower() == "true" else False
19
+ SLEEP_THRESHOLD = int(env.get("SLEEP_THRESHOLD", "60"))
20
+ FILE_PIC = env.get(
21
+ 'FILE_PIC',
22
+ "https://graph.org/file/5bb9935be0229adf98b73.jpg")
23
+ START_PIC = env.get(
24
+ 'START_PIC',
25
+ "https://graph.org/file/290af25276fa34fa8f0aa.jpg")
26
+ VERIFY_PIC = env.get(
27
+ 'VERIFY_PIC',
28
+ "https://graph.org/file/736e21cc0efa4d8c2a0e4.jpg")
29
+ MULTI_CLIENT = False
30
+ FLOG_CHANNEL = int(env.get(
31
+ "FLOG_CHANNEL", None)) # Logs channel for file logs
32
+ PFLOG_CHANNEL = int(env.get("PFLOG_CHANNEL"))
33
+ ULOG_GROUP = int(env.get(
34
+ "ULOG_GROUP", None)) # Logs channel for user logs
35
+ MODE = env.get("MODE", "primary")
36
+ SECONDARY = True if MODE.lower() == "secondary" else False
37
+ AUTH_USERS = list(set(int(x)for x in str(env.get("AUTH_USERS", "")).split()))
38
+ DATA_SOURCES = [FLOG_CHANNEL, PFLOG_CHANNEL, ULOG_GROUP]
39
+
40
+ class TMDB:
41
+ API = str(env.get("TMDB_API", ""))
42
+
43
+ class Server:
44
+ PORT = int(env.get("PORT", 7860))
45
+ BIND_ADDRESS = str(env.get("BIND_ADDRESS", "0.0.0.0"))
46
+ PING_INTERVAL = int(env.get("PING_INTERVAL", "1200"))
47
+ HAS_SSL = str(env.get("HAS_SSL","0").lower()) in ("1", "true", "t","yes", "y")
48
+ NO_PORT = str(env.get("NO_PORT","0").lower()) in ("1", "true", "t","yes", "y")
49
+ FQDN = str(env.get("FQDN", BIND_ADDRESS))
50
+ URL = str(env.get("URL", "https://privateone-tele_api.hf.space/"))
FileStream/server/Functions/downloader.py ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import time
3
+ import math
4
+ import logging
5
+ import asyncio
6
+ import traceback
7
+ from aiohttp import web
8
+ from pyrogram import raw
9
+
10
+ from aiohttp.http_exceptions import BadStatusLine
11
+
12
+ #---------------------Local Upload---------------------#
13
+
14
+ from FileStream.config import Telegram
15
+ from FileStream import utils, StartTime, __version__
16
+ from FileStream.Tools import mime_identifier, Time_ISTKolNow
17
+ from FileStream.bot import multi_clients, work_loads, req_client, FileStream
18
+ from FileStream.server.exceptions import FIleNotFound, InvalidHash
19
+ from FileStream.server.render_template import render_page, render_upload
20
+ from FileStream.utils.FileProcessors.custom_ul import TeleUploader
21
+
22
+ class_cache={}
23
+
24
+
25
+ async def media_streamer(request: web.Request, db_id: str):
26
+ range_header = request.headers.get("Range", 0)
27
+
28
+ #index = min(work_loads, key=work_loads.get)
29
+ #faster_client = multi_clients[index]
30
+ client = await req_client()
31
+
32
+ if Telegram.MULTI_CLIENT:
33
+ logging.info(f"Client {client['index']} is now serving {request.headers.get('X-FORWARDED-FOR',request.remote)}")
34
+
35
+ if client['client'] in class_cache:
36
+ tg_connect = class_cache[client['client']]
37
+ logging.debug(f"Using cached ByteStreamer object for client {client['index']}")
38
+ else:
39
+ logging.debug(f"Creating new ByteStreamer object for client {client['index']}")
40
+ tg_connect = utils.ByteStreamer(client['client'])
41
+ class_cache[client['client']] = tg_connect
42
+ logging.debug("before calling get_file_properties")
43
+ file_id = await tg_connect.get_file_properties(db_id, multi_clients)
44
+ logging.debug("after calling get_file_properties")
45
+
46
+ file_size = file_id.file_size
47
+
48
+ if range_header:
49
+ from_bytes, until_bytes = range_header.replace("bytes=", "").split("-")
50
+ from_bytes = int(from_bytes)
51
+ until_bytes = int(until_bytes) if until_bytes else file_size - 1
52
+ else:
53
+ from_bytes = request.http_range.start or 0
54
+ until_bytes = (request.http_range.stop or file_size) - 1
55
+
56
+ if (until_bytes > file_size) or (from_bytes < 0) or (until_bytes
57
+ < from_bytes):
58
+ return web.Response(
59
+ status=416,
60
+ body="416: Range not satisfiable",
61
+ headers={"Content-Range": f"bytes */{file_size}"},
62
+ )
63
+
64
+ chunk_size = 512 * 1024
65
+ until_bytes = min(until_bytes, file_size - 1)
66
+
67
+ offset = from_bytes - (from_bytes % chunk_size)
68
+ first_part_cut = from_bytes - offset
69
+ last_part_cut = until_bytes % chunk_size + 1
70
+
71
+ req_length = until_bytes - from_bytes + 1
72
+ part_count = math.ceil(until_bytes / chunk_size) - math.floor(
73
+ offset / chunk_size)
74
+ body = tg_connect.yield_file(file_id, client['index'], offset, first_part_cut,
75
+ last_part_cut, part_count, chunk_size)
76
+
77
+ mime_type = file_id.mime_type
78
+ file_name = utils.get_name(file_id)
79
+ disposition = "attachment"
80
+
81
+ if not mime_type:
82
+ mime_type = mimetypes.guess_type(
83
+ file_name)[0] or "application/octet-stream"
84
+
85
+ # if "video/" in mime_type or "audio/" in mime_type:
86
+ # disposition = "inline"
87
+
88
+ return web.Response(
89
+ status=206 if range_header else 200,
90
+ body=body,
91
+ headers={
92
+ "Content-Type": f"{mime_type}",
93
+ "Content-Range": f"bytes {from_bytes}-{until_bytes}/{file_size}",
94
+ "Content-Length": str(req_length),
95
+ "Content-Disposition": f'{disposition}; filename="{file_name}"',
96
+ "Accept-Ranges": "bytes",
97
+ },
98
+ )
FileStream/server/__init__.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from aiohttp import web
2
+ from .routes_main import routes
3
+ from .routes_api import api
4
+ from .routes_app import sub_app
5
+
6
+
7
+ async def root_route_handler(request):
8
+ return web.json_response({"status": "alive", "message": "Server is running"})
9
+
10
+
11
+
12
+ def web_server():
13
+ web_app = web.Application(client_max_size=500)
14
+ web_app.router.add_get('/', root_route_handler)
15
+ web_app.add_routes(routes)
16
+ web_app.add_subapp('/app', sub_app)
17
+ web_app.add_subapp('/api', api)
18
+ return web_app
19
+
FileStream/server/exceptions.py ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ class InvalidHash(Exception):
2
+ message = "Invalid hash"
3
+
4
+ class FIleNotFound(Exception):
5
+ message = "File not found"
FileStream/server/render_template.py ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import aiohttp
2
+ import jinja2
3
+ import urllib.parse
4
+ from FileStream.config import Telegram, Server
5
+ from FileStream.Database import Database
6
+ from FileStream.Tools.file import humanbytes
7
+
8
+ db = Database(Telegram.DATABASE_URL, Telegram.SESSION_NAME)
9
+
10
+
11
+ async def render_page(db_id):
12
+ file_data = await db.get_file(db_id)
13
+ src = urllib.parse.urljoin(Server.URL, f'api/dl/{file_data["_id"]}')
14
+ file_size = humanbytes(file_data['file']['file_size'])
15
+ file_name = file_data['file']['file_name'].replace("_", " ")
16
+
17
+ if str((file_data['file']['mime_type']).split('/')[0].strip()) == 'video':
18
+ template_file = "FileStream/server/template/play.html"
19
+ else:
20
+ template_file = "FileStream/server/template/dl.html"
21
+ async with aiohttp.ClientSession() as s:
22
+ async with s.get(src) as u:
23
+ file_size = humanbytes(int(u.headers.get('Content-Length')))
24
+
25
+ with open(template_file) as f:
26
+ template = jinja2.Template(f.read())
27
+
28
+ return template.render(file_name=file_name,
29
+ file_url=src,
30
+ file_size=file_size)
31
+
32
+
33
+ async def render_upload():
34
+
35
+ template_file = "FileStream/server/template/upload.html"
36
+
37
+ with open(template_file) as f:
38
+ template = jinja2.Template(f.read())
39
+
40
+ return template.render()
FileStream/server/routes_api.py ADDED
@@ -0,0 +1,179 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+
3
+ import json
4
+ import time
5
+ import math
6
+ import logging
7
+ import asyncio
8
+ import traceback
9
+ from aiohttp import web
10
+ from pyrogram import raw
11
+ from bson import ObjectId
12
+ from bson.json_util import dumps
13
+ from aiohttp.http_exceptions import BadStatusLine
14
+
15
+ from FileStream.bot import req_client
16
+ from FileStream.config import Telegram,Server
17
+ from FileStream.Database import Database
18
+ from FileStream.TMDB.Endpoint import search_tmdb
19
+ from FileStream.server.exceptions import FIleNotFound, InvalidHash
20
+
21
+ from .Functions.downloader import media_streamer
22
+
23
+ async def handle_v2(request):
24
+ return web.Response(text="Hello from app api!")
25
+
26
+ async def list_all_files_db(request):
27
+ db = Database(Telegram.DATABASE_URL, Telegram.SESSION_NAME)
28
+ files= await db.get_all_files_api()
29
+ #print(files, type(files))
30
+ return web.json_response(json.loads(dumps(files)))
31
+
32
+
33
+ #api.router.add_get('/tmdb/list', list_all_files_tmdb)
34
+ async def list_all_files_tmdb(request):
35
+ db = Database(Telegram.DATABASE_URL, Telegram.SESSION_NAME)
36
+ files= await db.get_all_files()
37
+ #print(files)
38
+ response=[]
39
+ async for row in files:
40
+ print(row['file']['caption'])
41
+ try :
42
+ print("* Response",search_tmdb(row['file']['caption'] if row['file']['caption'] else row['file']['file_name']))
43
+ resp = search_tmdb( str(row['file']['caption']) if str(row['file']['caption']) else str(row['file']['file_name']))
44
+ if resp != None :
45
+ #resp= dict(resp)
46
+ print("TMDB Response :",resp)
47
+ response.append(resp)
48
+ else:
49
+ continue
50
+ except Exception as e:
51
+ print("Error ",e)
52
+ break
53
+
54
+ #print(response)
55
+ # Convert Python data to JSON
56
+ #json_response = json.dumps(response).encode('utf-8')
57
+ # Return as aiohttp response using web.json_response
58
+ #return web.json_response(response)
59
+ return web.json_response(json.loads(dumps(response)))
60
+
61
+ #api.router.add_get('/tmdb/files', list_all_files)
62
+ async def list_all_files(request):
63
+ db = Database(Telegram.DATABASE_URL, Telegram.SESSION_NAME)
64
+ files=await db.get_all_files_api()
65
+ #print(files[0])
66
+ """{"_id":
67
+ {"$oid":"664b9bee136af99d40f36ac4"},
68
+ "user_id":"780583126",
69
+ "user_type":"TELEGRAM",
70
+ "message_id":{"$numberInt":"230"},
71
+ "location":{"$numberLong":"-1001713565158"},
72
+ "file":{
73
+ "file_id":"BAACAgIAAx0EZiLt5gAD5mZLm_BFwLE0BtOz3x74uJVDMPyKAAIISAACVyEJSugUJlXYybnGHgQ",
74
+ "caption":"Godzilla x Kong: The New Empire (2024)IMDB 6.5/10..Audio - Hindi + English",
75
+ "file_unique_id":"AgADCEgAAlchCUo",
76
+ "file_name":"[Tg- @New_Movies_OnTG] Godzilla x Kong: The New Empire (2024.mkv",
77
+ "file_size":{"$numberInt":"1191876267"},
78
+ "mime_type":"video/x-matroska",
79
+ "tagged_users":{"780583126":"PUBLIC","908083534":"PUBLIC"}},
80
+ "time":"Tue May 21 00:22:28 2024",
81
+ "privacy_type":"PUBLIC",
82
+ "file_ids":{"7143040931":"BAACAgIAAx0CZiLt5gAD5mZLm_JkEd4FIhfPJMNx4yrn_ku2AAIISAACVyEJStMWKGOMGmA8HgQ","7137723582":"BAACAgIAAx0CZiLt5gAD5mZLm_L1n-OtIh2xs9VTfPg9ng-jAAIISAACVyEJSgwG7RQMGjI4HgQ","7186717764":"BAACAgIAAx0CZiLt5gAD5mZLm_LHCB1_h5anoEEStvf4l_fyAAIISAACVyEJSpNn5Oa7x8LDHgQ","6589995279":"BAACAgIAAx0CZiLt5gAD5mZLm_JkQEwGvFwxwQXtfMk9FrBYAAIISAACVyEJSovis_Nx3os5HgQ","6539834495":"BAACAgIAAx0CZiLt5gAD5mZblPC_hDA4ZXq9Uw2NiHhRZakvAAIISAACVyEJSk4a1yBMKm1jHgQ","7142960273":"BAACAgIAAx0CZiLt5gAD5mZblU_WJD3j98Z_fwS4zkhZU16WAAIISAACVyEJStP84jRi0R9YHgQ"}}
83
+ """
84
+ resp=[{
85
+ "adult": False,
86
+ "backdrop_path": "/c1bz69r0v065TGFA5nqBiKzPDys.jpg",
87
+ "genre_ids": [
88
+ 35,
89
+ 10751,
90
+ 10402
91
+ ],
92
+ "id": f"{row['_id']}",
93
+ "original_language": "en-hi",
94
+ "original_title": f"{str(row['file']['caption'])}",
95
+ "overview": "XRepo Movies",
96
+ "popularity": 1710.176,
97
+ "poster_path": "/irIS5Tn3TXjNi1R9BpWvGAN4CZ1.jpg",
98
+ "release_date": "2022-10-07",
99
+ "title": f"{str(row['file']['caption'])}",
100
+ "link": f"{Server.URL}api/dl/{row['_id']}",
101
+ "vote_average": 7.8,
102
+ "vote_count": 122,
103
+ }
104
+ for row in files]
105
+ return web.json_response(json.loads(dumps(resp)))
106
+
107
+ #----------------------------------------Upload----------------------------------------------#
108
+ #@routes.post("/upload")
109
+ async def upload_file(request: web.Request):
110
+
111
+ data = await request.post()
112
+ file = data.get('file').file
113
+ chunk = file.read()
114
+ """
115
+ user_id :
116
+ file_id :"BAACAgUAAxkBAAJBHGYI_aJSvyL_ijKwrVHQVzFgC1YZAAItDQACOnNAVMIpWwl6b63EHg…"
117
+ file_unique_id :"AgADLQ0AAjpzQFQ"
118
+ file_name :"Dadur_Kirti_S01_COMBINED_720p_HOICHOI_WEB_DL_Bengali@COOL_MOVIES.mp4"
119
+ file_size : 1354816011
120
+ mime_type : "video/mp4"
121
+ time : 1711865251.1016757
122
+ user_type: "TELEGRAM"/"WEB"
123
+ privacy_type: "PUBLIC"/"PRIVATE"
124
+ file_ids :
125
+ """
126
+ file_details = dict(user_id="thebinary1",
127
+ dropzone_id=str(data["dzuuid"]),
128
+ file=dict(file_id=str(data["dzuuid"]),
129
+ file_unique_id=str(data["dzuuid"]),
130
+ file_name=str(data.get('file').filename),
131
+ file_size=int(data["dztotalfilesize"]),
132
+ mime_type=mime_identifier(str(data.get('file').filename)),
133
+ part_size=int(data["dzchunksize"]),
134
+ file_part=int(data["dzchunkindex"]),
135
+ total_parts=int(data["dztotalchunkcount"])),
136
+ time=Time_ISTKolNow(),
137
+ user_type="WEB",
138
+ privacy_type="PRIVATE")
139
+
140
+ print(file_details) if (file_details["file"]["file_part"] == 0) else None
141
+ client_req = await req_client()
142
+ #faster_client = client_req["client"]
143
+ #index = client_req["index"]
144
+ print("using :", client_req["index"])
145
+ tg_connect = TeleUploader(client_req["client"])
146
+ main = await tg_connect.upload_web_file(file_details, chunk)
147
+ #print("Response:", main)
148
+ return web.json_response({
149
+ "status": main.get("status"),
150
+ "message": main.get("message")
151
+ })
152
+
153
+
154
+ #-------------Routes to Downloada File Witha Path-----------------#
155
+ #@routes.get("/dl/{path}", allow_head=True)
156
+ async def stream_handler(request: web.Request):
157
+ try:
158
+ path = request.match_info["path"]
159
+ return await media_streamer(request, path)
160
+ except InvalidHash as e:
161
+ raise web.HTTPForbidden(text=e.message)
162
+ except FIleNotFound as e:
163
+ raise web.HTTPNotFound(text=e.message)
164
+ except (AttributeError, BadStatusLine, ConnectionResetError):
165
+ pass
166
+ except Exception as e:
167
+ traceback.print_exc()
168
+ logging.critical(e.with_traceback(None))
169
+ logging.debug(traceback.format_exc())
170
+ raise web.HTTPInternalServerError(text=str(e))
171
+
172
+
173
+ api = web.Application()
174
+ api.router.add_get('/', handle_v2)
175
+ api.router.add_get('/files', list_all_files_db)
176
+ api.router.add_get('/tmdb/files', list_all_files)
177
+ api.router.add_get('/tmdb/list', list_all_files_tmdb)
178
+ api.router.add_get('/upload', upload_file)
179
+ api.router.add_get('/dl/{path}', stream_handler)
FileStream/server/routes_app.py ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from aiohttp import web
2
+ from aiohttp.http_exceptions import BadStatusLine
3
+
4
+ from .Functions.downloader import media_streamer
5
+ from FileStream.server.exceptions import FIleNotFound, InvalidHash
6
+ from FileStream.server.render_template import render_page, render_upload
7
+
8
+
9
+ async def handle_v2(request):
10
+ return web.Response(text="Hello from app v2!")
11
+
12
+
13
+ #@sub_app.get("/watch/{path}", allow_head=True)
14
+ async def stream_handler(request: web.Request):
15
+ try:
16
+ path = request.match_info["path"]
17
+ return web.Response(text=await render_page(path), content_type='text/html')
18
+ except InvalidHash as e:
19
+ raise web.HTTPForbidden(text=e.message)
20
+ except FIleNotFound as e:
21
+ raise web.HTTPNotFound(text=e.message)
22
+ except (AttributeError, BadStatusLine, ConnectionResetError):
23
+ pass
24
+
25
+ #@sub_app.get("/up", allow_head=True)
26
+ async def upload_handler(request: web.Request):
27
+ # global faster_client,index,session, new_file_id
28
+ await asyncio.gather(*tasks)
29
+ try:
30
+ return web.Response(text=await render_upload(), content_type='text/html')
31
+ except InvalidHash as e:
32
+ raise web.HTTPForbidden(text=e.message)
33
+ except FIleNotFound as e:
34
+ raise web.HTTPNotFound(text=e.message)
35
+ except (AttributeError, BadStatusLine, ConnectionResetError):
36
+ pass
37
+
38
+ sub_app = web.Application()
39
+ sub_app.router.add_get('/', handle_v2)
40
+ sub_app.router.add_get('/watch/{path}', stream_handler)
41
+ sub_app.router.add_get('/up', upload_handler)
FileStream/server/routes_main.py ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import time
2
+ import math
3
+ import logging
4
+ import asyncio
5
+ import traceback
6
+ from aiohttp import web
7
+ from pyrogram import raw
8
+
9
+ from aiohttp.http_exceptions import BadStatusLine
10
+
11
+ #---------------------Local Upload---------------------#
12
+ from FileStream.config import Telegram
13
+ from FileStream.bot import multi_clients, work_loads, FileStream
14
+ from FileStream.server.exceptions import FIleNotFound, InvalidHash
15
+ from FileStream import utils, StartTime, __version__
16
+ from FileStream.utils.FileProcessors.custom_ul import TeleUploader
17
+ from FileStream.Tools import mime_identifier, Time_ISTKolNow
18
+ from FileStream.server.render_template import render_page, render_upload
19
+
20
+ tasks = []
21
+ routes = web.RouteTableDef()
22
+
23
+ @routes.get("/status", allow_head=True)
24
+ async def root_status_handler(_):
25
+ return web.json_response({
26
+ "server_status":"running",
27
+ "uptime": utils.get_readable_time(time.time() - StartTime),
28
+ "telegram_bot": "@" + FileStream.username,
29
+ "connected_bots": len(multi_clients),
30
+ "loads":dict(("bot" + str(c + 1), l) for c, (_, l) in enumerate(sorted(work_loads.items(), key=lambda x: x[1], reverse=True))),
31
+ "version": __version__,
32
+ })
33
+
34
+
FileStream/server/template/dl.html ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta property="og:image" content="https://www.flaticon.com/premium-icon/icons/svg/2626/2626281.svg" itemprop="thumbnailUrl">
6
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
7
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
8
+ <title>{{file_name}}</title>
9
+ <link rel="stylesheet" type='text/css' href="https://drive.google.com/uc?export=view&id=1pVLG4gZy7jdow3sO-wFS06aP_A9QX0O6">
10
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Raleway">
11
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Delius">
12
+ </head>
13
+
14
+ <body class='cyber'>
15
+ <header>
16
+ <div class="toogle"></div>
17
+ <div id="file-name" class="cyber">
18
+ {{file_name}}
19
+ </div>
20
+ </header>
21
+
22
+ <div class="container">
23
+ <a href="{{file_url}}">
24
+ <button class="cybr-btn">
25
+ Download
26
+ <span aria-hidden>_</span>
27
+ <span aria-hidden class="cybr-btn__glitch">_404 Error</span>
28
+ <span aria-hidden class="cybr-btn__tag">_%s</span>
29
+ </button>
30
+ </a>
31
+ </div>
32
+ <script>
33
+ const body = document.querySelector('body');
34
+ const title = document.querySelector('#file-name');
35
+ const footer = document.querySelector('footer');
36
+ const toogle = document.querySelector('.toogle');
37
+ toogle.onclick = () => {
38
+ body.classList.toggle('dark')
39
+ footer.classList.toggle('dark')
40
+ title.classList.toggle('dark')
41
+ }
42
+ </script>
43
+ </body>
44
+ </html>
FileStream/server/template/owner.js ADDED
@@ -0,0 +1,317 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ async function getDets() {
2
+ let randPage = Math.floor(1 + Math.random() * 100)
3
+ const apiKey = '6abcb6bb99fb77f33c37016a28866ed2';
4
+ let apiArr = [`https://api.themoviedb.org/3/movie/popular?api_key=${apiKey}&language=hin-US&page=${randPage}`, `https://api.themoviedb.org/3/trending/movie/day?api_key=${apiKey}&language=hin-US&page=${randPage}`, `https://api.themoviedb.org/3/movie/now_playing?api_key=${apiKey}&language=hin-US&page=${randPage}`]
5
+ let ArrRanIndex = Math.floor(Math.random() * apiArr.length)
6
+ let apiUrl = apiArr[ArrRanIndex]
7
+ let movieCont = document.querySelector('.movieSug')
8
+ let img = document.querySelector('.movieimg img')
9
+ let movieDets = document.querySelector('.movieDets')
10
+ let movieDetsMini = document.querySelector('.movieDets-mini')
11
+ let data = await fetch(apiUrl)
12
+ let resData = await data.json()
13
+ let ranIndex = Math.floor(Math.random() * resData.results.length)
14
+ let movie = resData.results[ranIndex]
15
+ movieDets.innerHTML = `
16
+ <h3>Must-see blockbuster film!</h3>
17
+ <h4><span>Title:</span> ${movie.title}</h4>
18
+ <h4><span>movie overview:</span> ${movie.overview}</h4>
19
+ <h4><span>Release Date:</span> ${movie.release_date}</h4>
20
+ <h4><span>Rating:</span> ${movie.vote_average.toFixed(1)} / 10</h4>
21
+ `
22
+ movieDetsMini.innerHTML = `
23
+ <h3><span>Title:</span> ${movie.title}</h3>
24
+ <h3><span>Release Date:</span> ${movie.release_date}</h3>
25
+ <h3><span>Rating:</span> ${movie.vote_average.toFixed(1)} / 10</h3>
26
+ `
27
+ img.src = `https://image.tmdb.org/t/p/w1280/${movie.poster_path}`
28
+ movieCont.style.backgroundImage = `url(https://image.tmdb.org/t/p/w1280/${movie.backdrop_path})`;
29
+ }
30
+ window.addEventListener("load", getDets())
31
+
32
+
33
+
34
+ let homeBtn = document.querySelector(".home-btn")
35
+ let abtBtn = document.querySelector(".about-btn")
36
+ let dldBtn_outer = document.querySelector(".downloadBtn")
37
+ let file_name = document.querySelector(".file-name")
38
+ let about_nav = document.querySelector(".about-nav")
39
+ let contact_btn = document.querySelector('.contact-btn')
40
+ let links = document.querySelectorAll('.links a')
41
+ let chnl_link = document.querySelectorAll('.chnl-link a')
42
+ let abt_chnl = document.querySelector('.abt-chnl')
43
+ let contact = document.querySelectorAll('.contact a')
44
+ let footer = document.querySelector('footer')
45
+
46
+ let timer = 0
47
+
48
+ if (document.getElementById("heading").classList.contains("title")) {
49
+ document.querySelector(".title").textContent = 'FILE STREAM'
50
+ }
51
+
52
+ // adding under in home btn at first
53
+ homeBtn.classList.add('active');
54
+
55
+ // when clicking about
56
+ abtBtn.addEventListener("click", () => {
57
+ dldBtn_outer.style.display = "none";
58
+ file_name.style.display = "none";
59
+ footer.style.display = "none";
60
+ about_nav.style.display = "block"
61
+ about_nav.style.display = "block"
62
+ about_nav.style.animation = "strtLoad 1s ease 0s forwards"
63
+
64
+ })
65
+ // when clicking home
66
+ homeBtn.addEventListener("click", () => {
67
+ dldBtn_outer.style.display = "flex";
68
+ file_name.style.display = "block";
69
+ footer.style.display = "block";
70
+ window.location.href = "#main";
71
+ about_nav.style.animation = "strtLoad 1s ease 0s forwards"
72
+ about_nav.style.display = "none"
73
+
74
+ })
75
+
76
+ abt_chnl.addEventListener("click", () => {
77
+ timer = 1
78
+ chnl_link.forEach((i) => {
79
+ i.style.animation = `strtLoad 1s ease ${timer}s forwards, linksBtnAn 2s ease ${timer}s infinite `
80
+ timer += 0.3;
81
+ });
82
+ timer = 0
83
+ });
84
+ function bot_btn_clicked() {
85
+ var about_btn = document.querySelector(".about-btn")
86
+ timer = 1;
87
+ bot_links.forEach((i) => {
88
+ i.style.animation = `linksBtnAn 2s ease ${timer}s infinite ,strtLoad 1s ease ${timer}s forwards`;
89
+ timer += 0.3;
90
+ });
91
+ timer = 0;
92
+ dldBtn_outer.style.display = "none";
93
+ file_name.style.display = "none";
94
+ footer.style.display = "none";
95
+ about_nav.style.display = "block"
96
+ about_nav.style.display = "block"
97
+ about_nav.style.animation = "strtLoad 1s ease 0s forwards"
98
+ var links = document.querySelectorAll('.nryt a');
99
+ links.forEach(function (link) {
100
+ link.classList.remove('active');
101
+ });
102
+ about_btn.classList.add('active');
103
+ var links = document.querySelectorAll('.about-nav a');
104
+ links.forEach(function (link) {
105
+ link.classList.remove('active');
106
+ });
107
+ let wlcm = document.querySelector(".wlcm")
108
+ wlcm.classList.add('active');
109
+ var links = document.querySelectorAll('.about-nav a');
110
+ links.forEach(function (link) {
111
+ link.classList.remove('active');
112
+ });
113
+ bot_btn.classList.add('active');
114
+ };
115
+ footer_btn_clicked = () => {
116
+ timer = 1;
117
+ contact.forEach((i) => {
118
+ i.style.animation = `linksBtnAn 2s ease ${timer}s infinite ,strtLoad 1s ease ${timer}s forwards`;
119
+ timer += 0.3;
120
+ });
121
+
122
+ timer = 0;
123
+ var about_btn = document.querySelector(".about-btn")
124
+ timer = 1;
125
+ bot_links.forEach((i) => {
126
+ i.style.animation = `linksBtnAn 2s ease ${timer}s infinite ,strtLoad 1s ease ${timer}s forwards`;
127
+ timer += 0.3;
128
+ });
129
+ timer = 0;
130
+ dldBtn_outer.style.display = "none";
131
+ file_name.style.display = "none";
132
+ footer.style.display = "none";
133
+ about_nav.style.display = "block"
134
+ about_nav.style.display = "block"
135
+ about_nav.style.animation = "strtLoad 1s ease 0s forwards"
136
+ var links = document.querySelectorAll('.nryt a');
137
+ links.forEach(function (link) {
138
+ link.classList.remove('active');
139
+ });
140
+ about_btn.classList.add('active');
141
+ var links = document.querySelectorAll('.about-nav a');
142
+ links.forEach(function (link) {
143
+ link.classList.remove('active');
144
+ });
145
+ let wlcm = document.querySelector(".wlcm")
146
+ wlcm.classList.add('active');
147
+ var links = document.querySelectorAll('.about-nav a');
148
+ links.forEach(function (link) {
149
+ link.classList.remove('active');
150
+ });
151
+ contact_btn.classList.add('active');
152
+ }
153
+
154
+ contact_btn.addEventListener("click", () => {
155
+ timer = 1;
156
+ contact.forEach((i) => {
157
+ i.style.animation = `linksBtnAn 2s ease ${timer}s infinite ,strtLoad 1s ease ${timer}s forwards`;
158
+ timer += 0.3;
159
+ });
160
+
161
+ timer = 0;
162
+ })
163
+
164
+ // btn animations
165
+ let dldBtn = document.querySelectorAll('.downloadBtn button')
166
+ dldBtn.forEach((i) => {
167
+ i.style.animation = `strtLoad 1s ease ${timer}s forwards, linksBtnAn 2s ease ${timer}s infinite`
168
+ timer += 0.3;
169
+ i.style.setProperty("--beforestyl", `button_shine ${2 + Math.random() * 7}s ease ${Math.random() * 10}s infinite`);
170
+
171
+ })
172
+
173
+ timer = 0
174
+ links.forEach((i) => {
175
+ i.style.animation = `linksBtnAn 2s ease ${timer}s infinite`
176
+ timer += 0.3
177
+ i.style.setProperty("--beforestyl", `button_shine ${2 + Math.random() * 7}s ease ${Math.random() * 10}s infinite`);
178
+
179
+ })
180
+ timer = 0
181
+ timer = 0
182
+
183
+ function toggleWidth(element) {
184
+ var links = document.querySelectorAll('.about-nav a');
185
+ links.forEach(function (link) {
186
+ link.classList.remove('active');
187
+ });
188
+
189
+ element.classList.add('active');
190
+ }
191
+ function toggleWidthnav(element) {
192
+ var links = document.querySelectorAll('.nryt a');
193
+ links.forEach(function (link) {
194
+ link.classList.remove('active');
195
+ });
196
+
197
+ element.classList.add('active');
198
+ var links = document.querySelectorAll('.about-nav a');
199
+ links.forEach(function (link) {
200
+ link.classList.remove('active');
201
+ });
202
+ let wlcm = document.querySelector(".wlcm")
203
+ wlcm.classList.add('active');
204
+ }
205
+
206
+ if (!(/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent))) {
207
+ Shery.mouseFollower();
208
+ Shery.makeMagnet(".magnet");
209
+ }
210
+
211
+
212
+ // file name showing
213
+ var div = document.getElementById('myDiv');
214
+ var text = div.textContent;
215
+ if (text.length > 300) {
216
+ div.textContent = text.slice(0, 300) + "....";
217
+ }
218
+
219
+ // video player
220
+ const controls = [
221
+ 'play-large',
222
+ 'rewind', 'play',
223
+ 'fast-forward',
224
+ 'progress',
225
+ 'current-time',
226
+ 'duration',
227
+ //'mute',
228
+ //'volume',
229
+ 'captions',
230
+ 'settings',
231
+ 'pip',
232
+ 'airplay',
233
+ // 'download',
234
+ 'fullscreen'
235
+ ];
236
+ document.addEventListener('DOMContentLoaded', () => {
237
+ const player = Plyr.setup('.player', { controls });
238
+ });
239
+
240
+ // disabling right click
241
+ document.addEventListener("contextmenu", function (e) {
242
+ e.preventDefault();
243
+ });
244
+ document.addEventListener('keydown', function (e) {
245
+ if (
246
+ e.key === 'F12' ||
247
+ (e.ctrlKey && e.shiftKey && e.key === 'I') ||
248
+ (e.ctrlKey && e.key === 'u') ||
249
+ e.ctrlKey ||
250
+ e.shiftKey ||
251
+ e.altKey
252
+ ) {
253
+ e.preventDefault();
254
+ }
255
+ });
256
+
257
+
258
+ const videolink = window.location.href;
259
+ const streamlink = videolink.replace("/watch/", "/dl/");
260
+
261
+ function vlc_player() {
262
+ const openstreamlink = streamlink;
263
+ const openVlc = `vlc://${openstreamlink}`;
264
+ window.location.href = openVlc;
265
+ }
266
+
267
+ function mx_player() {
268
+ const openstreamlink = streamlink;
269
+ const openMx = `intent:${openstreamlink}#Intent;package=com.mxtech.videoplayer.ad;end`;
270
+ window.location.href = openMx;
271
+ }
272
+
273
+ function n_player() {
274
+ const openstreamlink = streamlink;
275
+ const openNplayer = `nplayer-${openstreamlink}`;
276
+ window.location.href = openNplayer;
277
+ }
278
+
279
+ function streamDownload() {
280
+ const openstreamlink = streamlink;
281
+ window.location.href = openstreamlink;
282
+ }
283
+
284
+ function copyStreamLink() {
285
+ const linkToCopy = streamlink.toLowerCase();
286
+
287
+ if (!navigator.clipboard) {
288
+ navigator.clipboard = {
289
+ writeText: function(text) {
290
+ return new Promise((resolve, reject) => {
291
+ try {
292
+ const textArea = document.createElement("textarea");
293
+ textArea.value = text;
294
+ document.body.appendChild(textArea);
295
+ textArea.focus();
296
+ textArea.select();
297
+ document.execCommand('copy');
298
+ document.body.removeChild(textArea);
299
+ resolve();
300
+ } catch (err) {
301
+ reject(err);
302
+ }
303
+ });
304
+ }
305
+ };
306
+ }
307
+
308
+ navigator.clipboard.writeText(linkToCopy)
309
+ .then(() => {
310
+ console.log('Stream link copied to clipboard!');
311
+ alert('Stream link copied successfully!');
312
+ })
313
+ .catch(err => {
314
+ console.error('Failed to copy link: ', err);
315
+ alert('Failed to copy link. Please try manually.');
316
+ });
317
+ }
FileStream/server/template/play.html ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>FileStreamBot | {{file_name}}</title>
8
+ <link rel="icon" href="https://i.ibb.co/Hh4kF2b/icon.png" type="image/x-icon">
9
+ <link rel="shortcut icon" href="https://i.ibb.co/Hh4kF2b/icon.png" type="image/x-icon">
10
+ <link rel="stylesheet" href="https://unpkg.com/sheryjs/dist/Shery.css" />
11
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/proavipatil/data@main/fs/src/style.css">
12
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/proavipatil/data@main/fs/src/plyr.css">
13
+ <link rel="preconnect" href="https://fonts.googleapis.com">
14
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
15
+ <link href="https://fonts.googleapis.com/css2?family=Josefin+Sans:wght@500;700&display=swap" rel="stylesheet">
16
+ <script src="https://cdn.tailwindcss.com"></script>
17
+
18
+ </head>
19
+
20
+ <body>
21
+ <nav>
22
+ <div class="nleft">
23
+ <a href="#">
24
+ <h3 id="heading" style="z-index: 100;" class="magnet title">FILE STREAM</h3>
25
+ </a>
26
+ </div>
27
+ <div class="nryt">
28
+ <a class="home-btn magnet" href="#main" onclick="toggleWidthnav(this)">HOME</a>
29
+
30
+ <a href="#abtus" class="about-btn magnet" onclick="toggleWidthnav(this)">ABOUT</a>
31
+ </div>
32
+ </nav>
33
+ <center>
34
+ <div class="about-nav">
35
+ <a href="#abtus" class="wlcm magnet" onclick="toggleWidth(this)">WELCOME</a>
36
+ <a href="#channels" class="abt-chnl magnet" onclick="toggleWidth(this)">CHANNELS</a>
37
+ <a href="#contact" class="magnet contact-btn" onclick="toggleWidth(this)">CONTACT</a>
38
+ </div>
39
+ </center>
40
+
41
+ <div class="outer">
42
+ <div class="inner">
43
+ <div class="main" id="main">
44
+ <video id="player" class="player" src="{{file_url}}" type="video/mp4" playsinline controls
45
+ width="100%"></video>
46
+ <div class="player"></div>
47
+ <div class="file-name">
48
+ <h4 style="display: inline;">File Name: </h4>
49
+ <p style="display: inline;" id="myDiv">{{file_name}}</p><br>
50
+ <h4 style="display: inline;">File Size: </h4>
51
+ <p style="display: inline;">{{file_size}}</p>
52
+ </div>
53
+ <div class="downloadBtn">
54
+ <button class="magnet" onclick="streamDownload()">
55
+ <img style="height: 30px;" src="https://i.ibb.co/RjzYttX/dl.png" alt="">download video
56
+ </button>
57
+ <button class="magnet" onclick="copyStreamLink()">
58
+ <img src="https://i.ibb.co/CM4Y586/link.png" alt="Copy Link">copy link
59
+ </button>
60
+ <button class="magnet" onclick="vlc_player()">
61
+ <img src="https://i.ibb.co/px6fQs1/vlc.png" alt="">watch in VLC PLAYER
62
+ </button>
63
+ <button class="magnet" onclick="mx_player()">
64
+ <img src="https://i.ibb.co/41WvtQ3/mx.png" alt="">watch in MX PLAYER
65
+ </button>
66
+ <button class="magnet" onclick="n_player()">
67
+ <img src="https://i.ibb.co/Hd2dS4t/nPlayer.png" alt="">watch in nPlayer
68
+ </button>
69
+ </div>
70
+
71
+ </div>
72
+ <div class="abt">
73
+ <div class="about">
74
+ <div class="about-dets">
75
+
76
+ <div class="abt-sec" id="abtus" style="padding: 160px 30px;">
77
+ <h1 style="text-align: center;">WELCOME TO OUR <Span>FILE STREAM</Span> BOT</h1>
78
+ <p style="text-align: center; line-height: 2;word-spacing: 2px; letter-spacing: 0.8px;">
79
+ This is a Telegram Bot to Stream <span>Movies</span> and <span>Series</span> directly on
80
+ Telegram. You can also
81
+ <span>download</span> them if you want. This bot is developed by <a
82
+ href="https://github.com/AviPatilPro"><span style="font-weight: 700;">Avi</span></a>
83
+ <br><br>If you like this bot, then don't
84
+ forget to share it with your friends and family.
85
+ </p>
86
+ </div>
87
+
88
+ <div class="abt-sec" id="channels">
89
+ <h1>JOIN OUR <span>TELEGRAM</span> CHANNELS</h1>
90
+ <div class="links chnl-link">
91
+ <a class="magnet" href="https://t.me/CheapieDeals">
92
+ <button>CHEAP DEALS</button>
93
+ </a>
94
+ <a class="magnet" href="https://t.me/FilmyPixel">
95
+ <button>FILMYPIXEL</button>
96
+ </a>
97
+ <a class="magnet" href="https://t.me/PostersZone">
98
+ <button>POSTERS ZONE</button>
99
+ </a>
100
+ <a class="magnet" href="https://t.me/EpitomeQuality">
101
+ <button>EPITOME QUALITY</button>
102
+ </a>
103
+ </div>
104
+ </div>
105
+
106
+ <div class="abt-sec" id="contact">
107
+ <p style="text-align: center;">Report Bugs and Contact us on Telegram Below</p>
108
+ <div class="links contact">
109
+ <a href="https://t.me/AvishkarPatil">
110
+ <button>CONTACT</button>
111
+ </a>
112
+ </div>
113
+ </div>
114
+
115
+ </div>
116
+ </div>
117
+ </div>
118
+ </div>
119
+ <footer>
120
+ <center>
121
+
122
+ <div class="movie-cont">
123
+ <div class="movieSug">
124
+ <div class="movieDets">
125
+
126
+ </div>
127
+ <div class="movieimg">
128
+ <img src="">
129
+ </div>
130
+ </div>
131
+ <div class="low-width-movie-dets">
132
+ <div class="movieStsBar">
133
+ <div class="movieDets-mini">
134
+
135
+ </div>
136
+ </div>
137
+ </div>
138
+ <button class="ranMovBtn" onclick="getDets()">Get More Movies Suggestion</button>
139
+ </div>
140
+
141
+ </center>
142
+
143
+ <center>
144
+ <div class="copyright">
145
+ <h5 class="text-center">Copyright © 2024 <a href="https://github.com/AviPatilPro"><span
146
+ style="font-weight: 700;">Avishkar Patil</span></a>. All
147
+ Rights Reserved.</h5>
148
+ </div>
149
+ </center>
150
+ </footer>
151
+ </div>
152
+ </body>
153
+
154
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
155
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/ScrollTrigger.min.js"></script>
156
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/0.155.0/three.min.js"></script>
157
+ <script src="https://cdn.jsdelivr.net/gh/automat/controlkit.js@master/bin/controlKit.min.js"></script>
158
+ <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/sheryjs/dist/Shery.js"></script>
159
+ <script>
160
+ document.addEventListener("DOMContentLoaded", function () {
161
+ const uncopyableElement = document.querySelector(".uncopyable");
162
+
163
+ uncopyableElement.addEventListener("selectstart", function (event) {
164
+ event.preventDefault();
165
+ });
166
+ });
167
+ </script>
168
+ <script src="https://cdn.plyr.io/3.6.9/plyr.js"></script>
169
+ <script src="/FileStream/server/template/owner.js"></script>
170
+
171
+ </html>
FileStream/server/template/upload.html ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>File Upload</title>
5
+ <meta charset="UTF-8">
6
+ <link rel="stylesheet"
7
+ href="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.4.0/min/dropzone.min.css"/>
8
+ <link rel="stylesheet"
9
+ href="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.4.0/min/basic.min.css"/>
10
+ <script type="application/javascript"
11
+ src="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.4.0/min/dropzone.min.js">
12
+ </script>
13
+ </head>
14
+ <body>
15
+ <h1>File Upload</h1>
16
+ <form method="POST" action='/api/upload' class="dropzone dz-clickable"
17
+ id="dropper" enctype="multipart/form-data">
18
+ </form>
19
+
20
+
21
+ <script type="application/javascript">
22
+ Dropzone.options.dropper = {
23
+ paramName: 'file',
24
+ chunking: true,
25
+ forceChunking: true,
26
+ url: '/upload',
27
+ maxFilesize: 2049,
28
+ chunkSize: 524288,
29
+ //parallelChunkUploads: true,
30
+ //retryChunks: true,
31
+ //retryChunksLimit: 3,
32
+
33
+ }
34
+ </script>
35
+
36
+
37
+
38
+
39
+ </body>
40
+ </html>
FileStream/utils/FileProcessors/__init__.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ from .time_format import get_readable_time
2
+ from .file_properties import get_name, get_file_ids
3
+ from .custom_dl import ByteStreamer
FileStream/utils/FileProcessors/bot_utils.py ADDED
@@ -0,0 +1,350 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pyrogram.errors import UserNotParticipant, FloodWait
2
+ from pyrogram.enums.parse_mode import ParseMode
3
+ from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, Message,WebAppInfo
4
+ from FileStream.utils.FileProcessors.translation import LANG
5
+ from FileStream.Database import Database
6
+ from FileStream.utils.FileProcessors.human_readable import humanbytes
7
+ from FileStream.config import Telegram, Server
8
+ from FileStream.bot import FileStream
9
+ import asyncio
10
+ import functools
11
+ from typing import (Union)
12
+
13
+ db = Database(Telegram.DATABASE_URL, Telegram.SESSION_NAME)
14
+
15
+
16
+ async def get_invite_link(bot, chat_id: Union[str, int]):
17
+ try:
18
+ invite_link = await bot.create_chat_invite_link(chat_id=chat_id)
19
+ return invite_link
20
+ except FloodWait as e:
21
+ print(f"Sleep of {e.value}s caused by FloodWait ...")
22
+ await asyncio.sleep(e.value)
23
+ return await get_invite_link(bot, chat_id)
24
+
25
+
26
+ async def is_user_joined(bot, message: Message):
27
+ if Telegram.FORCE_SUB_ID and Telegram.FORCE_SUB_ID.startswith("-100"):
28
+ channel_chat_id = int(
29
+ Telegram.FORCE_SUB_ID) # When id startswith with -100
30
+ elif Telegram.FORCE_SUB_ID and (
31
+ not Telegram.FORCE_SUB_ID.startswith("-100")):
32
+ channel_chat_id = Telegram.FORCE_SUB_ID # When id not startswith -100
33
+ else:
34
+ return 200
35
+ try:
36
+ user = await bot.get_chat_member(chat_id=channel_chat_id,user_id=message.from_user.id)
37
+ if user.status == "BANNED":
38
+ await message.reply_text(text=LANG.BAN_TEXT.format(Telegram.OWNER_ID),
39
+ parse_mode=ParseMode.MARKDOWN,
40
+ disable_web_page_preview=True)
41
+ return False
42
+ except UserNotParticipant:
43
+ invite_link = await get_invite_link(bot, chat_id=channel_chat_id)
44
+ #------------------------------------------------------------------#
45
+ if Telegram.VERIFY_PIC:
46
+ ver = await message.reply_photo(
47
+ photo=Telegram.VERIFY_PIC,
48
+ caption="<i>Jᴏɪɴ ᴍʏ ᴜᴘᴅᴀᴛᴇ ᴄʜᴀɴɴᴇʟ ᴛᴏ ᴜsᴇ ᴍᴇ 🔐</i>",
49
+ parse_mode=ParseMode.HTML,
50
+ reply_markup=InlineKeyboardMarkup([[
51
+ InlineKeyboardButton("❆ Jᴏɪɴ Oᴜʀ Cʜᴀɴɴᴇʟ ❆",
52
+ url=invite_link.invite_link)
53
+ ]]))
54
+ else:
55
+ #---------------------------------------------------------------#
56
+ ver = await message.reply_text(
57
+ text="<i>Jᴏɪɴ ᴍʏ ᴜᴘᴅᴀᴛᴇ ᴄʜᴀɴɴᴇʟ ᴛᴏ ᴜsᴇ ᴍᴇ 🔐</i>",
58
+ reply_markup=InlineKeyboardMarkup([[
59
+ InlineKeyboardButton("❆ Jᴏɪɴ Oᴜʀ Cʜᴀɴɴᴇʟ ❆",
60
+ url=invite_link.invite_link)
61
+ ]]),
62
+ parse_mode=ParseMode.HTML)
63
+
64
+ await asyncio.sleep(30)
65
+ try:
66
+ await ver.delete()
67
+ await message.delete()
68
+ except Exception:
69
+ pass
70
+ return False
71
+ except Exception:
72
+ await message.reply_text(
73
+ text=
74
+ f"<i>Sᴏᴍᴇᴛʜɪɴɢ ᴡʀᴏɴɢ ᴄᴏɴᴛᴀᴄᴛ ᴍʏ ᴅᴇᴠᴇʟᴏᴘᴇʀ</i> <b><a href='https://t.me/{Telegram.UPDATES_CHANNEL}'>[ ᴄʟɪᴄᴋ ʜᴇʀᴇ ]</a></b>",
75
+ parse_mode=ParseMode.HTML,
76
+ disable_web_page_preview=True)
77
+ return False
78
+ return True
79
+
80
+
81
+ #-------------------------------------------------------------
82
+ async def upload_type_func(file_info):
83
+ """
84
+ //Used values Directly from file Info
85
+ file_name = file_info['file_name']
86
+ file_size = humanbytes(file_info['file_size'])
87
+ mime_type = file_info['mime_type']
88
+ user_id = file_info['user_id']
89
+ message_id = file_info['message_id']
90
+ """
91
+
92
+ existing_file =await db.get_file_by_fileuniqueid_only(file_info['file']['file_unique_id'])
93
+ if existing_file :
94
+ reply_markup, stream_text = await gen_link(existing_file['_id'])
95
+ #await update.message.edit_text(text=stream_text,parse_mode=ParseMode.HTML,disable_web_page_preview=True,reply_markup=reply_markup,)
96
+ return reply_markup, stream_text
97
+ else:
98
+ stream_text = LANG.STREAM_TEXT_Y.format(file_info['file']['file_name'],humanbytes(file_info['file']['file_size']))
99
+ reply_markup = InlineKeyboardMarkup([[
100
+ InlineKeyboardButton(
101
+ "PUBLIC UPLOAD",
102
+ callback_data=f"pubup_{file_info['user_id']}_{file_info['message_id']}"),
103
+ InlineKeyboardButton(
104
+ "PRIVATE UPLOAD",
105
+ callback_data=
106
+ f"privup_{file_info['user_id']}_{file_info['message_id']}")
107
+ ], [InlineKeyboardButton("ᴄʟᴏsᴇ", callback_data="close")]])
108
+
109
+ return reply_markup, stream_text
110
+
111
+
112
+ async def priv_func(file_name, file_size):
113
+
114
+ file_size = humanbytes(file_size)
115
+ stream_text = LANG.PRIV_FILE_RENAME.format(file_name, file_size)
116
+ reply_markup = InlineKeyboardMarkup(
117
+ [[InlineKeyboardButton("ᴄʟᴏsᴇ", callback_data="close")]])
118
+
119
+ return reply_markup, stream_text
120
+
121
+
122
+ #------------------[PRIV_FILE GEN LINK FUNC ]------------------#
123
+ async def gen_priv_file_link(_id):
124
+ file_info = await db.get_privfile(_id)
125
+ file_name = file_info['file_name']
126
+ file_size = humanbytes(file_info['file_size'])
127
+ mime_type = file_info['mime_type']
128
+
129
+ page_link = f"{Server.URL}app/watch/{_id}"
130
+ stream_link = f"{Server.URL}api/dl/{_id}"
131
+ file_link = f"https://t.me/{FileStream.username}?start=privfile_{_id}"
132
+
133
+ if "video" in mime_type:
134
+ stream_text = LANG.STREAM_TEXT.format(file_name, file_size, stream_link,
135
+ page_link, file_link)
136
+ reply_markup = InlineKeyboardMarkup(
137
+ [ [
138
+ InlineKeyboardButton("sᴛʀᴇᴀᴍ",url=page_link),
139
+ InlineKeyboardButton("ᴅᴏᴡɴʟᴏᴀᴅ", url=stream_link)
140
+ ],
141
+ [
142
+ InlineKeyboardButton("ɢᴇᴛ ғɪʟᴇ", url=file_link),
143
+ InlineKeyboardButton("ʀᴇᴠᴏᴋᴇ ғɪʟᴇ",
144
+ callback_data=f"msgdelpvt_{_id}")
145
+ ], [InlineKeyboardButton("ᴄʟᴏsᴇ", callback_data="close")]])
146
+ else:
147
+ stream_text = LANG.STREAM_TEXT_X.format(file_name, file_size, stream_link,
148
+ file_link)
149
+ reply_markup = InlineKeyboardMarkup(
150
+ [[InlineKeyboardButton("ᴅᴏᴡɴʟᴏᴀᴅ", url=stream_link)],
151
+ [
152
+ InlineKeyboardButton("ɢᴇᴛ ғɪʟᴇ", url=file_link),
153
+ InlineKeyboardButton("ʀᴇᴠᴏᴋᴇ ғɪʟᴇ",
154
+ callback_data=f"msgdelpvt_{_id}")
155
+ ], [InlineKeyboardButton("ᴄʟᴏsᴇ", callback_data="close")]])
156
+ return reply_markup, stream_text
157
+
158
+
159
+ #---------------------[ PRIVATE GEN LINK + CALLBACK ]---------------------#
160
+
161
+
162
+ async def gen_link(_id):
163
+ file_info = await db.get_file(_id)
164
+ file_name = file_info['file']['file_name']
165
+ file_size = humanbytes(file_info['file']['file_size'])
166
+ mime_type = file_info['file']['mime_type']
167
+
168
+ page_link = f"{Server.URL}app/watch/{_id}"
169
+ stream_link = f"{Server.URL}api/dl/{_id}"
170
+ file_link = f"https://t.me/{FileStream.username}?start=file_{_id}"
171
+
172
+ if "video" in mime_type:
173
+ stream_text = LANG.STREAM_TEXT.format(file_name, file_size, stream_link,
174
+ page_link, file_link)
175
+ reply_markup = InlineKeyboardMarkup(
176
+ [[
177
+ InlineKeyboardButton("sᴛʀᴇᴀᴍ", url=page_link),
178
+ InlineKeyboardButton("ᴅᴏᴡɴʟᴏᴀᴅ", url=stream_link)
179
+ ],
180
+ [
181
+ InlineKeyboardButton("ɢᴇᴛ ғɪʟᴇ", url=file_link),
182
+ InlineKeyboardButton("ʀᴇᴠᴏᴋᴇ ғɪʟᴇ",
183
+ callback_data=f"msgdelpvt_{_id}")
184
+ ], [InlineKeyboardButton("ᴄʟᴏsᴇ", callback_data="close")]])
185
+ else:
186
+ stream_text = LANG.STREAM_TEXT_X.format(file_name, file_size, stream_link,
187
+ file_link)
188
+ reply_markup = InlineKeyboardMarkup(
189
+ [[InlineKeyboardButton("ᴅᴏᴡɴʟᴏᴀᴅ", url=stream_link)],
190
+ [
191
+ InlineKeyboardButton("ɢᴇᴛ ғɪʟᴇ", url=file_link),
192
+ InlineKeyboardButton("ʀᴇᴠᴏᴋᴇ ғɪʟᴇ",
193
+ callback_data=f"msgdelpvt_{_id}")
194
+ ], [InlineKeyboardButton("ᴄʟᴏsᴇ", callback_data="close")]])
195
+ return reply_markup, stream_text
196
+
197
+
198
+ #---------------------[ GEN STREAM LINKS FOR CHANNEL ]---------------------#
199
+
200
+
201
+ async def gen_linkx(m: Message, _id, name: list):
202
+ file_info = await db.get_file(_id)
203
+ file_name = file_info['file_name']
204
+ mime_type = file_info['mime_type']
205
+ file_size = humanbytes(file_info['file_size'])
206
+
207
+ page_link = f"{Server.URL}app/watch/{_id}"
208
+ stream_link = f"{Server.URL}api/dl/{_id}"
209
+ file_link = f"https://t.me/{FileStream.username}?start=file_{_id}"
210
+
211
+ if "video" in mime_type:
212
+ stream_text = LANG.STREAM_TEXT_X.format(file_name, file_size, stream_link,
213
+ page_link)
214
+ reply_markup = InlineKeyboardMarkup([[
215
+ InlineKeyboardButton("sᴛʀᴇᴀᴍ", url=page_link),
216
+ InlineKeyboardButton("ᴅᴏᴡɴʟᴏᴀᴅ", url=stream_link)
217
+ ]])
218
+ else:
219
+ stream_text = LANG.STREAM_TEXT_X.format(file_name, file_size, stream_link,
220
+ file_link)
221
+ reply_markup = InlineKeyboardMarkup(
222
+ [[InlineKeyboardButton("ᴅᴏᴡɴʟᴏᴀᴅ", url=stream_link)]])
223
+ return reply_markup, stream_text
224
+
225
+
226
+ #---------------------[ USER BANNED ]---------------------#
227
+
228
+
229
+ async def is_user_banned(message):
230
+ if await db.is_user_banned(message.from_user.id):
231
+ await message.reply_text(text=LANG.BAN_TEXT.format(Telegram.OWNER_ID),
232
+ parse_mode=ParseMode.MARKDOWN,
233
+ disable_web_page_preview=True)
234
+ return True
235
+ return False
236
+
237
+
238
+ #---------------------[ CHANNEL BANNED ]---------------------#
239
+
240
+
241
+ async def is_channel_banned(bot, message):
242
+ if await db.is_user_banned(message.chat.id):
243
+ await bot.edit_message_reply_markup(
244
+ chat_id=message.chat.id,
245
+ message_id=message.id,
246
+ reply_markup=InlineKeyboardMarkup(
247
+ [[InlineKeyboardButton(f"ᴄʜᴀɴɴᴇʟ ɪs ʙᴀɴɴᴇᴅ",
248
+ callback_data="N/A")]]))
249
+ return True
250
+ return False
251
+
252
+
253
+ #---------------------[ USER AUTH ]---------------------#
254
+
255
+
256
+ async def is_user_authorized(message):
257
+ if hasattr(Telegram, 'AUTH_USERS') and Telegram.AUTH_USERS:
258
+ user_id = message.from_user.id
259
+ if user_id == Telegram.OWNER_ID:
260
+ return True
261
+ if not (user_id in Telegram.AUTH_USERS):
262
+ await message.reply_text(text="Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴀᴜᴛʜᴏʀɪᴢᴇᴅ ᴛᴏ ᴜsᴇ ᴛʜɪs ʙᴏᴛ.",parse_mode=ParseMode.MARKDOWN,disable_web_page_preview=True)
263
+ return False
264
+ return True
265
+
266
+
267
+ #---------------------[ USER EXIST ]---------------------#
268
+
269
+
270
+ async def is_user_exist(bot, message):
271
+ if not bool(await db.get_user(message.from_user.id)):
272
+ #await db.add_user(message.from_user.id)
273
+ await bot.send_message(
274
+ Telegram.ULOG_GROUP,
275
+ f"**#NᴇᴡUsᴇʀ**\n**⬩ ᴜsᴇʀ ɴᴀᴍᴇ :** [{message.from_user.first_name}](tg://user?id={message.from_user.id})\n**⬩ ᴜsᴇʀ ɪᴅ :** `{message.from_user.id}`"
276
+ )
277
+
278
+
279
+ #------------------[ User Status]--------------------#
280
+ async def user_status(bot, message):
281
+ user = await db.get_user(message.from_user.id)
282
+ #await db.add_user(message.from_user.id)
283
+ return user
284
+
285
+
286
+ async def is_channel_exist(bot, message):
287
+ if not bool(await db.get_user(message.chat.id)):
288
+ await db.add_user(message.chat.id)
289
+ members = await bot.get_chat_members_count(message.chat.id)
290
+ await bot.send_message(
291
+ Telegram.ULOG_GROUP,
292
+ f"**#NᴇᴡCʜᴀɴɴᴇʟ** \n**⬩ ᴄʜᴀᴛ ɴᴀᴍᴇ :** `{message.chat.title}`\n**⬩ ᴄʜᴀᴛ ɪᴅ :** `{message.chat.id}`\n**⬩ ᴛᴏᴛᴀʟ ᴍᴇᴍʙᴇʀs :** `{members}`"
293
+ )
294
+
295
+
296
+ # Decorator Function to check if user is authorized
297
+ #----------------------------------------------------------------
298
+ def verify_users(func):
299
+
300
+ @functools.wraps(func)
301
+ async def wrapper(bot, message):
302
+ response = {}
303
+ user = await user_status(bot, message)
304
+ if user:
305
+ if user['tele_status']['status'] == "ACTIVE":
306
+ response['status'] = "AUTHORIZED"
307
+ elif user['tele_status']['status'] == "BANNED":
308
+ response['status'] = "BANNED"
309
+
310
+ await bot.send_message(
311
+ Telegram.ULOG_GROUP,
312
+ f"**\n**⬩ ᴜsᴇʀ ɴᴀᴍᴇ :** [{message.from_user.first_name} {message.from_user.last_name}](tg://user?id={message.from_user.id})\n**⬩ ᴜsᴇʀ ɪᴅ :** `{message.from_user.id}` \n ** Status : {response['status']} \n Trying to access Services**"
313
+ )
314
+
315
+ await bot.send_message(
316
+ message.from_user.id,
317
+ f"**⬩ ᴜsᴇʀ ɴᴀᴍᴇ :** [{message.from_user.first_name}](tg://user?id={message.from_user.id})\n**⬩ ᴜsᴇʀ ɪᴅ :** `{message.from_user.id}` \n** You are Banned by Admins Contact Admins to unban you**"
318
+ )
319
+
320
+ else:
321
+
322
+ response['status'] = "NOT EXIST"
323
+ await bot.send_message(
324
+ Telegram.ULOG_GROUP,
325
+ f"**\n**⬩ ᴜsᴇʀ ɴᴀᴍᴇ :** [{message.from_user.first_name} {message.from_user.last_name}](tg://user?id={message.from_user.id})\n**⬩ ᴜsᴇʀ ɪᴅ :** `{message.from_user.id}` \n ** Status : {response['status']}**"
326
+ )
327
+ await bot.send_message(
328
+ message.from_user.id,
329
+ f"**⬩ ᴜsᴇʀ ɴᴀᴍᴇ :** [{message.from_user.first_name}](tg://user?id={message.from_user.id})\n**⬩ ᴜsᴇʀ ɪᴅ :** `{message.from_user.id}` \n** Ask Admins to Authorise You**"
330
+ )
331
+
332
+ return await func(bot, message, response)
333
+
334
+ return wrapper
335
+
336
+
337
+ async def verify_user(bot, message):
338
+ if not await is_user_authorized(message):
339
+ return False
340
+
341
+ if await is_user_banned(message):
342
+ return False
343
+
344
+ await is_user_exist(bot, message)
345
+
346
+ if Telegram.FORCE_SUB:
347
+ if not await is_user_joined(bot, message):
348
+ return False
349
+
350
+ return True
FileStream/utils/FileProcessors/broadcast_helper.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import asyncio
2
+ import traceback
3
+ from pyrogram.errors import FloodWait, InputUserDeactivated, UserIsBlocked, PeerIdInvalid
4
+
5
+ async def send_msg(user_id, message):
6
+ try:
7
+ await message.copy(chat_id=user_id)
8
+ return 200, None
9
+ except FloodWait as e:
10
+ await asyncio.sleep(e.value)
11
+ return send_msg(user_id, message)
12
+ except InputUserDeactivated:
13
+ return 400, f"{user_id} : deactivated\n"
14
+ except UserIsBlocked:
15
+ return 400, f"{user_id} : blocked the bot\n"
16
+ except PeerIdInvalid:
17
+ return 400, f"{user_id} : user id invalid\n"
18
+ except Exception as e:
19
+ return 500, f"{user_id} : {traceback.format_exc()}\n"
FileStream/utils/FileProcessors/custom_dl.py ADDED
@@ -0,0 +1,208 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import asyncio
2
+ import logging
3
+ from typing import Dict, Union
4
+ from FileStream.bot import work_loads
5
+ from pyrogram import Client, utils, raw
6
+ from .file_properties import get_file_ids
7
+ from pyrogram.session import Session, Auth
8
+ from pyrogram.errors import AuthBytesInvalid
9
+ from pyrogram.file_id import FileId, FileType, ThumbnailSource
10
+ from pyrogram.types import Message
11
+
12
+
13
+ class ByteStreamer:
14
+
15
+ def __init__(self, client: Client):
16
+ self.clean_timer = 30 * 60
17
+ self.client: Client = client
18
+ self.cached_file_ids: Dict[str, FileId] = {}
19
+ asyncio.create_task(self.clean_cache())
20
+
21
+ async def get_file_properties(self, db_id: str, multi_clients) -> FileId:
22
+ """
23
+ Returns the properties of a media of a specific message in a FIleId class.
24
+ if the properties are cached, then it'll return the cached results.
25
+ or it'll generate the properties from the Message ID and cache them.
26
+ """
27
+ if not db_id in self.cached_file_ids:
28
+ logging.debug("Before Calling generate_file_properties")
29
+ await self.generate_file_properties(db_id, multi_clients)
30
+ logging.debug(f"Cached file properties for file with ID {db_id}")
31
+ return self.cached_file_ids[db_id]
32
+
33
+ async def generate_file_properties(self, db_id: str,
34
+ multi_clients) -> FileId:
35
+ """
36
+ Generates the properties of a media file on a specific message.
37
+ returns ths properties in a FIleId class.
38
+ """
39
+ logging.debug("Before calling get_file_ids")
40
+ file_id = await get_file_ids(self.client, db_id, Message)
41
+ logging.debug(f"Generated file ID and Unique ID for file with ID {db_id}")
42
+ self.cached_file_ids[db_id] = file_id
43
+ logging.debug(f"Cached media file with ID {db_id}")
44
+ return self.cached_file_ids[db_id]
45
+
46
+ async def generate_media_session(self, client: Client,
47
+ file_id: FileId) -> Session:
48
+ """
49
+ Generates the media session for the DC that contains the media file.
50
+ This is required for getting the bytes from Telegram servers.
51
+ """
52
+
53
+ media_session = client.media_sessions.get(file_id.dc_id, None)
54
+
55
+ if media_session is None:
56
+ if file_id.dc_id != await client.storage.dc_id():
57
+ media_session = Session(
58
+ client,
59
+ file_id.dc_id,
60
+ await Auth(client, file_id.dc_id, await
61
+ client.storage.test_mode()).create(),
62
+ await client.storage.test_mode(),
63
+ is_media=True,
64
+ )
65
+ await media_session.start()
66
+
67
+ for _ in range(6):
68
+ exported_auth = await client.invoke(
69
+ raw.functions.auth.ExportAuthorization(dc_id=file_id.dc_id))
70
+
71
+ try:
72
+ await media_session.invoke(
73
+ raw.functions.auth.ImportAuthorization(
74
+ id=exported_auth.id, bytes=exported_auth.bytes))
75
+ break
76
+ except AuthBytesInvalid:
77
+ logging.debug(
78
+ f"Invalid authorization bytes for DC {file_id.dc_id}")
79
+ continue
80
+ else:
81
+ await media_session.stop()
82
+ raise AuthBytesInvalid
83
+ else:
84
+ media_session = Session(
85
+ client,
86
+ file_id.dc_id,
87
+ await client.storage.auth_key(),
88
+ await client.storage.test_mode(),
89
+ is_media=True,
90
+ )
91
+ await media_session.start()
92
+ logging.debug(f"Created media session for DC {file_id.dc_id}")
93
+ client.media_sessions[file_id.dc_id] = media_session
94
+ else:
95
+ logging.debug(f"Using cached media session for DC {file_id.dc_id}")
96
+ return media_session
97
+
98
+ @staticmethod
99
+ async def get_location(
100
+ file_id: FileId
101
+ ) -> Union[
102
+ raw.types.InputPhotoFileLocation,
103
+ raw.types.InputDocumentFileLocation,
104
+ raw.types.InputPeerPhotoFileLocation,
105
+ ]:
106
+ """
107
+ Returns the file location for the media file.
108
+ """
109
+ file_type = file_id.file_type
110
+
111
+ if file_type == FileType.CHAT_PHOTO:
112
+ if file_id.chat_id > 0:
113
+ peer = raw.types.InputPeerUser(user_id=file_id.chat_id,
114
+ access_hash=file_id.chat_access_hash)
115
+ else:
116
+ if file_id.chat_access_hash == 0:
117
+ peer = raw.types.InputPeerChat(chat_id=-file_id.chat_id)
118
+ else:
119
+ peer = raw.types.InputPeerChannel(
120
+ channel_id=utils.get_channel_id(file_id.chat_id),
121
+ access_hash=file_id.chat_access_hash,
122
+ )
123
+
124
+ location = raw.types.InputPeerPhotoFileLocation(
125
+ peer=peer,
126
+ volume_id=file_id.volume_id,
127
+ local_id=file_id.local_id,
128
+ big=file_id.thumbnail_source == ThumbnailSource.CHAT_PHOTO_BIG,
129
+ )
130
+ elif file_type == FileType.PHOTO:
131
+ location = raw.types.InputPhotoFileLocation(
132
+ id=file_id.media_id,
133
+ access_hash=file_id.access_hash,
134
+ file_reference=file_id.file_reference,
135
+ thumb_size=file_id.thumbnail_size,
136
+ )
137
+ else:
138
+ location = raw.types.InputDocumentFileLocation(
139
+ id=file_id.media_id,
140
+ access_hash=file_id.access_hash,
141
+ file_reference=file_id.file_reference,
142
+ thumb_size=file_id.thumbnail_size,
143
+ )
144
+ return location
145
+
146
+ async def yield_file(
147
+ self,
148
+ file_id: FileId,
149
+ index: int,
150
+ offset: int,
151
+ first_part_cut: int,
152
+ last_part_cut: int,
153
+ part_count: int,
154
+ chunk_size: int,
155
+ ) -> Union[str, None]:
156
+
157
+ client = self.client
158
+ work_loads[index] += 1
159
+ logging.debug(f"Starting to yielding file with client {index}.")
160
+ media_session = await self.generate_media_session(client, file_id)
161
+
162
+ current_part = 1
163
+
164
+ location = await self.get_location(file_id)
165
+
166
+ try:
167
+ r = await media_session.invoke(
168
+ raw.functions.upload.GetFile(location=location,
169
+ offset=offset,
170
+ limit=chunk_size), )
171
+ if isinstance(r, raw.types.upload.File):
172
+ while True:
173
+ chunk = r.bytes
174
+ if not chunk:
175
+ break
176
+ elif part_count == 1:
177
+ yield chunk[first_part_cut:last_part_cut]
178
+ elif current_part == 1:
179
+ yield chunk[first_part_cut:]
180
+ elif current_part == part_count:
181
+ yield chunk[:last_part_cut]
182
+ else:
183
+ yield chunk
184
+
185
+ current_part += 1
186
+ offset += chunk_size
187
+
188
+ if current_part > part_count:
189
+ break
190
+
191
+ r = await media_session.invoke(
192
+ raw.functions.upload.GetFile(location=location,
193
+ offset=offset,
194
+ limit=chunk_size), )
195
+ except (TimeoutError, AttributeError):
196
+ pass
197
+ finally:
198
+ logging.debug(f"Finished yielding file with {current_part} parts.")
199
+ work_loads[index] -= 1
200
+
201
+ async def clean_cache(self) -> None:
202
+ """
203
+ function to clean the cache to reduce memory usage
204
+ """
205
+ while True:
206
+ await asyncio.sleep(self.clean_timer)
207
+ self.cached_file_ids.clear()
208
+ logging.debug("Cleaned the cache")
FileStream/utils/FileProcessors/custom_mix.py ADDED
@@ -0,0 +1,385 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import asyncio
2
+ import logging
3
+ import asyncio
4
+ import functools
5
+ import logging
6
+ import math
7
+ import inspect
8
+ from hashlib import md5
9
+ from typing import Dict, Union, BinaryIO, Callable
10
+ from pyrogram import Client, utils, raw
11
+ from pyrogram.session import Session, Auth
12
+ from pyrogram.errors import AuthBytesInvalid
13
+ from pyrogram.file_id import FileId, FileType, ThumbnailSource
14
+ from pyrogram.types import Message
15
+ from pyrogram import StopTransmission
16
+
17
+ from FileStream.bot import work_loads
18
+ from typing import Dict, Union
19
+ from FileStream.bot import work_loads
20
+ from pyrogram import Client, utils, raw
21
+ from .file_properties import get_file_ids
22
+ from pyrogram.session import Session, Auth
23
+ from pyrogram.errors import AuthBytesInvalid
24
+ from pyrogram.file_id import FileId, FileType, ThumbnailSource
25
+ from typing import Union, BinaryIO, List, Optional, Callable
26
+ from pyrogram.types import Message
27
+ import os
28
+ import re
29
+ from datetime import datetime
30
+ import math
31
+ import time
32
+ import asyncio
33
+ import pyrogram
34
+ import traceback
35
+ import functools
36
+ from typing import Union, BinaryIO, List, Optional, Callable
37
+
38
+ from pyrogram import raw
39
+ from pyrogram import types
40
+ from pyrogram import utils as pgutils
41
+ from pyrogram import StopTransmission, enums
42
+ from pyrogram.errors import FilePartMissing
43
+ from pyrogram.file_id import FileType
44
+ from pyrogram.enums import ParseMode, ChatType
45
+ from pyrogram import filters, Client
46
+ from pyrogram.errors import FloodWait
47
+ from pyrogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton
48
+ from pyrogram.enums.parse_mode import ParseMode
49
+
50
+ #-----------------------Local Imports----------------------------------#
51
+ from FileStream import utils, StartTime, __version__
52
+ from FileStream.bot import FileStream, multi_clients, work_loads
53
+ from FileStream.utils.FileProcessors.bot_utils import is_user_banned, is_user_exist, is_user_joined, gen_link, is_channel_banned, is_channel_exist, is_user_authorized
54
+ from FileStream.Database import Database
55
+ from FileStream.utils.FileProcessors.file_properties import get_file_ids, get_file_info
56
+ from FileStream.Tools.tool import TimeFormatter
57
+ from FileStream.config import Telegram
58
+
59
+
60
+ class TGFileController:
61
+
62
+ def __init__(self, client: Client):
63
+ self.clean_timer = 30 * 60
64
+ self.client: Client = client
65
+ self.cached_file_ids: Dict[str, FileId] = {}
66
+ asyncio.create_task(self.clean_cache())
67
+
68
+ async def clean_cache(self) -> None:
69
+ """
70
+ function to clean the cache to reduce memory usage
71
+ """
72
+ while True:
73
+ await asyncio.sleep(self.clean_timer)
74
+ self.cached_file_ids.clear()
75
+ print("Cleaned the cache")
76
+ logging.debug("Cleaned the cache")
77
+
78
+ async def get_me(self):
79
+ return await self.client.get_me().username
80
+
81
+ async def get_file_properties(self, db_id: str, multi_clients) -> FileId:
82
+ """
83
+ Returns the properties of a media of a specific message in a FIleId class.
84
+ if the properties are cached, then it'll return the cached results.
85
+ or it'll generate the properties from the Message ID and cache them.
86
+ """
87
+ if not db_id in self.cached_file_ids:
88
+ logging.debug("Before Calling generate_file_properties")
89
+ await self.generate_file_properties(db_id, multi_clients)
90
+ logging.debug(f"Cached file properties for file with ID {db_id}")
91
+ return self.cached_file_ids[db_id]
92
+
93
+ async def generate_file_properties(self, db_id: str,
94
+ multi_clients) -> FileId:
95
+ """
96
+ Generates the properties of a media file on a specific message.
97
+ returns ths properties in a FIleId class.
98
+ """
99
+ logging.debug("Before calling get_file_ids")
100
+ file_id = await get_file_ids(self.client, db_id, Message)
101
+ logging.debug(f"Generated file ID and Unique ID for file with ID {db_id}")
102
+ self.cached_file_ids[db_id] = file_id
103
+ logging.debug(f"Cached media file with ID {db_id}")
104
+ return self.cached_file_ids[db_id]
105
+
106
+ async def generate_media_session(self, client: Client,
107
+ file_id: FileId) -> Session:
108
+ """
109
+ Generates the media session for the DC that contains the media file.
110
+ This is required for getting the bytes from Telegram servers.
111
+ """
112
+
113
+ media_session = client.media_sessions.get(file_id.dc_id, None)
114
+
115
+ if media_session is None:
116
+ if file_id.dc_id != await client.storage.dc_id():
117
+ media_session = Session(
118
+ client,
119
+ file_id.dc_id,
120
+ await Auth(client, file_id.dc_id, await
121
+ client.storage.test_mode()).create(),
122
+ await client.storage.test_mode(),
123
+ is_media=True,
124
+ )
125
+ await media_session.start()
126
+
127
+ for _ in range(6):
128
+ exported_auth = await client.invoke(
129
+ raw.functions.auth.ExportAuthorization(dc_id=file_id.dc_id))
130
+
131
+ try:
132
+ await media_session.invoke(
133
+ raw.functions.auth.ImportAuthorization(
134
+ id=exported_auth.id, bytes=exported_auth.bytes))
135
+ break
136
+ except AuthBytesInvalid:
137
+ logging.debug(
138
+ f"Invalid authorization bytes for DC {file_id.dc_id}")
139
+ continue
140
+ else:
141
+ await media_session.stop()
142
+ raise AuthBytesInvalid
143
+ else:
144
+ media_session = Session(
145
+ client,
146
+ file_id.dc_id,
147
+ await client.storage.auth_key(),
148
+ await client.storage.test_mode(),
149
+ is_media=True,
150
+ )
151
+ await media_session.start()
152
+ logging.debug(f"Created media session for DC {file_id.dc_id}")
153
+ client.media_sessions[file_id.dc_id] = media_session
154
+ else:
155
+ logging.debug(f"Using cached media session for DC {file_id.dc_id}")
156
+ return media_session
157
+
158
+ @staticmethod
159
+ async def get_location(
160
+ file_id: FileId
161
+ ) -> Union[
162
+ raw.types.InputPhotoFileLocation,
163
+ raw.types.InputDocumentFileLocation,
164
+ raw.types.InputPeerPhotoFileLocation,
165
+ ]:
166
+ """
167
+ Returns the file location for the media file.
168
+ """
169
+ file_type = file_id.file_type
170
+
171
+ if file_type == FileType.CHAT_PHOTO:
172
+ if file_id.chat_id > 0:
173
+ peer = raw.types.InputPeerUser(user_id=file_id.chat_id,
174
+ access_hash=file_id.chat_access_hash)
175
+ else:
176
+ if file_id.chat_access_hash == 0:
177
+ peer = raw.types.InputPeerChat(chat_id=-file_id.chat_id)
178
+ else:
179
+ peer = raw.types.InputPeerChannel(
180
+ channel_id=utils.get_channel_id(file_id.chat_id),
181
+ access_hash=file_id.chat_access_hash,
182
+ )
183
+
184
+ location = raw.types.InputPeerPhotoFileLocation(
185
+ peer=peer,
186
+ volume_id=file_id.volume_id,
187
+ local_id=file_id.local_id,
188
+ big=file_id.thumbnail_source == ThumbnailSource.CHAT_PHOTO_BIG,
189
+ )
190
+ elif file_type == FileType.PHOTO:
191
+ location = raw.types.InputPhotoFileLocation(
192
+ id=file_id.media_id,
193
+ access_hash=file_id.access_hash,
194
+ file_reference=file_id.file_reference,
195
+ thumb_size=file_id.thumbnail_size,
196
+ )
197
+ else:
198
+ location = raw.types.InputDocumentFileLocation(
199
+ id=file_id.media_id,
200
+ access_hash=file_id.access_hash,
201
+ file_reference=file_id.file_reference,
202
+ thumb_size=file_id.thumbnail_size,
203
+ )
204
+ return location
205
+
206
+ async def send(self,
207
+ media: Union["types.InputMedia", "types.InputMediaPhoto",
208
+ "types.InputMediaVideo", "types.InputMediaAudio",
209
+ "types.InputMediaAnimation",
210
+ "types.InputMediaDocument",
211
+ "types.InputPhoneContact"], caption: str,
212
+ reply_to_msg_id: str, chat_id: Union[int, str]):
213
+ client = self.client
214
+ #while True:
215
+ try:
216
+ if reply_to_msg_id:
217
+ r = await client.invoke(
218
+ raw.functions.messages.SendMedia(
219
+ peer=await client.resolve_peer(chat_id),
220
+ media=media,
221
+ message=caption,
222
+ reply_to_msg_id=reply_to_msg_id,
223
+ random_id=client.rnd_id(),
224
+ ))
225
+ else:
226
+ print("This is the reply_to_msg_id")
227
+ r = await client.invoke(
228
+ raw.functions.messages.SendMedia(
229
+ peer=await client.resolve_peer(chat_id),
230
+ media=media,
231
+ message=caption,
232
+ random_id=client.rnd_id(),
233
+ ))
234
+
235
+ except Exception as e:
236
+ await client.send_message(chat_id=Telegram.ULOG_CHANNEL,
237
+ text=f"**#EʀʀᴏʀTʀᴀᴄᴋᴇʙᴀᴄᴋ:** `{e}`",
238
+ disable_web_page_preview=True)
239
+ print(
240
+ f"Cᴀɴ'ᴛ Eᴅɪᴛ Bʀᴏᴀᴅᴄᴀsᴛ Mᴇssᴀɢᴇ!\nEʀʀᴏʀ: **Gɪᴠᴇ ᴍᴇ ᴇᴅɪᴛ ᴘᴇʀᴍɪssɪᴏɴ ɪɴ ᴜᴘᴅᴀᴛᴇs ᴀɴᴅ ʙɪɴ Cʜᴀɴɴᴇʟ!{traceback.format_exc()}**"
241
+ )
242
+ else:
243
+ for i in r.updates:
244
+ if isinstance(
245
+ i, (raw.types.UpdateNewMessage, raw.types.UpdateNewChannelMessage,
246
+ raw.types.UpdateNewScheduledMessage)):
247
+ return await types.Message._parse(
248
+ client,
249
+ i.message, {i.id: i
250
+ for i in r.users}, {i.id: i
251
+ for i in r.chats},
252
+ is_scheduled=isinstance(i, raw.types.UpdateNewScheduledMessage))
253
+
254
+ async def upload_file(
255
+ self,
256
+ index: int,
257
+ file_id: FileId,
258
+ file_name: str,
259
+ file_size: int,
260
+ progress: Callable,
261
+ progress_args: tuple = ()) -> Union[str, None]:
262
+
263
+ async def worker(session):
264
+ while True:
265
+ data = await queue.get()
266
+
267
+ if data is None:
268
+ return
269
+
270
+ try:
271
+ await session.invoke(data)
272
+ except Exception as e:
273
+ log.exception(e)
274
+
275
+ client = self.client
276
+ part_size = 512 * 1024
277
+ file_id = file_id
278
+ index = index
279
+ chunk_size = part_size
280
+ file_name = file_name
281
+ file_size = file_size
282
+ if file_size == 0:
283
+ raise ValueError("File size equals to 0 B")
284
+
285
+ file_size_limit_mib = 4000 if client.me.is_premium else 2000
286
+ #file_size_limit_mib = 4000
287
+ if file_size > file_size_limit_mib * 1024 * 1024:
288
+ raise ValueError(
289
+ f"Can't upload files bigger than {file_size_limit_mib} MiB")
290
+
291
+ file_total_parts = int(math.ceil(file_size / part_size))
292
+ is_big = file_size > 10 * 1024 * 1024
293
+ workers_count = 4 if is_big else 1
294
+ #is_missing_part = file_id is not None
295
+ new_file_id = client.rnd_id()
296
+ if not is_big:
297
+ md5_sum = md5()
298
+
299
+ session = Session(client,
300
+ await client.storage.dc_id(),
301
+ await client.storage.auth_key(),
302
+ await client.storage.test_mode(),
303
+ is_media=True)
304
+ queue = asyncio.Queue(1)
305
+ workers = [
306
+ client.loop.create_task(worker(session)) for _ in range(workers_count)
307
+ ]
308
+
309
+ work_loads[index] += 1
310
+ logging.debug(f"Starting to yielding file with client {index}.")
311
+ media_session = await self.generate_media_session(client, file_id)
312
+
313
+ file_part = 0
314
+ offset = 0
315
+ location = await self.get_location(file_id)
316
+
317
+ try:
318
+ await session.start()
319
+ r = await media_session.invoke(
320
+ raw.functions.upload.GetFile(location=location,
321
+ offset=offset,
322
+ limit=chunk_size), )
323
+ if isinstance(r, raw.types.upload.File):
324
+ while True:
325
+ chunk = r.bytes
326
+ if not chunk:
327
+ break
328
+
329
+ if not is_big:
330
+ md5_sum.update(chunk)
331
+ if is_big:
332
+ rpc = raw.functions.upload.SaveBigFilePart(
333
+ file_id=new_file_id,
334
+ file_part=file_part,
335
+ file_total_parts=file_total_parts,
336
+ bytes=chunk)
337
+ else:
338
+ rpc = raw.functions.upload.SaveFilePart(file_id=new_file_id,
339
+ file_part=file_part,
340
+ bytes=chunk)
341
+
342
+ await queue.put(rpc)
343
+
344
+ file_part += 1
345
+ offset += chunk_size
346
+
347
+ if file_part >= file_total_parts:
348
+ break
349
+ r = await media_session.invoke(
350
+ raw.functions.upload.GetFile(location=location,
351
+ offset=offset,
352
+ limit=chunk_size), )
353
+
354
+ if progress:
355
+ func = functools.partial(progress,
356
+ min(file_part * part_size, file_size),
357
+ file_size, progress_args)
358
+
359
+ if inspect.iscoroutinefunction(progress):
360
+ await func()
361
+ else:
362
+ await client.loop.run_in_executor(client.executor, func)
363
+ except (TimeoutError, AttributeError):
364
+ pass
365
+ finally:
366
+ for _ in workers:
367
+ await queue.put(None)
368
+
369
+ await asyncio.gather(*workers)
370
+
371
+ await session.stop()
372
+ logging.debug(f"Finished yielding file with {file_part} parts.")
373
+ work_loads[index] -= 1
374
+
375
+ if is_big:
376
+ return raw.types.InputFileBig(
377
+ id=new_file_id,
378
+ parts=file_total_parts,
379
+ name=file_name,
380
+ )
381
+ else:
382
+ return raw.types.InputFile(id=new_file_id,
383
+ parts=file_total_parts,
384
+ name=file_name,
385
+ md5_checksum=md5_sum)
FileStream/utils/FileProcessors/custom_ul.py ADDED
@@ -0,0 +1,256 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import traceback
2
+ import urllib3
3
+ from hashlib import md5
4
+ from typing import Dict, Union, BinaryIO, Callable
5
+ #------------------------------------------------------
6
+
7
+ from pyrogram.session import Session
8
+ from pyrogram.errors import FloodWait
9
+ from pyrogram.enums.parse_mode import ParseMode
10
+ from pyrogram import filters, types, Client, raw
11
+ from pyrogram.file_id import FileId, FileType, PHOTO_TYPES, ThumbnailSource
12
+ from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery
13
+ #----------------------------------------------
14
+ from FileStream.bot import FileStream, multi_clients, work_loads
15
+ from FileStream.config import Telegram, Server
16
+ from FileStream.Database import Database
17
+ import asyncio
18
+ from FileStream.utils.FileProcessors.translation import LANG, BUTTON
19
+ from FileStream.utils.FileProcessors.bot_utils import gen_link, priv_func, gen_priv_file_link
20
+ from FileStream.utils.FileProcessors.file_properties import get_file_ids, get_file_info
21
+
22
+ db = Database(Telegram.DATABASE_URL, Telegram.SESSION_NAME)
23
+
24
+ Hash = {}
25
+
26
+
27
+
28
+
29
+ class TeleUploader:
30
+
31
+ def __init__(self, client: Client):
32
+ self.clean_timer = 30 * 60
33
+ self.client: Client = client
34
+ self.cached_file_ids: Dict[str, FileId] = {}
35
+ asyncio.create_task(self.clean_cache())
36
+
37
+ #print("\n* Client :", client, "\n")
38
+ async def clean_cache(self) -> None:
39
+ """
40
+ function to clean the cache to reduce memory usage
41
+ """
42
+ while True:
43
+ await asyncio.sleep(self.clean_timer)
44
+ self.cached_file_ids.clear()
45
+ print("Cleaned the cache")
46
+ logging.debug("Cleaned the cache")
47
+
48
+ async def get_me(self):
49
+ return await self.client.get_me().username
50
+
51
+ async def get_file_properties(self, db_id: str, multi_clients) -> FileId:
52
+ """
53
+ Returns the properties of a media of a specific message in a FIleId class.
54
+ if the properties are cached, then it'll return the cached results.
55
+ or it'll generate the properties from the Message ID and cache them.
56
+ """
57
+ if not db_id in self.cached_file_ids:
58
+ logging.debug("Before Calling generate_file_properties")
59
+ await self.generate_file_properties(db_id, multi_clients)
60
+ logging.debug(f"Cached file properties for file with ID {db_id}")
61
+ return self.cached_file_ids[db_id]
62
+
63
+ async def generate_media_session(self, client: Client,
64
+ file_id: FileId) -> Session:
65
+ """
66
+ Generates the media session for the DC that contains the media file.
67
+ This is required for getting the bytes from Telegram servers.
68
+ """
69
+
70
+ media_session = client.media_sessions.get(file_id.dc_id, None)
71
+
72
+ if media_session is None:
73
+ if file_id.dc_id != await client.storage.dc_id():
74
+ media_session = Session(
75
+ client,
76
+ file_id.dc_id,
77
+ await Auth(client, file_id.dc_id, await
78
+ client.storage.test_mode()).create(),
79
+ await client.storage.test_mode(),
80
+ is_media=True,
81
+ )
82
+ await media_session.start()
83
+
84
+ for _ in range(6):
85
+ exported_auth = await client.invoke(
86
+ raw.functions.auth.ExportAuthorization(dc_id=file_id.dc_id))
87
+
88
+ try:
89
+ await media_session.invoke(
90
+ raw.functions.auth.ImportAuthorization(
91
+ id=exported_auth.id, bytes=exported_auth.bytes))
92
+ break
93
+ except AuthBytesInvalid:
94
+ logging.debug(
95
+ f"Invalid authorization bytes for DC {file_id.dc_id}")
96
+ continue
97
+ else:
98
+ await media_session.stop()
99
+ raise AuthBytesInvalid
100
+ else:
101
+ media_session = Session(
102
+ client,
103
+ file_id.dc_id,
104
+ await client.storage.auth_key(),
105
+ await client.storage.test_mode(),
106
+ is_media=True,
107
+ )
108
+ await media_session.start()
109
+ logging.debug(f"Created media session for DC {file_id.dc_id}")
110
+ client.media_sessions[file_id.dc_id] = media_session
111
+ else:
112
+ logging.debug(f"Using cached media session for DC {file_id.dc_id}")
113
+ return media_session
114
+
115
+ def mime(self, filename):
116
+ import mimetypes
117
+ mime_type, encoding = mimetypes.guess_type(filename)
118
+
119
+ return mime_type
120
+
121
+ async def gen_session(self):
122
+ client = self.client
123
+
124
+ session = Session(client,
125
+ await client.storage.dc_id(),
126
+ await client.storage.auth_key(),
127
+ await client.storage.test_mode(),
128
+ is_media=True)
129
+
130
+ return session
131
+
132
+ async def upload_web_file(self, file_details, chunk):
133
+ client = self.client
134
+ """
135
+ These Name Are not Used Insted of that directly dictionary Name Used
136
+ file_name = file_details["file_name"]
137
+ file_size = file_details["file_size"]
138
+ file_part = file_details["file_part"]
139
+ total_parts = file_details["total_parts"]
140
+ upload_id = file_details["upload_id"]
141
+
142
+ """
143
+ file_details['file']["file_id"] = client.rnd_id()
144
+ #mime_type = file_details['file']["mime_type"]
145
+ response = dict(status="ok", message="ok")
146
+ if file_details["file"]["file_size"] == 0:
147
+ raise ValueError("File size equals to 0 B")
148
+
149
+ file_size_limit_mib = 4000 if client.me.is_premium else 2000
150
+ #file_size_limit_mib = 4000
151
+ if file_details["file"]["file_size"] > file_size_limit_mib * 1024 * 1024:
152
+ raise ValueError(
153
+ f"Can't upload files bigger than {file_size_limit_mib} MiB")
154
+
155
+ #file_total_parts = file_details["total_parts"]
156
+ #is_big = file_size > 10 * 1024 * 1024
157
+ is_big = file_details["file"]["file_size"] > 1
158
+ session = await self.gen_session()
159
+ await session.start()
160
+
161
+ file = await db.add_webfile(file_details)
162
+ #new_file_id = file["new_file_id"]
163
+ if not is_big or file_details["file"]["file_part"] == 0:
164
+ await client.send_message(
165
+ chat_id=Telegram.ULOG_GROUP,
166
+ text=f"Hi, I am just Started, Do Not Disturb Please",
167
+ disable_web_page_preview=True)
168
+ Hash['md5_sum'] = md5()
169
+
170
+ try:
171
+ if is_big:
172
+ rpc = raw.functions.upload.SaveBigFilePart(
173
+ file_id=file['file']["file_id"],
174
+ file_part=file_details["file"]["file_part"],
175
+ file_total_parts=file_details["file"]["total_parts"],
176
+ bytes=chunk)
177
+ response['status'] = "success"
178
+ response[
179
+ 'message'] = f"Uploading as Bigfile {file_details['file']['file_part']}/{file_details['file']['total_parts']}"
180
+ print("Response", response)
181
+
182
+ await session.invoke(rpc)
183
+
184
+ except (TimeoutError, AttributeError):
185
+ pass
186
+ if file_details['file'][
187
+ "file_part"] == file_details['file']["total_parts"] - 1:
188
+ print("Final Function")
189
+ if is_big:
190
+ final = raw.types.InputFileBig(
191
+ id=file['file']["file_id"],
192
+ parts=file_details['file']["total_parts"],
193
+ name=file_details['file']["file_name"],
194
+ )
195
+
196
+ media = raw.types.InputMediaUploadedDocument(
197
+ file=final,
198
+ mime_type=file_details['file']["mime_type"],
199
+ attributes=[
200
+ raw.types.DocumentAttributeFilename(
201
+ file_name=file_details['file']["file_name"])
202
+ ])
203
+
204
+ try:
205
+ msgs = await client.invoke(
206
+ raw.functions.messages.SendMedia(
207
+ peer=await client.resolve_peer(Telegram.FLOG_CHANNEL),
208
+ media=media,
209
+ message=file_details['file']["file_name"],
210
+ random_id=file['file']["file_id"]))
211
+
212
+ #print(msgs)
213
+ message = await FileStream.send_message(
214
+ Telegram.ULOG_GROUP, "Message sent with **Pyrogram**!")
215
+ message_id = getattr(
216
+ getattr(getattr(msgs, "updates", "")[1], "message", ""), "id", "")
217
+
218
+ print("Printing msg-id", message_id)
219
+ chat_id = Telegram.FLOG_CHANNEL
220
+ print("Printing ", message_id, chat_id)
221
+ MessageFile = await FileStream.get_messages(chat_id, message_id)
222
+ #print("Printing MessageFile", MessageFile)
223
+ instruction = {
224
+ "privacy_type": "PRIVATE",
225
+ "user_id": file_details["user_id"],
226
+ "user_type": "WEB"
227
+ }
228
+ file_info = get_file_info(MessageFile, instruction)
229
+ print("Printing file_info", file_info)
230
+
231
+ await db.uploaded_web_file(file_details["dropzone_id"])
232
+
233
+ # Here we are Adding the File Into the database First
234
+ #await db.add_webfile(file_info)
235
+ inserted_id = await db.add_file(file_info)
236
+ await get_file_ids(False, inserted_id, MessageFile)
237
+ reply_markup, stream_text = await gen_link(_id=inserted_id)
238
+ await message.edit_text(
239
+ text=stream_text,
240
+ parse_mode=ParseMode.HTML,
241
+ disable_web_page_preview=True,
242
+ reply_markup=reply_markup,
243
+ )
244
+
245
+ #log_msg = await send_file(FileStream, db_id, file_info['file_id'], message)
246
+ #await update_file_id(log_msg.id, multi_clients))
247
+ except Exception as e:
248
+ await client.send_message(chat_id=Telegram.ULOG_GROUP,
249
+ text=f"**#EʀʀᴏʀTʀᴀᴄᴋᴇʙᴀᴄᴋ:** `{e}`",
250
+ disable_web_page_preview=True)
251
+ print(
252
+ f"Cᴀɴ'ᴛ Eᴅɪᴛ Bʀᴏᴀᴅᴄᴀsᴛ Mᴇssᴀɢᴇ!\nEʀʀᴏʀ: **Gɪᴠᴇ ᴍᴇ ᴇᴅɪᴛ ᴘᴇʀᴍɪssɪᴏɴ ɪɴ ᴜᴘᴅᴀᴛᴇs ᴀɴᴅ ʙɪɴ Cʜᴀɴɴᴇʟ!{traceback.format_exc()}**"
253
+ )
254
+ await session.stop()
255
+
256
+ return response
FileStream/utils/FileProcessors/file_properties.py ADDED
@@ -0,0 +1,221 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+ import logging
3
+ from datetime import datetime
4
+ from pyrogram import Client
5
+ from typing import Any, Optional
6
+
7
+ from pyrogram.enums import ParseMode, ChatType
8
+ from pyrogram.types import Message
9
+ from pyrogram.file_id import FileId
10
+ #-----------------------------------------------------
11
+ from FileStream.bot import FileStream, multi_clients
12
+ from FileStream.Database import Database
13
+ from FileStream.config import Telegram, Server
14
+ from FileStream.Tools import Time_ISTKolNow
15
+ from FileStream.Tools.cleanup import clean_text
16
+
17
+ db = Database(Telegram.DATABASE_URL, Telegram.SESSION_NAME)
18
+
19
+
20
+ async def send_file(client: Client, db_id, file_id: str, message, send_to):
21
+ file_caption = getattr(message, 'caption', None) or get_name(message)
22
+ log_msg = await client.send_cached_media(chat_id=send_to, file_id=file_id, caption=f"**{file_caption}**")
23
+
24
+ if message.chat.type == ChatType.PRIVATE:
25
+ await log_msg.reply_text(
26
+ text=
27
+ f"**RᴇQᴜᴇꜱᴛᴇᴅ ʙʏ :** [{message.from_user.first_name}](tg://user?id={message.from_user.id})\n**Uꜱᴇʀ ɪᴅ :** `{message.from_user.id}`\n**Fɪʟᴇ ɪᴅ :** `{db_id}`",
28
+ disable_web_page_preview=True,
29
+ parse_mode=ParseMode.MARKDOWN,
30
+ quote=True)
31
+ else:
32
+ await log_msg.reply_text(
33
+ text=
34
+ f"**RᴇQᴜᴇꜱᴛᴇᴅ ʙʏ :** {message.chat.title} \n**Cʜᴀɴɴᴇʟ ɪᴅ :** `{message.chat.id}`\n**Fɪʟᴇ ɪᴅ :** `{db_id}`",
35
+ disable_web_page_preview=True,
36
+ parse_mode=ParseMode.MARKDOWN,
37
+ quote=True)
38
+
39
+ return {"message": log_msg, "sent_to": send_to}
40
+
41
+
42
+ async def update_file_id(message, multi_clients):
43
+ file_ids = {}
44
+ for client_id, client in multi_clients.items():
45
+ #log_msg = await client.get_messages(message['location'],message['message_id'])
46
+ media = get_media_from_message(await client.get_messages(message['location'],message['message_id']))
47
+ file_ids[str(client.id)] = getattr(media, "file_id", "")
48
+
49
+ return file_ids
50
+
51
+
52
+ #------------------------------------Update Private File IDs------------------------------------#
53
+ async def get_private_file_ids(client: Client | bool, db_id: str,message) -> Optional[FileId]:
54
+ file_info = await db.get_private_file(db_id)
55
+ file_id_info = file_info.setdefault("file_ids", {})
56
+ if not str(client.id) in file_id_info:
57
+ logging.debug("Storing file_id in DB")
58
+ #msg = await client.get_messages(Telegram.PFLOG_CHANNEL,file_info['message_id'])
59
+ media = get_media_from_message(await client.get_messages(
60
+ Telegram.PFLOG_CHANNEL, file_info['message_id']))
61
+ file_id_info[str(client.id)] = getattr(media, "file_id", "")
62
+ await db.update_private_file_ids(db_id, file_id_info)
63
+ logging.debug("Stored file_id in DB")
64
+ file_info = await db.get_private_file(db_id)
65
+ return file_info[str(client.id)]
66
+ if not client:
67
+ return file_info['file']['file_id']
68
+
69
+
70
+ #------------------------Update Public File ID s --------------------------- #
71
+ async def get_file_ids(client: Client | bool, db_id: str, message) -> Optional[FileId]:
72
+
73
+ logging.debug("Starting of get_file_ids")
74
+ file_info = await db.get_file(db_id)
75
+
76
+ if (not "file_ids" in file_info) or not client:
77
+ if file_info['user_type'] == "TELEGRAM":
78
+ if file_info['location'] in Telegram.DATA_SOURCES:
79
+ print("Already Present in Data Sources ", Telegram.DATA_SOURCES)
80
+ else:
81
+ log_msg = await send_file(FileStream, db_id,file_info['file']['file_id'], message,Telegram.FLOG_CHANNEL)
82
+ #updated_info = update_file_info(log_msg)
83
+ await db.update_file_info(db_id, update_file_info(log_msg))
84
+ await db.update_file_ids(db_id, await update_file_id(await db.get_file(db_id),multi_clients))
85
+
86
+ logging.debug("Stored file_id of all clients in DB")
87
+ if not client:
88
+ return
89
+ file_info = await db.get_file(db_id)
90
+
91
+ if file_info['user_type'] == "WEB":
92
+ await db.update_file_ids(db_id, await update_file_id(await db.get_file(db_id), multi_clients))
93
+ logging.debug("Stored file_id of all clients in DB")
94
+ if not client:
95
+ return
96
+ file_info = await db.get_file(db_id)
97
+
98
+ file_id_info = file_info.setdefault("file_ids", {})
99
+ if not str(client.id) in file_id_info:
100
+ logging.debug("Storing file_id in DB")
101
+ #log_msg = await send_file(FileStream, db_id, file_info['file_id'], message,Telegram.FLOG_CHANNEL)
102
+ msg = await client.get_messages(file_info['location'],file_info['message_id'])
103
+ media = get_media_from_message(msg)
104
+ file_id_info[str(client.id)] = getattr(media, "file_id", "")
105
+ await db.update_file_ids(db_id, file_id_info)
106
+ logging.debug("Stored file_id in DB")
107
+
108
+ logging.debug("Middle of get_file_ids")
109
+ file_id = FileId.decode(file_id_info[str(client.id)])
110
+ setattr(file_id, "file_size", file_info['file']['file_size'])
111
+ setattr(file_id, "mime_type", file_info['file']['mime_type'])
112
+ setattr(file_id, "file_name", file_info['file']['file_name'])
113
+ setattr(file_id, "unique_id", file_info['file']['file_unique_id'])
114
+ logging.debug("Ending of get_file_ids")
115
+ return file_id
116
+
117
+
118
+ #------------------------------
119
+ def get_media_from_message(message: "Message") -> Any:
120
+ media_types = (
121
+ "audio",
122
+ "document",
123
+ "photo",
124
+ "sticker",
125
+ "animation",
126
+ "video",
127
+ "voice",
128
+ "video_note",
129
+ )
130
+ for attr in media_types:
131
+ media = getattr(message, attr, None)
132
+ if media:
133
+ return media
134
+
135
+
136
+ def get_media_file_size(m):
137
+ media = get_media_from_message(m)
138
+ return getattr(media, "file_size", "None")
139
+
140
+
141
+ def get_name(media_msg: Message | FileId) -> str:
142
+ if isinstance(media_msg, Message):
143
+ media = get_media_from_message(media_msg)
144
+ file_name = getattr(media, "file_name", "")
145
+
146
+ elif isinstance(media_msg, FileId):
147
+ file_name = getattr(media_msg, "file_name", "")
148
+
149
+ if not file_name:
150
+ if isinstance(media_msg, Message) and media_msg.media:
151
+ media_type = media_msg.media.value
152
+ elif media_msg.file_type:
153
+ media_type = media_msg.file_type.name.lower()
154
+ else:
155
+ media_type = "file"
156
+
157
+ formats = {
158
+ "photo": "jpg",
159
+ "audio": "mp3",
160
+ "voice": "ogg",
161
+ "video": "mp4",
162
+ "animation": "mp4",
163
+ "video_note": "mp4",
164
+ "sticker": "webp"
165
+ }
166
+
167
+ ext = formats.get(media_type)
168
+ ext = "." + ext if ext else ""
169
+
170
+ date = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
171
+ file_name = f"{media_type}-{date}{ext}"
172
+
173
+ return file_name
174
+
175
+
176
+ def get_file_info(message, instruction):
177
+ media = get_media_from_message(message)
178
+ """
179
+ //Used a single Liner Insted of this Block
180
+ if message.chat.type == ChatType.PRIVATE:
181
+ user_idx = message.from_user.id
182
+ else:
183
+ user_idx = message.chat.id
184
+ """
185
+
186
+ return {
187
+ "user_id": instruction['user_id'],
188
+ "user_type": instruction['user_type'],
189
+ "message_id": message.id,
190
+ "location": message.from_user.id if (message.chat.type == ChatType.PRIVATE) else message.chat.id,
191
+ "file": {
192
+ "file_id": getattr(media, "file_id", ""),
193
+ "caption": clean_text(getattr(message, "caption", f"{get_name(message)}")),
194
+ "file_unique_id": getattr(media, "file_unique_id", ""),
195
+ "file_name": get_name(message),
196
+ "file_size": getattr(media, "file_size", 0),
197
+ "mime_type": getattr(media, "mime_type", "None/unknown"),
198
+ "tagged_users": {
199
+ str(message.from_user.id) if (message.chat.type == ChatType.PRIVATE) else str(Telegram.OWNER_ID): instruction['privacy_type']
200
+ }
201
+ },
202
+ "time":Time_ISTKolNow(),
203
+ "privacy_type":instruction['privacy_type']
204
+ }
205
+
206
+
207
+ def update_file_info(updates):
208
+ media = get_media_from_message(updates['message'])
209
+ return {
210
+ "message_id": updates['message'].id,
211
+ "location": updates['sent_to'],
212
+ "file": {
213
+ "file_id":getattr(media, "file_id", ""),
214
+ "caption":clean_text(getattr(updates['message'], "caption",f"{get_name(updates['message'])}")),
215
+ "file_unique_id":getattr(media, "file_unique_id", ""),
216
+ "file_name":get_name(updates['message']),
217
+ "file_size":getattr(media, "file_size", 0),
218
+ "mime_type":getattr(media, "mime_type", "None/unknown"),
219
+ "tagged_users": {}
220
+ },
221
+ }
FileStream/utils/FileProcessors/human_readable.py ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ def humanbytes(size):
2
+ if not size:
3
+ return ""
4
+ power = 2**10
5
+ n = 0
6
+ Dic_powerN = {0: ' ', 1: 'Ki', 2: 'Mi', 3: 'Gi', 4: 'Ti'}
7
+ while size > power:
8
+ size /= power
9
+ n += 1
10
+ return str(round(size, 2)) + " " + Dic_powerN[n] + 'B'
FileStream/utils/FileProcessors/time_format.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ def get_readable_time(seconds: int) -> str:
2
+ count = 0
3
+ readable_time = ""
4
+ time_list = []
5
+ time_suffix_list = ["s", "m", "h", " days"]
6
+ while count < 4:
7
+ count += 1
8
+ if count < 3:
9
+ remainder, result = divmod(seconds, 60)
10
+ else:
11
+ remainder, result = divmod(seconds, 24)
12
+ if seconds == 0 and remainder == 0:
13
+ break
14
+ time_list.append(int(result))
15
+ seconds = int(remainder)
16
+ for x in range(len(time_list)):
17
+ time_list[x] = str(time_list[x]) + time_suffix_list[x]
18
+ if len(time_list) == 4:
19
+ readable_time += time_list.pop() + ", "
20
+ time_list.reverse()
21
+ readable_time += ": ".join(time_list)
22
+ return readable_time
23
+
24
+
25
+
26
+
FileStream/utils/FileProcessors/translation.py ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton
2
+ from FileStream.config import Telegram
3
+ from FileStream.bot import FileStream
4
+
5
+
6
+ class LANG(object):
7
+
8
+ START_TEXT = """
9
+ <b>👋 Hᴇʏ, </b>{}\n
10
+ <b>I'ᴍ ᴛᴇʟᴇɢʀᴀᴍ ғɪʟᴇs sᴛʀᴇᴀᴍɪɴɢ ʙᴏᴛ ᴀs ᴡᴇʟʟ ᴅɪʀᴇᴄᴛ ʟɪɴᴋs ɢᴇɴᴇʀᴀᴛᴏʀ</b>\n
11
+ <b>ᴡᴏʀᴋɪɴɢ ᴏɴ ᴄʜᴀɴɴᴇʟs ᴀɴᴅ ᴘʀɪᴠᴀᴛᴇ ᴄʜᴀᴛ</b>\n
12
+ <b>💕 @{}</b>\n"""
13
+
14
+ HELP_TEXT = """
15
+ <b>- ᴀᴅᴅ ᴍᴇ ᴀs ᴀɴ ᴀᴅᴍɪɴ ᴏɴ ᴛʜᴇ ᴄʜᴀɴɴᴇʟ</b>
16
+ <b>- sᴇɴᴅ ᴍᴇ ᴀɴʏ ᴅᴏᴄᴜᴍᴇɴᴛ ᴏʀ ᴍᴇᴅɪᴀ</b>
17
+ <b>- ɪ'ʟʟ ᴘʀᴏᴠɪᴅᴇ sᴛʀᴇᴀᴍᴀʙʟᴇ ʟɪɴᴋ</b>\n
18
+ <b>🔞 ᴀᴅᴜʟᴛ ᴄᴏɴᴛᴇɴᴛ sᴛʀɪᴄᴛʟʏ ᴘʀᴏʜɪʙɪᴛᴇᴅ.</b>\n
19
+ <i><b> ʀᴇᴘᴏʀᴛ ʙᴜɢs ᴛᴏ <a href='#'>ᴅᴇᴠᴇʟᴏᴘᴇʀ</a></b></i>"""
20
+
21
+ ABOUT_TEXT = """
22
+ <b>⚜ ᴍʏ ɴᴀᴍᴇ : {}</b>\n
23
+ <b>✦ ᴠᴇʀsɪᴏɴ : {}</b>
24
+ <b>✦ ᴜᴘᴅᴀᴛᴇᴅ ᴏɴ : 06-January-2024</b>
25
+ <b>✦ ᴅᴇᴠᴇʟᴏᴘᴇʀ : <a href='https://t.me/blendersb'>BlendersBD</a></b>
26
+ <b>✦ CREDIT & SPECIAL Thanks To : <a href='https://github.com/avipatilpro/FileStreamBot'>Avishkar Patil & This Repo Owners </a></b>
27
+ \n
28
+ """
29
+
30
+ STREAM_TEXT = """
31
+ <i><u>𝗬𝗼𝘂𝗿 𝗟𝗶𝗻𝗸 𝗚𝗲𝗻𝗲𝗿𝗮𝘁𝗲𝗱 !</u></i>\n
32
+ <b>📂 Fɪʟᴇ ɴᴀᴍᴇ :</b> <b><code>{}</code></b>\n
33
+ <b>📦 Fɪʟᴇ ꜱɪᴢᴇ :</b> <code>{}</code>\n
34
+ <b>📥 Dᴏᴡɴʟᴏᴀᴅ :</b> <code>{}</code>\n
35
+ <b>🖥 Wᴀᴛᴄʜ :</b> <code>{}</code>\n
36
+ <b>🔗 Sʜᴀʀᴇ :</b> <code>{}</code>\n"""
37
+
38
+ STREAM_TEXT_Y = """
39
+ <b>🪂 : 𝔹𝕊ℙ𝔸ℝ𝕂 𝔻ℝ𝕀𝕍𝔼 : 🪂</b>\n
40
+ <b>📂 Fɪʟᴇ ɴᴀᴍᴇ :</b> <b>{}</b>\n
41
+ <b>📦 Fɪʟᴇ ꜱɪᴢᴇ :</b> <code>{}</code>\n
42
+ """
43
+
44
+ STREAM_TEXT_X = """
45
+ <i>Chose where you wand to upload this file !</i>\n
46
+ <b>📂 Fɪʟᴇ ɴᴀᴍᴇ :</b> <b>{}</b>\n
47
+ <b>📦 Fɪʟᴇ ꜱɪᴢᴇ :</b> <code>{}</code>\n
48
+ <b>📥 Dᴏᴡɴʟᴏᴀᴅ :</b> <code>{}</code>\n
49
+ <b>🔗 Sʜᴀʀᴇ :</b> <code>{}</code>\n"""
50
+
51
+ PRIV_FILE_RENAME = """
52
+ <b>🪂 : 𝔹𝕊ℙ𝔸ℝ𝕂 𝔻ℝ𝕀𝕍𝔼 : 🪂</b>\n
53
+ <i>🅄🄿🄻🄾🄰🄳 🄵🄸🄻🄴 🄸🄽 🄿🅁🄸🅅🄰🅃🄴 🅂🄿🄰🄲🄴</i>\n
54
+ <b>📂 Fɪʟᴇ ɴᴀᴍᴇ :</b> <b><code>{}</code></b>\n
55
+ <b>📦 Fɪʟᴇ ꜱɪᴢᴇ :</b> <code>{}</code>\n
56
+ <b>ɪꜰ ʏᴏᴜ ᴜᴘʟᴏᴀᴅ ᴡɪᴛʜ ᴅɪꜰꜰᴇʀᴇɴᴛ ɴᴀᴍᴇ ᴘʟᴇᴀꜱᴇ ʀᴇᴘʟʏ ᴛʜɪꜱ ᴍᴇꜱꜱᴀɢᴇ ᴡɪᴛʜ ɴᴇᴡ ɴᴀᴍᴇ </b>\n
57
+ <b>ᴏʀ ʀᴇᴘʟʏ ᴡɪᴛʜ N or No ꜰᴏʀ ᴜᴘʟᴏᴀᴅ ᴡɪᴛʜ ᴏʀɪɢɪɴᴀʟ ɴᴀᴍᴇ</b>\n"""
58
+
59
+ SUCCESS_PRIV_FILE = """
60
+ <b>🪂 : 𝔹𝕊ℙ𝔸ℝ𝕂 𝔻ℝ𝕀𝕍𝔼 : 🪂</b>\n
61
+ <i>!! ꜰɪʟᴇ ᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴜᴘʟᴏᴀᴅᴇᴅ ᴛᴏ ᴘʀɪᴠᴀᴛᴇ ꜱᴘᴀᴄᴇ !!</i>\n
62
+ <b>📂 Fɪʟᴇ ɴᴀᴍᴇ :</b> <b>{}</b>\n
63
+ <b>📦 Fɪʟᴇ ꜱɪᴢᴇ :</b> <code>{}</code>\n"""
64
+ BASIC_PRIV_FILE = """
65
+ <b>🪂 : 𝔹𝕊ℙ𝔸ℝ𝕂 𝔻ℝ𝕀𝕍𝔼 : 🪂</b>\n
66
+ <i>----------------------------------------------------------------------------</i>\n
67
+ <b>📂 Fɪʟᴇ ɴᴀᴍᴇ :</b> <b>{}</b>\n
68
+ <b>📦 Fɪʟᴇ ꜱɪᴢᴇ :</b> <code>{}</code>\n"""
69
+
70
+ HEART_EMOJI = [
71
+ '💘', '💝', '💖', '💗', '💓', '💞', '💟', '❣️', '💔', '❤️', '🧡', '💛', '💚', '💙',
72
+ '💜', '🤎', '🖤', '🤍'
73
+ ]
74
+
75
+ BAN_TEXT = "__Sᴏʀʀʏ Sɪʀ, Yᴏᴜ ᴀʀᴇ Bᴀɴɴᴇᴅ ᴛᴏ ᴜsᴇ ᴍᴇ.__\n\n**[Cᴏɴᴛᴀᴄᴛ Dᴇᴠᴇʟᴏᴘᴇʀ](tg://user?id={}) Tʜᴇʏ Wɪʟʟ Hᴇʟᴘ Yᴏᴜ**"
76
+
77
+ PROGRESS_BAR = """\n
78
+ ╭━━━━❰ᴘʀᴏɢʀᴇss ʙᴀʀ❱━➣
79
+ ┣⪼ 🗂️ : {current} | {total}
80
+ ┣⪼ ⏳️ : {percentage}%
81
+ ┣⪼ 🚀 : {speed}/s
82
+ ┣⪼ ⏱️ : {est_time}
83
+ ╰━━━━━━━━━━━━━━━➣ """
84
+
85
+
86
+ class BUTTON(object):
87
+
88
+ START_BUTTONS = InlineKeyboardMarkup(
89
+ [[
90
+ InlineKeyboardButton('ʜᴇʟᴘ', callback_data='help'),
91
+ InlineKeyboardButton('ᴀʙᴏᴜᴛ', callback_data='about'),
92
+ InlineKeyboardButton('ᴄʟᴏsᴇ', callback_data='close')
93
+ ],
94
+ [
95
+ InlineKeyboardButton(
96
+ "📢 ᴜᴘᴅᴀᴛᴇ ᴄʜᴀɴɴᴇʟ",
97
+ url=f'https://t.me/{Telegram.UPDATES_CHANNEL}')
98
+ ]])
99
+ HELP_BUTTONS = InlineKeyboardMarkup(
100
+ [[
101
+ InlineKeyboardButton('ʜᴏᴍᴇ', callback_data='home'),
102
+ InlineKeyboardButton('ᴀʙᴏᴜᴛ', callback_data='about'),
103
+ InlineKeyboardButton('ᴄʟᴏsᴇ', callback_data='close'),
104
+ ],
105
+ [
106
+ InlineKeyboardButton(
107
+ "📢 ᴜᴘᴅᴀᴛᴇ ᴄʜᴀɴɴᴇʟ",
108
+ url=f'https://t.me/{Telegram.UPDATES_CHANNEL}')
109
+ ]])
110
+ ABOUT_BUTTONS = InlineKeyboardMarkup(
111
+ [[
112
+ InlineKeyboardButton('ʜᴏᴍᴇ', callback_data='home'),
113
+ InlineKeyboardButton('ʜᴇʟᴘ', callback_data='help'),
114
+ InlineKeyboardButton('ᴄʟᴏsᴇ', callback_data='close'),
115
+ ],
116
+ [
117
+ InlineKeyboardButton(
118
+ "📢 ᴜᴘᴅᴀᴛᴇ ᴄʜᴀɴɴᴇʟ",
119
+ url=f'https://t.me/{Telegram.UPDATES_CHANNEL}')
120
+ ]])
FileStream/utils/__init__.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ from .FileProcessors import get_readable_time
2
+ from .FileProcessors import get_name, get_file_ids
3
+ from .FileProcessors import ByteStreamer
app.json ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "FileStreamBot",
3
+ "description": "A Telegram Bot to Convert Telegram Files To Direct & Streamable Links.",
4
+ "keywords": [
5
+ "telegram",
6
+ "files",
7
+ "stream"
8
+ ],
9
+ "repository": "https://github.com/avipatilpro/FileStreamBot/",
10
+ "success_url": "/",
11
+ "logo": "https://i.ibb.co/ZJzJ9Hq/link-3x.png",
12
+ "env": {
13
+ "ENV": {
14
+ "description": "Set this to True if you don't want to crash the bot",
15
+ "value": "True"
16
+ },
17
+ "API_ID": {
18
+ "description": "Get this value from https://my.telegram.org"
19
+ },
20
+ "API_HASH": {
21
+ "description": "Get this value from https://my.telegram.org"
22
+ },
23
+ "BOT_TOKEN": {
24
+ "description": "Get this value from @BotFather"
25
+ },
26
+ "FLOG_CHANNEL": {
27
+ "description": "ID of Channel Where store files sent by users. Read the readme for more info about this var"
28
+ },
29
+ "ULOG_CHANNEL": {
30
+ "description": "ID of Channel Where store New Users data. Read the readme for more info about this var"
31
+ },
32
+ "OWNER_ID": {
33
+ "description": "Your Telegram User ID as Owner"
34
+ },
35
+ "DATABASE_URL": {
36
+ "description": "MongoDB URI for saving User Data and Files List created by user."
37
+ },
38
+ "AUTH_USERS": {
39
+ "description": "Put IDs of Auth Usrs where bot will work. You can add multiple IDs & separate with Space.",
40
+ "required": false
41
+ },
42
+ "UPDATES_CHANNEL": {
43
+ "description": "Channel Username without `@` to set channel as Update Channel",
44
+ "required": false
45
+ },
46
+ "FORCE_SUB_ID": {
47
+ "description": "Channel ID starts with -100 to set channel as Force Sub Channel",
48
+ "required": false
49
+ },
50
+ "FORCE_SUB": {
51
+ "description": "Set to True, so every user have to Join update channel to use the bot.",
52
+ "required": false
53
+ },
54
+ "SLEEP_THRESHOLD": {
55
+ "description": "Set global flood wait threshold, auto-retry requests under 60s. ",
56
+ "required": false
57
+ },
58
+ "WORKERS": {
59
+ "description": "No. of workers that is to be assigned.",
60
+ "required": false
61
+ },
62
+ "PORT": {
63
+ "description": "The port that you want your webapp to be listened to",
64
+ "required": false
65
+ },
66
+ "NO_PORT": {
67
+ "description": "If you don't want your port to be displayed. Set True or False",
68
+ "value": "True",
69
+ "required": false
70
+ },
71
+ "HAS_SSL": {
72
+ "description": "(can be either True or False) If you want the generated links in https format.",
73
+ "value": "True",
74
+ "required": false
75
+ },
76
+ "BIND_ADDRESS": {
77
+ "description": "Your server bind address. default to 0.0.0.0",
78
+ "required": false
79
+ },
80
+ "FQDN": {
81
+ "description": "Heroku app Link without http/s://, you can set later. its required",
82
+ "required": false
83
+ },
84
+ "SESSION_NAME": {
85
+ "description": "Name for the Database created on your MongoDB. Defaults to FileStream",
86
+ "required": false
87
+ },
88
+ "FILE_PIC": {
89
+ "description": "To set Image at /files command. Defaults to pre-set image.",
90
+ "required": false
91
+ },
92
+ "START_PIC": {
93
+ "description": "To set Image at /start command. Defaults to pre-set image.",
94
+ "required": false
95
+ },
96
+ "VERIFY_PIC": {
97
+ "description": "To set Image at Force Subscribe Verify. Defaults to pre-set image.",
98
+ "required": false
99
+ },
100
+ "MODE": {
101
+ "description": "Should be set to `secondary` if you only want to use the server for serving files.",
102
+ "required": false
103
+ }
104
+ },
105
+ "buildpacks": [
106
+ {
107
+ "url": "heroku/python"
108
+ }
109
+ ],
110
+ "stack": "heroku-22",
111
+ "formation": {
112
+ "web": {
113
+ "quantity": 1,
114
+ "size": "eco"
115
+ }
116
+ }
117
+ }
requirement.txt ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ tmdbv3api==1.9.0
2
+ aiofiles==23.2.1
3
+ aiohttp==3.9.3
4
+ aiosignal==1.3.1
5
+ aiosqlite==0.20.0
6
+ async-timeout==4.0.3
7
+ attrs==23.2.0
8
+ certifi==2024.2.2
9
+ charset-normalizer==3.3.2
10
+ dnspython==2.6.1
11
+ frozenlist==1.4.1
12
+ idna==3.6
13
+ Jinja2==3.1.3
14
+ MarkupSafe==2.1.5
15
+ motor==3.3.2
16
+ multidict==6.0.5
17
+ pyaes==1.6.1
18
+ pymediainfo-pyrofork==6.0.1
19
+ pymongo==4.6.2
20
+ pyrofork==2.3.19.post2
21
+ pyrogram-repl==2.0.106
22
+ PySocks==1.7.1
23
+ python-dotenv==1.0.1
24
+ pytz==2024.1
25
+ requests==2.31.0
26
+ TgCrypto==1.2.5
27
+ typing_extensions==4.10.0
28
+ urllib3==2.2.1
29
+ yarl==1.9.4
streambot.log ADDED
@@ -0,0 +1,407 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [16/09/2024 21:08:11] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py:421} ERROR - Error handling request
2
+ Traceback (most recent call last):
3
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py", line 350, in data_received
4
+ messages, upgraded, tail = self._request_parser.feed_data(data)
5
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6
+ File "aiohttp\\_http_parser.pyx", line 557, in aiohttp._http_parser.HttpParser.feed_data
7
+ aiohttp.http_exceptions.BadStatusLine: 400, message:
8
+ Invalid method encountered:
9
+
10
+ bytearray(b'\x16\x03\x01')
11
+ ^
12
+ [16/09/2024 21:08:18] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py:421} ERROR - Error handling request
13
+ Traceback (most recent call last):
14
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py", line 350, in data_received
15
+ messages, upgraded, tail = self._request_parser.feed_data(data)
16
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17
+ File "aiohttp\\_http_parser.pyx", line 557, in aiohttp._http_parser.HttpParser.feed_data
18
+ aiohttp.http_exceptions.BadStatusLine: 400, message:
19
+ Invalid method encountered:
20
+
21
+ bytearray(b'\x16\x03\x01')
22
+ ^
23
+ [16/09/2024 21:09:12] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\pyrogram\methods\utilities\idle.py:76} INFO - Stop signal received (SIGINT). Exiting...
24
+ [16/09/2024 21:12:50] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\pyrogram\methods\utilities\idle.py:76} INFO - Stop signal received (SIGINT). Exiting...
25
+ [16/09/2024 21:28:38] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py:421} ERROR - Error handling request
26
+ Traceback (most recent call last):
27
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py", line 452, in _handle_request
28
+ resp = await request_handler(request)
29
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
30
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_app.py", line 543, in _handle
31
+ resp = await handler(request)
32
+ ^^^^^^^^^^^^^^^^^^^^^^
33
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 105, in list_all_files
34
+ return web.Response(dumps(resp))
35
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
36
+ TypeError: Response.__init__() takes 1 positional argument but 2 were given
37
+ [16/09/2024 21:30:48] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\pyrogram\methods\utilities\idle.py:76} INFO - Stop signal received (SIGINT). Exiting...
38
+ [16/09/2024 21:34:39] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\pyrogram\methods\utilities\idle.py:76} INFO - Stop signal received (SIGINT). Exiting...
39
+ [16/09/2024 21:35:42] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py:421} ERROR - Error handling request
40
+ Traceback (most recent call last):
41
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py", line 452, in _handle_request
42
+ resp = await request_handler(request)
43
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
44
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_app.py", line 543, in _handle
45
+ resp = await handler(request)
46
+ ^^^^^^^^^^^^^^^^^^^^^^
47
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 84, in list_all_files
48
+ resp=[{
49
+ ^^
50
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 92, in <listcomp>
51
+ "id": str(row['_id']['$oid']),
52
+ ~~~~~~~~~~^^^^^^^^
53
+ TypeError: 'ObjectId' object is not subscriptable
54
+ [16/09/2024 21:36:20] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py:421} ERROR - Error handling request
55
+ Traceback (most recent call last):
56
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py", line 452, in _handle_request
57
+ resp = await request_handler(request)
58
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
59
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_app.py", line 543, in _handle
60
+ resp = await handler(request)
61
+ ^^^^^^^^^^^^^^^^^^^^^^
62
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 84, in list_all_files
63
+ resp=[{
64
+ ^^
65
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 92, in <listcomp>
66
+ "id": str(row['_id']),
67
+ ^^^^^^^^^^^^^
68
+ TypeError: 'ObjectId' object is not subscriptable
69
+ [16/09/2024 21:37:13] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py:421} ERROR - Error handling request
70
+ Traceback (most recent call last):
71
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py", line 452, in _handle_request
72
+ resp = await request_handler(request)
73
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
74
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_app.py", line 543, in _handle
75
+ resp = await handler(request)
76
+ ^^^^^^^^^^^^^^^^^^^^^^
77
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 84, in list_all_files
78
+ resp=[{
79
+ ^^
80
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 92, in <listcomp>
81
+ "id": str(ObjectId(row['_id'])),
82
+ ^^^^^^^^^^^^^^^^^^
83
+ TypeError: 'ObjectId' object is not subscriptable
84
+ [16/09/2024 21:42:07] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py:421} ERROR - Error handling request
85
+ Traceback (most recent call last):
86
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py", line 452, in _handle_request
87
+ resp = await request_handler(request)
88
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
89
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_app.py", line 543, in _handle
90
+ resp = await handler(request)
91
+ ^^^^^^^^^^^^^^^^^^^^^^
92
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 84, in list_all_files
93
+ resp=[{
94
+ ^^
95
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 92, in <listcomp>
96
+ "id": str(row['_id']['to_string']),
97
+ ^^^^^^^^^^^^^^^^^^
98
+ TypeError: 'ObjectId' object is not subscriptable
99
+ [16/09/2024 21:43:00] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py:421} ERROR - Error handling request
100
+ Traceback (most recent call last):
101
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py", line 452, in _handle_request
102
+ resp = await request_handler(request)
103
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
104
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_app.py", line 543, in _handle
105
+ resp = await handler(request)
106
+ ^^^^^^^^^^^^^^^^^^^^^^
107
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 84, in list_all_files
108
+ resp=[{
109
+ ^^
110
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 92, in <listcomp>
111
+ "id": row['_id'].to_dict(),
112
+ ^^^^^^^^^^^^^^^^^^
113
+ TypeError: 'ObjectId' object is not subscriptable
114
+ [16/09/2024 21:44:12] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py:421} ERROR - Error handling request
115
+ Traceback (most recent call last):
116
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py", line 452, in _handle_request
117
+ resp = await request_handler(request)
118
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
119
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_app.py", line 543, in _handle
120
+ resp = await handler(request)
121
+ ^^^^^^^^^^^^^^^^^^^^^^
122
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 84, in list_all_files
123
+ resp=[{
124
+ ^^
125
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 92, in <listcomp>
126
+ "id": row['_id'].oid,
127
+ ^^^^^^^^^^^^
128
+ TypeError: 'ObjectId' object is not subscriptable
129
+ [16/09/2024 21:47:21] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py:421} ERROR - Error handling request
130
+ Traceback (most recent call last):
131
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py", line 452, in _handle_request
132
+ resp = await request_handler(request)
133
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
134
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_app.py", line 543, in _handle
135
+ resp = await handler(request)
136
+ ^^^^^^^^^^^^^^^^^^^^^^
137
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 84, in list_all_files
138
+ resp=[{
139
+ ^^
140
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 92, in <listcomp>
141
+ "id": row["_id"],
142
+ ^^^^^^^^
143
+ TypeError: 'ObjectId' object is not subscriptable
144
+ [16/09/2024 21:47:49] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py:421} ERROR - Error handling request
145
+ Traceback (most recent call last):
146
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py", line 452, in _handle_request
147
+ resp = await request_handler(request)
148
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
149
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_app.py", line 543, in _handle
150
+ resp = await handler(request)
151
+ ^^^^^^^^^^^^^^^^^^^^^^
152
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 84, in list_all_files
153
+ resp=[{
154
+ ^^
155
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 92, in <listcomp>
156
+ "id": row["id"],
157
+ ^^^^^^^
158
+ TypeError: 'ObjectId' object is not subscriptable
159
+ [16/09/2024 21:48:17] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py:421} ERROR - Error handling request
160
+ Traceback (most recent call last):
161
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py", line 452, in _handle_request
162
+ resp = await request_handler(request)
163
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
164
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_app.py", line 543, in _handle
165
+ resp = await handler(request)
166
+ ^^^^^^^^^^^^^^^^^^^^^^
167
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 84, in list_all_files
168
+ resp=[{
169
+ ^^
170
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 92, in <listcomp>
171
+ "id": row["oid"],
172
+ ^^^^^^^^
173
+ TypeError: 'ObjectId' object is not subscriptable
174
+ [16/09/2024 21:48:38] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py:421} ERROR - Error handling request
175
+ Traceback (most recent call last):
176
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py", line 452, in _handle_request
177
+ resp = await request_handler(request)
178
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
179
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_app.py", line 543, in _handle
180
+ resp = await handler(request)
181
+ ^^^^^^^^^^^^^^^^^^^^^^
182
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 84, in list_all_files
183
+ resp=[{
184
+ ^^
185
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 92, in <listcomp>
186
+ "id": row["$oid"],
187
+ ^^^^^^^^^
188
+ TypeError: 'ObjectId' object is not subscriptable
189
+ [16/09/2024 21:49:09] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py:421} ERROR - Error handling request
190
+ Traceback (most recent call last):
191
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py", line 452, in _handle_request
192
+ resp = await request_handler(request)
193
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
194
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_app.py", line 543, in _handle
195
+ resp = await handler(request)
196
+ ^^^^^^^^^^^^^^^^^^^^^^
197
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 84, in list_all_files
198
+ resp=[{
199
+ ^^
200
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 92, in <listcomp>
201
+ "id": row['_id']["$oid"],
202
+ ^^^^^^^^^^^^^^^^
203
+ TypeError: 'ObjectId' object is not subscriptable
204
+ [16/09/2024 21:51:55] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\pyrogram\methods\utilities\idle.py:76} INFO - Stop signal received (SIGINT). Exiting...
205
+ [16/09/2024 21:52:52] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py:421} ERROR - Error handling request
206
+ Traceback (most recent call last):
207
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py", line 452, in _handle_request
208
+ resp = await request_handler(request)
209
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
210
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_app.py", line 543, in _handle
211
+ resp = await handler(request)
212
+ ^^^^^^^^^^^^^^^^^^^^^^
213
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 84, in list_all_files
214
+ resp=[{
215
+ ^^
216
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 92, in <listcomp>
217
+ "id": row['_id'].toString(),
218
+ ^^^^^^^^^^^^^^^^^^^
219
+ AttributeError: 'ObjectId' object has no attribute 'toString'
220
+ [16/09/2024 21:54:36] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py:421} ERROR - Error handling request
221
+ Traceback (most recent call last):
222
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py", line 452, in _handle_request
223
+ resp = await request_handler(request)
224
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
225
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_app.py", line 543, in _handle
226
+ resp = await handler(request)
227
+ ^^^^^^^^^^^^^^^^^^^^^^
228
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 84, in list_all_files
229
+ resp=[{
230
+ ^^
231
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 92, in <listcomp>
232
+ "id": str(row._id),
233
+ ^^^^^^^^^^^^^^
234
+ AttributeError: 'ObjectId' object has no attribute 'toString'
235
+ [16/09/2024 21:54:53] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\pyrogram\methods\utilities\idle.py:76} INFO - Stop signal received (SIGINT). Exiting...
236
+ [16/09/2024 21:55:27] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py:421} ERROR - Error handling request
237
+ Traceback (most recent call last):
238
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py", line 452, in _handle_request
239
+ resp = await request_handler(request)
240
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
241
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_app.py", line 543, in _handle
242
+ resp = await handler(request)
243
+ ^^^^^^^^^^^^^^^^^^^^^^
244
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 84, in list_all_files
245
+ resp=[{
246
+ ^^
247
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 92, in <listcomp>
248
+ "id": str(row._id),
249
+ ^^^^^^^
250
+ AttributeError: 'dict' object has no attribute '_id'
251
+ [16/09/2024 21:57:41] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py:421} ERROR - Error handling request
252
+ Traceback (most recent call last):
253
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py", line 452, in _handle_request
254
+ resp = await request_handler(request)
255
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
256
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_app.py", line 543, in _handle
257
+ resp = await handler(request)
258
+ ^^^^^^^^^^^^^^^^^^^^^^
259
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 84, in list_all_files
260
+ resp=[{
261
+ ^^
262
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 92, in <listcomp>
263
+ "id": str(row['_id'] * type(row['_id']) * row['id'].__dict__),
264
+ ^^^^^^^
265
+ AttributeError: 'dict' object has no attribute '_id'
266
+ [16/09/2024 21:58:13] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py:421} ERROR - Error handling request
267
+ Traceback (most recent call last):
268
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py", line 452, in _handle_request
269
+ resp = await request_handler(request)
270
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
271
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_app.py", line 543, in _handle
272
+ resp = await handler(request)
273
+ ^^^^^^^^^^^^^^^^^^^^^^
274
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 84, in list_all_files
275
+ resp=[{
276
+ ^^
277
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 92, in <listcomp>
278
+ "id": str(row['_id'] * type(row['_id']) * row['_id'].__dict__),
279
+ ^^^^^^^
280
+ AttributeError: 'dict' object has no attribute '_id'
281
+ [16/09/2024 21:59:00] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\pyrogram\methods\utilities\idle.py:76} INFO - Stop signal received (SIGINT). Exiting...
282
+ [16/09/2024 21:59:51] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py:421} ERROR - Error handling request
283
+ Traceback (most recent call last):
284
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py", line 452, in _handle_request
285
+ resp = await request_handler(request)
286
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
287
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_app.py", line 543, in _handle
288
+ resp = await handler(request)
289
+ ^^^^^^^^^^^^^^^^^^^^^^
290
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 84, in list_all_files
291
+ resp=[{
292
+ ^^
293
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 92, in <listcomp>
294
+ "id": str(row['_id'] +"\n"+ type(row['_id']) +"\n"+ row['_id'].__dict__),
295
+ ~~~~~~~~~~~^~~~~
296
+ TypeError: unsupported operand type(s) for +: 'ObjectId' and 'str'
297
+ [16/09/2024 22:00:36] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py:421} ERROR - Error handling request
298
+ Traceback (most recent call last):
299
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py", line 452, in _handle_request
300
+ resp = await request_handler(request)
301
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
302
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_app.py", line 543, in _handle
303
+ resp = await handler(request)
304
+ ^^^^^^^^^^^^^^^^^^^^^^
305
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 84, in list_all_files
306
+ resp=[{
307
+ ^^
308
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 92, in <listcomp>
309
+ "id": str(row['_id'] )+"*"+ type(row['_id']) +"*"+ row['_id'].__dict__,
310
+ ^^^^^^^^^^^^^^^^
311
+ TypeError: unsupported operand type(s) for +: 'ObjectId' and 'str'
312
+ [16/09/2024 22:01:17] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py:421} ERROR - Error handling request
313
+ Traceback (most recent call last):
314
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py", line 452, in _handle_request
315
+ resp = await request_handler(request)
316
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
317
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_app.py", line 543, in _handle
318
+ resp = await handler(request)
319
+ ^^^^^^^^^^^^^^^^^^^^^^
320
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 84, in list_all_files
321
+ resp=[{
322
+ ^^
323
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 92, in <listcomp>
324
+ "id": str(type(row['_id'])),
325
+ ^^^^^^^^^^^^^^^^
326
+ TypeError: unsupported operand type(s) for +: 'ObjectId' and 'str'
327
+ [16/09/2024 22:08:40] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\pyrogram\methods\utilities\idle.py:76} INFO - Stop signal received (SIGINT). Exiting...
328
+ [16/09/2024 22:15:21] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\pyrogram\methods\utilities\idle.py:76} INFO - Stop signal received (SIGINT). Exiting...
329
+ [16/09/2024 22:16:08] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py:421} ERROR - Error handling request
330
+ Traceback (most recent call last):
331
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py", line 452, in _handle_request
332
+ resp = await request_handler(request)
333
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
334
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_app.py", line 543, in _handle
335
+ resp = await handler(request)
336
+ ^^^^^^^^^^^^^^^^^^^^^^
337
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 84, in list_all_files
338
+ resp=[{
339
+ ^^
340
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 92, in <listcomp>
341
+ "id": str(type(row['_id'].oid)),
342
+ ^^^^^^^^^^^^^^
343
+ AttributeError: 'ObjectId' object has no attribute 'oid'
344
+ [16/09/2024 22:20:48] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\pyrogram\methods\utilities\idle.py:76} INFO - Stop signal received (SIGINT). Exiting...
345
+ [16/09/2024 22:21:17] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py:421} ERROR - Error handling request
346
+ Traceback (most recent call last):
347
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py", line 452, in _handle_request
348
+ resp = await request_handler(request)
349
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
350
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_app.py", line 543, in _handle
351
+ resp = await handler(request)
352
+ ^^^^^^^^^^^^^^^^^^^^^^
353
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 84, in list_all_files
354
+ resp=[{
355
+ ^^
356
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 92, in <listcomp>
357
+ "id": str(type(row._id.valueOf())),
358
+ ^^^^^^^
359
+ AttributeError: 'dict' object has no attribute '_id'
360
+ [16/09/2024 22:21:47] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py:421} ERROR - Error handling request
361
+ Traceback (most recent call last):
362
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py", line 452, in _handle_request
363
+ resp = await request_handler(request)
364
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
365
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_app.py", line 543, in _handle
366
+ resp = await handler(request)
367
+ ^^^^^^^^^^^^^^^^^^^^^^
368
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 84, in list_all_files
369
+ resp=[{
370
+ ^^
371
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 92, in <listcomp>
372
+ "id": str(type(row['_id'].valueOf())),
373
+ ^^^^^^^
374
+ AttributeError: 'dict' object has no attribute '_id'
375
+ [16/09/2024 22:22:04] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\pyrogram\methods\utilities\idle.py:76} INFO - Stop signal received (SIGINT). Exiting...
376
+ [16/09/2024 22:23:13] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py:421} ERROR - Error handling request
377
+ Traceback (most recent call last):
378
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py", line 452, in _handle_request
379
+ resp = await request_handler(request)
380
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
381
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_app.py", line 543, in _handle
382
+ resp = await handler(request)
383
+ ^^^^^^^^^^^^^^^^^^^^^^
384
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 84, in list_all_files
385
+ resp=[{
386
+ ^^
387
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 92, in <listcomp>
388
+ "id": str(type(row['_id'].valueOf())),
389
+ ^^^^^^^^^^^^^^^^^^
390
+ AttributeError: 'ObjectId' object has no attribute 'valueOf'
391
+ [16/09/2024 22:24:25] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\pyrogram\methods\utilities\idle.py:76} INFO - Stop signal received (SIGINT). Exiting...
392
+ [16/09/2024 22:26:07] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py:421} ERROR - Error handling request
393
+ Traceback (most recent call last):
394
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_protocol.py", line 452, in _handle_request
395
+ resp = await request_handler(request)
396
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
397
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\aiohttp\web_app.py", line 543, in _handle
398
+ resp = await handler(request)
399
+ ^^^^^^^^^^^^^^^^^^^^^^
400
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 84, in list_all_files
401
+ resp=[{
402
+ ^^
403
+ File "C:\Files\Codes\Python\TelegramBots\TelegramAPI\FileStream\server\routes_api.py", line 92, in <listcomp>
404
+ "id": str(row['_id'].value ),
405
+ ^^^^^^^^^^^^^^^^
406
+ AttributeError: 'ObjectId' object has no attribute 'value'
407
+ [16/09/2024 22:30:30] {C:\Files\Codes\Python\TelegramBots\TelegramAPI\TelegramENV\Lib\site-packages\pyrogram\methods\utilities\idle.py:76} INFO - Stop signal received (SIGINT). Exiting...