Spaces:
Running
Running
BinaryONe
commited on
Commit
·
e566133
1
Parent(s):
282455b
APP -sparkdrive
Browse files- Dockerfile +20 -0
- FileStream/.gitignore +162 -0
- FileStream/Database/__init__.py +1 -0
- FileStream/Database/database.py +382 -0
- FileStream/TMDB/Endpoint.py +37 -0
- FileStream/TMDB/__init__.py +14 -0
- FileStream/Tools/__init__.py +1 -0
- FileStream/Tools/cleanup.py +51 -0
- FileStream/Tools/file.py +11 -0
- FileStream/Tools/progress.py +87 -0
- FileStream/Tools/tool.py +25 -0
- FileStream/__init__.py +6 -0
- FileStream/__main__.py +94 -0
- FileStream/bot/__init__.py +28 -0
- FileStream/bot/clients.py +59 -0
- FileStream/bot/plugins/Admin/admin.py +197 -0
- FileStream/bot/plugins/FileHandlers/callback.py +584 -0
- FileStream/bot/plugins/FileHandlers/files.py +171 -0
- FileStream/bot/plugins/FileHandlers/stream.py +238 -0
- FileStream/bot/plugins/startup.py +134 -0
- FileStream/config.py +50 -0
- FileStream/server/Functions/downloader.py +98 -0
- FileStream/server/__init__.py +19 -0
- FileStream/server/exceptions.py +5 -0
- FileStream/server/render_template.py +40 -0
- FileStream/server/routes_api.py +179 -0
- FileStream/server/routes_app.py +41 -0
- FileStream/server/routes_main.py +34 -0
- FileStream/server/template/dl.html +44 -0
- FileStream/server/template/owner.js +317 -0
- FileStream/server/template/play.html +171 -0
- FileStream/server/template/upload.html +40 -0
- FileStream/utils/FileProcessors/__init__.py +3 -0
- FileStream/utils/FileProcessors/bot_utils.py +350 -0
- FileStream/utils/FileProcessors/broadcast_helper.py +19 -0
- FileStream/utils/FileProcessors/custom_dl.py +208 -0
- FileStream/utils/FileProcessors/custom_mix.py +385 -0
- FileStream/utils/FileProcessors/custom_ul.py +256 -0
- FileStream/utils/FileProcessors/file_properties.py +221 -0
- FileStream/utils/FileProcessors/human_readable.py +10 -0
- FileStream/utils/FileProcessors/time_format.py +26 -0
- FileStream/utils/FileProcessors/translation.py +120 -0
- FileStream/utils/__init__.py +3 -0
- app.json +117 -0
- requirement.txt +29 -0
- 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...
|