Commit
·
afce118
1
Parent(s):
0feaa16
Add application file
Browse files- .deepsource.toml +10 -0
- .github/FUNDING.yml +2 -0
- .github/ISSUE_TEMPLATE/bug_report.md +26 -0
- .github/ISSUE_TEMPLATE/feature_request.md +20 -0
- .github/dependabot.yml +14 -0
- .github/workflows/black-code-style.yml +32 -0
- .github/workflows/build-docker-image.yml +17 -0
- .github/workflows/codeql-analysis.yml +69 -0
- .github/workflows/publish-docker-image.yml +46 -0
- .gitignore +89 -0
- .restyled.yml +19 -0
- .whitesource +14 -0
- CODE_OF_CONDUCT.md +128 -0
- CreateMongoDB.md +23 -0
- Dockerfile +13 -0
- LICENSE +21 -0
- Procfile +1 -0
- app.json +54 -0
- bot_thumb.jpg +0 -0
- changelog.md +427 -0
- config.py +20 -0
- heroku.yml +5 -0
- renovate.json +6 -0
- requirements.txt +15 -0
- runtime.txt +1 -0
- start.sh +9 -0
- unzipper/__init__.py +38 -0
- unzipper/__main__.py +63 -0
- unzipper/helpers/database.py +519 -0
- unzipper/helpers/start.py +131 -0
- unzipper/helpers/unzip_help.py +164 -0
- unzipper/modules/bot_data.py +1062 -0
- unzipper/modules/callbacks.py +1233 -0
- unzipper/modules/commands.py +819 -0
- unzipper/modules/ext_script/custom_thumbnail.py +93 -0
- unzipper/modules/ext_script/ext_helper.py +136 -0
- unzipper/modules/ext_script/up_helper.py +310 -0
- unzipper/modules/ext_script/url_parser.py +122 -0
.deepsource.toml
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version = 1
|
| 2 |
+
|
| 3 |
+
[[analyzers]]
|
| 4 |
+
name = "secrets"
|
| 5 |
+
|
| 6 |
+
[[analyzers]]
|
| 7 |
+
name = "python"
|
| 8 |
+
|
| 9 |
+
[analyzers.meta]
|
| 10 |
+
runtime_version = "3.x.x"
|
.github/FUNDING.yml
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
github: EDM115
|
| 2 |
+
custom: ["https://paypal.me/8EDM115", "https://www.buymeacoffee.com/edm115", "https://t.me/EDM115bots/544", "https://edm115.shadd.eu.org/"]
|
.github/ISSUE_TEMPLATE/bug_report.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
name: Bug report
|
| 3 |
+
about: Report any bug you found
|
| 4 |
+
title: "[BUG] "
|
| 5 |
+
labels: bug
|
| 6 |
+
assignees: EDM115
|
| 7 |
+
|
| 8 |
+
---
|
| 9 |
+
|
| 10 |
+
**Describe the bug**
|
| 11 |
+
A clear and concise description of what the bug is.
|
| 12 |
+
|
| 13 |
+
**To Reproduce**
|
| 14 |
+
Steps to reproduce the behavior:
|
| 15 |
+
1. Do this
|
| 16 |
+
2. Then that
|
| 17 |
+
3. See error
|
| 18 |
+
|
| 19 |
+
**Expected behavior**
|
| 20 |
+
A clear and concise description of what you expected to happen.
|
| 21 |
+
|
| 22 |
+
**Screenshots**
|
| 23 |
+
If applicable, add screenshots to help explain your problem.
|
| 24 |
+
|
| 25 |
+
**Additional context**
|
| 26 |
+
Add any other context about the problem here.
|
.github/ISSUE_TEMPLATE/feature_request.md
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
name: Feature request
|
| 3 |
+
about: Suggest an idea for this project
|
| 4 |
+
title: "[FEATURE REQUEST] "
|
| 5 |
+
labels: enhancement
|
| 6 |
+
assignees: EDM115
|
| 7 |
+
|
| 8 |
+
---
|
| 9 |
+
|
| 10 |
+
**Is your feature request related to a problem ? Please describe :**
|
| 11 |
+
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
| 12 |
+
|
| 13 |
+
**Describe the solution you'd like**
|
| 14 |
+
A clear and concise description of what you want to happen.
|
| 15 |
+
|
| 16 |
+
**Describe alternatives you've considered**
|
| 17 |
+
A clear and concise description of any alternative solutions or features you've considered.
|
| 18 |
+
|
| 19 |
+
**Additional context**
|
| 20 |
+
Add any other context or screenshots about the feature request here.
|
.github/dependabot.yml
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# To get started with Dependabot version updates, you'll need to specify which
|
| 2 |
+
# package ecosystems to update and where the package manifests are located.
|
| 3 |
+
# Please see the documentation for all configuration options:
|
| 4 |
+
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
| 5 |
+
|
| 6 |
+
version: 2
|
| 7 |
+
updates:
|
| 8 |
+
- package-ecosystem: "pip"
|
| 9 |
+
directory: "/"
|
| 10 |
+
schedule:
|
| 11 |
+
interval: "daily"
|
| 12 |
+
assignees:
|
| 13 |
+
- "EDM115"
|
| 14 |
+
open-pull-requests-limit: 15
|
.github/workflows/black-code-style.yml
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
name: Renders the whole code using Black code style
|
| 2 |
+
|
| 3 |
+
on:
|
| 4 |
+
workflow_dispatch:
|
| 5 |
+
|
| 6 |
+
jobs:
|
| 7 |
+
black:
|
| 8 |
+
runs-on: ubuntu-latest
|
| 9 |
+
steps:
|
| 10 |
+
- name: Checkout
|
| 11 |
+
uses: actions/checkout@v4
|
| 12 |
+
with:
|
| 13 |
+
persist-credentials: false
|
| 14 |
+
fetch-depth: 0
|
| 15 |
+
- name: Black-ify
|
| 16 |
+
uses: psf/black@stable
|
| 17 |
+
with:
|
| 18 |
+
options: "--verbose"
|
| 19 |
+
- name: Commit changes
|
| 20 |
+
run: |
|
| 21 |
+
d=`date '+%Y/%m/%dT%H:%M:%SZ'`
|
| 22 |
+
git config --local user.email ${{ secrets.MAIL }}
|
| 23 |
+
git config --local user.name ${{ secrets.USERNAME }}
|
| 24 |
+
git add -A
|
| 25 |
+
git commit -m "Code style changed to Black at ${d}"
|
| 26 |
+
- name: Push commit
|
| 27 |
+
uses: ad-m/github-push-action@v0.6.0
|
| 28 |
+
with:
|
| 29 |
+
force: true
|
| 30 |
+
directory: "."
|
| 31 |
+
branch: ${{ github.ref }}
|
| 32 |
+
github_token: ${{ secrets.GITHUB_TOKEN }}
|
.github/workflows/build-docker-image.yml
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
name: Build Docker Image
|
| 2 |
+
|
| 3 |
+
on:
|
| 4 |
+
# push:
|
| 5 |
+
# branches: [ main ]
|
| 6 |
+
# pull_request:
|
| 7 |
+
# branches: [ main ]
|
| 8 |
+
workflow_dispatch:
|
| 9 |
+
|
| 10 |
+
jobs:
|
| 11 |
+
build:
|
| 12 |
+
runs-on: ubuntu-latest
|
| 13 |
+
|
| 14 |
+
steps:
|
| 15 |
+
- uses: actions/checkout@v4
|
| 16 |
+
- name: Build the Docker image
|
| 17 |
+
run: docker build . --file Dockerfile --tag unzip-bot:$(date +%s)
|
.github/workflows/codeql-analysis.yml
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# For most projects, this workflow file will not need changing; you simply need
|
| 2 |
+
# to commit it to your repository.
|
| 3 |
+
#
|
| 4 |
+
# You may wish to alter this file to override the set of languages analyzed,
|
| 5 |
+
# or to provide custom queries or build logic.
|
| 6 |
+
#
|
| 7 |
+
# ******** NOTE ********
|
| 8 |
+
# We have attempted to detect the languages in your repository. Please check
|
| 9 |
+
# the `language` matrix defined below to confirm you have the correct set of
|
| 10 |
+
# supported CodeQL languages.
|
| 11 |
+
#
|
| 12 |
+
name: "CodeQL"
|
| 13 |
+
|
| 14 |
+
on:
|
| 15 |
+
# push:
|
| 16 |
+
# branches: [ master ]
|
| 17 |
+
# pull_request:
|
| 18 |
+
# # The branches below must be a subset of the branches above
|
| 19 |
+
# branches: [ master ]
|
| 20 |
+
# schedule:
|
| 21 |
+
# - cron: '0 4 * * 6'
|
| 22 |
+
workflow_dispatch:
|
| 23 |
+
|
| 24 |
+
jobs:
|
| 25 |
+
analyze:
|
| 26 |
+
name: Analyze
|
| 27 |
+
runs-on: ubuntu-latest
|
| 28 |
+
permissions:
|
| 29 |
+
actions: read
|
| 30 |
+
contents: read
|
| 31 |
+
security-events: write
|
| 32 |
+
|
| 33 |
+
strategy:
|
| 34 |
+
fail-fast: false
|
| 35 |
+
matrix:
|
| 36 |
+
language: [ 'python' ]
|
| 37 |
+
|
| 38 |
+
steps:
|
| 39 |
+
- name: Checkout repository
|
| 40 |
+
uses: actions/checkout@v4
|
| 41 |
+
|
| 42 |
+
# Initializes the CodeQL tools for scanning.
|
| 43 |
+
- name: Initialize CodeQL
|
| 44 |
+
uses: github/codeql-action/init@v2
|
| 45 |
+
with:
|
| 46 |
+
languages: ${{ matrix.language }}
|
| 47 |
+
# If you wish to specify custom queries, you can do so here or in a config file.
|
| 48 |
+
# By default, queries listed here will override any specified in a config file.
|
| 49 |
+
# Prefix the list here with "+" to use these queries and those in the config file.
|
| 50 |
+
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
| 51 |
+
|
| 52 |
+
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
| 53 |
+
# If this step fails, then you should remove it and run the build manually (see below)
|
| 54 |
+
- name: Autobuild
|
| 55 |
+
uses: github/codeql-action/autobuild@v2
|
| 56 |
+
|
| 57 |
+
# ℹ️ Command-line programs to run using the OS shell.
|
| 58 |
+
# 📚 https://git.io/JvXDl
|
| 59 |
+
|
| 60 |
+
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
| 61 |
+
# and modify them (or add more) to build your code if your project
|
| 62 |
+
# uses a compiled language
|
| 63 |
+
|
| 64 |
+
#- run: |
|
| 65 |
+
# make bootstrap
|
| 66 |
+
# make release
|
| 67 |
+
|
| 68 |
+
- name: Perform CodeQL Analysis
|
| 69 |
+
uses: github/codeql-action/analyze@v2
|
.github/workflows/publish-docker-image.yml
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
name: Publish Docker Image
|
| 2 |
+
|
| 3 |
+
on:
|
| 4 |
+
release:
|
| 5 |
+
types: [published]
|
| 6 |
+
workflow_dispatch:
|
| 7 |
+
|
| 8 |
+
jobs:
|
| 9 |
+
push_to_registries:
|
| 10 |
+
name: Push Docker image to GHCR & Docker Hub
|
| 11 |
+
runs-on: ubuntu-latest
|
| 12 |
+
permissions:
|
| 13 |
+
packages: write
|
| 14 |
+
contents: read
|
| 15 |
+
steps:
|
| 16 |
+
- name: Check out the repo
|
| 17 |
+
uses: actions/checkout@v4
|
| 18 |
+
|
| 19 |
+
- name: Log in to Docker Hub
|
| 20 |
+
uses: docker/login-action@v3
|
| 21 |
+
with:
|
| 22 |
+
username: ${{ secrets.DOCKER_USERNAME }}
|
| 23 |
+
password: ${{ secrets.DOCKER_TOKEN }}
|
| 24 |
+
|
| 25 |
+
- name: Log in to the GitHub Container registry
|
| 26 |
+
uses: docker/login-action@v3
|
| 27 |
+
with:
|
| 28 |
+
registry: ghcr.io
|
| 29 |
+
username: ${{ github.actor }}
|
| 30 |
+
password: ${{ secrets.GITHUB_TOKEN }}
|
| 31 |
+
|
| 32 |
+
- name: Extract metadata (tags, labels) for Docker
|
| 33 |
+
id: meta
|
| 34 |
+
uses: docker/metadata-action@v5
|
| 35 |
+
with:
|
| 36 |
+
images: |
|
| 37 |
+
edm115/unzip-bot
|
| 38 |
+
ghcr.io/${{ github.repository }}
|
| 39 |
+
|
| 40 |
+
- name: Build and push Docker images
|
| 41 |
+
uses: docker/build-push-action@v5
|
| 42 |
+
with:
|
| 43 |
+
context: .
|
| 44 |
+
push: true
|
| 45 |
+
tags: ${{ steps.meta.outputs.tags }}
|
| 46 |
+
labels: ${{ steps.meta.outputs.labels }}
|
.gitignore
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Byte-compiled / optimized / DLL files
|
| 2 |
+
__pycache__/
|
| 3 |
+
*.py[cod]
|
| 4 |
+
*$py.class
|
| 5 |
+
|
| 6 |
+
# Distribution / packaging
|
| 7 |
+
.Python
|
| 8 |
+
build/
|
| 9 |
+
develop-eggs/
|
| 10 |
+
dist/
|
| 11 |
+
downloads/
|
| 12 |
+
eggs/
|
| 13 |
+
.eggs/
|
| 14 |
+
lib/
|
| 15 |
+
lib64/
|
| 16 |
+
parts/
|
| 17 |
+
sdist/
|
| 18 |
+
var/
|
| 19 |
+
wheels/
|
| 20 |
+
pip-wheel-metadata/
|
| 21 |
+
share/python-wheels/
|
| 22 |
+
*.egg-info/
|
| 23 |
+
.installed.cfg
|
| 24 |
+
*.egg
|
| 25 |
+
MANIFEST
|
| 26 |
+
|
| 27 |
+
# PyInstaller
|
| 28 |
+
# Usually these files are written by a python script from a template
|
| 29 |
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
| 30 |
+
*.manifest
|
| 31 |
+
*.spec
|
| 32 |
+
|
| 33 |
+
# Installer logs
|
| 34 |
+
pip-log.txt
|
| 35 |
+
pip-delete-this-directory.txt
|
| 36 |
+
|
| 37 |
+
# Unit test / coverage reports
|
| 38 |
+
htmlcov/
|
| 39 |
+
.tox/
|
| 40 |
+
.nox/
|
| 41 |
+
.coverage
|
| 42 |
+
.coverage.*
|
| 43 |
+
.cache
|
| 44 |
+
nosetests.xml
|
| 45 |
+
coverage.xml
|
| 46 |
+
*.cover
|
| 47 |
+
*.py,cover
|
| 48 |
+
.hypothesis/
|
| 49 |
+
.pytest_cache/
|
| 50 |
+
|
| 51 |
+
# PyBuilder
|
| 52 |
+
target/
|
| 53 |
+
|
| 54 |
+
# Jupyter Notebook
|
| 55 |
+
.ipynb_checkpoints
|
| 56 |
+
|
| 57 |
+
# IPython
|
| 58 |
+
profile_default/
|
| 59 |
+
ipython_config.py
|
| 60 |
+
|
| 61 |
+
# pyenv
|
| 62 |
+
.python-version
|
| 63 |
+
|
| 64 |
+
# pipenv
|
| 65 |
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
| 66 |
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
| 67 |
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
| 68 |
+
# install all needed dependencies.
|
| 69 |
+
#Pipfile.lock
|
| 70 |
+
|
| 71 |
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
| 72 |
+
__pypackages__/
|
| 73 |
+
|
| 74 |
+
# Environments
|
| 75 |
+
.env
|
| 76 |
+
.venv
|
| 77 |
+
env/
|
| 78 |
+
venv/
|
| 79 |
+
ENV/
|
| 80 |
+
env.bak/
|
| 81 |
+
venv.bak/
|
| 82 |
+
|
| 83 |
+
# VS Code
|
| 84 |
+
.vscode
|
| 85 |
+
.vscode/
|
| 86 |
+
.vscode/*
|
| 87 |
+
|
| 88 |
+
# Secrets
|
| 89 |
+
*.session
|
.restyled.yml
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
enabled: false
|
| 2 |
+
exclude:
|
| 3 |
+
- "unzipper/modules/ext_script/ext_helper.py"
|
| 4 |
+
- "unzipper/modules/ext_script/up_helper.py"
|
| 5 |
+
auto: false
|
| 6 |
+
pull_requests: true
|
| 7 |
+
commit_template: |
|
| 8 |
+
Restyled by ${restyler.name}
|
| 9 |
+
statuses:
|
| 10 |
+
differences: false
|
| 11 |
+
no_differences: true
|
| 12 |
+
error: true
|
| 13 |
+
labels:
|
| 14 |
+
- style
|
| 15 |
+
restylers:
|
| 16 |
+
- name: autopep8
|
| 17 |
+
- name: isort
|
| 18 |
+
- name: black
|
| 19 |
+
- name: yapf
|
.whitesource
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"scanSettings": {
|
| 3 |
+
"baseBranches": []
|
| 4 |
+
},
|
| 5 |
+
"checkRunSettings": {
|
| 6 |
+
"vulnerableCheckRunConclusionLevel": "failure",
|
| 7 |
+
"displayMode": "diff",
|
| 8 |
+
"useMendCheckNames": true
|
| 9 |
+
},
|
| 10 |
+
"issueSettings": {
|
| 11 |
+
"minSeverityLevel": "LOW",
|
| 12 |
+
"issueType": "DEPENDENCY"
|
| 13 |
+
}
|
| 14 |
+
}
|
CODE_OF_CONDUCT.md
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Contributor Covenant Code of Conduct
|
| 2 |
+
|
| 3 |
+
## Our Pledge
|
| 4 |
+
|
| 5 |
+
We as members, contributors, and leaders pledge to make participation in our
|
| 6 |
+
community a harassment-free experience for everyone, regardless of age, body
|
| 7 |
+
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
| 8 |
+
identity and expression, level of experience, education, socio-economic status,
|
| 9 |
+
nationality, personal appearance, race, religion, or sexual identity
|
| 10 |
+
and orientation.
|
| 11 |
+
|
| 12 |
+
We pledge to act and interact in ways that contribute to an open, welcoming,
|
| 13 |
+
diverse, inclusive, and healthy community.
|
| 14 |
+
|
| 15 |
+
## Our Standards
|
| 16 |
+
|
| 17 |
+
Examples of behavior that contributes to a positive environment for our
|
| 18 |
+
community include:
|
| 19 |
+
|
| 20 |
+
* Demonstrating empathy and kindness toward other people
|
| 21 |
+
* Being respectful of differing opinions, viewpoints, and experiences
|
| 22 |
+
* Giving and gracefully accepting constructive feedback
|
| 23 |
+
* Accepting responsibility and apologizing to those affected by our mistakes,
|
| 24 |
+
and learning from the experience
|
| 25 |
+
* Focusing on what is best not just for us as individuals, but for the
|
| 26 |
+
overall community
|
| 27 |
+
|
| 28 |
+
Examples of unacceptable behavior include:
|
| 29 |
+
|
| 30 |
+
* The use of sexualized language or imagery, and sexual attention or
|
| 31 |
+
advances of any kind
|
| 32 |
+
* Trolling, insulting or derogatory comments, and personal or political attacks
|
| 33 |
+
* Public or private harassment
|
| 34 |
+
* Publishing others' private information, such as a physical or email
|
| 35 |
+
address, without their explicit permission
|
| 36 |
+
* Other conduct which could reasonably be considered inappropriate in a
|
| 37 |
+
professional setting
|
| 38 |
+
|
| 39 |
+
## Enforcement Responsibilities
|
| 40 |
+
|
| 41 |
+
Community leaders are responsible for clarifying and enforcing our standards of
|
| 42 |
+
acceptable behavior and will take appropriate and fair corrective action in
|
| 43 |
+
response to any behavior that they deem inappropriate, threatening, offensive,
|
| 44 |
+
or harmful.
|
| 45 |
+
|
| 46 |
+
Community leaders have the right and responsibility to remove, edit, or reject
|
| 47 |
+
comments, commits, code, wiki edits, issues, and other contributions that are
|
| 48 |
+
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
| 49 |
+
decisions when appropriate.
|
| 50 |
+
|
| 51 |
+
## Scope
|
| 52 |
+
|
| 53 |
+
This Code of Conduct applies within all community spaces, and also applies when
|
| 54 |
+
an individual is officially representing the community in public spaces.
|
| 55 |
+
Examples of representing our community include using an official e-mail address,
|
| 56 |
+
posting via an official social media account, or acting as an appointed
|
| 57 |
+
representative at an online or offline event.
|
| 58 |
+
|
| 59 |
+
## Enforcement
|
| 60 |
+
|
| 61 |
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
| 62 |
+
reported to the community leaders responsible for enforcement at
|
| 63 |
+
dev@edm115.eu.org.
|
| 64 |
+
All complaints will be reviewed and investigated promptly and fairly.
|
| 65 |
+
|
| 66 |
+
All community leaders are obligated to respect the privacy and security of the
|
| 67 |
+
reporter of any incident.
|
| 68 |
+
|
| 69 |
+
## Enforcement Guidelines
|
| 70 |
+
|
| 71 |
+
Community leaders will follow these Community Impact Guidelines in determining
|
| 72 |
+
the consequences for any action they deem in violation of this Code of Conduct:
|
| 73 |
+
|
| 74 |
+
### 1. Correction
|
| 75 |
+
|
| 76 |
+
**Community Impact**: Use of inappropriate language or other behavior deemed
|
| 77 |
+
unprofessional or unwelcome in the community.
|
| 78 |
+
|
| 79 |
+
**Consequence**: A private, written warning from community leaders, providing
|
| 80 |
+
clarity around the nature of the violation and an explanation of why the
|
| 81 |
+
behavior was inappropriate. A public apology may be requested.
|
| 82 |
+
|
| 83 |
+
### 2. Warning
|
| 84 |
+
|
| 85 |
+
**Community Impact**: A violation through a single incident or series
|
| 86 |
+
of actions.
|
| 87 |
+
|
| 88 |
+
**Consequence**: A warning with consequences for continued behavior. No
|
| 89 |
+
interaction with the people involved, including unsolicited interaction with
|
| 90 |
+
those enforcing the Code of Conduct, for a specified period of time. This
|
| 91 |
+
includes avoiding interactions in community spaces as well as external channels
|
| 92 |
+
like social media. Violating these terms may lead to a temporary or
|
| 93 |
+
permanent ban.
|
| 94 |
+
|
| 95 |
+
### 3. Temporary Ban
|
| 96 |
+
|
| 97 |
+
**Community Impact**: A serious violation of community standards, including
|
| 98 |
+
sustained inappropriate behavior.
|
| 99 |
+
|
| 100 |
+
**Consequence**: A temporary ban from any sort of interaction or public
|
| 101 |
+
communication with the community for a specified period of time. No public or
|
| 102 |
+
private interaction with the people involved, including unsolicited interaction
|
| 103 |
+
with those enforcing the Code of Conduct, is allowed during this period.
|
| 104 |
+
Violating these terms may lead to a permanent ban.
|
| 105 |
+
|
| 106 |
+
### 4. Permanent Ban
|
| 107 |
+
|
| 108 |
+
**Community Impact**: Demonstrating a pattern of violation of community
|
| 109 |
+
standards, including sustained inappropriate behavior, harassment of an
|
| 110 |
+
individual, or aggression toward or disparagement of classes of individuals.
|
| 111 |
+
|
| 112 |
+
**Consequence**: A permanent ban from any sort of public interaction within
|
| 113 |
+
the community.
|
| 114 |
+
|
| 115 |
+
## Attribution
|
| 116 |
+
|
| 117 |
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
| 118 |
+
version 2.0, available at
|
| 119 |
+
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
| 120 |
+
|
| 121 |
+
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
| 122 |
+
enforcement ladder](https://github.com/mozilla/diversity).
|
| 123 |
+
|
| 124 |
+
[homepage]: https://www.contributor-covenant.org
|
| 125 |
+
|
| 126 |
+
For answers to common questions about this code of conduct, see the FAQ at
|
| 127 |
+
https://www.contributor-covenant.org/faq. Translations are available at
|
| 128 |
+
https://www.contributor-covenant.org/translations.
|
CreateMongoDB.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# How to create a MongoDB URL in 10min ?
|
| 2 |
+
|
| 3 |
+
1. Go to [MongoDB website](https://mongodb.com/cloud/atlas/register)
|
| 4 |
+
*(skip steps 2 and 3 if you already have an account, just create a new cluster)*
|
| 5 |
+
1. On the account setup page, choose wisely your Organization name and Project name (you can't change that). Select Python as preferred language
|
| 6 |
+
2. Choose `Create a cluster` on the `Shared Clusters` category (the free one)
|
| 7 |
+
3. Choose `Azure` as provider and `Netherlands` as region, then click on `Create Cluster` (it takes 1-5 minutes, but don't close the window !)
|
| 8 |
+
4. When it's done, click on `Network Access` on left panel
|
| 9 |
+
1. `Add IP Address`
|
| 10 |
+
2. `Allow access from anywhere` (because Heroku IP addresses changes everytime)
|
| 11 |
+
3. `Confirm` (it can take up to 2 minutes)
|
| 12 |
+
5. Click on `Clusters` on left panel
|
| 13 |
+
1. `Connect`
|
| 14 |
+
2. Create a Database User (remember the credentials you choose !)
|
| 15 |
+
3. `Choose a connection method`
|
| 16 |
+
4. `Connect with your application`
|
| 17 |
+
5. Choose `Python` as Driver
|
| 18 |
+
6. Choose `3.6 or later` as Version
|
| 19 |
+
7. Copy the URL
|
| 20 |
+
6. Replace `<password>` with the one you chosen at step 5.ii
|
| 21 |
+
|
| 22 |
+
## You're done :partying_face:
|
| 23 |
+
### Now use that as `MONGODB_URL`
|
Dockerfile
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM archlinux:latest
|
| 2 |
+
|
| 3 |
+
RUN pacman -Syyu --noconfirm
|
| 4 |
+
RUN pacman -S --noconfirm python-pip zstd p7zip gcc git ffmpeg
|
| 5 |
+
RUN python -m venv /venv
|
| 6 |
+
ENV PATH="/venv/bin:$PATH"
|
| 7 |
+
RUN pip install -U pip setuptools wheel
|
| 8 |
+
RUN mkdir /app/
|
| 9 |
+
WORKDIR /app/
|
| 10 |
+
RUN git clone https://github.com/EDM115/unzip-bot.git /app/
|
| 11 |
+
COPY requirements.txt /app/requirements.txt
|
| 12 |
+
RUN pip install -U -r requirements.txt
|
| 13 |
+
CMD bash start.sh
|
LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
MIT License
|
| 2 |
+
|
| 3 |
+
Copyright (c) 2022 - 2023 EDM115
|
| 4 |
+
|
| 5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 6 |
+
of this software and associated documentation files (the "Software"), to deal
|
| 7 |
+
in the Software without restriction, including without limitation the rights
|
| 8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 9 |
+
copies of the Software, and to permit persons to whom the Software is
|
| 10 |
+
furnished to do so, subject to the following conditions:
|
| 11 |
+
|
| 12 |
+
The above copyright notice and this permission notice shall be included in all
|
| 13 |
+
copies or substantial portions of the Software.
|
| 14 |
+
|
| 15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| 19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| 20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
| 21 |
+
SOFTWARE.
|
Procfile
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
unzipper: bash start.sh
|
app.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "Unzipper Bot",
|
| 3 |
+
"description": "A Telegram bot to extract various types of archives",
|
| 4 |
+
"logo": "https://telegra.ph/file/d4ba24682e030fc58613f.jpg",
|
| 5 |
+
"keywords": [
|
| 6 |
+
"7z",
|
| 7 |
+
"zip",
|
| 8 |
+
"rar",
|
| 9 |
+
"Telegram Bot",
|
| 10 |
+
"unzipper bot"
|
| 11 |
+
],
|
| 12 |
+
"website": "https://edm115.dev/unzip",
|
| 13 |
+
"repository": "https://github.com/EDM115/unzip-bot",
|
| 14 |
+
"success_url": "https://t.me/EDM115bots",
|
| 15 |
+
"env": {
|
| 16 |
+
"APP_ID": {
|
| 17 |
+
"description": "Your APP_ID from my.telegram.org",
|
| 18 |
+
"required": true
|
| 19 |
+
},
|
| 20 |
+
"API_HASH": {
|
| 21 |
+
"description": "Your API_HASH from my.telegram.org",
|
| 22 |
+
"required": true
|
| 23 |
+
},
|
| 24 |
+
"BOT_OWNER": {
|
| 25 |
+
"description": "Telegram Id of your account",
|
| 26 |
+
"required": true
|
| 27 |
+
},
|
| 28 |
+
"BOT_TOKEN": {
|
| 29 |
+
"description": "Your Bot Token From @BotFather",
|
| 30 |
+
"required": true
|
| 31 |
+
},
|
| 32 |
+
"MONGODB_URL": {
|
| 33 |
+
"description": "Your MongoDB url, Get it from https://www.mongodb.com/",
|
| 34 |
+
"required": true
|
| 35 |
+
},
|
| 36 |
+
"LOGS_CHANNEL": {
|
| 37 |
+
"description": "ID of a channel, can also be a group",
|
| 38 |
+
"required": true
|
| 39 |
+
}
|
| 40 |
+
},
|
| 41 |
+
"addons": [],
|
| 42 |
+
"buildpacks": [
|
| 43 |
+
{
|
| 44 |
+
"url": "heroku/python"
|
| 45 |
+
}
|
| 46 |
+
],
|
| 47 |
+
"formation": {
|
| 48 |
+
"worker": {
|
| 49 |
+
"quantity": 1,
|
| 50 |
+
"size": "eco"
|
| 51 |
+
}
|
| 52 |
+
},
|
| 53 |
+
"stack": "container"
|
| 54 |
+
}
|
bot_thumb.jpg
ADDED
|
|
changelog.md
ADDED
|
@@ -0,0 +1,427 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<div align="center">
|
| 2 |
+
|
| 3 |
+
<h1><a href="https://github.com/EDM115/unzip-bot" target="_blank" rel="noreferrer"><img src="https://telegra.ph/file/d4ba24682e030fc58613f.jpg" alt="unzip-bot" width="40" height="40"/></a> Unarchiver Bot • Changelog</h1>
|
| 4 |
+
|
| 5 |
+
## You will find here all the changes made with each version, in antichronological order
|
| 6 |
+
|
| 7 |
+
#### Convention : `vX.Y.Z`, where `X` stands for a major change and a lot of new features, `Y` for some new features and bug fixes, `Z` for testing stuff and undebugged things
|
| 8 |
+
|
| 9 |
+
</div>
|
| 10 |
+
|
| 11 |
+
---
|
| 12 |
+
|
| 13 |
+
### v6.3.2 **[LATEST STABLE RELEASE]**
|
| 14 |
+
|
| 15 |
+
- Fixed thumbnails not being saved
|
| 16 |
+
- Premium related stuff is moved to its own branch (buggy so yes)
|
| 17 |
+
- Fixed files being nearly all the time not uploaded
|
| 18 |
+
- Better logging
|
| 19 |
+
- Added [Mend Bolt](https://github.com/marketplace/whitesource-bolt)
|
| 20 |
+
- Downgraded pyromod to 1.5 again (too much errors, I know they had been fixed in 2.1.0 but still)
|
| 21 |
+
- Client specification in decorators instead of global @Client
|
| 22 |
+
- New maintenance logic
|
| 23 |
+
- Attempt to support files sent as TG links (may fail for topics, unaccessible chats and forward-restricted files)
|
| 24 |
+
|
| 25 |
+
### v6.3.1
|
| 26 |
+
|
| 27 |
+
- Finally fixed [#133](https://github.com/EDM115/unzip-bot/issues/133)
|
| 28 |
+
- Attempt to create a premium user to upload +2Gb files
|
| 29 |
+
- Added `/maintenance`
|
| 30 |
+
|
| 31 |
+
### v6.3.0
|
| 32 |
+
|
| 33 |
+
- Ongoing tasks are removed from the database after a restart
|
| 34 |
+
- Added a new command : /cleantasks
|
| 35 |
+
- Finally upgraded pyromod to v2
|
| 36 |
+
- Upgraded from python-3.11.3 to python-3.11.5
|
| 37 |
+
- Removed any trace of bayfiles upload since the service is dead
|
| 38 |
+
- Support for `.partx.rar` splitted archives
|
| 39 |
+
- Download files in 10 Mb chunks instead of 5 Mb
|
| 40 |
+
- Added maintenance on DB
|
| 41 |
+
- Aded VIP methods in DB + implementation of no-restrictions for VIP ([#205](https://github.com/EDM115/unzip-bot/issues/205))
|
| 42 |
+
|
| 43 |
+
### v6.2.4
|
| 44 |
+
|
| 45 |
+
- Attempt to add some URL parsers (fail)
|
| 46 |
+
- Even more refactor
|
| 47 |
+
- Splitted files can be renamed
|
| 48 |
+
- Url are checked before extracting
|
| 49 |
+
- If a thumbnail fails to be uploaded to telegra.ph, the error message is no longer saved in the db (and on download, non url strings are skipped)
|
| 50 |
+
- `/broadcast` now shows how many users had been processed
|
| 51 |
+
|
| 52 |
+
### v6.2.3
|
| 53 |
+
|
| 54 |
+
- Fixes little error on strings
|
| 55 |
+
- Closes a lot of issues opened by DeepSource (mostly style)
|
| 56 |
+
- Added a task limit (configurable in `config.py`)
|
| 57 |
+
- FloodWait is now handled correctly everywhere
|
| 58 |
+
- The bot is no longer blocking any task (finally)
|
| 59 |
+
|
| 60 |
+
### v6.2.2
|
| 61 |
+
|
| 62 |
+
- Bugfix : No longer use of `subprocess.communicate()`, as it's thread blocking
|
| 63 |
+
- All strings are in `bot_data.py`, hope this should ease [#179](https://github.com/EDM115/unzip-bot/issues/179)
|
| 64 |
+
- Even less thread block : use of `async for` and `yield`
|
| 65 |
+
- Any file unreachable/with a size of 0B is skipped, thus avoiding the bot being stuck on an impossible task
|
| 66 |
+
|
| 67 |
+
### v6.2.1
|
| 68 |
+
|
| 69 |
+
- Security fix : Merging files could lead to paths being swapped between users. It's now fixed
|
| 70 |
+
|
| 71 |
+
### v6.2.0
|
| 72 |
+
|
| 73 |
+
- Added a new command : /merge (and /done)
|
| 74 |
+
- Allows to merge splitted archives in .XXX format
|
| 75 |
+
- Upload of thumbnails on telegra.ph now handles errors
|
| 76 |
+
|
| 77 |
+
### v6.1.0
|
| 78 |
+
|
| 79 |
+
- URL's also shows a progressbar + ETA when possible
|
| 80 |
+
- Downloads are 28 times faster
|
| 81 |
+
- Some databases are cleared upon restart
|
| 82 |
+
- Attempt to implement [#137](https://github.com/EDM115/unzip-bot/issues/137)
|
| 83 |
+
- New boot sequence
|
| 84 |
+
|
| 85 |
+
### v6.0.0
|
| 86 |
+
|
| 87 |
+
- Dependencies update
|
| 88 |
+
- tgz and zst archives are now supported
|
| 89 |
+
- Thumbnail change tasks are now removed from DB after completion
|
| 90 |
+
- Dockerfile have been updated : Add of ffmpeg and venv
|
| 91 |
+
- Uploading videos as media is fixed ! [#133](https://github.com/EDM115/unzip-bot/issues/133)
|
| 92 |
+
- Added Docker instructions on the README
|
| 93 |
+
- Added GitHub Actions for Docker publishing and deployment
|
| 94 |
+
- Updated the FUNDING.yml
|
| 95 |
+
- New command : /donate, plus donate button appears on /start and after a task is processed
|
| 96 |
+
- Tell users that they can rate the bot after a task is processed
|
| 97 |
+
- [#33](https://github.com/EDM115/unzip-bot/issues/33) is gone (no longer useless alerts)
|
| 98 |
+
- ETA is now correct
|
| 99 |
+
- Tried to add a way to cancel tasks, but it's not working
|
| 100 |
+
- Files above 2 GB are now splitted
|
| 101 |
+
|
| 102 |
+
---
|
| 103 |
+
|
| 104 |
+
### v5.3.1
|
| 105 |
+
|
| 106 |
+
- Added /gitpull command to try the latest updates (removed at each restart)
|
| 107 |
+
- /delthumb also works locally
|
| 108 |
+
- Logs the boot time on database
|
| 109 |
+
- Clears the logs on /restart (because in the end they're sent before actually restarting)
|
| 110 |
+
- /user2 now correctly format the link when an username is provided
|
| 111 |
+
- Users are warned when the bot have restarted
|
| 112 |
+
- So the ongoing tasks are also stored in the DB
|
| 113 |
+
- And so /stats shows how many tasks are ongoing
|
| 114 |
+
- X7 archives are now supported
|
| 115 |
+
|
| 116 |
+
### v5.3.0
|
| 117 |
+
|
| 118 |
+
- Splitted archives are no longer processed (even .rar ones)
|
| 119 |
+
- Sending videos as media worked but now instantly fails for an unknown reason
|
| 120 |
+
- Heroku deployment file now complies to their drop of the free their
|
| 121 |
+
- Added THUMB_DEL buttons
|
| 122 |
+
- Added ZIPX support
|
| 123 |
+
- Added a Refresh button on /stats ([#143](https://github.com/EDM115/unzip-bot/issues/143))
|
| 124 |
+
|
| 125 |
+
### v5.2.2
|
| 126 |
+
|
| 127 |
+
- Happy new year 2023 🎉
|
| 128 |
+
- Avoids double ban/unban
|
| 129 |
+
- Fixed extentions recognition
|
| 130 |
+
- Added a "Processing task" message
|
| 131 |
+
|
| 132 |
+
|
| 133 |
+
### v5.2.1
|
| 134 |
+
|
| 135 |
+
- Added the website to /help
|
| 136 |
+
- Python 3.10 -> 3.11
|
| 137 |
+
- Added a new command : /report
|
| 138 |
+
|
| 139 |
+
### v5.2.0
|
| 140 |
+
|
| 141 |
+
- Removal of the personal_only and beta branches, only master remains
|
| 142 |
+
- Added permalink to the profile on /user2
|
| 143 |
+
- Half refactor, a lot of errors and misuse of functions gone
|
| 144 |
+
- Added renovate[bot]
|
| 145 |
+
- Better new user formatting
|
| 146 |
+
- ban/unban also acts on main user_db
|
| 147 |
+
- Added support for IPSW archives on request
|
| 148 |
+
|
| 149 |
+
### v5.1.2
|
| 150 |
+
|
| 151 |
+
- URL downloaded files finally have their original name
|
| 152 |
+
- Split goes stonks (lie)
|
| 153 |
+
- Prompting users to transload files I can't download
|
| 154 |
+
- What happens on the terminal is now on the logs
|
| 155 |
+
- Made /listdir and /sendfile for testing purposes
|
| 156 |
+
- Added issue templates
|
| 157 |
+
- /delthumb now also deletes it from the DB
|
| 158 |
+
|
| 159 |
+
### v5.1.1
|
| 160 |
+
|
| 161 |
+
- **Huge code refactoring**
|
| 162 |
+
- Little fixes
|
| 163 |
+
- Still trying to split files
|
| 164 |
+
- Thumbnail support is permanant 🥳 Redownloads them at every server restart
|
| 165 |
+
- Clears correctly the thumbnails
|
| 166 |
+
- FloodWait correctly handled
|
| 167 |
+
- Bot starting happens on another file (so we can use async/await)
|
| 168 |
+
|
| 169 |
+
### v5.1.0
|
| 170 |
+
|
| 171 |
+
- We fetch the file size *before* uploading
|
| 172 |
+
- We try to split files above 2 GB (fail)
|
| 173 |
+
|
| 174 |
+
### v5.0.3
|
| 175 |
+
|
| 176 |
+
- Added /user2 and /self
|
| 177 |
+
- Added ability to just change the thumbnail of the file (archive or not)
|
| 178 |
+
- Also we can rename it
|
| 179 |
+
|
| 180 |
+
### v5.0.2
|
| 181 |
+
|
| 182 |
+
- Heroku runtime shifted from Python 3.9.11 to 3.10.6
|
| 183 |
+
- Added wheel for faster deployment
|
| 184 |
+
- /getthumbs work
|
| 185 |
+
|
| 186 |
+
### v5.0.1
|
| 187 |
+
|
| 188 |
+
- Made thumbnail support better (with buttons)
|
| 189 |
+
- Saves the thumbnail URL (telegra.ph) to the DB
|
| 190 |
+
- Buttons are side-by-side
|
| 191 |
+
- Checks if sent file is actually an archive (so we stop processing PDF and MKV 😭)
|
| 192 |
+
- Code style shifted to Black 🖤
|
| 193 |
+
- Upgraded to Pyrogram v2 (finally)
|
| 194 |
+
- The bot can process other things while extracting
|
| 195 |
+
- Better password handling
|
| 196 |
+
- Progressbar on uploads too
|
| 197 |
+
- Uploads as media by default
|
| 198 |
+
- Avoids splitted archives to be processed
|
| 199 |
+
- Better LOG_CHANNEL verification
|
| 200 |
+
|
| 201 |
+
### v5.0.0
|
| 202 |
+
|
| 203 |
+
- Added extensions list (for verification)
|
| 204 |
+
- Medias are sent as native media
|
| 205 |
+
- Fixed ENTITY_BOUNDS_INVALID error
|
| 206 |
+
- Removed numpy as we don't use it
|
| 207 |
+
- Added requests
|
| 208 |
+
- Added development followup ([#38](https://github.com/EDM115/unzip-bot/issues/38))
|
| 209 |
+
- Uptime on /stats works correctly
|
| 210 |
+
- Simpler buttons
|
| 211 |
+
- Thumbnails on upload are officially supported 🥳
|
| 212 |
+
- Commands updates (no /setmode, /me become /info, addded stats for everyone)
|
| 213 |
+
|
| 214 |
+
---
|
| 215 |
+
|
| 216 |
+
### v4.5.0
|
| 217 |
+
|
| 218 |
+
- Attempt to add /merge and /cancel commands + linked callbacks. Actually failed
|
| 219 |
+
|
| 220 |
+
### v4.4.5
|
| 221 |
+
|
| 222 |
+
- The logs are better. Putting the text message _before_ file, as it does with URL & replies to text message instead of file
|
| 223 |
+
- Made a way more permissive regex for URL
|
| 224 |
+
- Fixed exceptions on nearly all commands
|
| 225 |
+
- Performing a /restart send the logs automatically
|
| 226 |
+
|
| 227 |
+
### v4.4.4
|
| 228 |
+
|
| 229 |
+
- Definitely fixed #NEW_USER
|
| 230 |
+
- Once again tweaks on BayFiles
|
| 231 |
+
|
| 232 |
+
### v4.4.3
|
| 233 |
+
|
| 234 |
+
- Way better handling of `check_logs()` on start
|
| 235 |
+
- Fixed the #NEW_USER
|
| 236 |
+
- Few changes on BayFiles upload
|
| 237 |
+
|
| 238 |
+
### v4.4.2
|
| 239 |
+
|
| 240 |
+
- A lot of changes on BayFiles upload :
|
| 241 |
+
- Errors sent to logs
|
| 242 |
+
- Formatting the results with size, url and filename
|
| 243 |
+
- Correct formatting of the errors
|
| 244 |
+
- Created get_cloud(), will improve it to let choose the upload platform for the user (bayfiles, anonfiles, …)
|
| 245 |
+
|
| 246 |
+
### v4.4.1
|
| 247 |
+
|
| 248 |
+
- Instead of using things from other users, I use the official curl method from BayFiles docs
|
| 249 |
+
|
| 250 |
+
### v4.4.0
|
| 251 |
+
|
| 252 |
+
- If a file is above 2 Gb, it's uploaded to Bayfiles instead
|
| 253 |
+
- Better get_files() according to what Nexa made. Looks faster
|
| 254 |
+
|
| 255 |
+
### v4.3.4
|
| 256 |
+
|
| 257 |
+
- Fixed crashes
|
| 258 |
+
- Made `/stats` working for non owner, as requested in [#34](https://github.com/EDM115/unzip-bot/issues/34)
|
| 259 |
+
|
| 260 |
+
### v4.3.3
|
| 261 |
+
|
| 262 |
+
- Added `/getthumbs`, which don't work 😅
|
| 263 |
+
- User Name is better on the database (better formatting when he joins)
|
| 264 |
+
|
| 265 |
+
### v4.3.2
|
| 266 |
+
|
| 267 |
+
- Custom thumb made better + logging on it
|
| 268 |
+
|
| 269 |
+
### v4.3.1
|
| 270 |
+
|
| 271 |
+
- Buggy thumbnails (files didn't uploads due to this)
|
| 272 |
+
- That version crashes
|
| 273 |
+
- The thumbnail is resized according to Telegram API specifications
|
| 274 |
+
- Thumbnails are saved to a separate folder
|
| 275 |
+
- Created thumb_exists()
|
| 276 |
+
|
| 277 |
+
### v4.3.0
|
| 278 |
+
|
| 279 |
+
- Created this changelog to track updates
|
| 280 |
+
- Once again updated the uptime
|
| 281 |
+
- Added numpy and Pillow in the requirements
|
| 282 |
+
- Tried to have a thumbnail support. Nevertheless, it's removed at each restart. Will look for a Telegra.ph support
|
| 283 |
+
|
| 284 |
+
### v4.2.1
|
| 285 |
+
|
| 286 |
+
- Major bug fixes
|
| 287 |
+
|
| 288 |
+
### v4.2.0
|
| 289 |
+
|
| 290 |
+
- Added workaround for [#26](https://github.com/EDM115/unzip-bot/issues/26)
|
| 291 |
+
- The bot now edit its messages each 7s (instead of 10s)
|
| 292 |
+
- Attempt to make a really better ETA
|
| 293 |
+
- Working around allowing user to cancel file/URL download (will look for the extracting process, bot can't reply while extracting)
|
| 294 |
+
|
| 295 |
+
### v4.1.1
|
| 296 |
+
|
| 297 |
+
- Reduced amount of lines in logs (that was too much 💀)
|
| 298 |
+
- Definitely fixed the bug of `v4.0.1`
|
| 299 |
+
- Better texts
|
| 300 |
+
- Keyboard now refreshes correctly after sending a file
|
| 301 |
+
|
| 302 |
+
### v4.1.0
|
| 303 |
+
|
| 304 |
+
- Better handling of issue #2 + better usage of it (no longer systematically delete message)
|
| 305 |
+
- Added `/dbexport`, `/commands`, `/admincmd`
|
| 306 |
+
- Added exec and eval, but not usable now
|
| 307 |
+
|
| 308 |
+
### v4.0.7
|
| 309 |
+
|
| 310 |
+
- Empty keyboard buttons are side to side
|
| 311 |
+
|
| 312 |
+
### v4.0.6
|
| 313 |
+
|
| 314 |
+
- Major bug fixes
|
| 315 |
+
|
| 316 |
+
### v4.0.5
|
| 317 |
+
|
| 318 |
+
- Tried to add date+time on logs filename. Can't actually do it because I will need to work with wildcards
|
| 319 |
+
- Added logging for motor and asyncio
|
| 320 |
+
- Added `/sendto` that works like `/broadcast` but to a single user. Works with chats and channels too. Will look for handling replies as well
|
| 321 |
+
- You can use commands in more places
|
| 322 |
+
|
| 323 |
+
### v4.0.4
|
| 324 |
+
|
| 325 |
+
- Major bug fixes
|
| 326 |
+
- Upload count return 0 instead of None if it doesn't exist
|
| 327 |
+
- Try to automatically perform a `/clean` when a task failed
|
| 328 |
+
|
| 329 |
+
### v4.0.3
|
| 330 |
+
|
| 331 |
+
- Logs message now replies to the concerned archive. Better if multiple archives are processed at the same time
|
| 332 |
+
- Errors shows up in logs
|
| 333 |
+
- Created an empty keyboard where only Upload all & Cancel shows up
|
| 334 |
+
- Fixed major bug : REPLY_MARKUP_TOO_LONG ([#2](https://github.com/EDM115/unzip-bot/issues/2))
|
| 335 |
+
- Try to close session (to fix [#4](https://github.com/EDM115/unzip-bot/issues/4))
|
| 336 |
+
|
| 337 |
+
### v4.0.2
|
| 338 |
+
|
| 339 |
+
- `/mode` work finally as expected _(previous behavior added users to banned db when they changed their upload mode, thus the command couldn't work. That huge bug is present in Nexa's repo)_
|
| 340 |
+
- Created a TimeFormatter with seconds as input
|
| 341 |
+
- Created upload file count (buggy). Barely saves in DB + only shows up in logs when user selected upload all mode
|
| 342 |
+
|
| 343 |
+
### v4.0.1
|
| 344 |
+
|
| 345 |
+
- Tried to fetch the SITERM signal
|
| 346 |
+
- Trying to fix a bug where the User Id no longer shows up in logs
|
| 347 |
+
|
| 348 |
+
### v4.0.0
|
| 349 |
+
|
| 350 |
+
- Added logging instead of print
|
| 351 |
+
- Bot sends start time to logs _(may send stop time as well, but I need to handle SIGTERM gracefully)_
|
| 352 |
+
- `/restart` now works _(but not as expected. Instead of killing and restart the process, it creates a subprocess that behave the same way)_
|
| 353 |
+
- Added `/logs` to send a `.txt` containing the logs to the owner
|
| 354 |
+
|
| 355 |
+
---
|
| 356 |
+
|
| 357 |
+
### v3.3.4
|
| 358 |
+
|
| 359 |
+
- More emojis
|
| 360 |
+
- Created `/help` and `/about` from home text
|
| 361 |
+
|
| 362 |
+
### v3.3.3
|
| 363 |
+
|
| 364 |
+
- Minor bug fixes
|
| 365 |
+
|
| 366 |
+
### v3.3.2
|
| 367 |
+
|
| 368 |
+
- Fully upgraded `/stats`
|
| 369 |
+
- Added `/redbutton`, `/restart`, `/cleanall`, `/addthumb`, `/delthumb`
|
| 370 |
+
|
| 371 |
+
### v3.3.1
|
| 372 |
+
|
| 373 |
+
- Minor text changes
|
| 374 |
+
|
| 375 |
+
### v3.3.0
|
| 376 |
+
|
| 377 |
+
- Password archives no longer shows an empty upload button
|
| 378 |
+
- Sends file downloaded from URL to logs
|
| 379 |
+
|
| 380 |
+
### v3.2.2
|
| 381 |
+
|
| 382 |
+
- Added password warning in both user chat and logs
|
| 383 |
+
|
| 384 |
+
### v3.2.1
|
| 385 |
+
|
| 386 |
+
- Less imports on `ext_helper.py`
|
| 387 |
+
|
| 388 |
+
### v3.2.0
|
| 389 |
+
|
| 390 |
+
- Added another HumanBytes and functions for a better ETA
|
| 391 |
+
- BIG CHANGE : Bot no longer hang up when a password protected archive is extracted normally ! 🥳
|
| 392 |
+
|
| 393 |
+
### v3.1.1
|
| 394 |
+
|
| 395 |
+
- Fixed some errors
|
| 396 |
+
|
| 397 |
+
### v3.1.0
|
| 398 |
+
|
| 399 |
+
- Captions _really_ works now
|
| 400 |
+
|
| 401 |
+
### v3.0.2
|
| 402 |
+
|
| 403 |
+
- Added precise versionning of packages (due to PyroGram 2 release)
|
| 404 |
+
- Python 3.9.11 as default runtime
|
| 405 |
+
- Removed mentions of Nexa since this project take a slightly different direction
|
| 406 |
+
|
| 407 |
+
### v3.0.1
|
| 408 |
+
|
| 409 |
+
- Added `/me`, `/user`, `/db`, `/dbdive`
|
| 410 |
+
|
| 411 |
+
### v3.0.0
|
| 412 |
+
|
| 413 |
+
- Added filename in description while uploading
|
| 414 |
+
- Sending password of archive in logs
|
| 415 |
+
|
| 416 |
+
---
|
| 417 |
+
|
| 418 |
+
### v2.0.0
|
| 419 |
+
|
| 420 |
+
- Same as `v1.0.0`, but with text changed, typos fixed, mentions of me, more emojis, less formatting, …
|
| 421 |
+
- Changed license from GPL 3.0 to MIT
|
| 422 |
+
|
| 423 |
+
---
|
| 424 |
+
|
| 425 |
+
### v1.0.0
|
| 426 |
+
|
| 427 |
+
- Consider this as the [original work of Nexa](https://github.com/EDM115/unzip-bot#license--copyright-%EF%B8%8F)
|
config.py
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) 2023 EDM115
|
| 2 |
+
import os
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
class Config:
|
| 6 |
+
APP_ID = int(os.environ.get("APP_ID"))
|
| 7 |
+
API_HASH = os.environ.get("API_HASH")
|
| 8 |
+
BOT_TOKEN = os.environ.get("BOT_TOKEN")
|
| 9 |
+
LOGS_CHANNEL = int(os.environ.get("LOGS_CHANNEL"))
|
| 10 |
+
MONGODB_URL = os.environ.get("MONGODB_URL")
|
| 11 |
+
BOT_OWNER = int(os.environ.get("BOT_OWNER"))
|
| 12 |
+
DOWNLOAD_LOCATION = f"{os.path.dirname(__file__)}/Downloaded"
|
| 13 |
+
THUMB_LOCATION = f"{os.path.dirname(__file__)}/Thumbnails"
|
| 14 |
+
TG_MAX_SIZE = 2097152000
|
| 15 |
+
# Default chunk size (0.005 MB → 1024*6) Increase if you need faster downloads
|
| 16 |
+
CHUNK_SIZE = 1024 * 1024 * 10 # 10 MB
|
| 17 |
+
BOT_THUMB = f"{os.path.dirname(__file__)}/bot_thumb.jpg"
|
| 18 |
+
MAX_CONCURRENT_TASKS = 50
|
| 19 |
+
MAX_TASK_DURATION_EXTRACT = 45 * 60 # 45 minutes (in seconds)
|
| 20 |
+
MAX_TASK_DURATION_MERGE = 90 * 60 # 1 hour 30 minutes (in seconds)
|
heroku.yml
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
build:
|
| 2 |
+
docker:
|
| 3 |
+
worker: Dockerfile
|
| 4 |
+
run:
|
| 5 |
+
worker: bash start.sh
|
renovate.json
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
| 3 |
+
"extends": [
|
| 4 |
+
"config:base"
|
| 5 |
+
]
|
| 6 |
+
}
|
requirements.txt
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
aiofiles==23.2.1
|
| 2 |
+
aiohttp==3.8.5
|
| 3 |
+
base58check==1.0.2
|
| 4 |
+
dnspython==2.4.2
|
| 5 |
+
gitdb==4.0.10
|
| 6 |
+
GitPython==3.1.37
|
| 7 |
+
motor==3.3.1
|
| 8 |
+
Pillow==10.0.1
|
| 9 |
+
psutil==5.9.5
|
| 10 |
+
pykeyboard==0.1.5
|
| 11 |
+
pyrogram==2.0.106
|
| 12 |
+
pyromod==1.5
|
| 13 |
+
requests==2.31.0
|
| 14 |
+
TgCrypto==1.2.5
|
| 15 |
+
unzip-http==0.4
|
runtime.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
python-3.11.5
|
start.sh
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
echo "
|
| 2 |
+
🔥 Unzip Bot 🔥
|
| 3 |
+
|
| 4 |
+
Copyright (c) 2022 - 2023 EDM115
|
| 5 |
+
|
| 6 |
+
--> Join @EDM115bots on Telegram
|
| 7 |
+
--> Follow EDM115 on Github
|
| 8 |
+
"
|
| 9 |
+
python3 -m unzipper
|
unzipper/__init__.py
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) 2023 EDM115
|
| 2 |
+
import logging
|
| 3 |
+
import time
|
| 4 |
+
|
| 5 |
+
from pyrogram import Client
|
| 6 |
+
from pyromod import listen # skipcq: PY-W2000
|
| 7 |
+
|
| 8 |
+
from config import Config
|
| 9 |
+
|
| 10 |
+
boottime = time.time()
|
| 11 |
+
|
| 12 |
+
plugins = dict(root="modules")
|
| 13 |
+
unzipperbot = Client(
|
| 14 |
+
"UnzipperBot",
|
| 15 |
+
bot_token=Config.BOT_TOKEN,
|
| 16 |
+
api_id=Config.APP_ID,
|
| 17 |
+
api_hash=Config.API_HASH,
|
| 18 |
+
plugins=plugins,
|
| 19 |
+
sleep_threshold=10,
|
| 20 |
+
max_concurrent_transmissions=3,
|
| 21 |
+
)
|
| 22 |
+
|
| 23 |
+
logging.basicConfig(
|
| 24 |
+
level=logging.INFO,
|
| 25 |
+
handlers=[logging.FileHandler("unzip-log.txt"), logging.StreamHandler()],
|
| 26 |
+
format="%(asctime)s - %(levelname)s - %(name)s - %(threadName)s - %(message)s",
|
| 27 |
+
)
|
| 28 |
+
LOGGER = logging.getLogger(__name__)
|
| 29 |
+
logging.getLogger("asyncio").setLevel(logging.WARNING)
|
| 30 |
+
logging.getLogger("aiohttp").setLevel(logging.WARNING)
|
| 31 |
+
logging.getLogger("aiofiles").setLevel(logging.WARNING)
|
| 32 |
+
logging.getLogger("dnspython").setLevel(logging.WARNING)
|
| 33 |
+
logging.getLogger("GitPython").setLevel(logging.WARNING)
|
| 34 |
+
logging.getLogger("motor").setLevel(logging.WARNING)
|
| 35 |
+
logging.getLogger("Pillow").setLevel(logging.WARNING)
|
| 36 |
+
logging.getLogger("psutil").setLevel(logging.WARNING)
|
| 37 |
+
logging.getLogger("pyrogram").setLevel(logging.WARNING)
|
| 38 |
+
logging.getLogger("requests").setLevel(logging.WARNING)
|
unzipper/__main__.py
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) 2023 EDM115
|
| 2 |
+
import logging
|
| 3 |
+
import os
|
| 4 |
+
import signal
|
| 5 |
+
import time
|
| 6 |
+
|
| 7 |
+
from pyrogram import idle
|
| 8 |
+
from pyrogram.errors import AuthKeyDuplicated
|
| 9 |
+
|
| 10 |
+
from config import Config
|
| 11 |
+
|
| 12 |
+
from . import LOGGER, unzipperbot
|
| 13 |
+
from .helpers.start import check_logs, dl_thumbs, set_boot_time, removal
|
| 14 |
+
from .modules.bot_data import Messages
|
| 15 |
+
|
| 16 |
+
running = True
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
def handler_stop_signals(signum, frame):
|
| 20 |
+
global running
|
| 21 |
+
running = False
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
signal.signal(signal.SIGINT, handler_stop_signals)
|
| 25 |
+
signal.signal(signal.SIGTERM, handler_stop_signals)
|
| 26 |
+
|
| 27 |
+
while running:
|
| 28 |
+
if __name__ == "__main__":
|
| 29 |
+
if not os.path.isdir(Config.DOWNLOAD_LOCATION):
|
| 30 |
+
os.makedirs(Config.DOWNLOAD_LOCATION)
|
| 31 |
+
if not os.path.isdir(Config.THUMB_LOCATION):
|
| 32 |
+
os.makedirs(Config.THUMB_LOCATION)
|
| 33 |
+
LOGGER.info(Messages.STARTING_BOT)
|
| 34 |
+
unzipperbot.start()
|
| 35 |
+
starttime = time.strftime("%Y/%m/%d - %H:%M:%S")
|
| 36 |
+
unzipperbot.send_message(
|
| 37 |
+
chat_id=Config.LOGS_CHANNEL, text=Messages.START_TXT.format(starttime)
|
| 38 |
+
)
|
| 39 |
+
set_boot_time()
|
| 40 |
+
dl_thumbs()
|
| 41 |
+
LOGGER.info(Messages.CHECK_LOG)
|
| 42 |
+
if check_logs():
|
| 43 |
+
LOGGER.info(Messages.LOG_CHECKED)
|
| 44 |
+
LOGGER.info(Messages.BOT_RUNNING)
|
| 45 |
+
removal(True)
|
| 46 |
+
idle()
|
| 47 |
+
else:
|
| 48 |
+
try:
|
| 49 |
+
unzipperbot.send_message(
|
| 50 |
+
chat_id=Config.BOT_OWNER,
|
| 51 |
+
text=Messages.WRONG_LOG.format(Config.LOGS_CHANNEL),
|
| 52 |
+
)
|
| 53 |
+
except:
|
| 54 |
+
pass
|
| 55 |
+
unzipperbot.stop()
|
| 56 |
+
|
| 57 |
+
LOGGER.info("Received SIGTERM")
|
| 58 |
+
stoptime = time.strftime("%Y/%m/%d - %H:%M:%S")
|
| 59 |
+
unzipperbot.send_message(
|
| 60 |
+
chat_id=Config.LOGS_CHANNEL, text=Messages.STOP_TXT.format(stoptime)
|
| 61 |
+
)
|
| 62 |
+
unzipperbot.stop()
|
| 63 |
+
LOGGER.info("Bot stopped 😪")
|
unzipper/helpers/database.py
ADDED
|
@@ -0,0 +1,519 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) 2023 EDM115
|
| 2 |
+
|
| 3 |
+
from motor.motor_asyncio import AsyncIOMotorClient
|
| 4 |
+
import requests
|
| 5 |
+
import base58check
|
| 6 |
+
|
| 7 |
+
from config import Config
|
| 8 |
+
from asyncio import sleep
|
| 9 |
+
from pyrogram.errors import FloodWait
|
| 10 |
+
from unzipper import LOGGER, unzipperbot
|
| 11 |
+
from unzipper.modules.bot_data import Messages
|
| 12 |
+
|
| 13 |
+
mongodb = AsyncIOMotorClient(Config.MONGODB_URL)
|
| 14 |
+
unzipper_db = mongodb["Unzipper_Bot"]
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
# Users Database
|
| 18 |
+
user_db = unzipper_db["users_db"]
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
async def add_user(user_id):
|
| 22 |
+
new_user_id = int(user_id)
|
| 23 |
+
is_exist = await user_db.find_one({"user_id": new_user_id})
|
| 24 |
+
if is_exist is not None and is_exist:
|
| 25 |
+
return -1
|
| 26 |
+
await user_db.insert_one({"user_id": new_user_id})
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
async def del_user(user_id):
|
| 30 |
+
del_user_id = int(user_id)
|
| 31 |
+
is_exist = await user_db.find_one({"user_id": del_user_id})
|
| 32 |
+
if is_exist is not None and is_exist:
|
| 33 |
+
await user_db.delete_one({"user_id": del_user_id})
|
| 34 |
+
else:
|
| 35 |
+
return -1
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
async def is_user_in_db(user_id):
|
| 39 |
+
u_id = int(user_id)
|
| 40 |
+
is_exist = await user_db.find_one({"user_id": u_id})
|
| 41 |
+
if is_exist is not None and is_exist:
|
| 42 |
+
return True
|
| 43 |
+
return False
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
async def count_users():
|
| 47 |
+
users = await user_db.count_documents({})
|
| 48 |
+
return users
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
async def get_users_list():
|
| 52 |
+
return [users_list async for users_list in user_db.find({})]
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
# Banned users database
|
| 56 |
+
b_user_db = unzipper_db["banned_users_db"]
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
async def add_banned_user(user_id):
|
| 60 |
+
new_user_id = int(user_id)
|
| 61 |
+
is_exist = await b_user_db.find_one({"banned_user_id": new_user_id})
|
| 62 |
+
if is_exist is not None and is_exist:
|
| 63 |
+
return -1
|
| 64 |
+
await b_user_db.insert_one({"banned_user_id": new_user_id})
|
| 65 |
+
|
| 66 |
+
|
| 67 |
+
async def del_banned_user(user_id):
|
| 68 |
+
del_user_id = int(user_id)
|
| 69 |
+
is_exist = await b_user_db.find_one({"banned_user_id": del_user_id})
|
| 70 |
+
if is_exist is not None and is_exist:
|
| 71 |
+
await b_user_db.delete_one({"banned_user_id": del_user_id})
|
| 72 |
+
else:
|
| 73 |
+
return -1
|
| 74 |
+
|
| 75 |
+
|
| 76 |
+
async def is_user_in_bdb(user_id):
|
| 77 |
+
u_id = int(user_id)
|
| 78 |
+
is_exist = await b_user_db.find_one({"banned_user_id": u_id})
|
| 79 |
+
if is_exist is not None and is_exist:
|
| 80 |
+
return True
|
| 81 |
+
return False
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
async def count_banned_users():
|
| 85 |
+
users = await b_user_db.count_documents({})
|
| 86 |
+
return users
|
| 87 |
+
|
| 88 |
+
|
| 89 |
+
async def get_banned_users_list():
|
| 90 |
+
return [banned_users_list async for banned_users_list in b_user_db.find({})]
|
| 91 |
+
|
| 92 |
+
|
| 93 |
+
async def check_user(message):
|
| 94 |
+
# Checking if user is banned
|
| 95 |
+
is_banned = await is_user_in_bdb(message.from_user.id)
|
| 96 |
+
if is_banned:
|
| 97 |
+
await message.reply(Messages.BANNED)
|
| 98 |
+
await message.stop_propagation()
|
| 99 |
+
return
|
| 100 |
+
# Checking if user already in db
|
| 101 |
+
is_in_db = await is_user_in_db(message.from_user.id)
|
| 102 |
+
if not is_in_db:
|
| 103 |
+
await add_user(message.from_user.id)
|
| 104 |
+
try:
|
| 105 |
+
firstname = message.from_user.first_name
|
| 106 |
+
except:
|
| 107 |
+
firstname = " "
|
| 108 |
+
try:
|
| 109 |
+
lastname = message.from_user.last_name
|
| 110 |
+
except:
|
| 111 |
+
lastname = " "
|
| 112 |
+
try:
|
| 113 |
+
username = message.from_user.username
|
| 114 |
+
except:
|
| 115 |
+
username = " "
|
| 116 |
+
if firstname == " " and lastname == " " and username == " ":
|
| 117 |
+
uname = message.from_user.mention
|
| 118 |
+
try:
|
| 119 |
+
await unzipperbot.send_message(
|
| 120 |
+
chat_id=Config.LOGS_CHANNEL,
|
| 121 |
+
text=Messages.NEW_USER_BAD.format(uname),
|
| 122 |
+
disable_web_page_preview=False,
|
| 123 |
+
)
|
| 124 |
+
except FloodWait as f:
|
| 125 |
+
await sleep(f.value)
|
| 126 |
+
await unzipperbot.send_message(
|
| 127 |
+
chat_id=Config.LOGS_CHANNEL,
|
| 128 |
+
text=Messages.NEW_USER_BAD.format(uname),
|
| 129 |
+
disable_web_page_preview=False,
|
| 130 |
+
)
|
| 131 |
+
else:
|
| 132 |
+
if firstname is None:
|
| 133 |
+
firstname = " "
|
| 134 |
+
if lastname is None:
|
| 135 |
+
lastname = " "
|
| 136 |
+
if username is None:
|
| 137 |
+
username = " "
|
| 138 |
+
uname = firstname + " " + lastname
|
| 139 |
+
umention = " | @" + username
|
| 140 |
+
try:
|
| 141 |
+
await unzipperbot.send_message(
|
| 142 |
+
chat_id=Config.LOGS_CHANNEL,
|
| 143 |
+
text=Messages.NEW_USER.format(uname, umention, message.from_user.id, message.from_user.id, message.from_user.id),
|
| 144 |
+
disable_web_page_preview=False,
|
| 145 |
+
)
|
| 146 |
+
except FloodWait as f:
|
| 147 |
+
await sleep(f.value)
|
| 148 |
+
await unzipperbot.send_message(
|
| 149 |
+
chat_id=Config.LOGS_CHANNEL,
|
| 150 |
+
text=Messages.NEW_USER.format(uname, umention, message.from_user.id, message.from_user.id, message.from_user.id),
|
| 151 |
+
disable_web_page_preview=False,
|
| 152 |
+
)
|
| 153 |
+
await message.continue_propagation()
|
| 154 |
+
|
| 155 |
+
|
| 156 |
+
async def get_all_users():
|
| 157 |
+
users = []
|
| 158 |
+
banned = []
|
| 159 |
+
for i in range(await count_users()):
|
| 160 |
+
users.append((await get_users_list())[i]["user_id"])
|
| 161 |
+
for j in range(await count_banned_users()):
|
| 162 |
+
banned.append((await get_banned_users_list())[j]["banned_user_id"])
|
| 163 |
+
return users, banned
|
| 164 |
+
|
| 165 |
+
|
| 166 |
+
# Upload mode
|
| 167 |
+
mode_db = unzipper_db["ulmode_db"]
|
| 168 |
+
|
| 169 |
+
|
| 170 |
+
async def set_upload_mode(user_id, mode):
|
| 171 |
+
is_exist = await mode_db.find_one({"_id": user_id})
|
| 172 |
+
if is_exist is not None and is_exist:
|
| 173 |
+
await mode_db.update_one({"_id": user_id}, {"$set": {"mode": mode}})
|
| 174 |
+
else:
|
| 175 |
+
await mode_db.insert_one({"_id": user_id, "mode": mode})
|
| 176 |
+
|
| 177 |
+
|
| 178 |
+
async def get_upload_mode(user_id):
|
| 179 |
+
umode = await mode_db.find_one({"_id": user_id})
|
| 180 |
+
if umode is not None and umode:
|
| 181 |
+
return umode["mode"]
|
| 182 |
+
return "media"
|
| 183 |
+
|
| 184 |
+
|
| 185 |
+
# Db for how many files user uploaded
|
| 186 |
+
uploaded_db = unzipper_db["uploaded_count_db"]
|
| 187 |
+
|
| 188 |
+
|
| 189 |
+
async def get_uploaded(user_id):
|
| 190 |
+
up_count = await uploaded_db.find_one({"_id": user_id})
|
| 191 |
+
if up_count is not None and up_count:
|
| 192 |
+
return up_count["uploaded_files"]
|
| 193 |
+
return 0
|
| 194 |
+
|
| 195 |
+
|
| 196 |
+
async def update_uploaded(user_id, upload_count):
|
| 197 |
+
is_exist = await uploaded_db.find_one({"_id": user_id})
|
| 198 |
+
if is_exist is not None and is_exist:
|
| 199 |
+
new_count = await get_uploaded(user_id) + upload_count
|
| 200 |
+
await uploaded_db.update_one(
|
| 201 |
+
{"_id": user_id}, {"$set": {"uploaded_files": new_count}}
|
| 202 |
+
)
|
| 203 |
+
else:
|
| 204 |
+
await uploaded_db.insert_one({"_id": user_id, "uploaded_files": upload_count})
|
| 205 |
+
|
| 206 |
+
|
| 207 |
+
# DB for thumbnails
|
| 208 |
+
thumb_db = unzipper_db["thumb_db"]
|
| 209 |
+
|
| 210 |
+
|
| 211 |
+
async def get_thumb(user_id):
|
| 212 |
+
existing = await thumb_db.find_one({"_id": user_id})
|
| 213 |
+
if existing is not None and existing:
|
| 214 |
+
return existing["url"]
|
| 215 |
+
return None
|
| 216 |
+
|
| 217 |
+
|
| 218 |
+
async def update_thumb(user_id, thumb_url, force):
|
| 219 |
+
existing = await thumb_db.find_one({"_id": user_id})
|
| 220 |
+
if existing is not None and existing:
|
| 221 |
+
if not force:
|
| 222 |
+
return existing["url"]
|
| 223 |
+
await thumb_db.update_one({"_id": user_id}, {"$set": {"url": thumb_url}})
|
| 224 |
+
else:
|
| 225 |
+
await thumb_db.insert_one({"_id": user_id, "url": thumb_url})
|
| 226 |
+
|
| 227 |
+
|
| 228 |
+
async def upload_thumb(image):
|
| 229 |
+
try:
|
| 230 |
+
with open(image, "rb") as file:
|
| 231 |
+
response = requests.post(
|
| 232 |
+
"https://telegra.ph/upload", files={"file": ("file", file, "image/jpeg")}
|
| 233 |
+
)
|
| 234 |
+
response.raise_for_status() # Raise an exception if the request was not successful
|
| 235 |
+
request = response.json()[0]
|
| 236 |
+
LOGGER.info(response.json())
|
| 237 |
+
return f"https://telegra.ph{request['src']}"
|
| 238 |
+
except requests.exceptions.RequestException as err:
|
| 239 |
+
LOGGER.warning("Error occurred during telegra.ph upload : %s", err)
|
| 240 |
+
return -1
|
| 241 |
+
|
| 242 |
+
|
| 243 |
+
async def get_thumb_users():
|
| 244 |
+
return [thumb_list async for thumb_list in thumb_db.find({})]
|
| 245 |
+
|
| 246 |
+
|
| 247 |
+
async def count_thumb_users():
|
| 248 |
+
users = await thumb_db.count_documents({})
|
| 249 |
+
return users
|
| 250 |
+
|
| 251 |
+
|
| 252 |
+
async def del_thumb_db(user_id):
|
| 253 |
+
del_thumb_id = int(user_id)
|
| 254 |
+
is_exist = await thumb_db.find_one({"_id": del_thumb_id})
|
| 255 |
+
if is_exist is not None and is_exist:
|
| 256 |
+
await thumb_db.delete_one({"_id": del_thumb_id})
|
| 257 |
+
else:
|
| 258 |
+
return
|
| 259 |
+
|
| 260 |
+
|
| 261 |
+
# DB for bot data
|
| 262 |
+
bot_data = unzipper_db["bot_data"]
|
| 263 |
+
|
| 264 |
+
|
| 265 |
+
async def get_boot():
|
| 266 |
+
boot = await bot_data.find_one({"boot": True})
|
| 267 |
+
if boot is not None and boot:
|
| 268 |
+
return boot["time"]
|
| 269 |
+
return boot
|
| 270 |
+
|
| 271 |
+
|
| 272 |
+
async def set_boot(boottime):
|
| 273 |
+
is_exist = await bot_data.find_one({"boot": True})
|
| 274 |
+
if is_exist is not None and is_exist:
|
| 275 |
+
await bot_data.update_one({"boot": True}, {"$set": {"time": boottime}})
|
| 276 |
+
else:
|
| 277 |
+
await bot_data.insert_one({"boot": True, "time": boottime})
|
| 278 |
+
|
| 279 |
+
|
| 280 |
+
async def set_old_boot(boottime):
|
| 281 |
+
is_exist = await bot_data.find_one({"old_boot": True})
|
| 282 |
+
if is_exist is not None and is_exist:
|
| 283 |
+
await bot_data.update_one({"old_boot": True}, {"$set": {"time": boottime}})
|
| 284 |
+
else:
|
| 285 |
+
await bot_data.insert_one({"old_boot": True, "time": boottime})
|
| 286 |
+
|
| 287 |
+
|
| 288 |
+
async def get_old_boot():
|
| 289 |
+
old_boot = await bot_data.find_one({"old_boot": True})
|
| 290 |
+
if old_boot is not None and old_boot:
|
| 291 |
+
return old_boot["time"]
|
| 292 |
+
return old_boot
|
| 293 |
+
|
| 294 |
+
|
| 295 |
+
async def is_boot_different():
|
| 296 |
+
different = True
|
| 297 |
+
is_exist = await bot_data.find_one({"boot": True})
|
| 298 |
+
is_exist_old = await bot_data.find_one({"old_boot": True})
|
| 299 |
+
if (
|
| 300 |
+
is_exist
|
| 301 |
+
and is_exist_old
|
| 302 |
+
and is_exist["time"] == is_exist_old["time"]
|
| 303 |
+
):
|
| 304 |
+
different = False
|
| 305 |
+
return different
|
| 306 |
+
|
| 307 |
+
|
| 308 |
+
# DB for ongoing tasks
|
| 309 |
+
ongoing_tasks = unzipper_db["ongoing_tasks"]
|
| 310 |
+
|
| 311 |
+
|
| 312 |
+
async def get_ongoing_tasks():
|
| 313 |
+
return [ongoing_list async for ongoing_list in ongoing_tasks.find({})]
|
| 314 |
+
|
| 315 |
+
|
| 316 |
+
async def count_ongoing_tasks():
|
| 317 |
+
tasks = await ongoing_tasks.count_documents({})
|
| 318 |
+
return tasks
|
| 319 |
+
|
| 320 |
+
|
| 321 |
+
async def add_ongoing_task(user_id, start_time, task_type):
|
| 322 |
+
await ongoing_tasks.insert_one({"user_id": user_id, "start_time": start_time, "type": task_type})
|
| 323 |
+
|
| 324 |
+
|
| 325 |
+
async def del_ongoing_task(user_id):
|
| 326 |
+
is_exist = await ongoing_tasks.find_one({"user_id": user_id})
|
| 327 |
+
if is_exist is not None and is_exist:
|
| 328 |
+
await ongoing_tasks.delete_one({"user_id": user_id})
|
| 329 |
+
else:
|
| 330 |
+
return
|
| 331 |
+
|
| 332 |
+
|
| 333 |
+
async def clear_ongoing_tasks():
|
| 334 |
+
await ongoing_tasks.delete_many({})
|
| 335 |
+
|
| 336 |
+
|
| 337 |
+
# DB for cancel tasks (that's stupid)
|
| 338 |
+
cancel_tasks = unzipper_db["cancel_tasks"]
|
| 339 |
+
|
| 340 |
+
|
| 341 |
+
async def get_cancel_tasks():
|
| 342 |
+
return [cancel_list async for cancel_list in cancel_tasks.find({})]
|
| 343 |
+
|
| 344 |
+
|
| 345 |
+
async def count_cancel_tasks():
|
| 346 |
+
tasks = await cancel_tasks.count_documents({})
|
| 347 |
+
return tasks
|
| 348 |
+
|
| 349 |
+
|
| 350 |
+
async def add_cancel_task(user_id):
|
| 351 |
+
if not await get_cancel_task(user_id):
|
| 352 |
+
await cancel_tasks.insert_one({"user_id": user_id})
|
| 353 |
+
|
| 354 |
+
|
| 355 |
+
async def del_cancel_task(user_id):
|
| 356 |
+
is_exist = await cancel_tasks.find_one({"user_id": user_id})
|
| 357 |
+
if is_exist is not None and is_exist:
|
| 358 |
+
await cancel_tasks.delete_one({"user_id": user_id})
|
| 359 |
+
else:
|
| 360 |
+
return
|
| 361 |
+
|
| 362 |
+
|
| 363 |
+
async def get_cancel_task(user_id):
|
| 364 |
+
is_exist = await cancel_tasks.find_one({"user_id": user_id})
|
| 365 |
+
return bool(is_exist is not None and is_exist)
|
| 366 |
+
|
| 367 |
+
|
| 368 |
+
async def clear_cancel_tasks():
|
| 369 |
+
await cancel_tasks.delete_many({})
|
| 370 |
+
|
| 371 |
+
|
| 372 |
+
# DB for merge tasks
|
| 373 |
+
|
| 374 |
+
merge_tasks = unzipper_db["merge_tasks"]
|
| 375 |
+
|
| 376 |
+
|
| 377 |
+
async def get_merge_tasks():
|
| 378 |
+
return [merge_list async for merge_list in merge_tasks.find({})]
|
| 379 |
+
|
| 380 |
+
|
| 381 |
+
async def count_merge_tasks():
|
| 382 |
+
tasks = await merge_tasks.count_documents({})
|
| 383 |
+
return tasks
|
| 384 |
+
|
| 385 |
+
|
| 386 |
+
async def add_merge_task(user_id, message_id):
|
| 387 |
+
if not await get_merge_task(user_id):
|
| 388 |
+
await merge_tasks.insert_one({"user_id": user_id, "message_id": message_id})
|
| 389 |
+
else:
|
| 390 |
+
await merge_tasks.update_one({"user_id": user_id}, {"$set": {"message_id": message_id}})
|
| 391 |
+
|
| 392 |
+
|
| 393 |
+
async def del_merge_task(user_id):
|
| 394 |
+
is_exist = await merge_tasks.find_one({"user_id": user_id})
|
| 395 |
+
if is_exist is not None and is_exist:
|
| 396 |
+
await merge_tasks.delete_one({"user_id": user_id})
|
| 397 |
+
else:
|
| 398 |
+
return
|
| 399 |
+
|
| 400 |
+
|
| 401 |
+
async def get_merge_task(user_id):
|
| 402 |
+
is_exist = await merge_tasks.find_one({"user_id": user_id})
|
| 403 |
+
return bool(is_exist is not None and is_exist)
|
| 404 |
+
|
| 405 |
+
|
| 406 |
+
async def get_merge_task_message_id(user_id):
|
| 407 |
+
is_exist = await merge_tasks.find_one({"user_id": user_id})
|
| 408 |
+
if is_exist is not None and is_exist:
|
| 409 |
+
return is_exist["message_id"]
|
| 410 |
+
return False
|
| 411 |
+
|
| 412 |
+
|
| 413 |
+
async def clear_merge_tasks():
|
| 414 |
+
await merge_tasks.delete_many({})
|
| 415 |
+
|
| 416 |
+
|
| 417 |
+
# DB for maintenance mode
|
| 418 |
+
|
| 419 |
+
maintenance_mode = unzipper_db["maintenance_mode"]
|
| 420 |
+
|
| 421 |
+
|
| 422 |
+
async def get_maintenance():
|
| 423 |
+
maintenance = await maintenance_mode.find_one({"maintenance": True})
|
| 424 |
+
if maintenance is not None and maintenance:
|
| 425 |
+
return maintenance["val"]
|
| 426 |
+
return False
|
| 427 |
+
|
| 428 |
+
|
| 429 |
+
async def set_maintenance(val):
|
| 430 |
+
is_exist = await maintenance_mode.find_one({"maintenance": True})
|
| 431 |
+
if is_exist is not None and is_exist:
|
| 432 |
+
await maintenance_mode.update_one({"maintenance": True}, {"$set": {"val": val}})
|
| 433 |
+
else:
|
| 434 |
+
await maintenance_mode.insert_one({"maintenance": True, "val": val})
|
| 435 |
+
|
| 436 |
+
|
| 437 |
+
# DB for VIP users
|
| 438 |
+
|
| 439 |
+
vip_users = unzipper_db["vip_users"]
|
| 440 |
+
|
| 441 |
+
|
| 442 |
+
async def add_vip_user(uid, subscription, ends, used, billed, early, donator, started, successful, gap, gifted, referral, lifetime):
|
| 443 |
+
is_exist = await vip_users.find_one({"_id": uid})
|
| 444 |
+
if is_exist is not None and is_exist:
|
| 445 |
+
await vip_users.update_one({"_id": uid}, {"$set": {"subscription": subscription, "ends": ends, "used": used, "billed": billed, "early": early, "donator": donator, "started": started, "successful": successful, "gap": gap, "gifted": gifted, "referral": referral, "lifetime": lifetime}})
|
| 446 |
+
else:
|
| 447 |
+
await vip_users.insert_one({"_id": uid, "subscription": subscription, "ends": ends, "used": used, "billed": billed, "early": early, "donator": donator, "started": started, "successful": successful, "gap": gap, "gifted": gifted, "referral": referral, "lifetime": lifetime})
|
| 448 |
+
|
| 449 |
+
|
| 450 |
+
async def remove_vip_user(uid):
|
| 451 |
+
is_exist = await vip_users.find_one({"_id": uid})
|
| 452 |
+
if is_exist is not None and is_exist:
|
| 453 |
+
await vip_users.delete_one({"_id": uid})
|
| 454 |
+
else:
|
| 455 |
+
return
|
| 456 |
+
|
| 457 |
+
|
| 458 |
+
async def is_vip(uid):
|
| 459 |
+
is_exist = await vip_users.find_one({"_id": uid})
|
| 460 |
+
return bool(is_exist is not None and is_exist)
|
| 461 |
+
|
| 462 |
+
|
| 463 |
+
async def get_vip_users():
|
| 464 |
+
return [vip_list async for vip_list in vip_users.find({})]
|
| 465 |
+
|
| 466 |
+
|
| 467 |
+
async def count_vip_users():
|
| 468 |
+
users = await vip_users.count_documents({})
|
| 469 |
+
return users
|
| 470 |
+
|
| 471 |
+
|
| 472 |
+
async def get_vip_user(uid):
|
| 473 |
+
is_exist = await vip_users.find_one({"_id": uid})
|
| 474 |
+
if is_exist is not None and is_exist:
|
| 475 |
+
return is_exist
|
| 476 |
+
return None
|
| 477 |
+
|
| 478 |
+
|
| 479 |
+
# DB for referrals
|
| 480 |
+
|
| 481 |
+
referrals = unzipper_db["referrals"]
|
| 482 |
+
|
| 483 |
+
|
| 484 |
+
async def add_referee(uid, referral_code):
|
| 485 |
+
is_exist = await referrals.find_one({"_id": uid})
|
| 486 |
+
if is_exist is not None and is_exist:
|
| 487 |
+
await referrals.update_one({"_id": uid}, {"$set": {"type": "referee", "referral_code": referral_code}})
|
| 488 |
+
else:
|
| 489 |
+
await referrals.insert_one({"_id": uid, "type": "referee", "referral_code": referral_code})
|
| 490 |
+
|
| 491 |
+
|
| 492 |
+
async def add_referrer(uid, referees):
|
| 493 |
+
is_exist = await referrals.find_one({"_id": uid})
|
| 494 |
+
if is_exist is not None and is_exist:
|
| 495 |
+
await referrals.update_one({"_id": uid}, {"$set": {"type": "referrer", "referees": referees}})
|
| 496 |
+
else:
|
| 497 |
+
await referrals.insert_one({"_id": uid, "type": "referrer", "referees": referees})
|
| 498 |
+
|
| 499 |
+
|
| 500 |
+
async def get_referee(uid):
|
| 501 |
+
is_exist = await referrals.find_one({"_id": uid})
|
| 502 |
+
if is_exist is not None and is_exist:
|
| 503 |
+
return is_exist
|
| 504 |
+
return None
|
| 505 |
+
|
| 506 |
+
|
| 507 |
+
async def get_referrer(uid):
|
| 508 |
+
is_exist = await referrals.find_one({"_id": uid})
|
| 509 |
+
if is_exist is not None and is_exist:
|
| 510 |
+
return is_exist
|
| 511 |
+
return None
|
| 512 |
+
|
| 513 |
+
|
| 514 |
+
def get_referral_code(uid):
|
| 515 |
+
return base58check.b58encode(base58check.b58encode(str(uid).encode("ascii"))).decode("ascii")
|
| 516 |
+
|
| 517 |
+
|
| 518 |
+
def get_referral_uid(referral_code):
|
| 519 |
+
return int(base58check.b58decode(base58check.b58decode(referral_code).decode("ascii")).decode("ascii"))
|
unzipper/helpers/start.py
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) 2023 EDM115
|
| 2 |
+
import asyncio
|
| 3 |
+
import shutil
|
| 4 |
+
import sys
|
| 5 |
+
|
| 6 |
+
from pyrogram import enums
|
| 7 |
+
from pyrogram.errors import FloodWait
|
| 8 |
+
from time import time
|
| 9 |
+
|
| 10 |
+
from config import Config
|
| 11 |
+
from unzipper import LOGGER, boottime, unzipperbot
|
| 12 |
+
from unzipper.modules.bot_data import Messages
|
| 13 |
+
from unzipper.modules.callbacks import download
|
| 14 |
+
|
| 15 |
+
from .database import clear_cancel_tasks, clear_merge_tasks, del_ongoing_task, get_thumb_users, set_boot, get_boot, set_old_boot, get_old_boot, is_boot_different, count_ongoing_tasks, get_ongoing_tasks, clear_ongoing_tasks
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
def check_logs():
|
| 19 |
+
try:
|
| 20 |
+
if Config.LOGS_CHANNEL:
|
| 21 |
+
c_info = unzipperbot.get_chat(chat_id=Config.LOGS_CHANNEL)
|
| 22 |
+
if c_info.type in (enums.ChatType.PRIVATE, enums.ChatType.BOT):
|
| 23 |
+
LOGGER.error(Messages.PRIVATE_CHAT)
|
| 24 |
+
return False
|
| 25 |
+
return True
|
| 26 |
+
LOGGER.error(Messages.NO_LOG_ID)
|
| 27 |
+
return sys.exit()
|
| 28 |
+
except:
|
| 29 |
+
LOGGER.error(Messages.ERROR_LOG_CHECK)
|
| 30 |
+
return False
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
def dl_thumbs():
|
| 34 |
+
loop = asyncio.get_event_loop()
|
| 35 |
+
coroutine = get_thumb_users()
|
| 36 |
+
thumbs = loop.run_until_complete(coroutine)
|
| 37 |
+
i = 0
|
| 38 |
+
maxthumbs = len(thumbs)
|
| 39 |
+
LOGGER.info(Messages.DL_THUMBS.format(maxthumbs))
|
| 40 |
+
for thumb in thumbs:
|
| 41 |
+
loop2 = asyncio.get_event_loop()
|
| 42 |
+
coroutine2 = download(
|
| 43 |
+
thumb["url"], (Config.THUMB_LOCATION + "/" + str(thumb["_id"]) + ".jpg")
|
| 44 |
+
)
|
| 45 |
+
loop2.run_until_complete(coroutine2)
|
| 46 |
+
i += 1
|
| 47 |
+
if i % 10 == 0 or i == maxthumbs:
|
| 48 |
+
LOGGER.info(Messages.DOWNLOADED_THUMBS.format(i, maxthumbs))
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
def set_boot_time():
|
| 52 |
+
loop = asyncio.get_event_loop()
|
| 53 |
+
coroutine = check_boot()
|
| 54 |
+
loop.run_until_complete(coroutine)
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
async def check_boot():
|
| 58 |
+
boot = await get_boot()
|
| 59 |
+
await set_old_boot(boot)
|
| 60 |
+
await set_boot(boottime)
|
| 61 |
+
boot = await get_boot()
|
| 62 |
+
old_boot = await get_old_boot()
|
| 63 |
+
different = await is_boot_different()
|
| 64 |
+
if different:
|
| 65 |
+
try:
|
| 66 |
+
await unzipperbot.send_message(Config.BOT_OWNER, Messages.BOT_RESTARTED.format(old_boot, boot))
|
| 67 |
+
except:
|
| 68 |
+
pass # first start obviously
|
| 69 |
+
await warn_users()
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
async def warn_users():
|
| 73 |
+
await clear_cancel_tasks()
|
| 74 |
+
await clear_merge_tasks()
|
| 75 |
+
if await count_ongoing_tasks() > 0:
|
| 76 |
+
tasks = await get_ongoing_tasks()
|
| 77 |
+
for task in tasks:
|
| 78 |
+
try:
|
| 79 |
+
await unzipperbot.send_message(task["user_id"], Messages.RESEND_TASK)
|
| 80 |
+
except FloodWait as f:
|
| 81 |
+
await asyncio.sleep(f.value)
|
| 82 |
+
await unzipperbot.send_message(task["user_id"], Messages.RESEND_TASK)
|
| 83 |
+
except:
|
| 84 |
+
pass # user deleted chat
|
| 85 |
+
await clear_ongoing_tasks()
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
def removal(firststart=False):
|
| 89 |
+
loop = asyncio.get_event_loop()
|
| 90 |
+
loop.create_task(remove_expired_tasks(firststart))
|
| 91 |
+
loop.run_until_complete(asyncio.sleep(0))
|
| 92 |
+
|
| 93 |
+
|
| 94 |
+
async def remove_expired_tasks(firststart=False):
|
| 95 |
+
value = firststart
|
| 96 |
+
while True:
|
| 97 |
+
ongoing_tasks = await get_ongoing_tasks()
|
| 98 |
+
|
| 99 |
+
for task in ongoing_tasks:
|
| 100 |
+
user_id = task["user_id"]
|
| 101 |
+
if value:
|
| 102 |
+
await del_ongoing_task(user_id)
|
| 103 |
+
try:
|
| 104 |
+
shutil.rmtree(f"{Config.DOWNLOAD_LOCATION}/{user_id}")
|
| 105 |
+
except:
|
| 106 |
+
pass
|
| 107 |
+
else:
|
| 108 |
+
current_time = time()
|
| 109 |
+
start_time = task["start_time"]
|
| 110 |
+
task_type = task["type"]
|
| 111 |
+
time_gap = current_time - start_time
|
| 112 |
+
|
| 113 |
+
if task_type == "extract":
|
| 114 |
+
if time_gap > Config.MAX_TASK_DURATION_EXTRACT:
|
| 115 |
+
await del_ongoing_task(user_id)
|
| 116 |
+
try:
|
| 117 |
+
shutil.rmtree(f"{Config.DOWNLOAD_LOCATION}/{user_id}")
|
| 118 |
+
except:
|
| 119 |
+
pass
|
| 120 |
+
await unzipperbot.send_message(user_id, Messages.TASK_EXPIRED.format(Config.MAX_TASK_DURATION_EXTRACT // 60))
|
| 121 |
+
elif task_type == "merge":
|
| 122 |
+
if time_gap > Config.MAX_TASK_DURATION_MERGE:
|
| 123 |
+
await del_ongoing_task(user_id)
|
| 124 |
+
try:
|
| 125 |
+
shutil.rmtree(f"{Config.DOWNLOAD_LOCATION}/{user_id}")
|
| 126 |
+
except:
|
| 127 |
+
pass
|
| 128 |
+
await unzipperbot.send_message(user_id, Messages.TASK_EXPIRED.format(Config.MAX_TASK_DURATION_MERGE // 60))
|
| 129 |
+
|
| 130 |
+
value = False
|
| 131 |
+
await asyncio.sleep(5 * 60) # Sleep for 5 minutes
|
unzipper/helpers/unzip_help.py
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) 2023 EDM115
|
| 2 |
+
import math
|
| 3 |
+
import time
|
| 4 |
+
|
| 5 |
+
from asyncio import sleep
|
| 6 |
+
from pyrogram.errors import FloodWait
|
| 7 |
+
from unzipper.helpers.database import del_cancel_task, get_cancel_task
|
| 8 |
+
from unzipper.modules.bot_data import Buttons, Messages
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
async def progress_for_pyrogram(current, total, ud_type, message, start, unzip_bot):
|
| 12 |
+
if message.from_user is not None and await get_cancel_task(message.from_user.id):
|
| 13 |
+
unzip_bot.stop_transmission()
|
| 14 |
+
await message.edit(text=Messages.DL_STOPPED)
|
| 15 |
+
await del_cancel_task(message.from_user.id)
|
| 16 |
+
else:
|
| 17 |
+
now = time.time()
|
| 18 |
+
diff = now - start
|
| 19 |
+
if total == 0:
|
| 20 |
+
tmp = Messages.UNKNOWN_SIZE
|
| 21 |
+
try:
|
| 22 |
+
await message.edit(
|
| 23 |
+
text=Messages.PROGRESS_MSG.format(ud_type, tmp),
|
| 24 |
+
reply_markup=Buttons.I_PREFER_STOP,
|
| 25 |
+
)
|
| 26 |
+
except FloodWait as f:
|
| 27 |
+
await sleep(f.value)
|
| 28 |
+
await message.edit(
|
| 29 |
+
text=Messages.PROGRESS_MSG.format(ud_type, tmp),
|
| 30 |
+
reply_markup=Buttons.I_PREFER_STOP,
|
| 31 |
+
)
|
| 32 |
+
except:
|
| 33 |
+
pass
|
| 34 |
+
elif round(diff % 10.00) == 0 or current == total:
|
| 35 |
+
percentage = current * 100 / total
|
| 36 |
+
speed = current / diff
|
| 37 |
+
elapsed_time = round(diff) * 1000
|
| 38 |
+
time_to_completion = round((total - current) / speed) * 1000
|
| 39 |
+
estimated_total_time = time_to_completion
|
| 40 |
+
elapsed_time = TimeFormatter(milliseconds=elapsed_time)
|
| 41 |
+
estimated_total_time = TimeFormatter(milliseconds=estimated_total_time)
|
| 42 |
+
progress = f'[{"".join(["⬢" for i in range(math.floor(percentage / 5))])}{"".join(["⬡" for i in range(20 - math.floor(percentage / 5))])}] \n{Messages.PROCESSING} : `{round(percentage, 2)}%`\n'
|
| 43 |
+
tmp = progress + f'`{humanbytes(current)} of {humanbytes(total)}`\n{Messages.SPEED} `{humanbytes(speed)}/s`\n{Messages.ETA} `{estimated_total_time if estimated_total_time != "" or percentage != "100" else "0 s"}`\n'
|
| 44 |
+
try:
|
| 45 |
+
await message.edit(
|
| 46 |
+
text=Messages.PROGRESS_MSG.format(ud_type, tmp),
|
| 47 |
+
reply_markup=Buttons.I_PREFER_STOP,
|
| 48 |
+
)
|
| 49 |
+
except FloodWait as f:
|
| 50 |
+
await sleep(f.value)
|
| 51 |
+
await message.edit(
|
| 52 |
+
text=Messages.PROGRESS_MSG.format(ud_type, tmp),
|
| 53 |
+
reply_markup=Buttons.I_PREFER_STOP,
|
| 54 |
+
)
|
| 55 |
+
except:
|
| 56 |
+
pass
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
async def progress_urls(current, total, ud_type, message, start):
|
| 60 |
+
now = time.time()
|
| 61 |
+
diff = now - start
|
| 62 |
+
if round(diff % 10.00) == 0 or current == total:
|
| 63 |
+
percentage = current * 100 / total
|
| 64 |
+
speed = current / diff
|
| 65 |
+
elapsed_time = round(diff) * 1000
|
| 66 |
+
time_to_completion = round((total - current) / speed) * 1000
|
| 67 |
+
estimated_total_time = time_to_completion
|
| 68 |
+
elapsed_time = TimeFormatter(milliseconds=elapsed_time)
|
| 69 |
+
estimated_total_time = TimeFormatter(milliseconds=estimated_total_time)
|
| 70 |
+
progress = f'[{"".join(["⬢" for i in range(math.floor(percentage / 5))])}{"".join(["⬡" for i in range(20 - math.floor(percentage / 5))])}] \n{Messages.PROCESSING} : `{round(percentage, 2)}%`\n'
|
| 71 |
+
tmp = progress + f'{Messages.ETA} `{estimated_total_time if estimated_total_time != "" or percentage != "100" else "0 s"}`\n'
|
| 72 |
+
try:
|
| 73 |
+
await message.edit(Messages.PROGRESS_MSG.format(ud_type, tmp))
|
| 74 |
+
except FloodWait as f:
|
| 75 |
+
await sleep(f.value)
|
| 76 |
+
await message.edit(Messages.PROGRESS_MSG.format(ud_type, tmp))
|
| 77 |
+
except:
|
| 78 |
+
pass
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
def humanbytes(size):
|
| 82 |
+
if not size:
|
| 83 |
+
return ""
|
| 84 |
+
power = 2**10
|
| 85 |
+
n = 0
|
| 86 |
+
Dic_powerN = {0: " ", 1: "Ki", 2: "Mi", 3: "Gi", 4: "Ti"}
|
| 87 |
+
while size > power:
|
| 88 |
+
size /= power
|
| 89 |
+
n += 1
|
| 90 |
+
return str(round(size, 2)) + " " + Dic_powerN[n] + "B"
|
| 91 |
+
|
| 92 |
+
|
| 93 |
+
def TimeFormatter(milliseconds: int) -> str:
|
| 94 |
+
seconds, milliseconds = divmod(int(milliseconds), 1000)
|
| 95 |
+
minutes, seconds = divmod(seconds, 60)
|
| 96 |
+
hours, minutes = divmod(minutes, 60)
|
| 97 |
+
days, hours = divmod(hours, 24)
|
| 98 |
+
tmp = (
|
| 99 |
+
((str(days) + "d, ") if days else "")
|
| 100 |
+
+ ((str(hours) + "h, ") if hours else "")
|
| 101 |
+
+ ((str(minutes) + "m, ") if minutes else "")
|
| 102 |
+
+ ((str(seconds) + "s, ") if seconds else "")
|
| 103 |
+
+ ((str(milliseconds) + "ms, ") if milliseconds else "")
|
| 104 |
+
)
|
| 105 |
+
return tmp[:-2]
|
| 106 |
+
|
| 107 |
+
|
| 108 |
+
def timeformat_sec(seconds: int) -> str:
|
| 109 |
+
minutes, seconds = divmod(int(seconds), 60)
|
| 110 |
+
hours, minutes = divmod(minutes, 60)
|
| 111 |
+
days, hours = divmod(hours, 24)
|
| 112 |
+
tmp = (
|
| 113 |
+
((str(days) + "d, ") if days else "")
|
| 114 |
+
+ ((str(hours) + "h, ") if hours else "")
|
| 115 |
+
+ ((str(minutes) + "m, ") if minutes else "")
|
| 116 |
+
+ ((str(seconds) + "s, ") if seconds else "")
|
| 117 |
+
)
|
| 118 |
+
return tmp[:-2]
|
| 119 |
+
|
| 120 |
+
|
| 121 |
+
# List of common extentions
|
| 122 |
+
extentions_list = {
|
| 123 |
+
"archive": [
|
| 124 |
+
"7z",
|
| 125 |
+
"apk",
|
| 126 |
+
"apkm",
|
| 127 |
+
"apks",
|
| 128 |
+
"appx",
|
| 129 |
+
"arc",
|
| 130 |
+
"bcm",
|
| 131 |
+
"bin",
|
| 132 |
+
"br",
|
| 133 |
+
"bz2",
|
| 134 |
+
"dmg",
|
| 135 |
+
"exe",
|
| 136 |
+
"gz",
|
| 137 |
+
"img",
|
| 138 |
+
"ipsw",
|
| 139 |
+
"iso",
|
| 140 |
+
"jar",
|
| 141 |
+
"lz4",
|
| 142 |
+
"msi",
|
| 143 |
+
"paf",
|
| 144 |
+
"pak",
|
| 145 |
+
"pea",
|
| 146 |
+
"rar",
|
| 147 |
+
"tar",
|
| 148 |
+
"tgz",
|
| 149 |
+
"wim",
|
| 150 |
+
"x7",
|
| 151 |
+
"xapk",
|
| 152 |
+
"xz",
|
| 153 |
+
"z",
|
| 154 |
+
"zip",
|
| 155 |
+
"zipx",
|
| 156 |
+
"zpaq",
|
| 157 |
+
"zst",
|
| 158 |
+
"zstd",
|
| 159 |
+
],
|
| 160 |
+
"audio": ["aif", "aiff", "aac", "flac", "mp3", "ogg", "wav", "wma"],
|
| 161 |
+
"photo": ["gif", "ico", "jpg", "jpeg", "png", "tiff", "webp"],
|
| 162 |
+
"split": ["0*", "001", "002", "003", "004", "005", "006", "007", "008", "009"],
|
| 163 |
+
"video": ["3gp", "avi", "flv", "mp4", "mkv", "mov", "mpeg", "mpg", "webm"],
|
| 164 |
+
}
|
unzipper/modules/bot_data.py
ADDED
|
@@ -0,0 +1,1062 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) 2023 EDM115
|
| 2 |
+
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
class Messages:
|
| 6 |
+
|
| 7 |
+
# here
|
| 8 |
+
|
| 9 |
+
HELP = "Help 📜"
|
| 10 |
+
|
| 11 |
+
ABOUT = "About 👀"
|
| 12 |
+
|
| 13 |
+
STATS_BTN = "Stats 📊"
|
| 14 |
+
|
| 15 |
+
DONATE = "Donate 💸"
|
| 16 |
+
|
| 17 |
+
REFRESH = "Refresh ♻️"
|
| 18 |
+
|
| 19 |
+
BACK = "Back 🏡"
|
| 20 |
+
|
| 21 |
+
CLEAN = "Clean my files 🚮"
|
| 22 |
+
|
| 23 |
+
AS_DOC = "As document 📁"
|
| 24 |
+
|
| 25 |
+
AS_MEDIA = "As media 📺"
|
| 26 |
+
|
| 27 |
+
MERGE_BTN = "Merge 🛠️"
|
| 28 |
+
|
| 29 |
+
CHECK = "Check 👀"
|
| 30 |
+
|
| 31 |
+
REPLACE = "Replace ⏭"
|
| 32 |
+
|
| 33 |
+
SAVE = "Save 💾"
|
| 34 |
+
|
| 35 |
+
DELETE = "Delete 🚮"
|
| 36 |
+
|
| 37 |
+
RATE = "Rate me ⭐"
|
| 38 |
+
|
| 39 |
+
# start.py
|
| 40 |
+
|
| 41 |
+
PRIVATE_CHAT = "A private chat can't be used 😐"
|
| 42 |
+
|
| 43 |
+
NO_LOG_ID = "No log channel ID have been provided !"
|
| 44 |
+
|
| 45 |
+
ERROR_LOG_CHECK = "An error happened while checking Log channel 💀 Make sure haven't provided a wrong Log channel ID 🧐"
|
| 46 |
+
|
| 47 |
+
DL_THUMBS = "Downloading {} thumbs"
|
| 48 |
+
|
| 49 |
+
DOWNLOADED_THUMBS = "Downloaded {} of {} thumbs"
|
| 50 |
+
|
| 51 |
+
BOT_RESTARTED = """
|
| 52 |
+
Bot restarted !
|
| 53 |
+
|
| 54 |
+
**Old boot time** : `{}`
|
| 55 |
+
**New boot time** : `{}`
|
| 56 |
+
"""
|
| 57 |
+
|
| 58 |
+
RESEND_TASK = """
|
| 59 |
+
⚠️ **Warning** : the bot restarted while you were using it
|
| 60 |
+
Your task was stopped, kindly send it again
|
| 61 |
+
"""
|
| 62 |
+
|
| 63 |
+
TASK_EXPIRED = """
|
| 64 |
+
Your task was running for more than {} minutes, it has been stopped
|
| 65 |
+
|
| 66 |
+
Don't go AFK next time 😉
|
| 67 |
+
"""
|
| 68 |
+
|
| 69 |
+
# database.py
|
| 70 |
+
|
| 71 |
+
BANNED = """
|
| 72 |
+
**Sorry you're banned 💀**
|
| 73 |
+
|
| 74 |
+
Report this at @EDM115_chat if you think this is a mistake, I may unban you
|
| 75 |
+
"""
|
| 76 |
+
|
| 77 |
+
NEW_USER_BAD = """
|
| 78 |
+
**#NEW_USER** 🎙
|
| 79 |
+
|
| 80 |
+
**User profile :** `{}`
|
| 81 |
+
**User ID :** `[AttributeError]` Can't get it
|
| 82 |
+
**Profile URL :** Can't get it
|
| 83 |
+
"""
|
| 84 |
+
|
| 85 |
+
NEW_USER = """
|
| 86 |
+
**#NEW_USER** 🎙
|
| 87 |
+
|
| 88 |
+
**User profile :** `{}` {}
|
| 89 |
+
**User ID :** `{}`
|
| 90 |
+
**Profile URL :** [tg://user?id={}](tg://user?id={})
|
| 91 |
+
"""
|
| 92 |
+
|
| 93 |
+
# unzip_help.py
|
| 94 |
+
|
| 95 |
+
UNKNOWN_SIZE = """
|
| 96 |
+
**Size :** Unknown
|
| 97 |
+
|
| 98 |
+
This may take a while, go grab a coffee ☕️
|
| 99 |
+
"""
|
| 100 |
+
|
| 101 |
+
PROGRESS_MSG = """
|
| 102 |
+
{}
|
| 103 |
+
{}
|
| 104 |
+
|
| 105 |
+
**Powered by @EDM115bots**
|
| 106 |
+
"""
|
| 107 |
+
|
| 108 |
+
PROCESSING = "**Processing…**"
|
| 109 |
+
|
| 110 |
+
SPEED = "**Speed :**"
|
| 111 |
+
|
| 112 |
+
ETA = "**ETA :**"
|
| 113 |
+
|
| 114 |
+
# __main__.py
|
| 115 |
+
|
| 116 |
+
START_TXT = "ℹ️ The bot have successfully started at `{}` 💪"
|
| 117 |
+
|
| 118 |
+
STOP_TXT = "ℹ️ The bot goes sleeping at `{}` 😴"
|
| 119 |
+
|
| 120 |
+
STARTING_BOT = "Starting bot…"
|
| 121 |
+
|
| 122 |
+
CHECK_LOG = "Checking Log channel…"
|
| 123 |
+
|
| 124 |
+
LOG_CHECKED = "Log channel alright"
|
| 125 |
+
|
| 126 |
+
BOT_RUNNING = "Bot is running now ! Join @EDM115bots"
|
| 127 |
+
|
| 128 |
+
WRONG_LOG = """
|
| 129 |
+
Error : the provided **LOGS_CHANNEL** (`{}`) is incorrect
|
| 130 |
+
Bot crashed 😪
|
| 131 |
+
"""
|
| 132 |
+
|
| 133 |
+
# callbacks.py
|
| 134 |
+
|
| 135 |
+
MAX_TASKS = """
|
| 136 |
+
Sorry, the bot is currently full 🥺
|
| 137 |
+
|
| 138 |
+
{} tasks are already running, please wait few minutes
|
| 139 |
+
"""
|
| 140 |
+
|
| 141 |
+
CHOOSE_EXT_MODE = """
|
| 142 |
+
Select the extraction mode for that {} 👀
|
| 143 |
+
|
| 144 |
+
{} : **Normal mode**
|
| 145 |
+
🔐 : **Password protected**
|
| 146 |
+
🖼️ : **Change the thumbnail**
|
| 147 |
+
🖼️✏ : **Change the thumbnail and rename the file**
|
| 148 |
+
❌ : **Cancel your task**
|
| 149 |
+
"""
|
| 150 |
+
|
| 151 |
+
CHOOSE_EXT_MODE_MERGE = """
|
| 152 |
+
Select the extraction mode for that merged file 👀
|
| 153 |
+
|
| 154 |
+
🗂️ : **Normal mode**
|
| 155 |
+
🔐 : **Password protected**
|
| 156 |
+
❌ : **Cancel your task**
|
| 157 |
+
"""
|
| 158 |
+
|
| 159 |
+
EXT_CAPTION = """
|
| 160 |
+
`{}`
|
| 161 |
+
|
| 162 |
+
Successfully extracted by @unzip_edm115bot 🥰
|
| 163 |
+
"""
|
| 164 |
+
|
| 165 |
+
URL_UPLOAD = """
|
| 166 |
+
`{}` is too huge to be uploaded to Telegram (`{}`)
|
| 167 |
+
|
| 168 |
+
Instead, I made it available here : {} 🥰
|
| 169 |
+
"""
|
| 170 |
+
|
| 171 |
+
URL_ERROR = """
|
| 172 |
+
An error happened for `{}` 😕
|
| 173 |
+
|
| 174 |
+
**Error code :** `{}`
|
| 175 |
+
**Error type :** `{}`
|
| 176 |
+
**Error message :** `{}`
|
| 177 |
+
|
| 178 |
+
Please report this at @EDM115_chat if you think this is a serious error
|
| 179 |
+
"""
|
| 180 |
+
|
| 181 |
+
REPORT_TEXT = """
|
| 182 |
+
📢 --Report sent--
|
| 183 |
+
|
| 184 |
+
**User :** `{}`
|
| 185 |
+
**Message :** `{}`
|
| 186 |
+
|
| 187 |
+
#Report #Action_Required
|
| 188 |
+
"""
|
| 189 |
+
|
| 190 |
+
LOG_CAPTION = """
|
| 191 |
+
**The file : ** `{}`
|
| 192 |
+
|
| 193 |
+
have been saved from the URL
|
| 194 |
+
|
| 195 |
+
`{}`
|
| 196 |
+
"""
|
| 197 |
+
|
| 198 |
+
EXT_FAILED_TXT = """
|
| 199 |
+
**Extraction failed 😕**
|
| 200 |
+
|
| 201 |
+
**What to do ?**
|
| 202 |
+
|
| 203 |
+
• Please make sure archive isn’t corrupted
|
| 204 |
+
• Please make sure that you selected the right mode !
|
| 205 |
+
• Also check if you sent the right password (it's case sensitive)
|
| 206 |
+
• Maybe your archive format isn’t supported yet 😔
|
| 207 |
+
|
| 208 |
+
|
| 209 |
+
**⚠ IN ALL CASES ⚠**, please send **/clean**, else you couldn’t send any other task 🙂🔫 (may be fixed in the future)
|
| 210 |
+
|
| 211 |
+
Please report this at @EDM115_chat if you think this is a serious error
|
| 212 |
+
"""
|
| 213 |
+
|
| 214 |
+
HOW_MANY_UPLOADED = "`{}` files were extracted from that archive"
|
| 215 |
+
|
| 216 |
+
PLS_REPLY = "You need to reply to a picture for saving it as custom thumbnail 🤓"
|
| 217 |
+
|
| 218 |
+
NO_MERGE_TASK = """
|
| 219 |
+
Bruh there's no merge task ongoing 🗿
|
| 220 |
+
Use **/merge** to start one
|
| 221 |
+
"""
|
| 222 |
+
|
| 223 |
+
LOG_TXT = """
|
| 224 |
+
**Extract log 📝**
|
| 225 |
+
|
| 226 |
+
**User ID :** `{}`
|
| 227 |
+
**File name :** `{}`
|
| 228 |
+
**File size :** `{}`
|
| 229 |
+
"""
|
| 230 |
+
|
| 231 |
+
PASS_TXT = """
|
| 232 |
+
**Password of the above archive is 🔑**
|
| 233 |
+
|
| 234 |
+
`{}`
|
| 235 |
+
"""
|
| 236 |
+
|
| 237 |
+
DL_URL = """
|
| 238 |
+
**Trying to download… Please wait**
|
| 239 |
+
|
| 240 |
+
**URL :** `{}`
|
| 241 |
+
|
| 242 |
+
"""
|
| 243 |
+
|
| 244 |
+
REFRESH_STATS = "Refreshing stats… ♻️"
|
| 245 |
+
|
| 246 |
+
ACTUAL_THUMB = "Your actual thumbnail"
|
| 247 |
+
|
| 248 |
+
START_TEXT = """
|
| 249 |
+
Hi **{}** 👋, I'm **Unarchiver bot** 🥰
|
| 250 |
+
|
| 251 |
+
|
| 252 |
+
I can extract archives like `zip`, `rar`, `tar`, …
|
| 253 |
+
|
| 254 |
+
**Made with ❤️ by @EDM115bots**
|
| 255 |
+
|
| 256 |
+
**/donate** if you can 🥺
|
| 257 |
+
"""
|
| 258 |
+
|
| 259 |
+
HELP_TXT = """
|
| 260 |
+
**• How to extract 🤔**
|
| 261 |
+
|
| 262 |
+
**1)** Send the file or link that you want to extract
|
| 263 |
+
**2)** Click on extract button (If you sent a link use `🔗` button. If it's a file just use `🗂️` button)
|
| 264 |
+
|
| 265 |
+
|
| 266 |
+
**• How to change upload mode 🤔**
|
| 267 |
+
Send **/mode**
|
| 268 |
+
|
| 269 |
+
|
| 270 |
+
**Note :**
|
| 271 |
+
**1.** If your archive is password protected select `🔐` button
|
| 272 |
+
**2.** Please don’t send corrupted files ! If you sent one by mistake just send **/clean**
|
| 273 |
+
**3.** If your archive have +95 files in it then bot can’t show all of extracted files to select from (yet). So in that case if you can’t see your file in the buttons just click on `Upload all 📤` button. It will send all extracted files to you !
|
| 274 |
+
|
| 275 |
+
|
| 276 |
+
**• Got an error ?**
|
| 277 |
+
Visit edm115.eu.org/unzip#help
|
| 278 |
+
|
| 279 |
+
|
| 280 |
+
**• I wanna have help 🥺**
|
| 281 |
+
|
| 282 |
+
PM me at **@EDM115** or join the chat **@EDM115_chat**
|
| 283 |
+
"""
|
| 284 |
+
|
| 285 |
+
ABOUT_TXT = """
|
| 286 |
+
**About Unarchiver bot [v6.3.2]**
|
| 287 |
+
|
| 288 |
+
• **Language :** [Python 3.11.5](https://www.python.org/)
|
| 289 |
+
• **Framework :** [Pyrogram 2.0.106](https://pyrogram.org/)
|
| 290 |
+
• **Source code :** [EDM115/unzip-bot](https://github.com/EDM115/unzip-bot)
|
| 291 |
+
• **Developer :** [EDM115](https://github.com/EDM115)
|
| 292 |
+
|
| 293 |
+
**[Rate me ⭐](https://t.me/BotsArchive/2705)**
|
| 294 |
+
Made with ❤️ by **@EDM115bots**
|
| 295 |
+
"""
|
| 296 |
+
|
| 297 |
+
DONATE_TEXT = """
|
| 298 |
+
I'm going to be honest : **this bot costs me money**…
|
| 299 |
+
Nothing's free on this world, however I try to keep this bot for free for as many people as possible
|
| 300 |
+
I don't like to put restrictions, nor getting your PM's flooded with ads…
|
| 301 |
+
|
| 302 |
+
So if you can, donate :)
|
| 303 |
+
It helps out a ton, covers the costs (hosting, updating, … 👨💻)
|
| 304 |
+
|
| 305 |
+
--How ?--
|
| 306 |
+
• **[Paypal](https://www.paypal.me/8EDM115)**
|
| 307 |
+
• **[GitHub Sponsors](https://github.com/sponsors/EDM115)**
|
| 308 |
+
• **[Directly in Telegram](https://t.me/EDM115bots/544)**
|
| 309 |
+
• **[BuyMeACoffee](https://www.buymeacoffee.com/edm115)**
|
| 310 |
+
• **[Send cryptos (not recommended)](https://edm115.shadd.eu.org/)**
|
| 311 |
+
|
| 312 |
+
Thanks for your contribution 😊
|
| 313 |
+
|
| 314 |
+
--Side note :--
|
| 315 |
+
Donation doesn't count as a VIP subscription. Check **/vip** for more info
|
| 316 |
+
"""
|
| 317 |
+
|
| 318 |
+
VIP_INFO = """
|
| 319 |
+
Wanna help the developer of this __amazing__ bot ?
|
| 320 |
+
Here's how : Become a VIP user and benefit from extra perks !
|
| 321 |
+
|
| 322 |
+
**VIP perks :**
|
| 323 |
+
- No max tasks limit
|
| 324 |
+
- No AFK timeout
|
| 325 |
+
- Get a better support
|
| 326 |
+
- Upload files up to 4Gb
|
| 327 |
+
- Early access to new features
|
| 328 |
+
- Access a second bot exclusive to VIPs __(subject to conditions)__
|
| 329 |
+
- And more…
|
| 330 |
+
|
| 331 |
+
**What's the price ?**
|
| 332 |
+
- `1$/month`
|
| 333 |
+
- `10$/year`
|
| 334 |
+
|
| 335 |
+
**How to become a VIP ?**
|
| 336 |
+
1) Send **/pay** to the bot
|
| 337 |
+
2) Choose your subscription
|
| 338 |
+
3) Send a screenshot of your payment to **@EDM115**
|
| 339 |
+
4) Enjoy your VIP perks !
|
| 340 |
+
|
| 341 |
+
**What happens when my subscription ends ?**
|
| 342 |
+
If you choosed GitHub Sponsors, Telegram Donate or BuyMeACoffee, you will be automatically renewed until you cancel it
|
| 343 |
+
If you choosed PayPal, you will have to redo the 4 above steps
|
| 344 |
+
You will be notified few days before you subscription ends so you can check if you want to renew it or not
|
| 345 |
+
|
| 346 |
+
**I wanna cancel my subscription**
|
| 347 |
+
Just send **/stoppay** and follow the instructions according to the platform you selected
|
| 348 |
+
Your payment will be cancelled and you will keep your VIP perks until the end of your subscription
|
| 349 |
+
(i.e. if you paid for 1 month, from 05/01/2024 to 05/02/2024 and you cancel your subscription on 15/01/2024, your perks will stay until 05/02/2024)
|
| 350 |
+
|
| 351 |
+
**What is the referral system ?**
|
| 352 |
+
Referrals have benefits for both sides :)
|
| 353 |
+
- For the referrer : you get 1 month of VIP for free for each 3 new VIPs you bring
|
| 354 |
+
- For the referred : you get 1 month of VIP for free if you take the monthly subscription, and 3 months for free if you take the yearly subscription
|
| 355 |
+
How to input the referral code ? Just send **/pay** to the bot and follow the instructions
|
| 356 |
+
"""
|
| 357 |
+
|
| 358 |
+
VIP_REQUIRED_MESSAGE = """
|
| 359 |
+
Use this command as a reply to a messsage, where you have the following (ONE PER LINE) :
|
| 360 |
+
The user ID (int)
|
| 361 |
+
When the subscription starts (in %Y-%m-%dT%H:%M:%SZ format)
|
| 362 |
+
When the subscription ends (same)
|
| 363 |
+
Which platform had been used [paypal, telegram, sponsor, bmac]
|
| 364 |
+
At which frequency the user is billed [monthly, yearly]
|
| 365 |
+
Is the user a early supporter (can be obtained only the first 3 months) [True, False]
|
| 366 |
+
Is the user also a donator [True, False]
|
| 367 |
+
When does the user ever started a subscription (date)
|
| 368 |
+
How many successful payments had been done (int)
|
| 369 |
+
Is there been any gap between payments [True, False]
|
| 370 |
+
If the user had been gifted a Premium plan [True, False]
|
| 371 |
+
The user referral code (str)
|
| 372 |
+
Is this a lifetime free subscription [True, False]
|
| 373 |
+
"""
|
| 374 |
+
|
| 375 |
+
VIP_ADDED_USER = """
|
| 376 |
+
The following user had been added with the following infos :
|
| 377 |
+
User ID : `{}`
|
| 378 |
+
Start date : `{}`
|
| 379 |
+
End date : `{}`
|
| 380 |
+
Platform : `{}`
|
| 381 |
+
Frequency : `{}`
|
| 382 |
+
Early supporter : `{}`
|
| 383 |
+
Donator : `{}`
|
| 384 |
+
First subscription date : `{}`
|
| 385 |
+
Successful payments : `{}`
|
| 386 |
+
Gap between payments : `{}`
|
| 387 |
+
Gifted : `{}`
|
| 388 |
+
Referral code : `{}`
|
| 389 |
+
Lifetime : `{}`
|
| 390 |
+
"""
|
| 391 |
+
|
| 392 |
+
CLEAN_TXT = """
|
| 393 |
+
**Are sure want to clean your task 🤔**
|
| 394 |
+
|
| 395 |
+
Note : This action cannot be undone !
|
| 396 |
+
"""
|
| 397 |
+
|
| 398 |
+
SELECT_UPLOAD_MODE_TXT = """
|
| 399 |
+
Select your upload mode 👇
|
| 400 |
+
|
| 401 |
+
**Current upload mode is :** `{}`
|
| 402 |
+
"""
|
| 403 |
+
|
| 404 |
+
CHANGED_UPLOAD_MODE_TXT = "**Successfully changed upload mode to** `{}` ✅"
|
| 405 |
+
|
| 406 |
+
EXISTING_THUMB = """
|
| 407 |
+
A thumbnail already have been saved 😅 What you wanna do ?
|
| 408 |
+
• Checking the actual thumbnail
|
| 409 |
+
• Replace it with the new one you just sent
|
| 410 |
+
• Cancel
|
| 411 |
+
"""
|
| 412 |
+
|
| 413 |
+
SAVING_THUMB = "Are you sure you want to save this thumbnail 🤔"
|
| 414 |
+
|
| 415 |
+
SAVED_THUMBNAIL = "**Successfully saved this thumbnail ✅**"
|
| 416 |
+
|
| 417 |
+
DEL_CONFIRM_THUMB = """
|
| 418 |
+
Do you really want to delete your thumbnail ?
|
| 419 |
+
• Check the actual thumbnail
|
| 420 |
+
• Delete it
|
| 421 |
+
• Cancel
|
| 422 |
+
"""
|
| 423 |
+
|
| 424 |
+
DEL_CONFIRM_THUMB_2 = "Do you really want to delete your thumbnail ?"
|
| 425 |
+
|
| 426 |
+
DELETED_THUMB = "**Successfully removed your thumbnail ✅**"
|
| 427 |
+
|
| 428 |
+
ERROR_THUMB_RENAME = "Error on thumb rename"
|
| 429 |
+
|
| 430 |
+
ERROR_THUMB_UPDATE = "Error while updating thumb URL on DB"
|
| 431 |
+
|
| 432 |
+
ERROR_TELEGRAPH_UPLOAD = "Error on Telegra.ph upload"
|
| 433 |
+
|
| 434 |
+
ERROR_THUMB_DEL = "Error on thumb deletion in DB : {}"
|
| 435 |
+
|
| 436 |
+
AFTER_OK_DL_TXT = """
|
| 437 |
+
**Successfully downloaded ✅**
|
| 438 |
+
|
| 439 |
+
**Download time :** `{}`
|
| 440 |
+
**Status :** Testing the archive… Please wait
|
| 441 |
+
"""
|
| 442 |
+
|
| 443 |
+
AFTER_OK_MERGE_DL_TXT = """
|
| 444 |
+
**Successfully downloaded all {} files ✅**
|
| 445 |
+
|
| 446 |
+
**Download time :** `{}`
|
| 447 |
+
**Status :** Merging the archive… Please wait
|
| 448 |
+
"""
|
| 449 |
+
|
| 450 |
+
AFTER_OK_MERGE_TXT = """
|
| 451 |
+
**Successfully merged ✅**
|
| 452 |
+
|
| 453 |
+
**Merge time :** `{}`
|
| 454 |
+
**Status :** Processing the archive… Please wait
|
| 455 |
+
"""
|
| 456 |
+
|
| 457 |
+
AFTER_OK_TEST_TXT = """
|
| 458 |
+
**Successfully tested ✅**
|
| 459 |
+
|
| 460 |
+
**Test time :** `{}`
|
| 461 |
+
**Status :** Extracting the archive… Please wait
|
| 462 |
+
"""
|
| 463 |
+
|
| 464 |
+
EXT_OK_TXT = """
|
| 465 |
+
**Extraction successful ✅**
|
| 466 |
+
|
| 467 |
+
**Extraction time :** `{}`
|
| 468 |
+
**Status :** Processing the extracted files… Please wait
|
| 469 |
+
"""
|
| 470 |
+
|
| 471 |
+
ERROR_TXT = """
|
| 472 |
+
**Error happened 😕**
|
| 473 |
+
|
| 474 |
+
`{}`
|
| 475 |
+
|
| 476 |
+
Please report this at @EDM115_chat if you think this is a serious error
|
| 477 |
+
"""
|
| 478 |
+
|
| 479 |
+
CANCELLED_TXT = "**{} ✅**"
|
| 480 |
+
|
| 481 |
+
DL_STOPPED = "✅ The download of your file have successfully been cancelled 😌"
|
| 482 |
+
|
| 483 |
+
PROCESSING_TASK = "**✅ Processing your task… Please wait**"
|
| 484 |
+
|
| 485 |
+
ERROR_GET_MSG = "Error on getting messages from user : {}"
|
| 486 |
+
|
| 487 |
+
PROCESS_MSGS = "**Processing {} messages… Please wait**"
|
| 488 |
+
|
| 489 |
+
DL_FILES = """
|
| 490 |
+
**Trying to download file {}/{}… Please wait**
|
| 491 |
+
|
| 492 |
+
"""
|
| 493 |
+
|
| 494 |
+
PROCESS_MERGE = """
|
| 495 |
+
Processing an user query…
|
| 496 |
+
|
| 497 |
+
User ID : {}
|
| 498 |
+
Task : #Merge
|
| 499 |
+
|
| 500 |
+
File : {}
|
| 501 |
+
"""
|
| 502 |
+
|
| 503 |
+
PLS_SEND_PASSWORD = "**Please send me the password 🔑**"
|
| 504 |
+
|
| 505 |
+
PASSWORD_PROTECTED = "That archive is password protected 😡 **Don't fool me !** "
|
| 506 |
+
|
| 507 |
+
SELECT_FILES = "Select files to upload 👇"
|
| 508 |
+
|
| 509 |
+
UNABLE_GATHER_FILES = """
|
| 510 |
+
Unable to gather the files to upload 😥
|
| 511 |
+
Choose either to upload everything, or cancel the process
|
| 512 |
+
"""
|
| 513 |
+
|
| 514 |
+
FATAL_ERROR = "Fatal error : uncorrect archive format"
|
| 515 |
+
|
| 516 |
+
USER_QUERY = """
|
| 517 |
+
Processing an user query…
|
| 518 |
+
|
| 519 |
+
User ID : {}
|
| 520 |
+
"""
|
| 521 |
+
|
| 522 |
+
INVALID_URL = "That's not a valid url 💀"
|
| 523 |
+
|
| 524 |
+
NOT_AN_ARCHIVE = """
|
| 525 |
+
That's not an archive 💀
|
| 526 |
+
|
| 527 |
+
**Try to @transload it**
|
| 528 |
+
"""
|
| 529 |
+
|
| 530 |
+
DEF_NOT_AN_ARCHIVE = """
|
| 531 |
+
This file is NOT an archive 😐
|
| 532 |
+
If you believe it's an error, send the file to **@EDM115**
|
| 533 |
+
"""
|
| 534 |
+
|
| 535 |
+
PROCESSING2 = "`Processing… ⏳`"
|
| 536 |
+
|
| 537 |
+
UNZIP_HTTP = "Can't use unzip_http on {} : {}"
|
| 538 |
+
|
| 539 |
+
ERR_DL = "Error on download : {}"
|
| 540 |
+
|
| 541 |
+
CANT_DL_URL = "**Sorry, I can't download that URL 😭 Try to @transload it**"
|
| 542 |
+
|
| 543 |
+
GIVE_ARCHIVE = "Give me an archive to extract 😐"
|
| 544 |
+
|
| 545 |
+
ITS_SPLITTED = """
|
| 546 |
+
This file is splitted
|
| 547 |
+
Use the **/merge** command
|
| 548 |
+
"""
|
| 549 |
+
|
| 550 |
+
SPL_RZ = "Splitted RAR/ZIP files in .rxx or .zxx format can't be processed yet"
|
| 551 |
+
|
| 552 |
+
TRY_DL = """
|
| 553 |
+
**Trying to download… Please wait**
|
| 554 |
+
|
| 555 |
+
"""
|
| 556 |
+
|
| 557 |
+
QUERY_PARSE_ERR = """
|
| 558 |
+
Fatal query parsing error 💀
|
| 559 |
+
|
| 560 |
+
Please contact @EDM115_chat with details and screenshots
|
| 561 |
+
"""
|
| 562 |
+
|
| 563 |
+
GIVE_NEW_NAME = """
|
| 564 |
+
Current file name : `{}`
|
| 565 |
+
|
| 566 |
+
Please send the new file name (**--INCLUDE THE FILE EXTENTION !--**)
|
| 567 |
+
"""
|
| 568 |
+
|
| 569 |
+
SPLITTING = "**Splitting {}… Please wait**"
|
| 570 |
+
|
| 571 |
+
ERR_SPLIT = "An error occured while splitting a file above 2 Gb 😥"
|
| 572 |
+
|
| 573 |
+
SEND_ALL_PARTS = "Trying to send all parts of {} to you… Please wait"
|
| 574 |
+
|
| 575 |
+
UPLOADED = """
|
| 576 |
+
**Successfully uploaded ✅**
|
| 577 |
+
|
| 578 |
+
**Join @EDM115bots ❤️**
|
| 579 |
+
"""
|
| 580 |
+
|
| 581 |
+
NO_FILE_LEFT = "There's no file left to upload"
|
| 582 |
+
|
| 583 |
+
SENDING_FILE = "Sending that file to you… Please wait"
|
| 584 |
+
|
| 585 |
+
SEND_ALL_FILES = "Trying to send all files to you… Please wait"
|
| 586 |
+
|
| 587 |
+
REFRESHING = "Refreshing… ⏳"
|
| 588 |
+
|
| 589 |
+
CANCELLED = "**Cancelled successfully ✅**"
|
| 590 |
+
|
| 591 |
+
PROCESS_CANCELLED = "❌ Process cancelled"
|
| 592 |
+
|
| 593 |
+
# commands.py
|
| 594 |
+
|
| 595 |
+
PROCESS_RUNNING = """
|
| 596 |
+
Already one process is running, don't spam 😐
|
| 597 |
+
|
| 598 |
+
Wanna clear your files from my server ? Then just send **/clean** command
|
| 599 |
+
"""
|
| 600 |
+
|
| 601 |
+
SPLIT_NOPE = "Those type of splitted files can't be processed yet"
|
| 602 |
+
|
| 603 |
+
UNVALID = "Send a valid archive/URL"
|
| 604 |
+
|
| 605 |
+
MERGE = """
|
| 606 |
+
You have splitted archives to process ?
|
| 607 |
+
Send me **all** the splitted files (.001, .002, .00×, …)
|
| 608 |
+
|
| 609 |
+
**AFTER** you sent them all, send **/done** and click on the `Merge 🛠️` button
|
| 610 |
+
"""
|
| 611 |
+
|
| 612 |
+
DONE = """
|
| 613 |
+
If you have sent **ALL** the files, you can click on the `Merge 🛠️` button below
|
| 614 |
+
|
| 615 |
+
If you sent /done by mistake and haven't sent all the files yet, just ignore this message and re-send **/done** when ALL the files are sent
|
| 616 |
+
"""
|
| 617 |
+
|
| 618 |
+
STATS = """
|
| 619 |
+
**💫 Current bot stats 💫**
|
| 620 |
+
|
| 621 |
+
**💾 Disk usage :**
|
| 622 |
+
↳ **Total Disk Space :** `{}`
|
| 623 |
+
↳ **Used :** `{} - {}%`
|
| 624 |
+
↳ **Free :** `{}`
|
| 625 |
+
↳ **Ongoing tasks :** `{}`
|
| 626 |
+
|
| 627 |
+
**🎛 Hardware usage :**
|
| 628 |
+
↳ **CPU usage :** `{}%`
|
| 629 |
+
↳ **RAM usage :** `{}%`
|
| 630 |
+
↳ **Uptime :** `{}`
|
| 631 |
+
"""
|
| 632 |
+
|
| 633 |
+
STATS_OWNER = """
|
| 634 |
+
**💫 Current bot stats 💫**
|
| 635 |
+
|
| 636 |
+
**👥 Users :**
|
| 637 |
+
↳ **Users in database :** `{}`
|
| 638 |
+
↳ **Total banned users :** `{}`
|
| 639 |
+
|
| 640 |
+
**💾 Disk usage :**
|
| 641 |
+
↳ **Total Disk Space :** `{}`
|
| 642 |
+
↳ **Used :** `{} - {}%`
|
| 643 |
+
↳ **Free :** `{}`
|
| 644 |
+
↳ **Ongoing tasks :** `{}`
|
| 645 |
+
|
| 646 |
+
**🌐 Network usage :**
|
| 647 |
+
↳ **Uploaded :** `{}`
|
| 648 |
+
↳ **Downloaded :** `{}`
|
| 649 |
+
|
| 650 |
+
**🎛 Hardware usage :**
|
| 651 |
+
↳ **CPU usage :** `{}%`
|
| 652 |
+
↳ **RAM usage :** `{}%`
|
| 653 |
+
↳ **Uptime :** `{}`
|
| 654 |
+
"""
|
| 655 |
+
|
| 656 |
+
BC_REPLY = "Reply to a message to broadcast it 📡"
|
| 657 |
+
|
| 658 |
+
BC_START = """
|
| 659 |
+
Broadcasting has started, this may take a while 😪
|
| 660 |
+
|
| 661 |
+
Users : {}/{}
|
| 662 |
+
"""
|
| 663 |
+
|
| 664 |
+
BC_DONE = """
|
| 665 |
+
**Broadcast completed ✅**
|
| 666 |
+
|
| 667 |
+
**Total users :** `{}`
|
| 668 |
+
**Successful responses :** `{}`
|
| 669 |
+
**Failed responses :** `{}`
|
| 670 |
+
"""
|
| 671 |
+
|
| 672 |
+
SEND_REPLY = "Reply to a message to send it 📡"
|
| 673 |
+
|
| 674 |
+
PROVIDE_UID = "Please provide an user ID"
|
| 675 |
+
|
| 676 |
+
PROVIDE_UID2 = "Please provide an user ID/username"
|
| 677 |
+
|
| 678 |
+
SENDING = "Sending it, please wait… 😪"
|
| 679 |
+
|
| 680 |
+
SEND_SUCCESS = "Message successfully sent to `{}`"
|
| 681 |
+
|
| 682 |
+
SEND_FAILED = """
|
| 683 |
+
It failed 😣 Retry
|
| 684 |
+
|
| 685 |
+
If it fails again, it means that {} haven't started the bot yet (or deleted the chat), or he's private/banned/whatever
|
| 686 |
+
"""
|
| 687 |
+
|
| 688 |
+
REPORT_REPLY = "Reply to a message to report it to @EDM115"
|
| 689 |
+
|
| 690 |
+
REPORT_DONE = """
|
| 691 |
+
Report sucessfully sent ! An answer will arrive soon
|
| 692 |
+
|
| 693 |
+
Note : if you need to reply to replies, always use that /report command (or join **@EDM115_chat**)
|
| 694 |
+
"""
|
| 695 |
+
|
| 696 |
+
BAN_ID = "Give an user id to ban 😈"
|
| 697 |
+
|
| 698 |
+
ALREADY_BANNED = """
|
| 699 |
+
{} have already been banned
|
| 700 |
+
|
| 701 |
+
|
| 702 |
+
"""
|
| 703 |
+
|
| 704 |
+
ALREADY_REMOVED = "{} have already been removed from the user database"
|
| 705 |
+
|
| 706 |
+
BANNED = """
|
| 707 |
+
**Successfully banned that user ✅**
|
| 708 |
+
|
| 709 |
+
**User ID :** `{}`
|
| 710 |
+
"""
|
| 711 |
+
|
| 712 |
+
UNBAN_ID = "Give an user id to unban 😇"
|
| 713 |
+
|
| 714 |
+
ALREADY_ADDED = """
|
| 715 |
+
{} is already in the user database
|
| 716 |
+
|
| 717 |
+
|
| 718 |
+
"""
|
| 719 |
+
|
| 720 |
+
ALREADY_UNBANNED = "{} have already been deleted from banned users database"
|
| 721 |
+
|
| 722 |
+
UNBANNED = """
|
| 723 |
+
**Successfully unbanned that user ✅**
|
| 724 |
+
|
| 725 |
+
**User ID :** `{}`
|
| 726 |
+
"""
|
| 727 |
+
|
| 728 |
+
INFO = "Send a text (shorter possible) from any user/chat. And you will have infos about it 👀"
|
| 729 |
+
|
| 730 |
+
USER = "This is a WIP command that would allow you to get more stats about your utilisation of me 🤓"
|
| 731 |
+
|
| 732 |
+
UNABLE_FETCH = "Unable to fetch"
|
| 733 |
+
|
| 734 |
+
USER_INFO = """
|
| 735 |
+
**User ID :** `{}`
|
| 736 |
+
`{}` files uploaded
|
| 737 |
+
…
|
| 738 |
+
|
| 739 |
+
WIP
|
| 740 |
+
"""
|
| 741 |
+
|
| 742 |
+
UID_UNAME_INVALID = "Error happened, The user ID/username is probably invalid"
|
| 743 |
+
|
| 744 |
+
USER2_INFO = """
|
| 745 |
+
`{}`
|
| 746 |
+
|
| 747 |
+
**Direct link to profile :** tg://user?id={}
|
| 748 |
+
"""
|
| 749 |
+
|
| 750 |
+
MAINTENANCE = """
|
| 751 |
+
Do you want the bot to go in maintenance mode 🤔
|
| 752 |
+
Current state : `{}`
|
| 753 |
+
"""
|
| 754 |
+
|
| 755 |
+
MAINTENANCE_ASK = """
|
| 756 |
+
False : No maintenance
|
| 757 |
+
True : Maintenance
|
| 758 |
+
Send the appropriate string
|
| 759 |
+
"""
|
| 760 |
+
|
| 761 |
+
MAINTENANCE_DONE = "Successfully changed maintenance mode to `{}`"
|
| 762 |
+
|
| 763 |
+
MAINTENANCE_ON = "Maintenance mode is currently **ON**\nTasks can't be processed. Come back later"
|
| 764 |
+
|
| 765 |
+
MAINTENANCE_FAIL = "Provide one of the values"
|
| 766 |
+
|
| 767 |
+
NO_THUMBS = "No thumbnails on the server yet"
|
| 768 |
+
|
| 769 |
+
ERASE_ALL = """
|
| 770 |
+
🚧 WIP 🚧
|
| 771 |
+
|
| 772 |
+
**Cleaning…**
|
| 773 |
+
"""
|
| 774 |
+
|
| 775 |
+
CLEANED = "The whole server have been cleaned 😌"
|
| 776 |
+
|
| 777 |
+
NOT_CLEANED = "An error happened during /cleanall 😕"
|
| 778 |
+
|
| 779 |
+
ERASE_TASKS = "Deleting {} tasks… Please wait"
|
| 780 |
+
|
| 781 |
+
ERASE_TASKS_SUCCESS = "Successfully deleted {} tasks ✅"
|
| 782 |
+
|
| 783 |
+
LOG_SENT = "Log file sent to {}"
|
| 784 |
+
|
| 785 |
+
DELETED_FOLDER = "Deleted {} folder successfully"
|
| 786 |
+
|
| 787 |
+
RESTARTED_AT = "**ℹ️ Bot restarted successfully at **`{}`"
|
| 788 |
+
|
| 789 |
+
RESTARTING = "{} : Restarting…"
|
| 790 |
+
|
| 791 |
+
PULLING = "Pulling updates… ⌛"
|
| 792 |
+
|
| 793 |
+
PULLED = "✅ Pulled changes, restarting…"
|
| 794 |
+
|
| 795 |
+
NO_PULL = "Nothing to pull 😅"
|
| 796 |
+
|
| 797 |
+
COMMANDS_LIST = """
|
| 798 |
+
Here is the list of the commands you can use (only in private btw) :
|
| 799 |
+
|
| 800 |
+
**{send any file or URL}** : Prompt the extract dialog
|
| 801 |
+
**/start** : To know if I'm online
|
| 802 |
+
**/help** : Gives a simple help
|
| 803 |
+
**/about** : Know more about me
|
| 804 |
+
**/donate** : Know how you can contribute to this bot
|
| 805 |
+
**/clean** : Remove your files from my server. Also useful if a task failed
|
| 806 |
+
**/mode** : Change your upload mode (either `doc` or `media`)
|
| 807 |
+
**/stats** : Know all the current stats about me. If you're running on Heroku, it's reset every day
|
| 808 |
+
**/merge** : Merge splitted archives together
|
| 809 |
+
**/done** : After you sent all the splitted archives, use this to merge them
|
| 810 |
+
**/info** : Get full info about a [Message](https://docs.pyrogram.org/api/types/Message) (info returned by Pyrogram)
|
| 811 |
+
**/addthumb** : Upload with a custom thumbnail (not permanant yet)
|
| 812 |
+
**/delthumb** : Removes your thumbnail
|
| 813 |
+
**/report** : Used by replying to a message, sends it to the bot owner (useful for bug report, or any question)
|
| 814 |
+
**/commands** : This message
|
| 815 |
+
|
| 816 |
+
**/admincmd** : Only if you are the Owner
|
| 817 |
+
"""
|
| 818 |
+
|
| 819 |
+
ADMINCMD = """
|
| 820 |
+
Here's all the commands that only the owner (you) can use :
|
| 821 |
+
|
| 822 |
+
**/gitpull** : Pulls the latest changes from GitHub
|
| 823 |
+
**/broadcast** : Send something to all the users
|
| 824 |
+
**/sendto {user_id}** : Same as broadcast but for a single user. Don't handle replies for now…
|
| 825 |
+
**/ban {user_id}** : Ban an user. He no longer can use your bot, except if…
|
| 826 |
+
**/unban {user_id}** : …you unban him. All his stats and settings stays saved after a ban
|
| 827 |
+
**/user {user_id}** : Know more about the use of your bot by a single user
|
| 828 |
+
**/user2 {user_id}** : Get full info about an [User](https://docs.pyrogram.org/api/types/User) (info returned by Pyrogram)
|
| 829 |
+
**/self** : Get full info about me (info returned by Pyrogram)
|
| 830 |
+
**/redbutton** : Will fully restart bot + server
|
| 831 |
+
**/cleanall** : Same as `/clean`, but for the whole server
|
| 832 |
+
**/logs** : Send you the logs (all of them). Useful for bug tracking. Send them to **@EDM115** if you don't understand them/need help
|
| 833 |
+
**/restart** : Does a basic restart, less intrusive as the `/redbutton` one
|
| 834 |
+
**/dbexport** : Exports the whole database as CSV
|
| 835 |
+
**/admincmd** : This message
|
| 836 |
+
**/commands** : For all the other commands
|
| 837 |
+
"""
|
| 838 |
+
|
| 839 |
+
# cloud_upload.py
|
| 840 |
+
|
| 841 |
+
ERROR_UP_BAYFILES = "Error happened on BayFiles upload (check connection, or retry later)"
|
| 842 |
+
|
| 843 |
+
# custom_thumbnail.py
|
| 844 |
+
|
| 845 |
+
ALBUM = "{} tried to save a thumbnail from an album"
|
| 846 |
+
|
| 847 |
+
ALBUM_NOPE = "You can't use an album. Reply to a single picture sent as photo (not as document)"
|
| 848 |
+
|
| 849 |
+
DL_THUMB = "Downloading thumbnail of {}…"
|
| 850 |
+
|
| 851 |
+
THUMB_SAVED = "Thumbnail saved"
|
| 852 |
+
|
| 853 |
+
THUMB_FAILED = "Failed to generate thumb"
|
| 854 |
+
|
| 855 |
+
THUMB_ERROR = "Error happened 😕 Try again later"
|
| 856 |
+
|
| 857 |
+
NO_THUMB = "You already have no thumbnail 😅"
|
| 858 |
+
|
| 859 |
+
# ext_helper.py
|
| 860 |
+
|
| 861 |
+
UP_ALL = "Upload all 📤"
|
| 862 |
+
|
| 863 |
+
CANCEL_IT = "❌ Cancel"
|
| 864 |
+
|
| 865 |
+
# up_helper.py
|
| 866 |
+
|
| 867 |
+
TRY_UP = """
|
| 868 |
+
**Trying to upload {}… Please wait**
|
| 869 |
+
|
| 870 |
+
"""
|
| 871 |
+
|
| 872 |
+
CANT_FIND = "Sorry ! I can't find that file {} 💀"
|
| 873 |
+
|
| 874 |
+
TOO_LARGE = "URL file is too large to send in telegram 😥"
|
| 875 |
+
|
| 876 |
+
ARCHIVE_GONE = "Archive has gone from servers before uploading 😥"
|
| 877 |
+
|
| 878 |
+
EMPTY_FILE = "The file {} is empty/unreachable"
|
| 879 |
+
|
| 880 |
+
CHECK_MSG = """
|
| 881 |
+
**Verifying the file… Please wait**
|
| 882 |
+
|
| 883 |
+
"""
|
| 884 |
+
|
| 885 |
+
|
| 886 |
+
# List of error messages from p7zip
|
| 887 |
+
ERROR_MSGS = ["Error", "Can't open as archive"]
|
| 888 |
+
|
| 889 |
+
|
| 890 |
+
# Inline buttons
|
| 891 |
+
class Buttons:
|
| 892 |
+
START_BUTTON = InlineKeyboardMarkup(
|
| 893 |
+
[
|
| 894 |
+
[
|
| 895 |
+
InlineKeyboardButton(Messages.HELP, callback_data="helpcallback"),
|
| 896 |
+
InlineKeyboardButton(Messages.ABOUT, callback_data="aboutcallback"),
|
| 897 |
+
],
|
| 898 |
+
[
|
| 899 |
+
InlineKeyboardButton(Messages.STATS_BTN, callback_data="statscallback"),
|
| 900 |
+
InlineKeyboardButton(Messages.DONATE, callback_data="donatecallback"),
|
| 901 |
+
]
|
| 902 |
+
]
|
| 903 |
+
)
|
| 904 |
+
|
| 905 |
+
REFRESH_BUTTON = InlineKeyboardMarkup(
|
| 906 |
+
[
|
| 907 |
+
[
|
| 908 |
+
InlineKeyboardButton(Messages.REFRESH, callback_data="statscallback|refresh"),
|
| 909 |
+
InlineKeyboardButton(Messages.BACK, callback_data="megoinhome"),
|
| 910 |
+
]
|
| 911 |
+
]
|
| 912 |
+
)
|
| 913 |
+
|
| 914 |
+
CHOOSE_E_F__BTNS = InlineKeyboardMarkup(
|
| 915 |
+
[
|
| 916 |
+
[
|
| 917 |
+
InlineKeyboardButton(
|
| 918 |
+
"🗂️", callback_data="extract_file|tg_file|no_pass"
|
| 919 |
+
),
|
| 920 |
+
InlineKeyboardButton(
|
| 921 |
+
"🔐", callback_data="extract_file|tg_file|with_pass"
|
| 922 |
+
),
|
| 923 |
+
],
|
| 924 |
+
[
|
| 925 |
+
InlineKeyboardButton("🖼️", callback_data="extract_file|tg_file|thumb"),
|
| 926 |
+
InlineKeyboardButton(
|
| 927 |
+
"🖼️✏", callback_data="extract_file|tg_file|thumbrename"
|
| 928 |
+
),
|
| 929 |
+
],
|
| 930 |
+
[InlineKeyboardButton("❌", callback_data="cancel_dis")],
|
| 931 |
+
]
|
| 932 |
+
)
|
| 933 |
+
|
| 934 |
+
CHOOSE_E_F_M__BTNS = InlineKeyboardMarkup(
|
| 935 |
+
[
|
| 936 |
+
[
|
| 937 |
+
InlineKeyboardButton(
|
| 938 |
+
"🗂️", callback_data="merged|no_pass"
|
| 939 |
+
),
|
| 940 |
+
InlineKeyboardButton(
|
| 941 |
+
"🔐", callback_data="merged|with_pass"
|
| 942 |
+
),
|
| 943 |
+
],
|
| 944 |
+
[InlineKeyboardButton("❌", callback_data="cancel_dis")],
|
| 945 |
+
]
|
| 946 |
+
)
|
| 947 |
+
|
| 948 |
+
CHOOSE_E_U__BTNS = InlineKeyboardMarkup(
|
| 949 |
+
[
|
| 950 |
+
[
|
| 951 |
+
InlineKeyboardButton("🔗", callback_data="extract_file|url|no_pass"),
|
| 952 |
+
InlineKeyboardButton("🔐", callback_data="extract_file|url|with_pass"),
|
| 953 |
+
],
|
| 954 |
+
[
|
| 955 |
+
InlineKeyboardButton("🖼️", callback_data="extract_file|url|thumb"),
|
| 956 |
+
InlineKeyboardButton(
|
| 957 |
+
"🖼️✏", callback_data="extract_file|url|thumbrename"
|
| 958 |
+
),
|
| 959 |
+
],
|
| 960 |
+
[InlineKeyboardButton("❌", callback_data="cancel_dis")],
|
| 961 |
+
]
|
| 962 |
+
)
|
| 963 |
+
|
| 964 |
+
RENAME = InlineKeyboardMarkup(
|
| 965 |
+
[
|
| 966 |
+
[
|
| 967 |
+
InlineKeyboardButton("✏", callback_data="renameit"),
|
| 968 |
+
InlineKeyboardButton("🙅♂️", callback_data="norename"),
|
| 969 |
+
]
|
| 970 |
+
]
|
| 971 |
+
)
|
| 972 |
+
|
| 973 |
+
CLN_BTNS = InlineKeyboardMarkup(
|
| 974 |
+
[
|
| 975 |
+
[
|
| 976 |
+
InlineKeyboardButton(Messages.CLEAN, callback_data="cancel_dis"),
|
| 977 |
+
InlineKeyboardButton(Messages.CANCEL_IT, callback_data="nobully"),
|
| 978 |
+
]
|
| 979 |
+
]
|
| 980 |
+
)
|
| 981 |
+
|
| 982 |
+
ME_GOIN_HOME = InlineKeyboardMarkup(
|
| 983 |
+
[[InlineKeyboardButton(Messages.BACK, callback_data="megoinhome")]]
|
| 984 |
+
)
|
| 985 |
+
|
| 986 |
+
SET_UPLOAD_MODE_BUTTONS = InlineKeyboardMarkup(
|
| 987 |
+
[
|
| 988 |
+
[
|
| 989 |
+
InlineKeyboardButton(Messages.AS_DOC, callback_data="set_mode|doc"),
|
| 990 |
+
InlineKeyboardButton(Messages.AS_MEDIA, callback_data="set_mode|media")
|
| 991 |
+
],
|
| 992 |
+
]
|
| 993 |
+
)
|
| 994 |
+
|
| 995 |
+
I_PREFER_STOP = InlineKeyboardMarkup(
|
| 996 |
+
[[InlineKeyboardButton(Messages.CANCEL_IT, callback_data="canceldownload")]]
|
| 997 |
+
)
|
| 998 |
+
|
| 999 |
+
MERGE_THEM_ALL = InlineKeyboardMarkup(
|
| 1000 |
+
[
|
| 1001 |
+
[
|
| 1002 |
+
InlineKeyboardButton(Messages.MERGE_BTN, callback_data="merge_this"),
|
| 1003 |
+
InlineKeyboardButton(Messages.CANCEL_IT, callback_data="cancel_dis"),
|
| 1004 |
+
]
|
| 1005 |
+
]
|
| 1006 |
+
)
|
| 1007 |
+
|
| 1008 |
+
THUMB_REPLACEMENT = InlineKeyboardMarkup(
|
| 1009 |
+
[
|
| 1010 |
+
[
|
| 1011 |
+
InlineKeyboardButton(Messages.CHECK, callback_data="check_thumb"),
|
| 1012 |
+
InlineKeyboardButton(Messages.REPLACE, callback_data="save_thumb|replace"),
|
| 1013 |
+
],
|
| 1014 |
+
[InlineKeyboardButton(Messages.CANCEL_IT, callback_data="nope_thumb")],
|
| 1015 |
+
]
|
| 1016 |
+
)
|
| 1017 |
+
|
| 1018 |
+
THUMB_FINAL = InlineKeyboardMarkup(
|
| 1019 |
+
[
|
| 1020 |
+
[
|
| 1021 |
+
InlineKeyboardButton(Messages.REPLACE, callback_data="save_thumb|replace"),
|
| 1022 |
+
InlineKeyboardButton(Messages.CANCEL_IT, callback_data="nope_thumb"),
|
| 1023 |
+
]
|
| 1024 |
+
]
|
| 1025 |
+
)
|
| 1026 |
+
|
| 1027 |
+
THUMB_SAVE = InlineKeyboardMarkup(
|
| 1028 |
+
[
|
| 1029 |
+
[
|
| 1030 |
+
InlineKeyboardButton(Messages.SAVE, callback_data="save_thumb|save"),
|
| 1031 |
+
InlineKeyboardButton(Messages.CANCEL_IT, callback_data="nope_thumb"),
|
| 1032 |
+
]
|
| 1033 |
+
]
|
| 1034 |
+
)
|
| 1035 |
+
|
| 1036 |
+
THUMB_DEL = InlineKeyboardMarkup(
|
| 1037 |
+
[
|
| 1038 |
+
[
|
| 1039 |
+
InlineKeyboardButton(Messages.CHECK, callback_data="check_before_del"),
|
| 1040 |
+
InlineKeyboardButton(Messages.DELETE, callback_data="del_thumb"),
|
| 1041 |
+
],
|
| 1042 |
+
[InlineKeyboardButton(Messages.CANCEL_IT, callback_data="nope_thumb")],
|
| 1043 |
+
]
|
| 1044 |
+
)
|
| 1045 |
+
|
| 1046 |
+
THUMB_DEL_2 = InlineKeyboardMarkup(
|
| 1047 |
+
[
|
| 1048 |
+
[
|
| 1049 |
+
InlineKeyboardButton(Messages.DELETE, callback_data="del_thumb"),
|
| 1050 |
+
InlineKeyboardButton(Messages.CANCEL_IT, callback_data="nope_thumb")
|
| 1051 |
+
],
|
| 1052 |
+
]
|
| 1053 |
+
)
|
| 1054 |
+
|
| 1055 |
+
RATE_ME = InlineKeyboardMarkup(
|
| 1056 |
+
[
|
| 1057 |
+
[
|
| 1058 |
+
InlineKeyboardButton(Messages.RATE, url="https://t.me/BotsArchive/2705"),
|
| 1059 |
+
InlineKeyboardButton(Messages.DONATE, callback_data="donatecallback")
|
| 1060 |
+
],
|
| 1061 |
+
]
|
| 1062 |
+
)
|
unzipper/modules/callbacks.py
ADDED
|
@@ -0,0 +1,1233 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) 2023 EDM115
|
| 2 |
+
import asyncio
|
| 3 |
+
import concurrent.futures
|
| 4 |
+
import os
|
| 5 |
+
import re
|
| 6 |
+
import shutil
|
| 7 |
+
from fnmatch import fnmatch
|
| 8 |
+
from time import time
|
| 9 |
+
from urllib.parse import unquote
|
| 10 |
+
|
| 11 |
+
from aiofiles import open as openfile
|
| 12 |
+
from aiohttp import ClientSession, InvalidURL
|
| 13 |
+
from pyrogram import Client
|
| 14 |
+
from pyrogram.errors import ReplyMarkupTooLong
|
| 15 |
+
from pyrogram.types import CallbackQuery
|
| 16 |
+
import unzip_http
|
| 17 |
+
|
| 18 |
+
from config import Config
|
| 19 |
+
from unzipper import LOGGER, unzipperbot
|
| 20 |
+
from unzipper.helpers.database import (
|
| 21 |
+
add_cancel_task,
|
| 22 |
+
del_cancel_task,
|
| 23 |
+
del_merge_task,
|
| 24 |
+
del_thumb_db,
|
| 25 |
+
get_cancel_task,
|
| 26 |
+
get_maintenance,
|
| 27 |
+
get_merge_task_message_id,
|
| 28 |
+
get_ongoing_tasks,
|
| 29 |
+
set_upload_mode,
|
| 30 |
+
update_thumb,
|
| 31 |
+
update_uploaded,
|
| 32 |
+
upload_thumb,
|
| 33 |
+
add_ongoing_task,
|
| 34 |
+
del_ongoing_task,
|
| 35 |
+
count_ongoing_tasks,
|
| 36 |
+
)
|
| 37 |
+
from unzipper.helpers.unzip_help import (
|
| 38 |
+
TimeFormatter,
|
| 39 |
+
extentions_list,
|
| 40 |
+
humanbytes,
|
| 41 |
+
progress_for_pyrogram,
|
| 42 |
+
)
|
| 43 |
+
|
| 44 |
+
from .bot_data import ERROR_MSGS, Buttons, Messages
|
| 45 |
+
from .commands import https_url_regex, get_stats
|
| 46 |
+
from .ext_script.custom_thumbnail import silent_del
|
| 47 |
+
from .ext_script.ext_helper import (
|
| 48 |
+
_test_with_7z_helper,
|
| 49 |
+
extr_files,
|
| 50 |
+
get_files,
|
| 51 |
+
make_keyboard,
|
| 52 |
+
make_keyboard_empty,
|
| 53 |
+
merge_files,
|
| 54 |
+
split_files,
|
| 55 |
+
)
|
| 56 |
+
from .ext_script.up_helper import answer_query, get_size, send_file, send_url_logs
|
| 57 |
+
from .ext_script.url_parser import gdrive_dl
|
| 58 |
+
|
| 59 |
+
split_file_pattern = r"\.(?:z\d+|r\d{2})$"
|
| 60 |
+
rar_file_pattern = r"\.part\d+\.rar$"
|
| 61 |
+
telegram_url_pattern = r"(?:http[s]?:\/\/)?(?:www\.)?t\.me\/([a-zA-Z0-9_]+)\/(\d+)"
|
| 62 |
+
|
| 63 |
+
|
| 64 |
+
async def download(url, path):
|
| 65 |
+
try:
|
| 66 |
+
async with ClientSession() as session, session.get(url, timeout=None, allow_redirects=True) as resp, openfile(path, mode="wb") as file:
|
| 67 |
+
async for chunk in resp.content.iter_chunked(Config.CHUNK_SIZE):
|
| 68 |
+
await file.write(chunk)
|
| 69 |
+
await session.close()
|
| 70 |
+
except InvalidURL:
|
| 71 |
+
LOGGER.error(Messages.INVALID_URL)
|
| 72 |
+
except:
|
| 73 |
+
LOGGER.error(Messages.ERR_DL.format(url))
|
| 74 |
+
|
| 75 |
+
|
| 76 |
+
async def download_with_progress(url, path, message, unzip_bot):
|
| 77 |
+
async with ClientSession() as session, session.get(url, timeout=None, allow_redirects=True) as resp, openfile(path, mode="wb") as file:
|
| 78 |
+
total_size = int(resp.headers.get("Content-Length", 0))
|
| 79 |
+
current_size = 0
|
| 80 |
+
start_time = time()
|
| 81 |
+
|
| 82 |
+
async for chunk in resp.content.iter_chunked(Config.CHUNK_SIZE):
|
| 83 |
+
if message.from_user is not None and await get_cancel_task(message.from_user.id):
|
| 84 |
+
await session.close()
|
| 85 |
+
await message.edit(text=Messages.DL_STOPPED)
|
| 86 |
+
await del_cancel_task(message.from_user.id)
|
| 87 |
+
return False
|
| 88 |
+
|
| 89 |
+
await file.write(chunk)
|
| 90 |
+
current_size += len(chunk)
|
| 91 |
+
await progress_for_pyrogram(current_size, total_size, Messages.DL_URL.format(url), message, start_time, unzip_bot)
|
| 92 |
+
|
| 93 |
+
await session.close()
|
| 94 |
+
|
| 95 |
+
|
| 96 |
+
def get_zip_http(url):
|
| 97 |
+
rzf = unzip_http.RemoteZipFile(url)
|
| 98 |
+
paths = rzf.namelist()
|
| 99 |
+
return rzf, paths
|
| 100 |
+
|
| 101 |
+
|
| 102 |
+
async def async_generator(iterable):
|
| 103 |
+
for item in iterable:
|
| 104 |
+
yield item
|
| 105 |
+
|
| 106 |
+
|
| 107 |
+
# Callbacks
|
| 108 |
+
@unzipperbot.on_callback_query()
|
| 109 |
+
async def unzipper_cb(unzip_bot: Client, query: CallbackQuery):
|
| 110 |
+
uid = query.from_user.id
|
| 111 |
+
if uid != Config.BOT_OWNER: # skipcq: PTC-W0048
|
| 112 |
+
if await count_ongoing_tasks() >= Config.MAX_CONCURRENT_TASKS:
|
| 113 |
+
ogtasks = await get_ongoing_tasks()
|
| 114 |
+
if not any(ogtask["user_id"] == uid for ogtask in ogtasks):
|
| 115 |
+
await unzip_bot.send_message(
|
| 116 |
+
chat_id=uid,
|
| 117 |
+
text=Messages.MAX_TASKS.format(Config.MAX_CONCURRENT_TASKS),
|
| 118 |
+
)
|
| 119 |
+
return
|
| 120 |
+
|
| 121 |
+
if uid != Config.BOT_OWNER and await get_maintenance():
|
| 122 |
+
await answer_query(query, Messages.MAINTENANCE_ON)
|
| 123 |
+
return
|
| 124 |
+
|
| 125 |
+
sent_files = 0
|
| 126 |
+
global log_msg
|
| 127 |
+
|
| 128 |
+
if query.data == "megoinhome":
|
| 129 |
+
await query.edit_message_text(
|
| 130 |
+
text=Messages.START_TEXT.format(query.from_user.mention),
|
| 131 |
+
reply_markup=Buttons.START_BUTTON,
|
| 132 |
+
)
|
| 133 |
+
|
| 134 |
+
elif query.data == "helpcallback":
|
| 135 |
+
await query.edit_message_text(
|
| 136 |
+
text=Messages.HELP_TXT,
|
| 137 |
+
reply_markup=Buttons.ME_GOIN_HOME
|
| 138 |
+
)
|
| 139 |
+
|
| 140 |
+
elif query.data == "aboutcallback":
|
| 141 |
+
await query.edit_message_text(
|
| 142 |
+
text=Messages.ABOUT_TXT,
|
| 143 |
+
reply_markup=Buttons.ME_GOIN_HOME,
|
| 144 |
+
disable_web_page_preview=True,
|
| 145 |
+
)
|
| 146 |
+
|
| 147 |
+
elif query.data == "donatecallback":
|
| 148 |
+
await query.edit_message_text(
|
| 149 |
+
text=Messages.DONATE_TEXT,
|
| 150 |
+
reply_markup=Buttons.ME_GOIN_HOME,
|
| 151 |
+
disable_web_page_preview=True,
|
| 152 |
+
)
|
| 153 |
+
|
| 154 |
+
elif query.data.startswith("statscallback"):
|
| 155 |
+
if query.data.endswith("refresh"):
|
| 156 |
+
await query.edit_message_text(text=Messages.REFRESH_STATS)
|
| 157 |
+
text_stats = await get_stats(query.from_user.id)
|
| 158 |
+
await query.edit_message_text(
|
| 159 |
+
text=text_stats,
|
| 160 |
+
reply_markup=Buttons.REFRESH_BUTTON,
|
| 161 |
+
)
|
| 162 |
+
|
| 163 |
+
elif query.data == "canceldownload":
|
| 164 |
+
await add_cancel_task(query.from_user.id)
|
| 165 |
+
|
| 166 |
+
elif query.data == "check_thumb":
|
| 167 |
+
user_id = query.from_user.id
|
| 168 |
+
thumb_location = Config.THUMB_LOCATION + "/" + str(user_id) + ".jpg"
|
| 169 |
+
await unzip_bot.send_photo(
|
| 170 |
+
chat_id=user_id,
|
| 171 |
+
photo=thumb_location,
|
| 172 |
+
caption=Messages.ACTUAL_THUMB
|
| 173 |
+
)
|
| 174 |
+
await unzip_bot.delete_messages(
|
| 175 |
+
chat_id=user_id,
|
| 176 |
+
message_ids=query.message.id
|
| 177 |
+
)
|
| 178 |
+
await unzip_bot.send_message(
|
| 179 |
+
chat_id=user_id,
|
| 180 |
+
text=Messages.EXISTING_THUMB,
|
| 181 |
+
reply_markup=Buttons.THUMB_FINAL,
|
| 182 |
+
)
|
| 183 |
+
|
| 184 |
+
elif query.data == "check_before_del":
|
| 185 |
+
user_id = query.from_user.id
|
| 186 |
+
thumb_location = Config.THUMB_LOCATION + "/" + str(user_id) + ".jpg"
|
| 187 |
+
await unzip_bot.send_photo(
|
| 188 |
+
chat_id=user_id,
|
| 189 |
+
photo=thumb_location,
|
| 190 |
+
caption=Messages.ACTUAL_THUMB
|
| 191 |
+
)
|
| 192 |
+
await unzip_bot.delete_messages(
|
| 193 |
+
chat_id=user_id,
|
| 194 |
+
message_ids=query.message.id
|
| 195 |
+
)
|
| 196 |
+
await unzip_bot.send_message(
|
| 197 |
+
chat_id=user_id,
|
| 198 |
+
text=Messages.DEL_CONFIRM_THUMB_2,
|
| 199 |
+
reply_markup=Buttons.THUMB_DEL_2,
|
| 200 |
+
)
|
| 201 |
+
|
| 202 |
+
elif query.data.startswith("save_thumb"):
|
| 203 |
+
user_id = query.from_user.id
|
| 204 |
+
replace = query.data.split("|")[1]
|
| 205 |
+
if replace == "replace":
|
| 206 |
+
await silent_del(user_id)
|
| 207 |
+
thumb_location = Config.THUMB_LOCATION + "/" + str(user_id) + ".jpg"
|
| 208 |
+
final_thumb = Config.THUMB_LOCATION + "/waiting_" + str(user_id) + ".jpg"
|
| 209 |
+
try:
|
| 210 |
+
os.rename(final_thumb, thumb_location)
|
| 211 |
+
except:
|
| 212 |
+
LOGGER.warning(Messages.ERROR_THUMB_RENAME)
|
| 213 |
+
try:
|
| 214 |
+
thumb_url = await upload_thumb(thumb_location)
|
| 215 |
+
try:
|
| 216 |
+
if thumb_url != -1 and re.match(https_url_regex, thumb_url):
|
| 217 |
+
await update_thumb(query.from_user.id, thumb_url, force=True)
|
| 218 |
+
except:
|
| 219 |
+
LOGGER.error(Messages.ERROR_THUMB_UPDATE)
|
| 220 |
+
except:
|
| 221 |
+
LOGGER.error(Messages.ERROR_TELEGRAPH_UPLOAD)
|
| 222 |
+
await answer_query(query, Messages.SAVED_THUMBNAIL)
|
| 223 |
+
|
| 224 |
+
elif query.data == "del_thumb":
|
| 225 |
+
user_id = query.from_user.id
|
| 226 |
+
thumb_location = Config.THUMB_LOCATION + "/" + str(user_id) + ".jpg"
|
| 227 |
+
try:
|
| 228 |
+
await del_thumb_db(user_id)
|
| 229 |
+
except Exception as e:
|
| 230 |
+
LOGGER.error(Messages.ERROR_THUMB_DEL.format(e))
|
| 231 |
+
try:
|
| 232 |
+
os.remove(thumb_location)
|
| 233 |
+
except:
|
| 234 |
+
pass
|
| 235 |
+
await query.edit_message_text(text=Messages.DELETED_THUMB)
|
| 236 |
+
|
| 237 |
+
elif query.data == "nope_thumb":
|
| 238 |
+
user_id = query.from_user.id
|
| 239 |
+
del_1 = Config.THUMB_LOCATION + "/not_resized_" + str(user_id) + ".jpg"
|
| 240 |
+
del_2 = Config.THUMB_LOCATION + "/waiting_" + str(user_id) + ".jpg"
|
| 241 |
+
try:
|
| 242 |
+
os.remove(del_1)
|
| 243 |
+
except:
|
| 244 |
+
pass
|
| 245 |
+
try:
|
| 246 |
+
os.remove(del_2)
|
| 247 |
+
except:
|
| 248 |
+
pass
|
| 249 |
+
await query.edit_message_text(
|
| 250 |
+
text=Messages.CANCELLED_TXT.format(Messages.PROCESS_CANCELLED))
|
| 251 |
+
|
| 252 |
+
elif query.data.startswith("set_mode"):
|
| 253 |
+
user_id = query.from_user.id
|
| 254 |
+
mode = query.data.split("|")[1]
|
| 255 |
+
await set_upload_mode(user_id, mode)
|
| 256 |
+
await answer_query(
|
| 257 |
+
query,
|
| 258 |
+
Messages.CHANGED_UPLOAD_MODE_TXT.format(mode)
|
| 259 |
+
)
|
| 260 |
+
|
| 261 |
+
elif query.data == "merge_this":
|
| 262 |
+
user_id = query.from_user.id
|
| 263 |
+
m_id = query.message.id
|
| 264 |
+
start_time = time()
|
| 265 |
+
await add_ongoing_task(user_id, start_time, "merge")
|
| 266 |
+
s_id = await get_merge_task_message_id(user_id)
|
| 267 |
+
merge_msg = await query.message.edit(Messages.PROCESSING_TASK)
|
| 268 |
+
download_path = f"{Config.DOWNLOAD_LOCATION}/{user_id}/merge"
|
| 269 |
+
if s_id and (m_id - s_id) > 1:
|
| 270 |
+
files_array = list(range(s_id, m_id))
|
| 271 |
+
try:
|
| 272 |
+
messages_array = await unzip_bot.get_messages(user_id, files_array)
|
| 273 |
+
except Exception as e:
|
| 274 |
+
LOGGER.error(Messages.ERROR_GET_MSG.format(e))
|
| 275 |
+
await answer_query(query, Messages.ERROR_TXT.format(e))
|
| 276 |
+
await del_ongoing_task(user_id)
|
| 277 |
+
await del_merge_task(user_id)
|
| 278 |
+
try:
|
| 279 |
+
shutil.rmtree(f"{Config.DOWNLOAD_LOCATION}/{user_id}")
|
| 280 |
+
except:
|
| 281 |
+
pass
|
| 282 |
+
return
|
| 283 |
+
length = len(messages_array)
|
| 284 |
+
if not os.path.isdir(download_path):
|
| 285 |
+
os.makedirs(download_path)
|
| 286 |
+
rs_time = time()
|
| 287 |
+
newarray = []
|
| 288 |
+
await merge_msg.edit(Messages.PROCESS_MSGS.format(length))
|
| 289 |
+
for message in messages_array:
|
| 290 |
+
if message.document is None:
|
| 291 |
+
pass
|
| 292 |
+
else:
|
| 293 |
+
if message.from_user.id == user_id: # avoid getting files from other users, tho idk why this could happen
|
| 294 |
+
newarray.append(message)
|
| 295 |
+
length = len(newarray)
|
| 296 |
+
if length == 0:
|
| 297 |
+
await answer_query(query, Messages.NO_MERGE_TASK)
|
| 298 |
+
await del_ongoing_task(user_id)
|
| 299 |
+
await del_merge_task(user_id)
|
| 300 |
+
try:
|
| 301 |
+
shutil.rmtree(f"{Config.DOWNLOAD_LOCATION}/{user_id}")
|
| 302 |
+
except:
|
| 303 |
+
pass
|
| 304 |
+
return
|
| 305 |
+
i = 0
|
| 306 |
+
async_newarray = async_generator(newarray)
|
| 307 |
+
async for message in async_newarray:
|
| 308 |
+
i += 1
|
| 309 |
+
fname = message.document.file_name
|
| 310 |
+
await message.forward(chat_id=Config.LOGS_CHANNEL)
|
| 311 |
+
location = f"{download_path}/{fname}"
|
| 312 |
+
s_time = time()
|
| 313 |
+
await message.download(
|
| 314 |
+
file_name=location,
|
| 315 |
+
progress=progress_for_pyrogram,
|
| 316 |
+
progress_args=(
|
| 317 |
+
Messages.DL_FILES.format(i, length),
|
| 318 |
+
merge_msg,
|
| 319 |
+
s_time,
|
| 320 |
+
unzip_bot,
|
| 321 |
+
),
|
| 322 |
+
)
|
| 323 |
+
e_time = time()
|
| 324 |
+
dltime = TimeFormatter(round(e_time - rs_time) * 1000)
|
| 325 |
+
if dltime == "":
|
| 326 |
+
dltime = "1 s"
|
| 327 |
+
await merge_msg.edit(Messages.AFTER_OK_MERGE_DL_TXT.format(i, dltime))
|
| 328 |
+
await merge_msg.edit(
|
| 329 |
+
text=Messages.CHOOSE_EXT_MODE_MERGE,
|
| 330 |
+
reply_markup=Buttons.CHOOSE_E_F_M__BTNS,
|
| 331 |
+
)
|
| 332 |
+
await del_merge_task(user_id)
|
| 333 |
+
else:
|
| 334 |
+
await answer_query(query, Messages.NO_MERGE_TASK)
|
| 335 |
+
await del_ongoing_task(user_id)
|
| 336 |
+
await del_merge_task(user_id)
|
| 337 |
+
try:
|
| 338 |
+
shutil.rmtree(f"{Config.DOWNLOAD_LOCATION}/{user_id}")
|
| 339 |
+
except:
|
| 340 |
+
pass
|
| 341 |
+
|
| 342 |
+
elif query.data.startswith("merged"):
|
| 343 |
+
user_id = query.from_user.id
|
| 344 |
+
download_path = f"{Config.DOWNLOAD_LOCATION}/{user_id}/merge"
|
| 345 |
+
ext_files_dir = f"{Config.DOWNLOAD_LOCATION}/{user_id}/extracted"
|
| 346 |
+
os.makedirs(ext_files_dir)
|
| 347 |
+
try:
|
| 348 |
+
files = await get_files(download_path)
|
| 349 |
+
file = files[0]
|
| 350 |
+
except IndexError:
|
| 351 |
+
await answer_query(query, Messages.NO_MERGE_TASK)
|
| 352 |
+
await del_ongoing_task(user_id)
|
| 353 |
+
await del_merge_task(user_id)
|
| 354 |
+
try:
|
| 355 |
+
shutil.rmtree(f"{Config.DOWNLOAD_LOCATION}/{user_id}")
|
| 356 |
+
except:
|
| 357 |
+
pass
|
| 358 |
+
return
|
| 359 |
+
splitted_data = query.data.split("|")
|
| 360 |
+
log_msg = await unzip_bot.send_message(
|
| 361 |
+
chat_id=Config.LOGS_CHANNEL,
|
| 362 |
+
text=Messages.PROCESS_MERGE.format(user_id, ".".join(file.split("/")[-1].split(".")[:-1])),
|
| 363 |
+
)
|
| 364 |
+
try:
|
| 365 |
+
await query.message.edit(Messages.PROCESSING_TASK)
|
| 366 |
+
except:
|
| 367 |
+
pass
|
| 368 |
+
if splitted_data[1] == "with_pass":
|
| 369 |
+
password = await unzip_bot.ask(
|
| 370 |
+
chat_id=query.message.chat.id,
|
| 371 |
+
text=Messages.PLS_SEND_PASSWORD,
|
| 372 |
+
)
|
| 373 |
+
ext_s_time = time()
|
| 374 |
+
extractor = await merge_files(
|
| 375 |
+
iinput=file,
|
| 376 |
+
ooutput=ext_files_dir,
|
| 377 |
+
password=password.text,
|
| 378 |
+
)
|
| 379 |
+
ext_e_time = time()
|
| 380 |
+
else:
|
| 381 |
+
# Can't test the archive apparently
|
| 382 |
+
ext_s_time = time()
|
| 383 |
+
extractor = await merge_files(iinput=file, ooutput=ext_files_dir)
|
| 384 |
+
ext_e_time = time()
|
| 385 |
+
# Checks if there is an error happened while extracting the archive
|
| 386 |
+
if any(err in extractor for err in ERROR_MSGS):
|
| 387 |
+
try:
|
| 388 |
+
await query.message.edit(Messages.EXT_FAILED_TXT)
|
| 389 |
+
shutil.rmtree(ext_files_dir)
|
| 390 |
+
shutil.rmtree(download_path)
|
| 391 |
+
await del_ongoing_task(user_id)
|
| 392 |
+
except:
|
| 393 |
+
try:
|
| 394 |
+
await query.message.delete()
|
| 395 |
+
except:
|
| 396 |
+
pass
|
| 397 |
+
await unzip_bot.send_message(
|
| 398 |
+
chat_id=query.message.chat.id,
|
| 399 |
+
text=Messages.EXT_FAILED_TXT
|
| 400 |
+
)
|
| 401 |
+
shutil.rmtree(ext_files_dir)
|
| 402 |
+
await del_ongoing_task(user_id)
|
| 403 |
+
return
|
| 404 |
+
# Check if user was dumb 😐
|
| 405 |
+
paths = await get_files(path=ext_files_dir)
|
| 406 |
+
if not paths:
|
| 407 |
+
await unzip_bot.send_message(
|
| 408 |
+
chat_id=query.message.chat.id,
|
| 409 |
+
text=Messages.PASSWORD_PROTECTED,
|
| 410 |
+
)
|
| 411 |
+
await answer_query(
|
| 412 |
+
query,
|
| 413 |
+
Messages.EXT_FAILED_TXT,
|
| 414 |
+
unzip_client=unzip_bot
|
| 415 |
+
)
|
| 416 |
+
shutil.rmtree(ext_files_dir)
|
| 417 |
+
shutil.rmtree(download_path)
|
| 418 |
+
await del_ongoing_task(user_id)
|
| 419 |
+
return
|
| 420 |
+
|
| 421 |
+
try:
|
| 422 |
+
shutil.rmtree(download_path)
|
| 423 |
+
except:
|
| 424 |
+
pass
|
| 425 |
+
|
| 426 |
+
# Upload extracted files
|
| 427 |
+
extrtime = TimeFormatter(round(ext_e_time - ext_s_time) * 1000)
|
| 428 |
+
if extrtime == "":
|
| 429 |
+
extrtime = "1s"
|
| 430 |
+
await answer_query(
|
| 431 |
+
query,
|
| 432 |
+
Messages.EXT_OK_TXT.format(extrtime),
|
| 433 |
+
unzip_client=unzip_bot
|
| 434 |
+
)
|
| 435 |
+
|
| 436 |
+
try:
|
| 437 |
+
i_e_buttons = await make_keyboard(
|
| 438 |
+
paths=paths,
|
| 439 |
+
user_id=user_id,
|
| 440 |
+
chat_id=query.message.chat.id,
|
| 441 |
+
unziphttp=False
|
| 442 |
+
)
|
| 443 |
+
try:
|
| 444 |
+
await query.message.edit(Messages.SELECT_FILES, reply_markup=i_e_buttons)
|
| 445 |
+
except ReplyMarkupTooLong:
|
| 446 |
+
empty_buttons = await make_keyboard_empty(
|
| 447 |
+
user_id=user_id,
|
| 448 |
+
chat_id=query.message.chat.id,
|
| 449 |
+
unziphttp=False
|
| 450 |
+
)
|
| 451 |
+
await query.message.edit(
|
| 452 |
+
Messages.UNABLE_GATHER_FILES,
|
| 453 |
+
reply_markup=empty_buttons,
|
| 454 |
+
)
|
| 455 |
+
except:
|
| 456 |
+
try:
|
| 457 |
+
await query.message.delete()
|
| 458 |
+
i_e_buttons = await make_keyboard(
|
| 459 |
+
paths=paths,
|
| 460 |
+
user_id=user_id,
|
| 461 |
+
chat_id=query.message.chat.id,
|
| 462 |
+
unziphttp=False
|
| 463 |
+
)
|
| 464 |
+
await unzip_bot.send_message(
|
| 465 |
+
chat_id=query.message.chat.id,
|
| 466 |
+
text=Messages.SELECT_FILES,
|
| 467 |
+
reply_markup=i_e_buttons,
|
| 468 |
+
)
|
| 469 |
+
except:
|
| 470 |
+
try:
|
| 471 |
+
await query.message.delete()
|
| 472 |
+
empty_buttons = await make_keyboard_empty(
|
| 473 |
+
user_id=user_id,
|
| 474 |
+
chat_id=query.message.chat.id,
|
| 475 |
+
unziphttp=False
|
| 476 |
+
)
|
| 477 |
+
await unzip_bot.send_message(
|
| 478 |
+
chat_id=query.message.chat.id,
|
| 479 |
+
text=Messages.UNABLE_GATHER_FILES,
|
| 480 |
+
reply_markup=empty_buttons,
|
| 481 |
+
)
|
| 482 |
+
except:
|
| 483 |
+
await answer_query(
|
| 484 |
+
query,
|
| 485 |
+
Messages.EXT_FAILED_TXT,
|
| 486 |
+
unzip_client=unzip_bot
|
| 487 |
+
)
|
| 488 |
+
shutil.rmtree(ext_files_dir)
|
| 489 |
+
LOGGER.error(Messages.FATAL_ERROR)
|
| 490 |
+
await del_ongoing_task(user_id)
|
| 491 |
+
return
|
| 492 |
+
|
| 493 |
+
elif query.data.startswith("extract_file"):
|
| 494 |
+
user_id = query.from_user.id
|
| 495 |
+
start_time = time()
|
| 496 |
+
await add_ongoing_task(user_id, start_time, "extract")
|
| 497 |
+
download_path = f"{Config.DOWNLOAD_LOCATION}/{user_id}"
|
| 498 |
+
ext_files_dir = f"{download_path}/extracted"
|
| 499 |
+
r_message = query.message.reply_to_message
|
| 500 |
+
splitted_data = query.data.split("|")
|
| 501 |
+
try:
|
| 502 |
+
await query.message.edit(Messages.PROCESSING_TASK)
|
| 503 |
+
except:
|
| 504 |
+
pass
|
| 505 |
+
log_msg = await unzip_bot.send_message(
|
| 506 |
+
chat_id=Config.LOGS_CHANNEL,
|
| 507 |
+
text=Messages.USER_QUERY.format(user_id)
|
| 508 |
+
)
|
| 509 |
+
global archive_msg
|
| 510 |
+
|
| 511 |
+
try:
|
| 512 |
+
if splitted_data[1] == "url":
|
| 513 |
+
url = r_message.text
|
| 514 |
+
# Double check
|
| 515 |
+
if not re.match(https_url_regex, url):
|
| 516 |
+
await del_ongoing_task(user_id)
|
| 517 |
+
await query.message.edit(Messages.INVALID_URL)
|
| 518 |
+
return
|
| 519 |
+
if re.match(telegram_url_pattern, url):
|
| 520 |
+
r_message = await unzip_bot.get_messages(
|
| 521 |
+
chat_id=url.split("/")[-2],
|
| 522 |
+
message_ids=int(url.split("/")[-1])
|
| 523 |
+
)
|
| 524 |
+
splitted_data[1] = "tg_file"
|
| 525 |
+
if splitted_data[1] == "url":
|
| 526 |
+
s = ClientSession()
|
| 527 |
+
if "drive.google.com" in url:
|
| 528 |
+
url = await gdrive_dl(url)
|
| 529 |
+
if url is None:
|
| 530 |
+
await del_ongoing_task(user_id)
|
| 531 |
+
await query.message.edit(Messages.INVALID_URL)
|
| 532 |
+
return
|
| 533 |
+
async with s as session:
|
| 534 |
+
# Get the file size
|
| 535 |
+
unzip_head = await session.head(url, allow_redirects=True)
|
| 536 |
+
f_size = unzip_head.headers.get("content-length")
|
| 537 |
+
u_file_size = f_size if f_size else "undefined"
|
| 538 |
+
await log_msg.edit(Messages.LOG_TXT.format(user_id, url, u_file_size))
|
| 539 |
+
archive_msg = log_msg
|
| 540 |
+
# Checks if file is an archive using content-type header
|
| 541 |
+
unzip_resp = await session.get(url, timeout=None, allow_redirects=True)
|
| 542 |
+
if "application/" not in unzip_resp.headers.get("content-type"):
|
| 543 |
+
await del_ongoing_task(user_id)
|
| 544 |
+
await query.message.edit(Messages.NOT_AN_ARCHIVE)
|
| 545 |
+
return
|
| 546 |
+
rfnamebro = unquote(url.split("/")[-1])
|
| 547 |
+
if unzip_resp.status == 200:
|
| 548 |
+
# Makes download dir
|
| 549 |
+
os.makedirs(download_path)
|
| 550 |
+
s_time = time()
|
| 551 |
+
fname = unquote(os.path.splitext(url)[1])
|
| 552 |
+
fext = fname.split(".")[-1].casefold()
|
| 553 |
+
if (
|
| 554 |
+
splitted_data[2] not in ["thumb", "thumbrename"]
|
| 555 |
+
and fext not in extentions_list["archive"]
|
| 556 |
+
):
|
| 557 |
+
await del_ongoing_task(user_id)
|
| 558 |
+
await query.message.edit(Messages.DEF_NOT_AN_ARCHIVE)
|
| 559 |
+
try:
|
| 560 |
+
shutil.rmtree(f"{Config.DOWNLOAD_LOCATION}/{user_id}")
|
| 561 |
+
except:
|
| 562 |
+
pass
|
| 563 |
+
return
|
| 564 |
+
archive = f"{download_path}/archive_from_{user_id}{fname}"
|
| 565 |
+
location = archive
|
| 566 |
+
await answer_query(
|
| 567 |
+
query,
|
| 568 |
+
Messages.PROCESSING2,
|
| 569 |
+
unzip_client=unzip_bot
|
| 570 |
+
)
|
| 571 |
+
# HTTP server must send Accept-Ranges: bytes and Content-Length in headers
|
| 572 |
+
if fext == "zip" and "accept-ranges" in unzip_resp.headers and "content-length" in unzip_resp.headers:
|
| 573 |
+
try:
|
| 574 |
+
loop = asyncio.get_event_loop()
|
| 575 |
+
with concurrent.futures.ThreadPoolExecutor() as pool:
|
| 576 |
+
rzf, paths = await loop.run_in_executor(pool, get_zip_http, url)
|
| 577 |
+
try:
|
| 578 |
+
i_e_buttons = await make_keyboard(
|
| 579 |
+
paths=paths,
|
| 580 |
+
user_id=user_id,
|
| 581 |
+
chat_id=query.message.chat.id,
|
| 582 |
+
unziphttp=True,
|
| 583 |
+
rzfile=rzf,
|
| 584 |
+
)
|
| 585 |
+
try:
|
| 586 |
+
await query.message.edit(
|
| 587 |
+
Messages.SELECT_FILES,
|
| 588 |
+
reply_markup=i_e_buttons
|
| 589 |
+
)
|
| 590 |
+
except ReplyMarkupTooLong:
|
| 591 |
+
empty_buttons = await make_keyboard_empty(
|
| 592 |
+
user_id=user_id, chat_id=query.message.chat.id, unziphttp=True, rzfile=rzf)
|
| 593 |
+
await query.message.edit(
|
| 594 |
+
Messages.UNABLE_GATHER_FILES,
|
| 595 |
+
reply_markup=empty_buttons,
|
| 596 |
+
)
|
| 597 |
+
except:
|
| 598 |
+
try:
|
| 599 |
+
await query.message.delete()
|
| 600 |
+
i_e_buttons = await make_keyboard(
|
| 601 |
+
paths=paths,
|
| 602 |
+
user_id=user_id,
|
| 603 |
+
chat_id=query.message.chat.id,
|
| 604 |
+
unziphttp=True,
|
| 605 |
+
rzfile=rzf,
|
| 606 |
+
)
|
| 607 |
+
await unzip_bot.send_message(
|
| 608 |
+
chat_id=query.message.chat.id,
|
| 609 |
+
text=Messages.SELECT_FILES,
|
| 610 |
+
reply_markup=i_e_buttons,
|
| 611 |
+
)
|
| 612 |
+
except:
|
| 613 |
+
try:
|
| 614 |
+
await query.message.delete()
|
| 615 |
+
empty_buttons = await make_keyboard_empty(
|
| 616 |
+
user_id=user_id,
|
| 617 |
+
chat_id=query.message.chat.id,
|
| 618 |
+
unziphttp=True,
|
| 619 |
+
rzfile=rzf
|
| 620 |
+
)
|
| 621 |
+
await unzip_bot.send_message(
|
| 622 |
+
chat_id=query.message.chat.id,
|
| 623 |
+
text=Messages.UNABLE_GATHER_FILES,
|
| 624 |
+
reply_markup=empty_buttons,
|
| 625 |
+
)
|
| 626 |
+
except:
|
| 627 |
+
pass
|
| 628 |
+
except Exception as e:
|
| 629 |
+
LOGGER.error(Messages.UNZIP_HTTP.format(url, e))
|
| 630 |
+
try:
|
| 631 |
+
dled = await download_with_progress(url, archive, query.message, unzip_bot)
|
| 632 |
+
except Exception as e:
|
| 633 |
+
dled = False
|
| 634 |
+
LOGGER.error(Messages.ERR_DL.format(e))
|
| 635 |
+
if isinstance(dled, bool) and not dled:
|
| 636 |
+
return
|
| 637 |
+
e_time = time()
|
| 638 |
+
# Send copy in logs in case url has gone
|
| 639 |
+
# paths = await get_files(path=archive)
|
| 640 |
+
await send_url_logs(
|
| 641 |
+
unzip_bot=unzip_bot,
|
| 642 |
+
c_id=Config.LOGS_CHANNEL,
|
| 643 |
+
doc_f=archive,
|
| 644 |
+
source=url,
|
| 645 |
+
message=query.message,
|
| 646 |
+
)
|
| 647 |
+
else:
|
| 648 |
+
await del_ongoing_task(user_id)
|
| 649 |
+
await query.message.edit(Messages.CANT_DL_URL)
|
| 650 |
+
try:
|
| 651 |
+
shutil.rmtree(f"{Config.DOWNLOAD_LOCATION}/{user_id}")
|
| 652 |
+
except:
|
| 653 |
+
pass
|
| 654 |
+
return
|
| 655 |
+
|
| 656 |
+
elif splitted_data[1] == "tg_file":
|
| 657 |
+
if r_message.document is None:
|
| 658 |
+
await del_ongoing_task(user_id)
|
| 659 |
+
await query.message.edit(Messages.GIVE_ARCHIVE)
|
| 660 |
+
return
|
| 661 |
+
fname = r_message.document.file_name
|
| 662 |
+
rfnamebro = fname
|
| 663 |
+
archive_msg = await r_message.forward(chat_id=Config.LOGS_CHANNEL)
|
| 664 |
+
await log_msg.edit(Messages.LOG_TXT.format(
|
| 665 |
+
user_id,
|
| 666 |
+
fname,
|
| 667 |
+
humanbytes(r_message.document.file_size)
|
| 668 |
+
))
|
| 669 |
+
# Checks if it's actually an archive
|
| 670 |
+
# fext = (pathlib.Path(fname).suffix).casefold()
|
| 671 |
+
if splitted_data[2] not in ["thumb", "thumbrename"]:
|
| 672 |
+
fext = fname.split(".")[-1].casefold()
|
| 673 |
+
if (
|
| 674 |
+
fnmatch(fext, extentions_list["split"][0])
|
| 675 |
+
or fext in extentions_list["split"] or bool(re.search(rar_file_pattern, fname))
|
| 676 |
+
):
|
| 677 |
+
await query.message.edit(Messages.ITS_SPLITTED)
|
| 678 |
+
return
|
| 679 |
+
if bool(re.search(split_file_pattern, fname)):
|
| 680 |
+
await del_ongoing_task(user_id)
|
| 681 |
+
await query.message.edit(Messages.SPL_RZ)
|
| 682 |
+
return
|
| 683 |
+
if fext not in extentions_list["archive"]:
|
| 684 |
+
await del_ongoing_task(user_id)
|
| 685 |
+
await query.message.edit(Messages.DEF_NOT_AN_ARCHIVE)
|
| 686 |
+
return
|
| 687 |
+
# Makes download dir
|
| 688 |
+
os.makedirs(download_path)
|
| 689 |
+
s_time = time()
|
| 690 |
+
location = f"{download_path}/archive_from_{user_id}{os.path.splitext(fname)[1]}"
|
| 691 |
+
archive = await r_message.download(
|
| 692 |
+
file_name=location,
|
| 693 |
+
progress=progress_for_pyrogram,
|
| 694 |
+
progress_args=(
|
| 695 |
+
Messages.TRY_DL,
|
| 696 |
+
query.message,
|
| 697 |
+
s_time,
|
| 698 |
+
unzip_bot,
|
| 699 |
+
),
|
| 700 |
+
)
|
| 701 |
+
e_time = time()
|
| 702 |
+
else:
|
| 703 |
+
await del_ongoing_task(user_id)
|
| 704 |
+
await answer_query(
|
| 705 |
+
query,
|
| 706 |
+
Messages.QUERY_PARSE_ERR,
|
| 707 |
+
answer_only=True,
|
| 708 |
+
unzip_client=unzip_bot,
|
| 709 |
+
)
|
| 710 |
+
return
|
| 711 |
+
|
| 712 |
+
if splitted_data[2].startswith("thumb"):
|
| 713 |
+
await query.message.edit(Messages.PROCESSING2)
|
| 714 |
+
archive_name = location.split("/")[-1]
|
| 715 |
+
if "rename" in splitted_data[2]:
|
| 716 |
+
newname = await unzip_bot.ask(
|
| 717 |
+
chat_id=user_id,
|
| 718 |
+
text=Messages.GIVE_NEW_NAME.format(rfnamebro),
|
| 719 |
+
)
|
| 720 |
+
renamed = location.replace(archive_name, newname.text)
|
| 721 |
+
else:
|
| 722 |
+
renamed = location.replace(archive_name, rfnamebro)
|
| 723 |
+
try:
|
| 724 |
+
os.rename(location, renamed)
|
| 725 |
+
except OSError as e:
|
| 726 |
+
await del_ongoing_task(user_id)
|
| 727 |
+
LOGGER.error(e)
|
| 728 |
+
return
|
| 729 |
+
newfname = renamed.split("/")[-1]
|
| 730 |
+
fsize = await get_size(renamed)
|
| 731 |
+
if fsize <= Config.TG_MAX_SIZE:
|
| 732 |
+
await send_file(
|
| 733 |
+
unzip_bot=unzip_bot,
|
| 734 |
+
c_id=user_id,
|
| 735 |
+
doc_f=renamed,
|
| 736 |
+
query=query,
|
| 737 |
+
full_path=renamed,
|
| 738 |
+
log_msg=log_msg,
|
| 739 |
+
split=False,
|
| 740 |
+
)
|
| 741 |
+
await query.message.delete()
|
| 742 |
+
await del_ongoing_task(user_id)
|
| 743 |
+
return shutil.rmtree(f"{Config.DOWNLOAD_LOCATION}/{user_id}")
|
| 744 |
+
await query.message.edit(Messages.SPLITTING.format(newfname))
|
| 745 |
+
splitteddir = f"{Config.DOWNLOAD_LOCATION}/splitted/{user_id}"
|
| 746 |
+
os.makedirs(splitteddir)
|
| 747 |
+
ooutput = f"{splitteddir}/{newfname}"
|
| 748 |
+
if await (user_id):
|
| 749 |
+
splittedfiles = await split_files(renamed, ooutput, Config.TG_PREMIUM_SIZE)
|
| 750 |
+
else:
|
| 751 |
+
splittedfiles = await split_files(renamed, ooutput, Config.TG_MAX_SIZE)
|
| 752 |
+
if not splittedfiles:
|
| 753 |
+
try:
|
| 754 |
+
shutil.rmtree(splitteddir)
|
| 755 |
+
except:
|
| 756 |
+
pass
|
| 757 |
+
await del_ongoing_task(user_id)
|
| 758 |
+
await query.message.edit(Messages.ERR_SPLIT)
|
| 759 |
+
return
|
| 760 |
+
await query.message.edit(Messages.SEND_ALL_PARTS.format(newfname))
|
| 761 |
+
async_splittedfiles = async_generator(splittedfiles)
|
| 762 |
+
async for file in async_splittedfiles:
|
| 763 |
+
sent_files += 1
|
| 764 |
+
await send_file(
|
| 765 |
+
unzip_bot=unzip_bot,
|
| 766 |
+
c_id=user_id,
|
| 767 |
+
doc_f=file,
|
| 768 |
+
query=query,
|
| 769 |
+
full_path=splitteddir,
|
| 770 |
+
log_msg=log_msg,
|
| 771 |
+
split=True,
|
| 772 |
+
)
|
| 773 |
+
try:
|
| 774 |
+
shutil.rmtree(splitteddir)
|
| 775 |
+
shutil.rmtree(renamed.replace(newfname, ""))
|
| 776 |
+
except:
|
| 777 |
+
pass
|
| 778 |
+
await del_ongoing_task(user_id)
|
| 779 |
+
try:
|
| 780 |
+
await query.message.edit(
|
| 781 |
+
text=Messages.UPLOADED,
|
| 782 |
+
reply_markup=Buttons.RATE_ME
|
| 783 |
+
)
|
| 784 |
+
except:
|
| 785 |
+
await unzip_bot.send_message(
|
| 786 |
+
chat_id=user_id,
|
| 787 |
+
text=Messages.UPLOADED,
|
| 788 |
+
reply_markup=Buttons.RATE_ME
|
| 789 |
+
)
|
| 790 |
+
return
|
| 791 |
+
|
| 792 |
+
dltime = TimeFormatter(round(e_time - s_time) * 1000)
|
| 793 |
+
if dltime == "":
|
| 794 |
+
dltime = "1s"
|
| 795 |
+
await answer_query(
|
| 796 |
+
query,
|
| 797 |
+
Messages.AFTER_OK_DL_TXT.format(dltime),
|
| 798 |
+
unzip_client=unzip_bot
|
| 799 |
+
)
|
| 800 |
+
|
| 801 |
+
# Attempt to fetch password protected archives
|
| 802 |
+
if splitted_data[2] == "with_pass":
|
| 803 |
+
password = await unzip_bot.ask(
|
| 804 |
+
chat_id=query.message.chat.id,
|
| 805 |
+
text=Messages.PLS_SEND_PASSWORD
|
| 806 |
+
)
|
| 807 |
+
ext_s_time = time()
|
| 808 |
+
extractor = await extr_files(
|
| 809 |
+
path=ext_files_dir,
|
| 810 |
+
archive_path=archive,
|
| 811 |
+
password=password.text,
|
| 812 |
+
)
|
| 813 |
+
ext_e_time = time()
|
| 814 |
+
await archive_msg.reply(Messages.PASS_TXT.format(password.text))
|
| 815 |
+
else:
|
| 816 |
+
ext_s_time = time()
|
| 817 |
+
tested = await _test_with_7z_helper(archive)
|
| 818 |
+
ext_t_time = time()
|
| 819 |
+
testtime = TimeFormatter(round(ext_t_time - ext_s_time) * 1000)
|
| 820 |
+
if testtime == "":
|
| 821 |
+
testtime = "1s"
|
| 822 |
+
await answer_query(
|
| 823 |
+
query,
|
| 824 |
+
Messages.AFTER_OK_TEST_TXT.format(testtime),
|
| 825 |
+
unzip_client=unzip_bot
|
| 826 |
+
)
|
| 827 |
+
if tested:
|
| 828 |
+
extractor = await extr_files(
|
| 829 |
+
path=ext_files_dir,
|
| 830 |
+
archive_path=archive
|
| 831 |
+
)
|
| 832 |
+
ext_e_time = time()
|
| 833 |
+
else:
|
| 834 |
+
extractor = "Error"
|
| 835 |
+
ext_e_time = time()
|
| 836 |
+
# Checks if there is an error happened while extracting the archive
|
| 837 |
+
if any(err in extractor for err in ERROR_MSGS):
|
| 838 |
+
try:
|
| 839 |
+
await query.message.edit(Messages.EXT_FAILED_TXT)
|
| 840 |
+
shutil.rmtree(ext_files_dir)
|
| 841 |
+
await del_ongoing_task(user_id)
|
| 842 |
+
await log_msg.reply(Messages.EXT_FAILED_TXT)
|
| 843 |
+
return
|
| 844 |
+
except:
|
| 845 |
+
try:
|
| 846 |
+
await query.message.delete()
|
| 847 |
+
except:
|
| 848 |
+
pass
|
| 849 |
+
await unzip_bot.send_message(
|
| 850 |
+
chat_id=query.message.chat.id,
|
| 851 |
+
text=Messages.EXT_FAILED_TXT
|
| 852 |
+
)
|
| 853 |
+
shutil.rmtree(ext_files_dir)
|
| 854 |
+
await del_ongoing_task(user_id)
|
| 855 |
+
await archive_msg.reply(Messages.EXT_FAILED_TXT)
|
| 856 |
+
return
|
| 857 |
+
# Check if user was dumb 😐
|
| 858 |
+
paths = await get_files(path=ext_files_dir)
|
| 859 |
+
if not paths:
|
| 860 |
+
await archive_msg.reply(Messages.PASSWORD_PROTECTED)
|
| 861 |
+
await unzip_bot.send_message(
|
| 862 |
+
chat_id=query.message.chat.id,
|
| 863 |
+
text=Messages.PASSWORD_PROTECTED,
|
| 864 |
+
)
|
| 865 |
+
await answer_query(
|
| 866 |
+
query,
|
| 867 |
+
Messages.EXT_FAILED_TXT,
|
| 868 |
+
unzip_client=unzip_bot
|
| 869 |
+
)
|
| 870 |
+
shutil.rmtree(ext_files_dir)
|
| 871 |
+
await del_ongoing_task(user_id)
|
| 872 |
+
return
|
| 873 |
+
|
| 874 |
+
# Upload extracted files
|
| 875 |
+
extrtime = TimeFormatter(round(ext_e_time - ext_s_time) * 1000)
|
| 876 |
+
if extrtime == "":
|
| 877 |
+
extrtime = "1s"
|
| 878 |
+
await answer_query(
|
| 879 |
+
query,
|
| 880 |
+
Messages.EXT_OK_TXT.format(extrtime),
|
| 881 |
+
unzip_client=unzip_bot
|
| 882 |
+
)
|
| 883 |
+
|
| 884 |
+
try:
|
| 885 |
+
i_e_buttons = await make_keyboard(
|
| 886 |
+
paths=paths,
|
| 887 |
+
user_id=user_id,
|
| 888 |
+
chat_id=query.message.chat.id,
|
| 889 |
+
unziphttp=False
|
| 890 |
+
)
|
| 891 |
+
try:
|
| 892 |
+
await query.message.edit(Messages.SELECT_FILES, reply_markup=i_e_buttons)
|
| 893 |
+
except ReplyMarkupTooLong:
|
| 894 |
+
empty_buttons = await make_keyboard_empty(
|
| 895 |
+
user_id=user_id,
|
| 896 |
+
chat_id=query.message.chat.id,
|
| 897 |
+
unziphttp=False
|
| 898 |
+
)
|
| 899 |
+
await query.message.edit(
|
| 900 |
+
Messages.UNABLE_GATHER_FILES,
|
| 901 |
+
reply_markup=empty_buttons,
|
| 902 |
+
)
|
| 903 |
+
except:
|
| 904 |
+
try:
|
| 905 |
+
await query.message.delete()
|
| 906 |
+
i_e_buttons = await make_keyboard(
|
| 907 |
+
paths=paths,
|
| 908 |
+
user_id=user_id,
|
| 909 |
+
chat_id=query.message.chat.id,
|
| 910 |
+
unziphttp=False
|
| 911 |
+
)
|
| 912 |
+
await unzip_bot.send_message(
|
| 913 |
+
chat_id=query.message.chat.id,
|
| 914 |
+
text=Messages.SELECT_FILES,
|
| 915 |
+
reply_markup=i_e_buttons,
|
| 916 |
+
)
|
| 917 |
+
except:
|
| 918 |
+
try:
|
| 919 |
+
await query.message.delete()
|
| 920 |
+
empty_buttons = await make_keyboard_empty(
|
| 921 |
+
user_id=user_id,
|
| 922 |
+
chat_id=query.message.chat.id,
|
| 923 |
+
unziphttp=False
|
| 924 |
+
)
|
| 925 |
+
await unzip_bot.send_message(
|
| 926 |
+
chat_id=query.message.chat.id,
|
| 927 |
+
text=Messages.UNABLE_GATHER_FILES,
|
| 928 |
+
reply_markup=empty_buttons,
|
| 929 |
+
)
|
| 930 |
+
except:
|
| 931 |
+
await answer_query(
|
| 932 |
+
query,
|
| 933 |
+
Messages.EXT_FAILED_TXT,
|
| 934 |
+
unzip_client=unzip_bot
|
| 935 |
+
)
|
| 936 |
+
await archive_msg.reply(Messages.EXT_FAILED_TXT)
|
| 937 |
+
shutil.rmtree(ext_files_dir)
|
| 938 |
+
LOGGER.error(Messages.FATAL_ERROR)
|
| 939 |
+
await del_ongoing_task(user_id)
|
| 940 |
+
return
|
| 941 |
+
|
| 942 |
+
except Exception as e:
|
| 943 |
+
await del_ongoing_task(user_id)
|
| 944 |
+
try:
|
| 945 |
+
try:
|
| 946 |
+
await query.message.edit(Messages.ERROR_TXT.format(e))
|
| 947 |
+
except:
|
| 948 |
+
await unzip_bot.send_message(
|
| 949 |
+
chat_id=query.message.chat.id,
|
| 950 |
+
text=Messages.ERROR_TXT.format(e))
|
| 951 |
+
await archive_msg.reply(Messages.ERROR_TXT.format(e))
|
| 952 |
+
shutil.rmtree(ext_files_dir)
|
| 953 |
+
try:
|
| 954 |
+
await ClientSession().close()
|
| 955 |
+
except:
|
| 956 |
+
pass
|
| 957 |
+
LOGGER.error(e)
|
| 958 |
+
except Exception as err:
|
| 959 |
+
LOGGER.error(err)
|
| 960 |
+
await archive_msg.reply(err)
|
| 961 |
+
|
| 962 |
+
elif query.data.startswith("ext_f"):
|
| 963 |
+
LOGGER.info(query.data)
|
| 964 |
+
user_id = query.from_user.id
|
| 965 |
+
spl_data = query.data.split("|")
|
| 966 |
+
file_path = f"{Config.DOWNLOAD_LOCATION}/{spl_data[1]}/extracted"
|
| 967 |
+
try:
|
| 968 |
+
urled = spl_data[4] if isinstance(spl_data[4], bool) else False
|
| 969 |
+
except:
|
| 970 |
+
urled = False
|
| 971 |
+
if urled:
|
| 972 |
+
paths = spl_data[5].namelist()
|
| 973 |
+
else:
|
| 974 |
+
paths = await get_files(path=file_path)
|
| 975 |
+
if not paths and not urled:
|
| 976 |
+
if os.path.isdir(f"{Config.DOWNLOAD_LOCATION}/{spl_data[1]}"):
|
| 977 |
+
shutil.rmtree(f"{Config.DOWNLOAD_LOCATION}/{spl_data[1]}")
|
| 978 |
+
await del_ongoing_task(user_id)
|
| 979 |
+
await query.message.edit(
|
| 980 |
+
text=Messages.NO_FILE_LEFT,
|
| 981 |
+
reply_markup=Buttons.RATE_ME
|
| 982 |
+
)
|
| 983 |
+
return
|
| 984 |
+
LOGGER.info("ext_f paths : " + str(paths))
|
| 985 |
+
try:
|
| 986 |
+
await query.answer(Messages.SENDING_FILE)
|
| 987 |
+
except:
|
| 988 |
+
pass
|
| 989 |
+
sent_files += 1
|
| 990 |
+
if urled:
|
| 991 |
+
file = spl_data[5].open(paths[int(spl_data[3])])
|
| 992 |
+
else:
|
| 993 |
+
file = paths[int(spl_data[3])]
|
| 994 |
+
fsize = await get_size(file)
|
| 995 |
+
split = False
|
| 996 |
+
if fsize <= Config.TG_MAX_SIZE:
|
| 997 |
+
await send_file(
|
| 998 |
+
unzip_bot=unzip_bot,
|
| 999 |
+
c_id=spl_data[2],
|
| 1000 |
+
doc_f=file,
|
| 1001 |
+
query=query,
|
| 1002 |
+
full_path=f"{Config.DOWNLOAD_LOCATION}/{spl_data[1]}",
|
| 1003 |
+
log_msg=log_msg,
|
| 1004 |
+
split=False,
|
| 1005 |
+
)
|
| 1006 |
+
else:
|
| 1007 |
+
split = True
|
| 1008 |
+
if split:
|
| 1009 |
+
fname = file.split('/')[-1]
|
| 1010 |
+
smessage = await unzip_bot.send_message(
|
| 1011 |
+
chat_id=user_id,
|
| 1012 |
+
text=Messages.SPLITTING.format(fname)
|
| 1013 |
+
)
|
| 1014 |
+
splitteddir = f"{Config.DOWNLOAD_LOCATION}/splitted/{user_id}"
|
| 1015 |
+
os.makedirs(splitteddir)
|
| 1016 |
+
ooutput = f"{splitteddir}/{fname}"
|
| 1017 |
+
splittedfiles = await split_files(file, ooutput, Config.TG_MAX_SIZE)
|
| 1018 |
+
LOGGER.info(splittedfiles)
|
| 1019 |
+
if not splittedfiles:
|
| 1020 |
+
try:
|
| 1021 |
+
shutil.rmtree(splitteddir)
|
| 1022 |
+
except:
|
| 1023 |
+
pass
|
| 1024 |
+
await del_ongoing_task(user_id)
|
| 1025 |
+
await smessage.edit(Messages.ERR_SPLIT)
|
| 1026 |
+
return
|
| 1027 |
+
await smessage.edit(Messages.SEND_ALL_PARTS.format(fname))
|
| 1028 |
+
async_splittedfiles = async_generator(splittedfiles)
|
| 1029 |
+
async for file in async_splittedfiles:
|
| 1030 |
+
sent_files += 1
|
| 1031 |
+
await send_file(
|
| 1032 |
+
unzip_bot=unzip_bot,
|
| 1033 |
+
c_id=user_id,
|
| 1034 |
+
doc_f=file,
|
| 1035 |
+
query=query,
|
| 1036 |
+
full_path=splitteddir,
|
| 1037 |
+
log_msg=log_msg,
|
| 1038 |
+
split=True,
|
| 1039 |
+
)
|
| 1040 |
+
try:
|
| 1041 |
+
shutil.rmtree(splitteddir)
|
| 1042 |
+
os.remove(file)
|
| 1043 |
+
except:
|
| 1044 |
+
pass
|
| 1045 |
+
try:
|
| 1046 |
+
await smessage.delete()
|
| 1047 |
+
except:
|
| 1048 |
+
pass
|
| 1049 |
+
|
| 1050 |
+
await query.message.edit(Messages.REFRESHING)
|
| 1051 |
+
if urled:
|
| 1052 |
+
rpaths = paths.remove(paths[int(spl_data[3])])
|
| 1053 |
+
else:
|
| 1054 |
+
rpaths = await get_files(path=file_path)
|
| 1055 |
+
if not rpaths:
|
| 1056 |
+
try:
|
| 1057 |
+
shutil.rmtree(f"{Config.DOWNLOAD_LOCATION}/{spl_data[1]}")
|
| 1058 |
+
except:
|
| 1059 |
+
pass
|
| 1060 |
+
await del_ongoing_task(user_id)
|
| 1061 |
+
await query.message.edit(
|
| 1062 |
+
text=Messages.NO_FILE_LEFT,
|
| 1063 |
+
reply_markup=Buttons.RATE_ME
|
| 1064 |
+
)
|
| 1065 |
+
return
|
| 1066 |
+
if urled:
|
| 1067 |
+
try:
|
| 1068 |
+
i_e_buttons = await make_keyboard(
|
| 1069 |
+
paths=rpaths,
|
| 1070 |
+
user_id=query.from_user.id,
|
| 1071 |
+
chat_id=query.message.chat.id,
|
| 1072 |
+
unziphttp=True,
|
| 1073 |
+
rzfile=spl_data[5],
|
| 1074 |
+
)
|
| 1075 |
+
await query.message.edit(Messages.SELECT_FILES, reply_markup=i_e_buttons)
|
| 1076 |
+
except ReplyMarkupTooLong:
|
| 1077 |
+
empty_buttons = await make_keyboard_empty(
|
| 1078 |
+
user_id=user_id,
|
| 1079 |
+
chat_id=query.message.chat.id,
|
| 1080 |
+
unziphttp=True,
|
| 1081 |
+
rzfile=spl_data[5]
|
| 1082 |
+
)
|
| 1083 |
+
await query.message.edit(
|
| 1084 |
+
Messages.UNABLE_GATHER_FILES,
|
| 1085 |
+
reply_markup=empty_buttons,
|
| 1086 |
+
)
|
| 1087 |
+
else:
|
| 1088 |
+
try:
|
| 1089 |
+
i_e_buttons = await make_keyboard(
|
| 1090 |
+
paths=rpaths,
|
| 1091 |
+
user_id=query.from_user.id,
|
| 1092 |
+
chat_id=query.message.chat.id,
|
| 1093 |
+
unziphttp=False
|
| 1094 |
+
)
|
| 1095 |
+
await query.message.edit(Messages.SELECT_FILES, reply_markup=i_e_buttons)
|
| 1096 |
+
except ReplyMarkupTooLong:
|
| 1097 |
+
empty_buttons = await make_keyboard_empty(
|
| 1098 |
+
user_id=user_id,
|
| 1099 |
+
chat_id=query.message.chat.id,
|
| 1100 |
+
unziphttp=False
|
| 1101 |
+
)
|
| 1102 |
+
await query.message.edit(
|
| 1103 |
+
Messages.UNABLE_GATHER_FILES,
|
| 1104 |
+
reply_markup=empty_buttons,
|
| 1105 |
+
)
|
| 1106 |
+
await update_uploaded(user_id, upload_count=sent_files)
|
| 1107 |
+
|
| 1108 |
+
elif query.data.startswith("ext_a"):
|
| 1109 |
+
LOGGER.info(query.data)
|
| 1110 |
+
user_id = query.from_user.id
|
| 1111 |
+
spl_data = query.data.split("|")
|
| 1112 |
+
file_path = f"{Config.DOWNLOAD_LOCATION}/{spl_data[1]}/extracted"
|
| 1113 |
+
try:
|
| 1114 |
+
urled = spl_data[4] if isinstance(spl_data[3], bool) else False
|
| 1115 |
+
except:
|
| 1116 |
+
urled = False
|
| 1117 |
+
if urled:
|
| 1118 |
+
paths = spl_data[4].namelist()
|
| 1119 |
+
else:
|
| 1120 |
+
paths = await get_files(path=file_path)
|
| 1121 |
+
LOGGER.info("ext_a paths : " + str(paths))
|
| 1122 |
+
if not paths and not urled:
|
| 1123 |
+
try:
|
| 1124 |
+
shutil.rmtree(f"{Config.DOWNLOAD_LOCATION}/{spl_data[1]}")
|
| 1125 |
+
except:
|
| 1126 |
+
pass
|
| 1127 |
+
await del_ongoing_task(user_id)
|
| 1128 |
+
await query.message.edit(
|
| 1129 |
+
text=Messages.NO_FILE_LEFT,
|
| 1130 |
+
reply_markup=Buttons.RATE_ME
|
| 1131 |
+
)
|
| 1132 |
+
return
|
| 1133 |
+
await query.message.edit(Messages.SEND_ALL_FILES)
|
| 1134 |
+
async_paths = async_generator(paths)
|
| 1135 |
+
async for file in async_paths:
|
| 1136 |
+
sent_files += 1
|
| 1137 |
+
if urled:
|
| 1138 |
+
file = spl_data[4].open(file)
|
| 1139 |
+
fsize = Config.TG_MAX_SIZE + 1
|
| 1140 |
+
# secutity as we can't retrieve the file size from URL
|
| 1141 |
+
else:
|
| 1142 |
+
fsize = await get_size(file)
|
| 1143 |
+
split = False
|
| 1144 |
+
if fsize <= Config.TG_MAX_SIZE:
|
| 1145 |
+
await send_file(
|
| 1146 |
+
unzip_bot=unzip_bot,
|
| 1147 |
+
c_id=spl_data[2],
|
| 1148 |
+
doc_f=file,
|
| 1149 |
+
query=query,
|
| 1150 |
+
full_path=f"{Config.DOWNLOAD_LOCATION}/{spl_data[1]}",
|
| 1151 |
+
log_msg=log_msg,
|
| 1152 |
+
split=False,
|
| 1153 |
+
)
|
| 1154 |
+
else:
|
| 1155 |
+
split = True
|
| 1156 |
+
if split:
|
| 1157 |
+
fname = file.split('/')[-1]
|
| 1158 |
+
smessage = await unzip_bot.send_message(
|
| 1159 |
+
chat_id=user_id,
|
| 1160 |
+
text=Messages.SPLITTING.format(fname)
|
| 1161 |
+
)
|
| 1162 |
+
splitteddir = f"{Config.DOWNLOAD_LOCATION}/splitted/{user_id}"
|
| 1163 |
+
os.makedirs(splitteddir)
|
| 1164 |
+
ooutput = f"{splitteddir}/{fname}"
|
| 1165 |
+
splittedfiles = await split_files(file, ooutput, Config.TG_MAX_SIZE)
|
| 1166 |
+
LOGGER.info(splittedfiles)
|
| 1167 |
+
if not splittedfiles:
|
| 1168 |
+
try:
|
| 1169 |
+
shutil.rmtree(splitteddir)
|
| 1170 |
+
except:
|
| 1171 |
+
pass
|
| 1172 |
+
await del_ongoing_task(user_id)
|
| 1173 |
+
await smessage.edit(Messages.ERR_SPLIT)
|
| 1174 |
+
return
|
| 1175 |
+
await smessage.edit(Messages.SEND_ALL_PARTS.format(fname))
|
| 1176 |
+
async_splittedfiles = async_generator(splittedfiles)
|
| 1177 |
+
async for file in async_splittedfiles:
|
| 1178 |
+
sent_files += 1
|
| 1179 |
+
await send_file(
|
| 1180 |
+
unzip_bot=unzip_bot,
|
| 1181 |
+
c_id=user_id,
|
| 1182 |
+
doc_f=file,
|
| 1183 |
+
query=query,
|
| 1184 |
+
full_path=splitteddir,
|
| 1185 |
+
log_msg=log_msg,
|
| 1186 |
+
split=True,
|
| 1187 |
+
)
|
| 1188 |
+
try:
|
| 1189 |
+
shutil.rmtree(splitteddir)
|
| 1190 |
+
except:
|
| 1191 |
+
pass
|
| 1192 |
+
try:
|
| 1193 |
+
await smessage.delete()
|
| 1194 |
+
except:
|
| 1195 |
+
pass
|
| 1196 |
+
|
| 1197 |
+
await query.message.edit(
|
| 1198 |
+
text=Messages.UPLOADED,
|
| 1199 |
+
reply_markup=Buttons.RATE_ME
|
| 1200 |
+
)
|
| 1201 |
+
await log_msg.reply(Messages.HOW_MANY_UPLOADED.format(sent_files))
|
| 1202 |
+
await update_uploaded(user_id, upload_count=sent_files)
|
| 1203 |
+
await del_ongoing_task(user_id)
|
| 1204 |
+
try:
|
| 1205 |
+
shutil.rmtree(f"{Config.DOWNLOAD_LOCATION}/{spl_data[1]}")
|
| 1206 |
+
except Exception as e:
|
| 1207 |
+
await query.message.edit(Messages.ERROR_TXT.format(e))
|
| 1208 |
+
await archive_msg.reply(Messages.ERROR_TXT.format(e))
|
| 1209 |
+
|
| 1210 |
+
elif query.data == "cancel_dis":
|
| 1211 |
+
uid = query.from_user.id
|
| 1212 |
+
await del_ongoing_task(uid)
|
| 1213 |
+
await del_merge_task(uid)
|
| 1214 |
+
try:
|
| 1215 |
+
await query.message.edit(Messages.CANCELLED_TXT.format(Messages.PROCESS_CANCELLED))
|
| 1216 |
+
shutil.rmtree(f"{Config.DOWNLOAD_LOCATION}/{uid}")
|
| 1217 |
+
await update_uploaded(
|
| 1218 |
+
user_id=uid,
|
| 1219 |
+
upload_count=sent_files
|
| 1220 |
+
)
|
| 1221 |
+
try:
|
| 1222 |
+
await log_msg.reply(Messages.HOW_MANY_UPLOADED.format(sent_files))
|
| 1223 |
+
except:
|
| 1224 |
+
return
|
| 1225 |
+
except:
|
| 1226 |
+
await unzip_bot.send_message(
|
| 1227 |
+
chat_id=uid,
|
| 1228 |
+
text=Messages.CANCELLED_TXT.format(Messages.PROCESS_CANCELLED)
|
| 1229 |
+
)
|
| 1230 |
+
return
|
| 1231 |
+
|
| 1232 |
+
elif query.data == "nobully":
|
| 1233 |
+
await query.message.edit(Messages.CANCELLED)
|
unzipper/modules/commands.py
ADDED
|
@@ -0,0 +1,819 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) 2023 EDM115
|
| 2 |
+
import os
|
| 3 |
+
import re
|
| 4 |
+
import shutil
|
| 5 |
+
import time
|
| 6 |
+
from asyncio import sleep
|
| 7 |
+
from sys import executable
|
| 8 |
+
|
| 9 |
+
import git
|
| 10 |
+
import psutil
|
| 11 |
+
from pyrogram import enums, filters
|
| 12 |
+
from pyrogram.errors import FloodWait, RPCError
|
| 13 |
+
from pyrogram.types import Message
|
| 14 |
+
|
| 15 |
+
from config import Config
|
| 16 |
+
from unzipper import LOGGER, boottime, unzipperbot
|
| 17 |
+
from unzipper.helpers.database import (
|
| 18 |
+
add_merge_task,
|
| 19 |
+
add_user,
|
| 20 |
+
add_banned_user,
|
| 21 |
+
add_vip_user,
|
| 22 |
+
check_user,
|
| 23 |
+
count_banned_users,
|
| 24 |
+
count_users,
|
| 25 |
+
del_banned_user,
|
| 26 |
+
del_ongoing_task,
|
| 27 |
+
del_user,
|
| 28 |
+
get_maintenance,
|
| 29 |
+
get_merge_task,
|
| 30 |
+
get_ongoing_tasks,
|
| 31 |
+
get_upload_mode,
|
| 32 |
+
get_uploaded,
|
| 33 |
+
get_users_list,
|
| 34 |
+
count_ongoing_tasks,
|
| 35 |
+
set_maintenance,
|
| 36 |
+
)
|
| 37 |
+
from unzipper.helpers.unzip_help import humanbytes, timeformat_sec
|
| 38 |
+
from unzipper.modules.ext_script.custom_thumbnail import add_thumb, del_thumb
|
| 39 |
+
from unzipper.modules.ext_script.ext_helper import get_files
|
| 40 |
+
|
| 41 |
+
from .bot_data import Buttons, Messages
|
| 42 |
+
|
| 43 |
+
# Regex for urls
|
| 44 |
+
https_url_regex = r"((http|https)\:\/\/)?[a-zA-Z0-9\.\/\?\:@\-_=#]+\.([a-zA-Z]){2,6}([a-zA-Z0-9\.\&\/\?\:@\-_=#])*"
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
@unzipperbot.on_message(filters.private)
|
| 48 |
+
async def _(_, message: Message):
|
| 49 |
+
await check_user(message)
|
| 50 |
+
uid = message.from_user.id
|
| 51 |
+
if uid != Config.BOT_OWNER and await get_maintenance():
|
| 52 |
+
await message.reply(Messages.MAINTENANCE_ON)
|
| 53 |
+
return
|
| 54 |
+
if uid == Config.BOT_OWNER:
|
| 55 |
+
return
|
| 56 |
+
if await count_ongoing_tasks() >= Config.MAX_CONCURRENT_TASKS:
|
| 57 |
+
ogtasks = await get_ongoing_tasks()
|
| 58 |
+
if not any(uid == task["user_id"] for task in ogtasks):
|
| 59 |
+
try:
|
| 60 |
+
await message.reply(
|
| 61 |
+
text=Messages.MAX_TASKS.format(Config.MAX_CONCURRENT_TASKS),
|
| 62 |
+
)
|
| 63 |
+
except:
|
| 64 |
+
await unzipperbot.send_message(
|
| 65 |
+
chat_id=uid,
|
| 66 |
+
text=Messages.MAX_TASKS.format(Config.MAX_CONCURRENT_TASKS),
|
| 67 |
+
)
|
| 68 |
+
return
|
| 69 |
+
|
| 70 |
+
|
| 71 |
+
@unzipperbot.on_message(filters.command("start"))
|
| 72 |
+
async def start_bot(_, message: Message):
|
| 73 |
+
try:
|
| 74 |
+
await message.reply_text(
|
| 75 |
+
text=Messages.START_TEXT.format(message.from_user.mention),
|
| 76 |
+
reply_markup=Buttons.START_BUTTON,
|
| 77 |
+
disable_web_page_preview=True,
|
| 78 |
+
)
|
| 79 |
+
except FloodWait as f:
|
| 80 |
+
await sleep(f.value)
|
| 81 |
+
await start_bot(_, message)
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
@unzipperbot.on_message(filters.private & filters.command("clean"))
|
| 85 |
+
async def clean_my_files(_, message: Message):
|
| 86 |
+
try:
|
| 87 |
+
await message.reply_text(text=Messages.CLEAN_TXT, reply_markup=Buttons.CLN_BTNS)
|
| 88 |
+
except FloodWait as f:
|
| 89 |
+
await sleep(f.value)
|
| 90 |
+
await clean_my_files(_, message)
|
| 91 |
+
|
| 92 |
+
|
| 93 |
+
@unzipperbot.on_message(filters.command("help"))
|
| 94 |
+
async def help_me(_, message: Message):
|
| 95 |
+
try:
|
| 96 |
+
await message.reply_text(text=Messages.HELP_TXT, reply_markup=Buttons.ME_GOIN_HOME)
|
| 97 |
+
except FloodWait as f:
|
| 98 |
+
await sleep(f.value)
|
| 99 |
+
await help_me(_, message)
|
| 100 |
+
|
| 101 |
+
|
| 102 |
+
@unzipperbot.on_message(filters.command("about"))
|
| 103 |
+
async def about_me(_, message: Message):
|
| 104 |
+
try:
|
| 105 |
+
await message.reply_text(
|
| 106 |
+
text=Messages.ABOUT_TXT,
|
| 107 |
+
reply_markup=Buttons.ME_GOIN_HOME,
|
| 108 |
+
disable_web_page_preview=True,
|
| 109 |
+
)
|
| 110 |
+
except FloodWait as f:
|
| 111 |
+
await sleep(f.value)
|
| 112 |
+
await about_me(_, message)
|
| 113 |
+
|
| 114 |
+
|
| 115 |
+
@unzipperbot.on_message(
|
| 116 |
+
filters.incoming & filters.private & filters.document
|
| 117 |
+
| filters.regex(https_url_regex)
|
| 118 |
+
)
|
| 119 |
+
async def extract_archive(_, message: Message):
|
| 120 |
+
try:
|
| 121 |
+
if message.chat.type != enums.ChatType.PRIVATE:
|
| 122 |
+
return
|
| 123 |
+
unzip_msg = await message.reply(Messages.PROCESSING2, reply_to_message_id=message.id)
|
| 124 |
+
user_id = message.from_user.id
|
| 125 |
+
download_path = f"{Config.DOWNLOAD_LOCATION}/{user_id}"
|
| 126 |
+
if os.path.isdir(download_path):
|
| 127 |
+
await unzip_msg.edit(Messages.PROCESS_RUNNING)
|
| 128 |
+
return
|
| 129 |
+
if await get_merge_task(user_id):
|
| 130 |
+
await unzip_msg.delete()
|
| 131 |
+
return
|
| 132 |
+
if message.text and (re.match(https_url_regex, message.text)):
|
| 133 |
+
await unzip_msg.edit(
|
| 134 |
+
text=Messages.CHOOSE_EXT_MODE.format("URL", "🔗"),
|
| 135 |
+
reply_markup=Buttons.CHOOSE_E_U__BTNS,
|
| 136 |
+
)
|
| 137 |
+
elif message.document:
|
| 138 |
+
await unzip_msg.edit(
|
| 139 |
+
text=Messages.CHOOSE_EXT_MODE.format("file", "🗂️"),
|
| 140 |
+
reply_markup=Buttons.CHOOSE_E_F__BTNS,
|
| 141 |
+
)
|
| 142 |
+
else:
|
| 143 |
+
await unzip_msg.edit(Messages.UNVALID)
|
| 144 |
+
except FloodWait as f:
|
| 145 |
+
await sleep(f.value)
|
| 146 |
+
await extract_archive(_, message)
|
| 147 |
+
|
| 148 |
+
|
| 149 |
+
@unzipperbot.on_message(filters.private & filters.command("cancel"))
|
| 150 |
+
async def cancel_task_by_user(_, message):
|
| 151 |
+
idtodel = message.id - 1
|
| 152 |
+
try:
|
| 153 |
+
await unzipperbot.delete_messages(chat_id=message.from_user.id, message_ids=idtodel)
|
| 154 |
+
except:
|
| 155 |
+
pass
|
| 156 |
+
await message.reply(Messages.CANCELLED)
|
| 157 |
+
|
| 158 |
+
|
| 159 |
+
@unzipperbot.on_message(filters.private & filters.command("merge"))
|
| 160 |
+
async def merging(_, message: Message):
|
| 161 |
+
try:
|
| 162 |
+
merge_msg = await message.reply(Messages.MERGE)
|
| 163 |
+
await add_merge_task(message.from_user.id, merge_msg.id)
|
| 164 |
+
except FloodWait as f:
|
| 165 |
+
await sleep(f.value)
|
| 166 |
+
await merging(_, message)
|
| 167 |
+
|
| 168 |
+
|
| 169 |
+
@unzipperbot.on_message(filters.private & filters.command("done"))
|
| 170 |
+
async def done_merge(_, message: Message):
|
| 171 |
+
try:
|
| 172 |
+
await message.reply(
|
| 173 |
+
Messages.DONE,
|
| 174 |
+
reply_markup=Buttons.MERGE_THEM_ALL
|
| 175 |
+
)
|
| 176 |
+
except FloodWait as f:
|
| 177 |
+
await sleep(f.value)
|
| 178 |
+
await done_merge(_, message)
|
| 179 |
+
|
| 180 |
+
|
| 181 |
+
@unzipperbot.on_message(filters.private & filters.command("mode"))
|
| 182 |
+
async def set_mode_for_user(_, message: Message):
|
| 183 |
+
try:
|
| 184 |
+
upload_mode = await get_upload_mode(message.from_user.id)
|
| 185 |
+
await message.reply(
|
| 186 |
+
text=Messages.SELECT_UPLOAD_MODE_TXT.format(upload_mode),
|
| 187 |
+
reply_markup=Buttons.SET_UPLOAD_MODE_BUTTONS,
|
| 188 |
+
)
|
| 189 |
+
except FloodWait as f:
|
| 190 |
+
await sleep(f.value)
|
| 191 |
+
await set_mode_for_user(_, message)
|
| 192 |
+
|
| 193 |
+
|
| 194 |
+
async def get_stats(id):
|
| 195 |
+
total, used, free = shutil.disk_usage(".")
|
| 196 |
+
total = humanbytes(total)
|
| 197 |
+
used = humanbytes(used)
|
| 198 |
+
free = humanbytes(free)
|
| 199 |
+
sent = humanbytes(psutil.net_io_counters().bytes_sent)
|
| 200 |
+
recv = humanbytes(psutil.net_io_counters().bytes_recv)
|
| 201 |
+
cpu_usage = psutil.cpu_percent(interval=0.2)
|
| 202 |
+
ram_usage = psutil.virtual_memory().percent
|
| 203 |
+
disk_usage = psutil.disk_usage("/").percent
|
| 204 |
+
uptime = timeformat_sec(time.time() - boottime)
|
| 205 |
+
total_users = await count_users()
|
| 206 |
+
total_banned_users = await count_banned_users()
|
| 207 |
+
ongoing_tasks = await count_ongoing_tasks()
|
| 208 |
+
|
| 209 |
+
if id == Config.BOT_OWNER:
|
| 210 |
+
stats_string = Messages.STATS_OWNER.format(
|
| 211 |
+
total_users,
|
| 212 |
+
total_banned_users,
|
| 213 |
+
total,
|
| 214 |
+
used,
|
| 215 |
+
disk_usage,
|
| 216 |
+
free,
|
| 217 |
+
ongoing_tasks,
|
| 218 |
+
sent,
|
| 219 |
+
recv,
|
| 220 |
+
cpu_usage,
|
| 221 |
+
ram_usage,
|
| 222 |
+
uptime,
|
| 223 |
+
)
|
| 224 |
+
else:
|
| 225 |
+
stats_string = Messages.STATS.format(
|
| 226 |
+
total,
|
| 227 |
+
used,
|
| 228 |
+
disk_usage,
|
| 229 |
+
free,
|
| 230 |
+
ongoing_tasks,
|
| 231 |
+
cpu_usage,
|
| 232 |
+
ram_usage,
|
| 233 |
+
uptime,
|
| 234 |
+
)
|
| 235 |
+
|
| 236 |
+
return stats_string
|
| 237 |
+
|
| 238 |
+
|
| 239 |
+
@unzipperbot.on_message(filters.command("stats"))
|
| 240 |
+
async def send_stats(_, message: Message):
|
| 241 |
+
try:
|
| 242 |
+
stats_msg = await message.reply(Messages.PROCESSING2)
|
| 243 |
+
stats_txt = await get_stats(message.from_user.id)
|
| 244 |
+
await stats_msg.edit(text=stats_txt, reply_markup=Buttons.REFRESH_BUTTON)
|
| 245 |
+
except FloodWait as f:
|
| 246 |
+
await sleep(f.value)
|
| 247 |
+
await send_stats(_, message)
|
| 248 |
+
|
| 249 |
+
|
| 250 |
+
async def _do_broadcast(message, user):
|
| 251 |
+
try:
|
| 252 |
+
await message.copy(chat_id=int(user))
|
| 253 |
+
return 200
|
| 254 |
+
except FloodWait as f:
|
| 255 |
+
await sleep(f.value)
|
| 256 |
+
return _do_broadcast(message, user)
|
| 257 |
+
except Exception:
|
| 258 |
+
await del_user(user)
|
| 259 |
+
return 400
|
| 260 |
+
|
| 261 |
+
|
| 262 |
+
@unzipperbot.on_message(filters.command("broadcast") & filters.user(Config.BOT_OWNER))
|
| 263 |
+
async def broadcast_this(_, message: Message):
|
| 264 |
+
bc_msg = await message.reply(Messages.PROCESSING2)
|
| 265 |
+
r_msg = message.reply_to_message
|
| 266 |
+
if not r_msg:
|
| 267 |
+
await bc_msg.edit(Messages.BC_REPLY)
|
| 268 |
+
return
|
| 269 |
+
users_list = await get_users_list()
|
| 270 |
+
success_no = 0
|
| 271 |
+
failed_no = 0
|
| 272 |
+
done_no = 0
|
| 273 |
+
total_users = await count_users()
|
| 274 |
+
await bc_msg.edit(Messages.BC_START.format(done_no, total_users))
|
| 275 |
+
for user in users_list:
|
| 276 |
+
b_cast = await _do_broadcast(message=r_msg, user=user["user_id"])
|
| 277 |
+
if b_cast == 200:
|
| 278 |
+
success_no += 1
|
| 279 |
+
else:
|
| 280 |
+
failed_no += 1
|
| 281 |
+
done_no += 1
|
| 282 |
+
if done_no % 10 == 0 or done_no == total_users:
|
| 283 |
+
try:
|
| 284 |
+
await bc_msg.edit(Messages.BC_START.format(done_no, total_users))
|
| 285 |
+
except FloodWait:
|
| 286 |
+
pass
|
| 287 |
+
try:
|
| 288 |
+
await bc_msg.edit(Messages.BC_DONE.format(
|
| 289 |
+
total_users,
|
| 290 |
+
success_no,
|
| 291 |
+
failed_no,
|
| 292 |
+
))
|
| 293 |
+
except FloodWait as f:
|
| 294 |
+
await sleep(f.value)
|
| 295 |
+
await bc_msg.edit(Messages.BC_DONE.format(
|
| 296 |
+
total_users,
|
| 297 |
+
success_no,
|
| 298 |
+
failed_no,
|
| 299 |
+
))
|
| 300 |
+
|
| 301 |
+
|
| 302 |
+
@unzipperbot.on_message(filters.command("sendto") & filters.user(Config.BOT_OWNER))
|
| 303 |
+
async def send_this(_, message: Message):
|
| 304 |
+
sd_msg = await message.reply(Messages.PROCESSING2)
|
| 305 |
+
r_msg = message.reply_to_message
|
| 306 |
+
if not r_msg:
|
| 307 |
+
await sd_msg.edit(Messages.SEND_REPLY)
|
| 308 |
+
return
|
| 309 |
+
try:
|
| 310 |
+
user_id = message.text.split(None, 1)[1]
|
| 311 |
+
except:
|
| 312 |
+
await sd_msg.edit(Messages.PROVIDE_UID)
|
| 313 |
+
return
|
| 314 |
+
await sd_msg.edit(Messages.SENDING)
|
| 315 |
+
send = await _do_broadcast(message=r_msg, user=user_id)
|
| 316 |
+
if send == 200:
|
| 317 |
+
await sd_msg.edit(Messages.SEND_SUCCESS.format(user_id))
|
| 318 |
+
else:
|
| 319 |
+
await sd_msg.edit(Messages.SEND_FAILED.format(user_id))
|
| 320 |
+
|
| 321 |
+
|
| 322 |
+
@unzipperbot.on_message(filters.command("report"))
|
| 323 |
+
async def report_this(_, message: Message):
|
| 324 |
+
sd_msg = await message.reply(Messages.PROCESSING2)
|
| 325 |
+
r_msg = message.reply_to_message
|
| 326 |
+
u_id = message.from_user.id
|
| 327 |
+
if not r_msg:
|
| 328 |
+
await sd_msg.edit(Messages.REPORT_REPLY)
|
| 329 |
+
return
|
| 330 |
+
await sd_msg.edit(Messages.SENDING)
|
| 331 |
+
await unzipperbot.send_message(
|
| 332 |
+
chat_id=Config.LOGS_CHANNEL,
|
| 333 |
+
text=Messages.REPORT_TEXT.format(u_id, r_msg.text.markdown),
|
| 334 |
+
)
|
| 335 |
+
await sd_msg.edit(Messages.REPORT_DONE)
|
| 336 |
+
|
| 337 |
+
|
| 338 |
+
@unzipperbot.on_message(filters.command("ban") & filters.user(Config.BOT_OWNER))
|
| 339 |
+
async def ban_user(_, message: Message):
|
| 340 |
+
ban_msg = await message.reply(Messages.PROCESSING2)
|
| 341 |
+
try:
|
| 342 |
+
user_id = message.text.split(None, 1)[1]
|
| 343 |
+
except:
|
| 344 |
+
await ban_msg.edit(Messages.BAN_ID)
|
| 345 |
+
return
|
| 346 |
+
bdb = await add_banned_user(user_id)
|
| 347 |
+
db = await del_user(user_id)
|
| 348 |
+
text = ""
|
| 349 |
+
if bdb == -1:
|
| 350 |
+
text += Messages.ALREADY_BANNED.format(user_id)
|
| 351 |
+
if db == -1:
|
| 352 |
+
text += Messages.ALREADY_REMOVED.format(user_id)
|
| 353 |
+
if text != "":
|
| 354 |
+
await ban_msg.edit(text)
|
| 355 |
+
else:
|
| 356 |
+
await ban_msg.edit(Messages.BANNED.format(user_id))
|
| 357 |
+
|
| 358 |
+
|
| 359 |
+
@unzipperbot.on_message(filters.command("unban") & filters.user(Config.BOT_OWNER))
|
| 360 |
+
async def unban_user(_, message: Message):
|
| 361 |
+
unban_msg = await message.reply(Messages.PROCESSING2)
|
| 362 |
+
try:
|
| 363 |
+
user_id = message.text.split(None, 1)[1]
|
| 364 |
+
except:
|
| 365 |
+
await unban_msg.edit(Messages.UNBAN_ID)
|
| 366 |
+
return
|
| 367 |
+
db = await add_user(user_id)
|
| 368 |
+
bdb = await del_banned_user(user_id)
|
| 369 |
+
text = ""
|
| 370 |
+
if db == -1:
|
| 371 |
+
text += Messages.ALREADY_ADDED.format(user_id)
|
| 372 |
+
if bdb == -1:
|
| 373 |
+
text += Messages.ALREADY_UNBANNED.format(user_id)
|
| 374 |
+
if text != "":
|
| 375 |
+
await unban_msg.edit(text)
|
| 376 |
+
else:
|
| 377 |
+
await unban_msg.edit(Messages.UNBANNED.format(user_id))
|
| 378 |
+
|
| 379 |
+
|
| 380 |
+
@unzipperbot.on_message(filters.private & filters.command("info"))
|
| 381 |
+
async def me_stats(_, message: Message):
|
| 382 |
+
me_info = await unzipperbot.ask(
|
| 383 |
+
chat_id=message.chat.id,
|
| 384 |
+
text=Messages.INFO,
|
| 385 |
+
)
|
| 386 |
+
await unzipperbot.send_message(chat_id=message.chat.id, text=f"`{me_info}`")
|
| 387 |
+
|
| 388 |
+
|
| 389 |
+
@unzipperbot.on_message(filters.command("user") & filters.user(Config.BOT_OWNER))
|
| 390 |
+
async def info_user(_, message: Message):
|
| 391 |
+
await message.reply(Messages.USER)
|
| 392 |
+
info_user_msg = await message.reply(Messages.PROCESSING2)
|
| 393 |
+
try:
|
| 394 |
+
user_id = message.text.split(None, 1)[1]
|
| 395 |
+
except:
|
| 396 |
+
await info_user_msg.edit(Messages.PROVIDE_UID)
|
| 397 |
+
return
|
| 398 |
+
up_count = get_uploaded(user_id)
|
| 399 |
+
if up_count == "":
|
| 400 |
+
up_count = Messages.UNABLE_FETCH
|
| 401 |
+
await info_user_msg.edit(Messages.USER_INFO.format(user_id, up_count))
|
| 402 |
+
|
| 403 |
+
|
| 404 |
+
@unzipperbot.on_message(filters.command("user2") & filters.user(Config.BOT_OWNER))
|
| 405 |
+
async def info_user2(_, message: Message):
|
| 406 |
+
user2_msg = await message.reply(Messages.PROCESSING2)
|
| 407 |
+
try:
|
| 408 |
+
user_id = message.text.split(None, 1)[1]
|
| 409 |
+
except:
|
| 410 |
+
await user2_msg.edit(Messages.PROVIDE_UID2)
|
| 411 |
+
return
|
| 412 |
+
try:
|
| 413 |
+
infos = await unzipperbot.get_users(user_id)
|
| 414 |
+
except:
|
| 415 |
+
await user2_msg.edit(Messages.UID_UNAME_INVALID)
|
| 416 |
+
return
|
| 417 |
+
if not isinstance(user_id, int):
|
| 418 |
+
try:
|
| 419 |
+
user_id = infos.id
|
| 420 |
+
except:
|
| 421 |
+
pass
|
| 422 |
+
await user2_msg.edit(Messages.USER2_INFO.format(infos, user_id))
|
| 423 |
+
|
| 424 |
+
|
| 425 |
+
@unzipperbot.on_message(filters.command("self") & filters.user(Config.BOT_OWNER))
|
| 426 |
+
async def info_self(_, message: Message):
|
| 427 |
+
self_infos = await unzipperbot.get_me()
|
| 428 |
+
await message.reply(f"`{self_infos}`")
|
| 429 |
+
|
| 430 |
+
|
| 431 |
+
@unzipperbot.on_message(
|
| 432 |
+
filters.private & filters.command("getthumbs") & filters.user(Config.BOT_OWNER)
|
| 433 |
+
)
|
| 434 |
+
async def get_all_thumbs(_, message: Message):
|
| 435 |
+
paths = await get_files(path=Config.THUMB_LOCATION)
|
| 436 |
+
if not paths:
|
| 437 |
+
await message.reply(Messages.NO_THUMBS)
|
| 438 |
+
for doc_f in paths:
|
| 439 |
+
try:
|
| 440 |
+
await unzipperbot.send_document(
|
| 441 |
+
chat_id=message.chat.id,
|
| 442 |
+
document=doc_f,
|
| 443 |
+
file_name=doc_f.split("/")[-1],
|
| 444 |
+
reply_to_message_id=message.id,
|
| 445 |
+
caption=Messages.EXT_CAPTION.format(doc_f),
|
| 446 |
+
)
|
| 447 |
+
except FloodWait as f:
|
| 448 |
+
await sleep(f.value)
|
| 449 |
+
await unzipperbot.send_document(
|
| 450 |
+
chat_id=message.chat.id,
|
| 451 |
+
document=doc_f,
|
| 452 |
+
file_name=doc_f.split("/")[-1],
|
| 453 |
+
reply_to_message_id=message.id,
|
| 454 |
+
caption=Messages.EXT_CAPTION.format(doc_f),
|
| 455 |
+
)
|
| 456 |
+
except RPCError as e:
|
| 457 |
+
LOGGER.error(e)
|
| 458 |
+
|
| 459 |
+
|
| 460 |
+
@unzipperbot.on_message(
|
| 461 |
+
filters.private & filters.command("redbutton") & filters.user(Config.BOT_OWNER)
|
| 462 |
+
)
|
| 463 |
+
async def red_alert(_, message: Message):
|
| 464 |
+
await message.reply("🚧 WIP 🚧")
|
| 465 |
+
# restart the whole bot, maybe using execl
|
| 466 |
+
# but also need to stop currently ongoing processes…
|
| 467 |
+
|
| 468 |
+
|
| 469 |
+
@unzipperbot.on_message(filters.private & filters.command("maintenance") & filters.user(Config.BOT_OWNER))
|
| 470 |
+
async def maintenance_mode(_, message: Message):
|
| 471 |
+
mstatus = await get_maintenance()
|
| 472 |
+
text = Messages.MAINTENANCE.format(mstatus) + "\n\n" + Messages.MAINTENANCE_ASK
|
| 473 |
+
mess = await message.reply(text)
|
| 474 |
+
try:
|
| 475 |
+
newstate = message.text.split(None, 1)[1]
|
| 476 |
+
except:
|
| 477 |
+
await mess.edit(Messages.MAINTENANCE_FAIL)
|
| 478 |
+
return
|
| 479 |
+
if newstate not in ["True", "False"]:
|
| 480 |
+
await mess.edit(Messages.MAINTENANCE_FAIL)
|
| 481 |
+
return
|
| 482 |
+
await set_maintenance(newstate == "True")
|
| 483 |
+
await message.reply(Messages.MAINTENANCE_DONE.format(newstate))
|
| 484 |
+
|
| 485 |
+
|
| 486 |
+
@unzipperbot.on_message(filters.private & filters.command("addthumb"))
|
| 487 |
+
async def thumb_add(_, message: Message):
|
| 488 |
+
await add_thumb(unzipperbot, message)
|
| 489 |
+
|
| 490 |
+
|
| 491 |
+
@unzipperbot.on_message(filters.private & filters.command("delthumb"))
|
| 492 |
+
async def thumb_del(_, message: Message):
|
| 493 |
+
await del_thumb(message)
|
| 494 |
+
|
| 495 |
+
|
| 496 |
+
@unzipperbot.on_message(
|
| 497 |
+
filters.private & filters.command("cleanall") & filters.user(Config.BOT_OWNER)
|
| 498 |
+
)
|
| 499 |
+
async def del_everything(_, message: Message):
|
| 500 |
+
cleaner = await message.reply(Messages.ERASE_ALL)
|
| 501 |
+
try:
|
| 502 |
+
shutil.rmtree(Config.DOWNLOAD_LOCATION)
|
| 503 |
+
await cleaner.edit(Messages.CLEANED)
|
| 504 |
+
os.mkdir(Config.DOWNLOAD_LOCATION)
|
| 505 |
+
except:
|
| 506 |
+
await cleaner.edit(Messages.NOT_CLEANED)
|
| 507 |
+
|
| 508 |
+
|
| 509 |
+
@unzipperbot.on_message(
|
| 510 |
+
filters.private & filters.command("cleantasks") & filters.user(Config.BOT_OWNER)
|
| 511 |
+
)
|
| 512 |
+
async def del_tasks(_, message: Message):
|
| 513 |
+
ongoing_tasks = await get_ongoing_tasks()
|
| 514 |
+
number = len(ongoing_tasks)
|
| 515 |
+
cleaner = await message.reply(Messages.ERASE_TASKS.format(number))
|
| 516 |
+
|
| 517 |
+
for task in ongoing_tasks:
|
| 518 |
+
user_id = task["user_id"]
|
| 519 |
+
await del_ongoing_task(user_id)
|
| 520 |
+
try:
|
| 521 |
+
shutil.rmtree(f"{Config.DOWNLOAD_LOCATION}/{user_id}")
|
| 522 |
+
except:
|
| 523 |
+
pass
|
| 524 |
+
|
| 525 |
+
await cleaner.edit(Messages.ERASE_TASKS_SUCCESS.format(number))
|
| 526 |
+
|
| 527 |
+
|
| 528 |
+
async def send_logs(user_id):
|
| 529 |
+
with open("unzip-log.txt", "rb") as doc_f:
|
| 530 |
+
try:
|
| 531 |
+
await unzipperbot.send_document(
|
| 532 |
+
chat_id=user_id,
|
| 533 |
+
document=doc_f,
|
| 534 |
+
file_name=doc_f.name,
|
| 535 |
+
)
|
| 536 |
+
LOGGER.info(Messages.LOG_SENT.format(user_id))
|
| 537 |
+
except FloodWait as f:
|
| 538 |
+
await sleep(f.value)
|
| 539 |
+
await unzipperbot.send_document(
|
| 540 |
+
chat_id=user_id,
|
| 541 |
+
document=doc_f,
|
| 542 |
+
file_name=doc_f.name,
|
| 543 |
+
)
|
| 544 |
+
except RPCError as e:
|
| 545 |
+
await unzipperbot.send_message(chat_id=user_id, text=e)
|
| 546 |
+
|
| 547 |
+
|
| 548 |
+
def clear_logs():
|
| 549 |
+
open('file.txt', 'w').close()
|
| 550 |
+
|
| 551 |
+
|
| 552 |
+
@unzipperbot.on_message(
|
| 553 |
+
filters.private & filters.command("logs") & filters.user(Config.BOT_OWNER)
|
| 554 |
+
)
|
| 555 |
+
async def logz(_, message: Message):
|
| 556 |
+
await send_logs(message.from_user.id)
|
| 557 |
+
|
| 558 |
+
|
| 559 |
+
@unzipperbot.on_message(
|
| 560 |
+
filters.private & filters.command("restart") & filters.user(Config.BOT_OWNER)
|
| 561 |
+
)
|
| 562 |
+
async def restart(_, message: Message):
|
| 563 |
+
try:
|
| 564 |
+
folder_to_del = os.path.dirname(os.path.abspath(Config.DOWNLOAD_LOCATION))
|
| 565 |
+
shutil.rmtree(Config.DOWNLOAD_LOCATION)
|
| 566 |
+
LOGGER.info(Messages.DELETED_FOLDER.format(folder_to_del))
|
| 567 |
+
except:
|
| 568 |
+
pass
|
| 569 |
+
restarttime = time.strftime("%Y/%m/%d - %H:%M:%S")
|
| 570 |
+
await message.reply_text(
|
| 571 |
+
Messages.RESTARTED_AT.format(restarttime), quote=True
|
| 572 |
+
)
|
| 573 |
+
await send_logs(message.from_user.id)
|
| 574 |
+
LOGGER.info(Messages.RESTARTING.format(message.from_user.id))
|
| 575 |
+
clear_logs()
|
| 576 |
+
os.execl(executable, executable, "-m", "unzipper")
|
| 577 |
+
|
| 578 |
+
|
| 579 |
+
@unzipperbot.on_message(
|
| 580 |
+
filters.private & filters.command("gitpull") & filters.user(Config.BOT_OWNER)
|
| 581 |
+
)
|
| 582 |
+
async def pull_updates(_, message: Message):
|
| 583 |
+
git_reply = await message.reply(Messages.PULLING)
|
| 584 |
+
repo = git.Repo("/app")
|
| 585 |
+
current = repo.head.commit
|
| 586 |
+
repo.remotes.origin.pull()
|
| 587 |
+
time.sleep(2)
|
| 588 |
+
if current != repo.head.commit:
|
| 589 |
+
await git_reply.edit(Messages.PULLED)
|
| 590 |
+
await restart(_, message)
|
| 591 |
+
else:
|
| 592 |
+
await git_reply.edit(Messages.NO_PULL)
|
| 593 |
+
|
| 594 |
+
|
| 595 |
+
@unzipperbot.on_message(filters.command("donate"))
|
| 596 |
+
async def donate_help(_, message: Message):
|
| 597 |
+
await message.reply(Messages.DONATE_TEXT)
|
| 598 |
+
|
| 599 |
+
|
| 600 |
+
@unzipperbot.on_message(filters.command("vip"))
|
| 601 |
+
async def vip_help(_, message: Message):
|
| 602 |
+
await message.reply(Messages.VIP_INFO)
|
| 603 |
+
|
| 604 |
+
|
| 605 |
+
@unzipperbot.on_message(
|
| 606 |
+
filters.private & filters.command("addvip") & filters.user(Config.BOT_OWNER)
|
| 607 |
+
)
|
| 608 |
+
async def add_vip(_, message: Message):
|
| 609 |
+
if message.reply_to_message is None:
|
| 610 |
+
await message.reply(Messages.VIP_REQUIRED_MESSAGE)
|
| 611 |
+
return
|
| 612 |
+
message = message.reply_to_message
|
| 613 |
+
messagearray = message.text.splitlines()
|
| 614 |
+
if len(messagearray) != 13:
|
| 615 |
+
await message.reply(Messages.VIP_REQUIRED_MESSAGE)
|
| 616 |
+
return
|
| 617 |
+
if not messagearray[0].isdigit():
|
| 618 |
+
await message.reply(Messages.VIP_REQUIRED_MESSAGE)
|
| 619 |
+
return
|
| 620 |
+
user_id = int(messagearray[0])
|
| 621 |
+
dateregex = r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z"
|
| 622 |
+
if not re.match(dateregex, messagearray[1]):
|
| 623 |
+
await message.reply(Messages.VIP_REQUIRED_MESSAGE)
|
| 624 |
+
return
|
| 625 |
+
subscription = messagearray[1]
|
| 626 |
+
if not re.match(dateregex, messagearray[2]):
|
| 627 |
+
await message.reply(Messages.VIP_REQUIRED_MESSAGE)
|
| 628 |
+
return
|
| 629 |
+
ends = messagearray[2]
|
| 630 |
+
if messagearray[3] not in ["paypal", "telegram", "sponsor", "bmac"]:
|
| 631 |
+
await message.reply(Messages.VIP_REQUIRED_MESSAGE)
|
| 632 |
+
return
|
| 633 |
+
used = messagearray[3]
|
| 634 |
+
if messagearray[4] not in ["monthly", "yearly"]:
|
| 635 |
+
await message.reply(Messages.VIP_REQUIRED_MESSAGE)
|
| 636 |
+
return
|
| 637 |
+
billed = messagearray[4]
|
| 638 |
+
if messagearray[5] not in ["True", "False"]:
|
| 639 |
+
await message.reply(Messages.VIP_REQUIRED_MESSAGE)
|
| 640 |
+
return
|
| 641 |
+
early = messagearray[5] == "True"
|
| 642 |
+
if messagearray[6] not in ["True", "False"]:
|
| 643 |
+
await message.reply(Messages.VIP_REQUIRED_MESSAGE)
|
| 644 |
+
return
|
| 645 |
+
donator = messagearray[6] == "True"
|
| 646 |
+
if not re.match(dateregex, messagearray[7]):
|
| 647 |
+
await message.reply(Messages.VIP_REQUIRED_MESSAGE)
|
| 648 |
+
return
|
| 649 |
+
started = messagearray[7]
|
| 650 |
+
if not messagearray[8].isdigit():
|
| 651 |
+
await message.reply(Messages.VIP_REQUIRED_MESSAGE)
|
| 652 |
+
return
|
| 653 |
+
successful = int(messagearray[8])
|
| 654 |
+
if messagearray[9] not in ["True", "False"]:
|
| 655 |
+
await message.reply(Messages.VIP_REQUIRED_MESSAGE)
|
| 656 |
+
return
|
| 657 |
+
gap = messagearray[9] == "True"
|
| 658 |
+
if messagearray[10] not in ["True", "False"]:
|
| 659 |
+
await message.reply(Messages.VIP_REQUIRED_MESSAGE)
|
| 660 |
+
return
|
| 661 |
+
gifted = messagearray[10] == "True"
|
| 662 |
+
if not re.match(r"[a-zA-Z0-9]{1,34}", messagearray[11]):
|
| 663 |
+
await message.reply(Messages.VIP_REQUIRED_MESSAGE)
|
| 664 |
+
return
|
| 665 |
+
referral = messagearray[11]
|
| 666 |
+
if messagearray[12] not in ["True", "False"]:
|
| 667 |
+
await message.reply(Messages.VIP_REQUIRED_MESSAGE)
|
| 668 |
+
return
|
| 669 |
+
lifetime = messagearray[12] == "True"
|
| 670 |
+
await add_vip_user(user_id, subscription, ends, used, billed, early, donator, started, successful, gap, gifted, referral, lifetime)
|
| 671 |
+
await message.reply(Messages.VIP_ADDED_USER.format(user_id, subscription, ends, used, billed, early, donator, started, successful, gap, gifted, referral, lifetime))
|
| 672 |
+
|
| 673 |
+
|
| 674 |
+
@unzipperbot.on_message(filters.command("delvip") & filters.user(Config.BOT_OWNER))
|
| 675 |
+
async def del_vip(_, message: Message):
|
| 676 |
+
del_msg = await message.reply(Messages.PROVIDE_UID)
|
| 677 |
+
try:
|
| 678 |
+
user_id = message.text.split(None, 1)[1]
|
| 679 |
+
except:
|
| 680 |
+
await del_msg.edit(Messages.UNBAN_ID)
|
| 681 |
+
return
|
| 682 |
+
db = await add_user(user_id)
|
| 683 |
+
bdb = await del_banned_user(user_id)
|
| 684 |
+
text = ""
|
| 685 |
+
if db == -1:
|
| 686 |
+
text += Messages.ALREADY_ADDED.format(user_id)
|
| 687 |
+
if bdb == -1:
|
| 688 |
+
text += Messages.ALREADY_UNBANNED.format(user_id)
|
| 689 |
+
if text != "":
|
| 690 |
+
await del_msg.edit(text)
|
| 691 |
+
else:
|
| 692 |
+
await del_msg.edit(Messages.UNBANNED.format(user_id))
|
| 693 |
+
|
| 694 |
+
|
| 695 |
+
@unzipperbot.on_message(
|
| 696 |
+
filters.private & filters.command("dbexport") & filters.user(Config.BOT_OWNER)
|
| 697 |
+
)
|
| 698 |
+
async def export_db(_, message):
|
| 699 |
+
await message.reply("🚧 WIP 🚧")
|
| 700 |
+
# Will use https://www.mongodb.com/docs/database-tools/mongoexport/ on command to export as CSV
|
| 701 |
+
|
| 702 |
+
|
| 703 |
+
@unzipperbot.on_message(filters.command("commands"))
|
| 704 |
+
async def getall_cmds(_, message):
|
| 705 |
+
await message.reply(
|
| 706 |
+
Messages.COMMANDS_LIST,
|
| 707 |
+
disable_web_page_preview=True,
|
| 708 |
+
)
|
| 709 |
+
|
| 710 |
+
|
| 711 |
+
@unzipperbot.on_message(filters.command("admincmd") & filters.user(Config.BOT_OWNER))
|
| 712 |
+
async def getadmin_cmds(_, message):
|
| 713 |
+
await message.reply(
|
| 714 |
+
Messages.ADMINCMD,
|
| 715 |
+
disable_web_page_preview=True,
|
| 716 |
+
)
|
| 717 |
+
|
| 718 |
+
|
| 719 |
+
disabled = """ async def exec_message_f(client, message):
|
| 720 |
+
if message.from_user.id in AUTH_CHANNEL:
|
| 721 |
+
DELAY_BETWEEN_EDITS = 0.3
|
| 722 |
+
PROCESS_RUN_TIME = 100
|
| 723 |
+
cmd = message.text.split(" ", maxsplit=1)[1]
|
| 724 |
+
|
| 725 |
+
reply_to_id = message.message_id
|
| 726 |
+
if message.reply_to_message:
|
| 727 |
+
reply_to_id = message.reply_to_message.message_id
|
| 728 |
+
|
| 729 |
+
start_time = time.time() + PROCESS_RUN_TIME
|
| 730 |
+
process = await asyncio.create_subprocess_shell(
|
| 731 |
+
cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
|
| 732 |
+
)
|
| 733 |
+
stdout, stderr = await process.communicate()
|
| 734 |
+
e = stderr.decode()
|
| 735 |
+
if not e:
|
| 736 |
+
e = "No Error"
|
| 737 |
+
o = stdout.decode()
|
| 738 |
+
if not o:
|
| 739 |
+
o = "No Output"
|
| 740 |
+
else:
|
| 741 |
+
_o = o.split("\n")
|
| 742 |
+
o = "`\n".join(_o)
|
| 743 |
+
OUTPUT = f"**QUERY:**\n__Command:__\n`{cmd}` \n__PID:__\n`{process.pid}`\n\n**stderr:** \n`{e}`\n**Output:**\n{o}"
|
| 744 |
+
|
| 745 |
+
if len(OUTPUT) > MAX_MESSAGE_LENGTH:
|
| 746 |
+
with io.BytesIO(str.encode(OUTPUT)) as out_file:
|
| 747 |
+
out_file.name = "exec.text"
|
| 748 |
+
await client.send_document(
|
| 749 |
+
chat_id=message.chat.id,
|
| 750 |
+
document=out_file,
|
| 751 |
+
caption=cmd,
|
| 752 |
+
disable_notification=True,
|
| 753 |
+
reply_to_message_id=reply_to_id,
|
| 754 |
+
)
|
| 755 |
+
await message.delete()
|
| 756 |
+
else:
|
| 757 |
+
await message.reply_text(OUTPUT)
|
| 758 |
+
|
| 759 |
+
async def eval_message_f(client, message):
|
| 760 |
+
if message.from_user.id in AUTH_CHANNEL:
|
| 761 |
+
status_message = await message.reply_text("Processing ...")
|
| 762 |
+
cmd = message.text.split(" ", maxsplit=1)[1]
|
| 763 |
+
|
| 764 |
+
reply_to_id = message.message_id
|
| 765 |
+
if message.reply_to_message:
|
| 766 |
+
reply_to_id = message.reply_to_message.message_id
|
| 767 |
+
|
| 768 |
+
old_stderr = sys.stderr
|
| 769 |
+
old_stdout = sys.stdout
|
| 770 |
+
redirected_output = sys.stdout = io.StringIO()
|
| 771 |
+
redirected_error = sys.stderr = io.StringIO()
|
| 772 |
+
stdout, stderr, exc = None, None, None
|
| 773 |
+
|
| 774 |
+
try:
|
| 775 |
+
await aexec(cmd, client, message)
|
| 776 |
+
except Exception:
|
| 777 |
+
exc = traceback.format_exc()
|
| 778 |
+
|
| 779 |
+
stdout = redirected_output.getvalue()
|
| 780 |
+
stderr = redirected_error.getvalue()
|
| 781 |
+
sys.stdout = old_stdout
|
| 782 |
+
sys.stderr = old_stderr
|
| 783 |
+
|
| 784 |
+
evaluation = ""
|
| 785 |
+
if exc:
|
| 786 |
+
evaluation = exc
|
| 787 |
+
elif stderr:
|
| 788 |
+
evaluation = stderr
|
| 789 |
+
elif stdout:
|
| 790 |
+
evaluation = stdout
|
| 791 |
+
else:
|
| 792 |
+
evaluation = "Success"
|
| 793 |
+
|
| 794 |
+
final_output = (
|
| 795 |
+
"<b>EVAL</b>: <code>{}</code>\n\n<b>OUTPUT</b>:\n<code>{}</code> \n".format(
|
| 796 |
+
cmd, evaluation.strip()
|
| 797 |
+
)
|
| 798 |
+
)
|
| 799 |
+
|
| 800 |
+
if len(final_output) > MAX_MESSAGE_LENGTH:
|
| 801 |
+
with open("eval.text", "w+", encoding="utf8") as out_file:
|
| 802 |
+
out_file.write(str(final_output))
|
| 803 |
+
await message.reply_document(
|
| 804 |
+
document="eval.text",
|
| 805 |
+
caption=cmd,
|
| 806 |
+
disable_notification=True,
|
| 807 |
+
reply_to_message_id=reply_to_id,
|
| 808 |
+
)
|
| 809 |
+
os.remove("eval.text")
|
| 810 |
+
await status_message.delete()
|
| 811 |
+
else:
|
| 812 |
+
await status_message.edit(final_output)
|
| 813 |
+
|
| 814 |
+
async def aexec(code, client, message):
|
| 815 |
+
exec(
|
| 816 |
+
f"async def __aexec(client, message): "
|
| 817 |
+
+ "".join(f"\n {l}" for l in code.split("\n"))
|
| 818 |
+
)
|
| 819 |
+
return await locals()["__aexec"](client, message) """
|
unzipper/modules/ext_script/custom_thumbnail.py
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) 2023 EDM115
|
| 2 |
+
import os
|
| 3 |
+
|
| 4 |
+
from PIL import Image
|
| 5 |
+
|
| 6 |
+
from config import Config
|
| 7 |
+
from unzipper import LOGGER
|
| 8 |
+
from unzipper.modules.bot_data import Buttons, Messages
|
| 9 |
+
from pyrogram.errors import FloodWait
|
| 10 |
+
from asyncio import sleep
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
async def silent_del(user_id):
|
| 14 |
+
try:
|
| 15 |
+
thumb_location = Config.THUMB_LOCATION + "/" + str(user_id) + ".jpg"
|
| 16 |
+
os.remove(thumb_location)
|
| 17 |
+
except:
|
| 18 |
+
pass
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
async def add_thumb(_, message):
|
| 22 |
+
try:
|
| 23 |
+
user_id = str(message.from_user.id)
|
| 24 |
+
if message.reply_to_message is not None:
|
| 25 |
+
reply_message = message.reply_to_message
|
| 26 |
+
if reply_message.media_group_id is not None: # album sent
|
| 27 |
+
LOGGER.info(Messages.ALBUM.format(user_id))
|
| 28 |
+
await message.reply(Messages.ALBUM_NOPE)
|
| 29 |
+
return
|
| 30 |
+
thumb_location = Config.THUMB_LOCATION + "/" + user_id + ".jpg"
|
| 31 |
+
pre_thumb = Config.THUMB_LOCATION + "/not_resized_" + user_id + ".jpg"
|
| 32 |
+
final_thumb = Config.THUMB_LOCATION + "/waiting_" + user_id + ".jpg"
|
| 33 |
+
if os.path.exists(thumb_location) and os.path.isfile(thumb_location):
|
| 34 |
+
await message.reply(
|
| 35 |
+
text=Messages.EXISTING_THUMB, reply_markup=Buttons.THUMB_REPLACEMENT
|
| 36 |
+
)
|
| 37 |
+
else:
|
| 38 |
+
await message.reply(
|
| 39 |
+
text=Messages.SAVING_THUMB, reply_markup=Buttons.THUMB_SAVE
|
| 40 |
+
)
|
| 41 |
+
LOGGER.info(Messages.DL_THUMB.format(user_id))
|
| 42 |
+
file = await _.download_media(message=reply_message)
|
| 43 |
+
await _.send_document(
|
| 44 |
+
chat_id=Config.LOGS_CHANNEL,
|
| 45 |
+
document=file,
|
| 46 |
+
file_name=file.split("/")[-1],
|
| 47 |
+
caption=Messages.EXT_CAPTION.format(file),
|
| 48 |
+
)
|
| 49 |
+
os.rename(file, pre_thumb)
|
| 50 |
+
size = 320, 320
|
| 51 |
+
try:
|
| 52 |
+
with Image.open(pre_thumb) as previous:
|
| 53 |
+
previous.thumbnail(size, Image.Resampling.LANCZOS)
|
| 54 |
+
previous.save(final_thumb, "JPEG")
|
| 55 |
+
LOGGER.info(Messages.THUMB_SAVED)
|
| 56 |
+
except:
|
| 57 |
+
LOGGER.info(Messages.THUMB_FAILED)
|
| 58 |
+
try:
|
| 59 |
+
os.remove(pre_thumb)
|
| 60 |
+
except:
|
| 61 |
+
pass
|
| 62 |
+
try:
|
| 63 |
+
os.remove(final_thumb)
|
| 64 |
+
except:
|
| 65 |
+
pass
|
| 66 |
+
await message.reply(Messages.THUMB_ERROR)
|
| 67 |
+
else:
|
| 68 |
+
await _.send_message(
|
| 69 |
+
chat_id=message.chat.id,
|
| 70 |
+
text=Messages.PLS_REPLY,
|
| 71 |
+
reply_to_message_id=message.id,
|
| 72 |
+
)
|
| 73 |
+
except FloodWait as f:
|
| 74 |
+
await sleep(f.value)
|
| 75 |
+
return await add_thumb(_, message)
|
| 76 |
+
|
| 77 |
+
|
| 78 |
+
async def del_thumb(message):
|
| 79 |
+
try:
|
| 80 |
+
uid = message.from_user.id
|
| 81 |
+
thumb_location = Config.THUMB_LOCATION + "/" + str(uid) + ".jpg"
|
| 82 |
+
if not os.path.exists(thumb_location):
|
| 83 |
+
await message.reply(text=Messages.NO_THUMB)
|
| 84 |
+
else:
|
| 85 |
+
await message.reply(text=Messages.DEL_CONFIRM_THUMB, reply_markup=Buttons.THUMB_DEL)
|
| 86 |
+
except FloodWait as f:
|
| 87 |
+
await sleep(f.value)
|
| 88 |
+
return await del_thumb(message)
|
| 89 |
+
|
| 90 |
+
|
| 91 |
+
async def thumb_exists(chat_id):
|
| 92 |
+
thumb_location = Config.THUMB_LOCATION + "/" + str(chat_id) + ".jpg"
|
| 93 |
+
return os.path.exists(thumb_location)
|
unzipper/modules/ext_script/ext_helper.py
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) 2023 EDM115
|
| 2 |
+
import os
|
| 3 |
+
from asyncio import get_running_loop
|
| 4 |
+
from functools import partial
|
| 5 |
+
import subprocess
|
| 6 |
+
|
| 7 |
+
from pykeyboard import InlineKeyboard
|
| 8 |
+
from pyrogram.types import InlineKeyboardButton
|
| 9 |
+
|
| 10 |
+
from unzipper import LOGGER
|
| 11 |
+
from unzipper.modules.bot_data import Messages
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
def __run_cmds_unzipper(command):
|
| 15 |
+
ext_cmd = subprocess.Popen(
|
| 16 |
+
command["cmd"],
|
| 17 |
+
stdout=subprocess.PIPE,
|
| 18 |
+
stderr=subprocess.PIPE,
|
| 19 |
+
shell=True
|
| 20 |
+
)
|
| 21 |
+
ext_out = ext_cmd.stdout.read()[:-1].decode("utf-8").rstrip('\n')
|
| 22 |
+
LOGGER.info(ext_out)
|
| 23 |
+
if ext_cmd.stderr:
|
| 24 |
+
ext_cmd.stderr.close()
|
| 25 |
+
if ext_cmd.stdout:
|
| 26 |
+
ext_cmd.stdout.close()
|
| 27 |
+
return ext_out
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
async def run_cmds_on_cr(func, **kwargs):
|
| 31 |
+
loop = get_running_loop()
|
| 32 |
+
return await loop.run_in_executor(None, partial(func, kwargs))
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
# Extract with 7z
|
| 36 |
+
async def _extract_with_7z_helper(path, archive_path, password=None):
|
| 37 |
+
if password:
|
| 38 |
+
command = f'7z x -o{path} -p"{password}" {archive_path} -y'
|
| 39 |
+
else:
|
| 40 |
+
command = f"7z x -o{path} {archive_path} -y"
|
| 41 |
+
return await run_cmds_on_cr(__run_cmds_unzipper, cmd=command)
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
async def _test_with_7z_helper(archive_path):
|
| 45 |
+
command = f'7z t {archive_path} -p"IAmVeryProbablySureThatThisPasswordWillNeverBeUsedElseItsVeryStrangeAAAAAAAAAAAAAAAAAAA" -y' # skipcq: FLK-E501
|
| 46 |
+
return "Everything is Ok" in await run_cmds_on_cr(__run_cmds_unzipper, cmd=command)
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
# Extract with zstd (for .zst files)
|
| 50 |
+
async def _extract_with_zstd(path, archive_path):
|
| 51 |
+
command = f"zstd -f --output-dir-flat {path} -d {archive_path}"
|
| 52 |
+
return await run_cmds_on_cr(__run_cmds_unzipper, cmd=command)
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
# Main function to extract files
|
| 56 |
+
async def extr_files(path, archive_path, password=None):
|
| 57 |
+
file_path = os.path.splitext(archive_path)[1]
|
| 58 |
+
if file_path == ".zst":
|
| 59 |
+
os.mkdir(path)
|
| 60 |
+
return await _extract_with_zstd(path, archive_path)
|
| 61 |
+
return await _extract_with_7z_helper(path, archive_path, password)
|
| 62 |
+
|
| 63 |
+
|
| 64 |
+
# Split files
|
| 65 |
+
async def split_files(iinput, ooutput, size):
|
| 66 |
+
command = f'7z a -tzip -mx=0 "{ooutput}" "{iinput}" -v{size}b'
|
| 67 |
+
await run_cmds_on_cr(__run_cmds_unzipper, cmd=command)
|
| 68 |
+
spdir = ooutput.replace("/" + ooutput.split("/")[-1], "")
|
| 69 |
+
return await get_files(spdir)
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
# Merge files
|
| 73 |
+
async def merge_files(iinput, ooutput, password=None):
|
| 74 |
+
if password:
|
| 75 |
+
command = f'7z x -o"{ooutput}" -p"{password}" "{iinput}" -y'
|
| 76 |
+
else:
|
| 77 |
+
command = f'7z x -o"{ooutput}" "{iinput}" -y'
|
| 78 |
+
return await run_cmds_on_cr(__run_cmds_unzipper, cmd=command)
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
# Get files in directory as a list
|
| 82 |
+
async def get_files(path):
|
| 83 |
+
path_list = [val for sublist in [[os.path.join(i[0], j) for j in i[2]] for i in os.walk(path)] for val in sublist] # skipcq: FLK-E501
|
| 84 |
+
return sorted(path_list)
|
| 85 |
+
|
| 86 |
+
|
| 87 |
+
# Make keyboard
|
| 88 |
+
async def make_keyboard(paths, user_id, chat_id, unziphttp, rzfile=None):
|
| 89 |
+
num = 0
|
| 90 |
+
i_kbd = InlineKeyboard(row_width=1)
|
| 91 |
+
data = []
|
| 92 |
+
if unziphttp:
|
| 93 |
+
data.append(InlineKeyboardButton(
|
| 94 |
+
Messages.UP_ALL,
|
| 95 |
+
f"ext_a|{user_id}|{chat_id}|{unziphttp}|{rzfile}"
|
| 96 |
+
))
|
| 97 |
+
else:
|
| 98 |
+
data.append(InlineKeyboardButton(
|
| 99 |
+
Messages.UP_ALL,
|
| 100 |
+
f"ext_a|{user_id}|{chat_id}|{unziphttp}"
|
| 101 |
+
))
|
| 102 |
+
data.append(InlineKeyboardButton(Messages.CANCEL_IT, "cancel_dis"))
|
| 103 |
+
for file in paths:
|
| 104 |
+
if num > 96:
|
| 105 |
+
break
|
| 106 |
+
if unziphttp:
|
| 107 |
+
data.append(InlineKeyboardButton(
|
| 108 |
+
f"{num} - {os.path.basename(file)}".encode("utf-8").decode("utf-8"),
|
| 109 |
+
f"ext_f|{user_id}|{chat_id}|{num}|{unziphttp}|{rzfile}",
|
| 110 |
+
))
|
| 111 |
+
else:
|
| 112 |
+
data.append(InlineKeyboardButton(
|
| 113 |
+
f"{num} - {os.path.basename(file)}".encode("utf-8").decode("utf-8"),
|
| 114 |
+
f"ext_f|{user_id}|{chat_id}|{num}|{unziphttp}",
|
| 115 |
+
))
|
| 116 |
+
num += 1
|
| 117 |
+
i_kbd.add(*data)
|
| 118 |
+
return i_kbd
|
| 119 |
+
|
| 120 |
+
|
| 121 |
+
async def make_keyboard_empty(user_id, chat_id, unziphttp, rzfile=None):
|
| 122 |
+
i_kbd = InlineKeyboard(row_width=2)
|
| 123 |
+
data = []
|
| 124 |
+
if unziphttp:
|
| 125 |
+
data.append(InlineKeyboardButton(
|
| 126 |
+
Messages.UP_ALL,
|
| 127 |
+
f"ext_a|{user_id}|{chat_id}|{unziphttp}|{rzfile}"
|
| 128 |
+
))
|
| 129 |
+
else:
|
| 130 |
+
data.append(InlineKeyboardButton(
|
| 131 |
+
Messages.UP_ALL,
|
| 132 |
+
f"ext_a|{user_id}|{chat_id}|{unziphttp}"
|
| 133 |
+
))
|
| 134 |
+
data.append(InlineKeyboardButton(Messages.CANCEL_IT, "cancel_dis"))
|
| 135 |
+
i_kbd.add(*data)
|
| 136 |
+
return i_kbd
|
unzipper/modules/ext_script/up_helper.py
ADDED
|
@@ -0,0 +1,310 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) 2023 EDM115
|
| 2 |
+
import os
|
| 3 |
+
import pathlib
|
| 4 |
+
import re
|
| 5 |
+
import shutil
|
| 6 |
+
import subprocess
|
| 7 |
+
import asyncio
|
| 8 |
+
from time import time
|
| 9 |
+
|
| 10 |
+
from pyrogram.errors import FloodWait
|
| 11 |
+
|
| 12 |
+
from config import Config
|
| 13 |
+
from unzipper import LOGGER
|
| 14 |
+
from unzipper import unzipperbot
|
| 15 |
+
from unzipper.helpers.database import get_upload_mode
|
| 16 |
+
from unzipper.helpers.unzip_help import extentions_list, progress_urls
|
| 17 |
+
from unzipper.helpers.unzip_help import progress_for_pyrogram
|
| 18 |
+
from unzipper.modules.bot_data import Messages
|
| 19 |
+
from unzipper.modules.ext_script.custom_thumbnail import thumb_exists
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
# To get video duration and thumbnail
|
| 23 |
+
async def run_shell_cmds(command):
|
| 24 |
+
run = subprocess.Popen(
|
| 25 |
+
command,
|
| 26 |
+
stdout=subprocess.PIPE,
|
| 27 |
+
stderr=subprocess.PIPE,
|
| 28 |
+
shell=True
|
| 29 |
+
)
|
| 30 |
+
shell_output = run.stdout.read()[:-1].decode("utf-8").rstrip('\n')
|
| 31 |
+
LOGGER.info(shell_output)
|
| 32 |
+
if run.stderr:
|
| 33 |
+
run.stderr.close()
|
| 34 |
+
if run.stdout:
|
| 35 |
+
run.stdout.close()
|
| 36 |
+
return shell_output
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
# Get file size
|
| 40 |
+
async def get_size(doc_f):
|
| 41 |
+
try:
|
| 42 |
+
fsize = os.stat(doc_f).st_size
|
| 43 |
+
return fsize
|
| 44 |
+
except:
|
| 45 |
+
return -1
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
# Send file to a user
|
| 49 |
+
async def send_file(unzip_bot, c_id, doc_f, query, full_path, log_msg, split):
|
| 50 |
+
fsize = await get_size(doc_f)
|
| 51 |
+
if fsize == -1 or fsize == 0: # File not found or empty
|
| 52 |
+
try:
|
| 53 |
+
await unzipperbot.send_message(c_id, Messages.EMPTY_FILE.format(os.path.basename(doc_f)))
|
| 54 |
+
except:
|
| 55 |
+
pass
|
| 56 |
+
return
|
| 57 |
+
try:
|
| 58 |
+
ul_mode = await get_upload_mode(c_id)
|
| 59 |
+
fname = os.path.basename(doc_f)
|
| 60 |
+
fext = ((pathlib.Path(os.path.abspath(doc_f)).suffix).casefold().replace(".", ""))
|
| 61 |
+
thumbornot = await thumb_exists(c_id)
|
| 62 |
+
upmsg = await unzipperbot.send_message(c_id, Messages.PROCESSING2)
|
| 63 |
+
if ul_mode == "media" and fext in extentions_list["audio"]:
|
| 64 |
+
if thumbornot:
|
| 65 |
+
thumb_image = Config.THUMB_LOCATION + "/" + str(c_id) + ".jpg"
|
| 66 |
+
sentfile = await unzip_bot.send_audio(
|
| 67 |
+
chat_id=c_id,
|
| 68 |
+
audio=doc_f,
|
| 69 |
+
caption=Messages.EXT_CAPTION.format(fname),
|
| 70 |
+
thumb=thumb_image,
|
| 71 |
+
progress=progress_for_pyrogram,
|
| 72 |
+
progress_args=(
|
| 73 |
+
Messages.TRY_UP.format(fname),
|
| 74 |
+
upmsg,
|
| 75 |
+
time(),
|
| 76 |
+
unzip_bot,
|
| 77 |
+
),
|
| 78 |
+
)
|
| 79 |
+
else:
|
| 80 |
+
sentfile = await unzip_bot.send_audio(
|
| 81 |
+
chat_id=c_id,
|
| 82 |
+
audio=doc_f,
|
| 83 |
+
caption=Messages.EXT_CAPTION.format(fname),
|
| 84 |
+
progress=progress_for_pyrogram,
|
| 85 |
+
progress_args=(
|
| 86 |
+
Messages.TRY_UP.format(fname),
|
| 87 |
+
upmsg,
|
| 88 |
+
time(),
|
| 89 |
+
unzip_bot,
|
| 90 |
+
),
|
| 91 |
+
)
|
| 92 |
+
elif ul_mode == "media" and fext in extentions_list["photo"]:
|
| 93 |
+
# impossible to use a thumb here :(
|
| 94 |
+
sentfile = await unzip_bot.send_photo(
|
| 95 |
+
chat_id=c_id,
|
| 96 |
+
photo=doc_f,
|
| 97 |
+
caption=Messages.EXT_CAPTION.format(fname),
|
| 98 |
+
progress=progress_for_pyrogram,
|
| 99 |
+
progress_args=(
|
| 100 |
+
Messages.TRY_UP.format(fname),
|
| 101 |
+
upmsg,
|
| 102 |
+
time(),
|
| 103 |
+
unzip_bot,
|
| 104 |
+
),
|
| 105 |
+
)
|
| 106 |
+
elif ul_mode == "media" and fext in extentions_list["video"]:
|
| 107 |
+
vid_duration = await run_shell_cmds(
|
| 108 |
+
f"ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 {doc_f}"
|
| 109 |
+
)
|
| 110 |
+
if thumbornot:
|
| 111 |
+
thumb_image = Config.THUMB_LOCATION + "/" + str(c_id) + ".jpg"
|
| 112 |
+
sentfile = await unzip_bot.send_video(
|
| 113 |
+
chat_id=c_id,
|
| 114 |
+
video=doc_f,
|
| 115 |
+
caption=Messages.EXT_CAPTION.format(fname),
|
| 116 |
+
duration=int(vid_duration) if vid_duration.isnumeric() else 0,
|
| 117 |
+
thumb=thumb_image,
|
| 118 |
+
progress=progress_for_pyrogram,
|
| 119 |
+
progress_args=(
|
| 120 |
+
Messages.TRY_UP.format(fname),
|
| 121 |
+
upmsg,
|
| 122 |
+
time(),
|
| 123 |
+
unzip_bot,
|
| 124 |
+
),
|
| 125 |
+
)
|
| 126 |
+
else:
|
| 127 |
+
thmb_pth = (
|
| 128 |
+
f"{Config.THUMB_LOCATION}/thumbnail_{os.path.basename(doc_f)}.jpg"
|
| 129 |
+
)
|
| 130 |
+
if os.path.exists(thmb_pth):
|
| 131 |
+
os.remove(thmb_pth)
|
| 132 |
+
try:
|
| 133 |
+
await run_shell_cmds(
|
| 134 |
+
f"ffmpeg -ss 00:00:00.00 -i {doc_f} -vf 'scale=320:320:force_original_aspect_ratio=decrease' -vframes 1 {thmb_pth}"
|
| 135 |
+
)
|
| 136 |
+
except Exception as e:
|
| 137 |
+
LOGGER.warning(e)
|
| 138 |
+
shutil.copy(Config.BOT_THUMB, thmb_pth)
|
| 139 |
+
try:
|
| 140 |
+
sentfile = await unzip_bot.send_video(
|
| 141 |
+
chat_id=c_id,
|
| 142 |
+
video=doc_f,
|
| 143 |
+
caption=Messages.EXT_CAPTION.format(fname),
|
| 144 |
+
duration=int(vid_duration) if vid_duration.isnumeric() else 0,
|
| 145 |
+
thumb=str(thmb_pth),
|
| 146 |
+
progress=progress_for_pyrogram,
|
| 147 |
+
progress_args=(
|
| 148 |
+
Messages.TRY_UP.format(fname),
|
| 149 |
+
upmsg,
|
| 150 |
+
time(),
|
| 151 |
+
unzip_bot,
|
| 152 |
+
),
|
| 153 |
+
)
|
| 154 |
+
try:
|
| 155 |
+
os.remove(thmb_pth)
|
| 156 |
+
except:
|
| 157 |
+
pass
|
| 158 |
+
except:
|
| 159 |
+
try:
|
| 160 |
+
sentfile = await unzip_bot.send_video(
|
| 161 |
+
chat_id=c_id,
|
| 162 |
+
video=doc_f,
|
| 163 |
+
caption=Messages.EXT_CAPTION.format(fname),
|
| 164 |
+
duration=0,
|
| 165 |
+
thumb=str(Config.BOT_THUMB),
|
| 166 |
+
progress=progress_for_pyrogram,
|
| 167 |
+
progress_args=(
|
| 168 |
+
Messages.TRY_UP.format(fname),
|
| 169 |
+
upmsg,
|
| 170 |
+
time(),
|
| 171 |
+
unzip_bot,
|
| 172 |
+
),
|
| 173 |
+
)
|
| 174 |
+
except:
|
| 175 |
+
sentfile = await unzip_bot.send_document(
|
| 176 |
+
chat_id=c_id,
|
| 177 |
+
document=doc_f,
|
| 178 |
+
caption=Messages.EXT_CAPTION.format(fname),
|
| 179 |
+
force_document=True,
|
| 180 |
+
progress=progress_for_pyrogram,
|
| 181 |
+
progress_args=(
|
| 182 |
+
Messages.TRY_UP.format(fname),
|
| 183 |
+
upmsg,
|
| 184 |
+
time(),
|
| 185 |
+
unzip_bot,
|
| 186 |
+
),
|
| 187 |
+
)
|
| 188 |
+
else:
|
| 189 |
+
if thumbornot:
|
| 190 |
+
thumb_image = Config.THUMB_LOCATION + "/" + str(c_id) + ".jpg"
|
| 191 |
+
sentfile = await unzip_bot.send_document(
|
| 192 |
+
chat_id=c_id,
|
| 193 |
+
document=doc_f,
|
| 194 |
+
thumb=thumb_image,
|
| 195 |
+
caption=Messages.EXT_CAPTION.format(fname),
|
| 196 |
+
force_document=True,
|
| 197 |
+
progress=progress_for_pyrogram,
|
| 198 |
+
progress_args=(
|
| 199 |
+
Messages.TRY_UP.format(fname),
|
| 200 |
+
upmsg,
|
| 201 |
+
time(),
|
| 202 |
+
unzip_bot,
|
| 203 |
+
),
|
| 204 |
+
)
|
| 205 |
+
else:
|
| 206 |
+
sentfile = await unzip_bot.send_document(
|
| 207 |
+
chat_id=c_id,
|
| 208 |
+
document=doc_f,
|
| 209 |
+
caption=Messages.EXT_CAPTION.format(fname),
|
| 210 |
+
force_document=True,
|
| 211 |
+
progress=progress_for_pyrogram,
|
| 212 |
+
progress_args=(
|
| 213 |
+
Messages.TRY_UP.format(fname),
|
| 214 |
+
upmsg,
|
| 215 |
+
time(),
|
| 216 |
+
unzip_bot,
|
| 217 |
+
),
|
| 218 |
+
)
|
| 219 |
+
await upmsg.delete()
|
| 220 |
+
os.remove(doc_f)
|
| 221 |
+
except FloodWait as f:
|
| 222 |
+
await asyncio.sleep(f.value)
|
| 223 |
+
return await send_file(unzip_bot, c_id, doc_f, query, full_path, log_msg, split)
|
| 224 |
+
except FileNotFoundError:
|
| 225 |
+
try:
|
| 226 |
+
await unzipperbot.send_message(c_id, Messages.CANT_FIND.format(os.path.basename(doc_f)))
|
| 227 |
+
except:
|
| 228 |
+
pass
|
| 229 |
+
return
|
| 230 |
+
except BaseException as e:
|
| 231 |
+
LOGGER.error(e)
|
| 232 |
+
shutil.rmtree(full_path)
|
| 233 |
+
|
| 234 |
+
|
| 235 |
+
async def forward_file(message, cid):
|
| 236 |
+
try:
|
| 237 |
+
await unzipperbot.copy_message(
|
| 238 |
+
chat_id=cid,
|
| 239 |
+
from_chat_id=message.chat.id,
|
| 240 |
+
message_id=message.id,
|
| 241 |
+
)
|
| 242 |
+
except FloodWait as f:
|
| 243 |
+
await asyncio.sleep(f.value)
|
| 244 |
+
return await forward_file(message, cid)
|
| 245 |
+
|
| 246 |
+
|
| 247 |
+
async def send_url_logs(unzip_bot, c_id, doc_f, source, message):
|
| 248 |
+
try:
|
| 249 |
+
u_file_size = os.stat(doc_f).st_size
|
| 250 |
+
if Config.TG_MAX_SIZE < int(u_file_size):
|
| 251 |
+
await unzip_bot.send_message(
|
| 252 |
+
chat_id=c_id,
|
| 253 |
+
text=Messages.TOO_LARGE
|
| 254 |
+
)
|
| 255 |
+
return
|
| 256 |
+
fname = os.path.basename(doc_f)
|
| 257 |
+
await unzip_bot.send_document(
|
| 258 |
+
chat_id=c_id,
|
| 259 |
+
document=doc_f,
|
| 260 |
+
caption=Messages.LOG_CAPTION.format(fname, source),
|
| 261 |
+
progress=progress_urls,
|
| 262 |
+
progress_args=(
|
| 263 |
+
Messages.CHECK_MSG,
|
| 264 |
+
message,
|
| 265 |
+
time(),
|
| 266 |
+
),
|
| 267 |
+
)
|
| 268 |
+
except FloodWait as f:
|
| 269 |
+
await asyncio.sleep(f.value)
|
| 270 |
+
return send_url_logs(unzip_bot, c_id, doc_f, source, message)
|
| 271 |
+
except FileNotFoundError:
|
| 272 |
+
await unzip_bot.send_message(
|
| 273 |
+
chat_id=Config.LOGS_CHANNEL,
|
| 274 |
+
text=Messages.ARCHIVE_GONE,
|
| 275 |
+
)
|
| 276 |
+
except BaseException:
|
| 277 |
+
pass
|
| 278 |
+
|
| 279 |
+
|
| 280 |
+
async def merge_splitted_archives(user_id, path):
|
| 281 |
+
cmd = f"cd {path} && cat * > MERGED_{user_id}.zip"
|
| 282 |
+
await run_shell_cmds(cmd)
|
| 283 |
+
|
| 284 |
+
|
| 285 |
+
# Function to remove basic markdown characters from a string
|
| 286 |
+
async def rm_mark_chars(text: str):
|
| 287 |
+
return re.sub("[*`_]", "", text)
|
| 288 |
+
|
| 289 |
+
|
| 290 |
+
# Function to answer queries
|
| 291 |
+
async def answer_query(
|
| 292 |
+
query, message_text: str, answer_only: bool = False, unzip_client=None, buttons=None
|
| 293 |
+
):
|
| 294 |
+
try:
|
| 295 |
+
if answer_only:
|
| 296 |
+
await query.answer(await rm_mark_chars(message_text), show_alert=True)
|
| 297 |
+
else:
|
| 298 |
+
await query.message.edit(message_text, reply_markup=buttons)
|
| 299 |
+
except:
|
| 300 |
+
try:
|
| 301 |
+
if unzip_client:
|
| 302 |
+
await unzip_client.send_message(
|
| 303 |
+
chat_id=query.message.chat.id, text=message_text, reply_markup=buttons
|
| 304 |
+
)
|
| 305 |
+
else:
|
| 306 |
+
await unzipperbot.send_message(
|
| 307 |
+
chat_id=query.message.chat.id, text=message_text, reply_markup=buttons
|
| 308 |
+
)
|
| 309 |
+
except:
|
| 310 |
+
pass
|
unzipper/modules/ext_script/url_parser.py
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import requests
|
| 2 |
+
from unzipper import LOGGER
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
anonfilesBaseSites = ["anonfiles.com", "hotfile.io", "bayfiles.com", "megaupload.nz", "letsupload.cc", "filechan.org", "myfile.is", "vshare.is", "rapidshare.nu", "lolabits.se", "openload.cc", "share-online.is", "upvid.cc"]
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
async def get_gdrive_id(gdrive_url):
|
| 9 |
+
gdrive_url = gdrive_url.strip().rstrip('/')
|
| 10 |
+
|
| 11 |
+
if "drive.google.com" in gdrive_url:
|
| 12 |
+
if "/file/d/" in gdrive_url:
|
| 13 |
+
start_index = gdrive_url.find("/file/d/") + len("/file/d/")
|
| 14 |
+
end_index = gdrive_url.find("/", start_index)
|
| 15 |
+
file_id = gdrive_url[start_index:end_index]
|
| 16 |
+
return file_id
|
| 17 |
+
|
| 18 |
+
if "/open?id=" in gdrive_url:
|
| 19 |
+
start_index = gdrive_url.find("/open?id=") + len("/open?id=")
|
| 20 |
+
file_id = gdrive_url[start_index:]
|
| 21 |
+
return file_id
|
| 22 |
+
|
| 23 |
+
if "/file/d/" in gdrive_url and "/view" in gdrive_url:
|
| 24 |
+
start_index = gdrive_url.find("/file/d/") + len("/file/d/")
|
| 25 |
+
end_index = gdrive_url.find("/view", start_index)
|
| 26 |
+
file_id = gdrive_url[start_index:end_index]
|
| 27 |
+
return file_id
|
| 28 |
+
|
| 29 |
+
if "/uc?id=" in gdrive_url:
|
| 30 |
+
start_index = gdrive_url.find("/uc?id=") + len("/uc?id=")
|
| 31 |
+
end_index = gdrive_url.find("&", start_index)
|
| 32 |
+
file_id = gdrive_url[start_index:end_index]
|
| 33 |
+
return file_id
|
| 34 |
+
|
| 35 |
+
if "/uc?export=download&id=" in gdrive_url:
|
| 36 |
+
start_index = gdrive_url.find("/uc?export=download&id=") + len("/uc?export=download&id=")
|
| 37 |
+
end_index = gdrive_url.find("&", start_index)
|
| 38 |
+
file_id = gdrive_url[start_index:end_index]
|
| 39 |
+
return file_id
|
| 40 |
+
|
| 41 |
+
raise ValueError("Invalid or unrecognized Google Drive URL format")
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
async def gdrive_dl(url):
|
| 45 |
+
try:
|
| 46 |
+
file_id = await get_gdrive_id(url)
|
| 47 |
+
downloadable_link = f"https://drive.google.com/uc?id={file_id}&export=download"
|
| 48 |
+
return downloadable_link
|
| 49 |
+
except ValueError as e:
|
| 50 |
+
LOGGER.warning(e)
|
| 51 |
+
return None
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
async def yandisk_dl(url):
|
| 55 |
+
try:
|
| 56 |
+
file_id = url.split("/")[-1]
|
| 57 |
+
downloadable_link = f"https://cloud-api.yandex.net/v1/disk/public/resources/download?public_key={file_id}"
|
| 58 |
+
r = requests.get(downloadable_link)
|
| 59 |
+
download_link = r.json()["href"]
|
| 60 |
+
return download_link
|
| 61 |
+
except Exception as e:
|
| 62 |
+
LOGGER.warning(e)
|
| 63 |
+
return None
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
async def onedrive_dl(url):
|
| 67 |
+
try:
|
| 68 |
+
file_id = url.split("/")[-2]
|
| 69 |
+
downloadable_link = f"https://api.onedrive.com/v1.0/shares/u!{file_id}/root/content"
|
| 70 |
+
return downloadable_link
|
| 71 |
+
except Exception as e:
|
| 72 |
+
LOGGER.warning(e)
|
| 73 |
+
return None
|
| 74 |
+
|
| 75 |
+
|
| 76 |
+
async def mediafire_dl(url):
|
| 77 |
+
try:
|
| 78 |
+
file_id = url.split("/")[-2]
|
| 79 |
+
downloadable_link = f"https://download{file_id}.mediafire.com/file/{file_id}/file"
|
| 80 |
+
return downloadable_link
|
| 81 |
+
except Exception as e:
|
| 82 |
+
LOGGER.warning(e)
|
| 83 |
+
return None
|
| 84 |
+
|
| 85 |
+
|
| 86 |
+
async def anonfiles_dl(url):
|
| 87 |
+
basesite = url.split("/")[2].replace("www.", "")
|
| 88 |
+
if basesite not in anonfilesBaseSites:
|
| 89 |
+
return None
|
| 90 |
+
try:
|
| 91 |
+
file_id = url.split("/")[-1]
|
| 92 |
+
downloadable_link = f"https://api.anonfiles.com/v2/file/{file_id}/info"
|
| 93 |
+
r = requests.get(downloadable_link)
|
| 94 |
+
download_link = r.json()["data"]["file"]["url"]["full"]
|
| 95 |
+
return download_link
|
| 96 |
+
except Exception as e:
|
| 97 |
+
LOGGER.warning(e)
|
| 98 |
+
return None
|
| 99 |
+
|
| 100 |
+
|
| 101 |
+
async def krakenfiles_dl(url):
|
| 102 |
+
try:
|
| 103 |
+
file_id = url.split("/")[-1]
|
| 104 |
+
downloadable_link = f"https://krakenfiles.com/view/{file_id}"
|
| 105 |
+
r = requests.get(downloadable_link)
|
| 106 |
+
download_link = r.url
|
| 107 |
+
return download_link
|
| 108 |
+
except Exception as e:
|
| 109 |
+
LOGGER.warning(e)
|
| 110 |
+
return None
|
| 111 |
+
|
| 112 |
+
|
| 113 |
+
async def wetransfer_dl(url):
|
| 114 |
+
try:
|
| 115 |
+
file_id = url.split("/")[-1]
|
| 116 |
+
downloadable_link = f"https://wetransfer.com/api/ui/transfers/{file_id}/download"
|
| 117 |
+
r = requests.get(downloadable_link)
|
| 118 |
+
download_link = r.json()["direct_link"]
|
| 119 |
+
return download_link
|
| 120 |
+
except Exception as e:
|
| 121 |
+
LOGGER.warning(e)
|
| 122 |
+
return None
|