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...
|