Update version

This commit is contained in:
Yasir 2024-09-07 12:14:21 +07:00
parent 8908da603c
commit 52f7d6eb14
No known key found for this signature in database
GPG key ID: 76E9AB3E47AD20CA
9 changed files with 3213 additions and 3213 deletions

View file

@ -1,19 +1,19 @@
# * @author Yasir Aris M <yasiramunandar@gmail.com> # * @author Yasir Aris M <yasiramunandar@gmail.com>
# * @date 2022-12-01 09:12:27 # * @date 2022-12-01 09:12:27
# * @projectName MissKatyPyro # * @projectName MissKatyPyro
# * Copyright ©YasirPedia All rights reserved # * Copyright ©YasirPedia All rights reserved
# Base Docker Using Ubuntu 24.04, Python 3.12 and Built In Pip # Base Docker Using Ubuntu 24.04, Python 3.12 and Built In Pip
## With Built in Pip Package ## With Built in Pip Package
FROM yasirarism/misskaty-docker:py3.12 FROM yasirarism/misskaty-docker:py3.12
## Without Built in Pip Package ## Without Built in Pip Package
# FROM yasirarism/misskaty-docker:free # FROM yasirarism/misskaty-docker:free
# Set Hostname # Set Hostname
ENV HOSTNAME=yasir-server ENV HOSTNAME=yasir-server
# Copy Files # Copy Files
COPY . . COPY . .
# Instal pip package # Instal pip package
# RUN pip3 install --no-cache-dir -r requirements.txt # RUN pip3 install --no-cache-dir -r requirements.txt
# Set CMD Bot # Set CMD Bot
CMD ["bash", "start.sh"] CMD ["bash", "start.sh"]

406
README.md
View file

@ -1,203 +1,203 @@
# MissKatyPyro # MissKatyPyro
```diff ```diff
- I will not give any support to your fork, so try learn by yourself!! Don't contact me because of your fault. I will stop update to this repo, and i will only give minor bugfix to this repo. - I will not give any support to your fork, so try learn by yourself!! Don't contact me because of your fault. I will stop update to this repo, and i will only give minor bugfix to this repo.
``` ```
<!--Badges--> <!--Badges-->
![MIT License][license-shield] ![Repository Size][repository-size-shield] ![Issue Closed][issue-closed-shield] ![MIT License][license-shield] ![Repository Size][repository-size-shield] ![Issue Closed][issue-closed-shield]
<!--Project Title Image--> <!--Project Title Image-->
<p align="center"> <p align="center">
<img src="https://repository-images.githubusercontent.com/433350689/26cb713b-43c3-4dec-94cb-6c80599547e8" width="200" height="200"/> <img src="https://repository-images.githubusercontent.com/433350689/26cb713b-43c3-4dec-94cb-6c80599547e8" width="200" height="200"/>
</p> </p>
<!--Project Buttons--> <!--Project Buttons-->
[![Readme in Indonesian][readme-ko-shield]][readme-ko-url] [![View Demo][view-demo-shield]][view-demo-url] [![Report bug][report-bug-shield]][report-bug-url] <!-- [![Request feature][request-feature-shield]][request-feature-url] --> [![Readme in Indonesian][readme-ko-shield]][readme-ko-url] [![View Demo][view-demo-shield]][view-demo-url] [![Report bug][report-bug-shield]][report-bug-url] <!-- [![Request feature][request-feature-shield]][request-feature-url] -->
<!--Table of Contents--> <!--Table of Contents-->
# Table of Contents # Table of Contents
- [[1] About MissKaty](#1-about-misskaty) - [[1] About MissKaty](#1-about-misskaty)
- [[2] Framework Tools And Server That Used To Build This Bot](#2-framework-tools-and-server-that-used-to-build-this-bot) - [[2] Framework Tools And Server That Used To Build This Bot](#2-framework-tools-and-server-that-used-to-build-this-bot)
- [[3] Support Creator](#3-donation) - [[3] Support Creator](#3-donation)
- [[4] Notes](#4-notes) - [[4] Notes](#4-notes)
- [[5] Features](#5-features) - [[5] Features](#5-features)
- [[6] Variables](#6-variables) - [[6] Variables](#6-variables)
- [[7] Deploying Tutorial](#7-deploy-recommended-using-dockerdocker-compose) - [[7] Deploying Tutorial](#7-deploy-recommended-using-dockerdocker-compose)
- [Build And Run Using Legacy Method](#build-and-run-using-legacy-method) - [Build And Run Using Legacy Method](#build-and-run-using-legacy-method)
- [Build And Run Using Docker](#build-and-run-using-docker) - [Build And Run Using Docker](#build-and-run-using-docker)
- [Build And Run The Docker Image Using docker-compose](#build-and-run-the-docker-image-using-docker-compose) - [Build And Run The Docker Image Using docker-compose](#build-and-run-the-docker-image-using-docker-compose)
- [[8] Credits](#8-thanks-to) - [[8] Credits](#8-thanks-to)
- [[9] Disclaimer](#8-disclaimer) - [[9] Disclaimer](#8-disclaimer)
# [1] About MissKaty # [1] About MissKaty
*MissKaty* is a Telegram Bot built using Python and the Pyrogram library. Many useful features for us to use. I hope that one day this project will be discontinued, someone will continue or develop it again. I gave the name MissKaty because I like cats, a cute animal that likes to be played with and friendly with humans. *MissKaty* is a Telegram Bot built using Python and the Pyrogram library. Many useful features for us to use. I hope that one day this project will be discontinued, someone will continue or develop it again. I gave the name MissKaty because I like cats, a cute animal that likes to be played with and friendly with humans.
## [2] Framework Tools And Server That Used To Build This Bot ## [2] Framework Tools And Server That Used To Build This Bot
🌱 PyroFork v2.x.x (Fork of Pyrogram with Topics, Stories Support and Some Patch)<br> 🌱 PyroFork v2.x.x (Fork of Pyrogram with Topics, Stories Support and Some Patch)<br>
🌱 Python 3.12 Support<br> 🌱 Python 3.12 Support<br>
🌱 MongoDB as Database<br> 🌱 MongoDB as Database<br>
🌱 PyKeyboard for Building Pagination<br> 🌱 PyKeyboard for Building Pagination<br>
🌱 VS Code<br> 🌱 VS Code<br>
🌱 VPS/Server With Root and Docker Support (Recommended)<br> 🌱 VPS/Server With Root and Docker Support (Recommended)<br>
## [3] Donation and Support ## [3] Donation and Support
*For Indonesian Only and some supported country:*<br> *For Indonesian Only and some supported country:*<br>
🌱 [QRIS][qris-url]<br> 🌱 [QRIS][qris-url]<br>
*For International Payment:*<br> *For International Payment:*<br>
🌱 [Paypal][paypal-url]<br> 🌱 [Paypal][paypal-url]<br>
## [4] Notes ## [4] Notes
If you want help me fixing some error in my bot, you can make pull request to this repo. I'm very glad if you can help me. You can also give support to me for buying server. If you want help me fixing some error in my bot, you can make pull request to this repo. I'm very glad if you can help me. You can also give support to me for buying server.
## [5] Features ## [5] Features
| FEATURE MY BOT |🌱| | FEATURE MY BOT |🌱|
| ------------- | ------------- | | ------------- | ------------- |
| Basic Admin Feature |✔️| | Basic Admin Feature |✔️|
| AFK Feature |✔️| | AFK Feature |✔️|
| Downloader FB, TikTok and YT-DLP Support |✔️| | Downloader FB, TikTok and YT-DLP Support |✔️|
| MultiLanguage Support (Unfinished) |⚠️| | MultiLanguage Support (Unfinished) |⚠️|
| NightMode |✔️| | NightMode |✔️|
| ChatBot based on OpenAI and Google Bard |✔️| | ChatBot based on OpenAI and Google Bard |✔️|
| MissKaty Mata |✔️| | MissKaty Mata |✔️|
| Inline Search |✔️| | Inline Search |✔️|
| Sticker Tools |✔️| | Sticker Tools |✔️|
| PasteBin Tools |✔️| | PasteBin Tools |✔️|
| WebScraper (Pahe, MelongMovie, LK21, Terbit21, Kusonime, etc) |✔️| | WebScraper (Pahe, MelongMovie, LK21, Terbit21, Kusonime, etc) |✔️|
| IMDB Search With Multi Language Per User |✔️| | IMDB Search With Multi Language Per User |✔️|
| GenSS From Media and MediaInfo Generator |✔️| | GenSS From Media and MediaInfo Generator |✔️|
| And Many More.. |✔️| | And Many More.. |✔️|
## [6] Variables ## [6] Variables
### Required Variables ### Required Variables
* `BOT_TOKEN`: Create a bot using [@BotFather](https://t.me/BotFather), and get the Telegram API token. * `BOT_TOKEN`: Create a bot using [@BotFather](https://t.me/BotFather), and get the Telegram API token.
* `API_ID`: Get this value from [telegram.org](https://my.telegram.org/apps) * `API_ID`: Get this value from [telegram.org](https://my.telegram.org/apps)
* `API_HASH`: Get this value from [telegram.org](https://my.telegram.org/apps) * `API_HASH`: Get this value from [telegram.org](https://my.telegram.org/apps)
* `DATABASE_URI`: [mongoDB](https://www.mongodb.com) URI. Get this value from [mongoDB](https://www.mongodb.com). * `DATABASE_URI`: [mongoDB](https://www.mongodb.com) URI. Get this value from [mongoDB](https://www.mongodb.com).
* `LOG_CHANNEL` : A channel to log the activities of bot. Make sure bot is an admin in the channel. * `LOG_CHANNEL` : A channel to log the activities of bot. Make sure bot is an admin in the channel.
### Optional Variables ### Optional Variables
* `YT_COOKIES` : Get YT cookies using https://chromewebstore.google.com/detail/get-cookiestxt-locally/cclelndahbckbenkjhflpdbgdldlbecc?pli=1 and save cookies value on github gist. Copy raw url and fill in this vars. * `YT_COOKIES` : Get YT cookies using https://chromewebstore.google.com/detail/get-cookiestxt-locally/cclelndahbckbenkjhflpdbgdldlbecc?pli=1 and save cookies value on github gist. Copy raw url and fill in this vars.
* `USER_SESSION` : Session string for Userbot. * `USER_SESSION` : Session string for Userbot.
* `DATABASE_NAME`: Name of the database in MongoDB * `DATABASE_NAME`: Name of the database in MongoDB
* `COMMAND_HANDLER`: List of handler bot command splitted by space. Ex: `. !` > so bot will respond with `.cmd` or `!cmd` * `COMMAND_HANDLER`: List of handler bot command splitted by space. Ex: `. !` > so bot will respond with `.cmd` or `!cmd`
* `SUDO`: User ID that have access to bot, split by space * `SUDO`: User ID that have access to bot, split by space
* `OPENAI_API`: Create personal access token from github, and set as this env. Make sure you have access to Github Model. * `OPENAI_API`: Create personal access token from github, and set as this env. Make sure you have access to Github Model.
* `GOOGLEAI_KEY`: Learn how to get api key from this https://ai.google.dev/tutorials/python_quickstart?hl=en. * `GOOGLEAI_KEY`: Learn how to get api key from this https://ai.google.dev/tutorials/python_quickstart?hl=en.
* `CURRENCY_API`: Get API Key from https://app.exchangerate-api.com/sign-up * `CURRENCY_API`: Get API Key from https://app.exchangerate-api.com/sign-up
## [7] Tutorial Deploy (Recommended using Docker/Docker Compose) ## [7] Tutorial Deploy (Recommended using Docker/Docker Compose)
#### Build And Run Using Legacy Method #### Build And Run Using Legacy Method
- Make sure minimum python version is 3.8 and max python 3.12 to prevent some errors. Check it with this command: - Make sure minimum python version is 3.8 and max python 3.12 to prevent some errors. Check it with this command:
``` ```
python3 --version python3 --version
``` ```
- Install all dependency that needed bot to run. *(need root access, you can skip this if your server didn't have root access but some plugins will not work)* - Install all dependency that needed bot to run. *(need root access, you can skip this if your server didn't have root access but some plugins will not work)*
``` ```
apt update -y & apt install libjpeg-dev zlib1g-dev libwebp-dev python3-pip python3-lxml git wget curl ffmpeg locales tzdata neofetch mediainfo speedtest-cli -y apt update -y & apt install libjpeg-dev zlib1g-dev libwebp-dev python3-pip python3-lxml git wget curl ffmpeg locales tzdata neofetch mediainfo speedtest-cli -y
``` ```
- Install requirements.txt, if using python => 3.11, you need use venv when install pip package.<br/> - Install requirements.txt, if using python => 3.11, you need use venv when install pip package.<br/>
*Python < 3.10* *Python < 3.10*
``` ```
pip3 install -r requirements.txt pip3 install -r requirements.txt
``` ```
*Python => 3.11* *Python => 3.11*
``` ```
python3 -m venv nama_venv python3 -m venv nama_venv
source nama_venv/bin/activate source nama_venv/bin/activate
pip3 install -r requirements.txt pip3 install -r requirements.txt
``` ```
- Setting your config.env or via environment and dont forget fill all required value. - Setting your config.env or via environment and dont forget fill all required value.
- Run Bot - Run Bot
``` ```
bash start.sh bash start.sh
``` ```
#### Build And Run Using Docker #### Build And Run Using Docker
- Start Docker daemon (Skip if already running): - Start Docker daemon (Skip if already running):
``` ```
sudo dockerd sudo dockerd
``` ```
- Build Docker image: - Build Docker image:
``` ```
sudo docker build . -t misskaty sudo docker build . -t misskaty
``` ```
- Run the image: - Run the image:
``` ```
sudo docker run misskaty sudo docker run misskaty
``` ```
- To stop the image: - To stop the image:
``` ```
sudo docker ps sudo docker ps
sudo docker stop <pid> sudo docker stop <pid>
``` ```
#### Build And Run The Docker Image Using docker-compose #### Build And Run The Docker Image Using docker-compose
- Install docker-compose - Install docker-compose
``` ```
sudo apt install docker-compose sudo apt install docker-compose
``` ```
- Build and run Docker image or to view current running image: - Build and run Docker image or to view current running image:
``` ```
sudo docker-compose up sudo docker-compose up
``` ```
- After editing files with nano for example (nano start.sh): - After editing files with nano for example (nano start.sh):
``` ```
sudo docker-compose up --build sudo docker-compose up --build
``` ```
- To stop the running image: - To stop the running image:
``` ```
sudo docker ps sudo docker ps
``` ```
``` ```
sudo docker-compose stop <pid> sudo docker-compose stop <pid>
``` ```
---- ----
## [8] Thanks to ## [8] Thanks to
- Thanks To Allah Swt. - Thanks To Allah Swt.
- Thanks To Dan For [Pyrogram Library](https://github.com/pyrogram/pyrogram) as founder of pyrogram. - Thanks To Dan For [Pyrogram Library](https://github.com/pyrogram/pyrogram) as founder of pyrogram.
- Thanks To Mayuri For [Pyrofork Library](https://github.com/Mayuri-Chan) as owner of pyrofork library. - Thanks To Mayuri For [Pyrofork Library](https://github.com/Mayuri-Chan) as owner of pyrofork library.
- Thanks To TeamDrivecok and SecretGroup TBK in Telegram. - Thanks To TeamDrivecok and SecretGroup TBK in Telegram.
- Thanks To [The Hamker Cat](https://github.com/TheHamkerCat) For WilliamButcher Code. - Thanks To [The Hamker Cat](https://github.com/TheHamkerCat) For WilliamButcher Code.
- Thanks To [Team Yukki](https://github.com/TeamYukki) For AFK Bot Code. - Thanks To [Team Yukki](https://github.com/TeamYukki) For AFK Bot Code.
- Thanks To [Wrench](https://github.com/EverythingSuckz) For Some Code. - Thanks To [Wrench](https://github.com/EverythingSuckz) For Some Code.
- Thanks To [AmanoTeam](https://github.com/AmanoTeam) For MultiLanguage Template. - Thanks To [AmanoTeam](https://github.com/AmanoTeam) For MultiLanguage Template.
- And All People Who Help Me In My Life... - And All People Who Help Me In My Life...
If your code used in this repo and want to give credit please open issue.. If your code used in this repo and want to give credit please open issue..
## [9] Disclaimer ## [9] Disclaimer
[![GNU Affero General Public License 2.0](https://www.gnu.org/graphics/agplv3-155x51.png)](https://www.gnu.org/licenses/agpl-3.0.en.html#header) [![GNU Affero General Public License 2.0](https://www.gnu.org/graphics/agplv3-155x51.png)](https://www.gnu.org/licenses/agpl-3.0.en.html#header)
Licensed under [GNU AGPL 2.0.](https://github.com/yasirarism/MissKatyPyro/blob/master/LICENSE) Licensed under [GNU AGPL 2.0.](https://github.com/yasirarism/MissKatyPyro/blob/master/LICENSE)
WARNING: Selling The Codes To Other People For Money Is *Strictly Prohibited*. Or i will stop this project forever. WARNING: Selling The Codes To Other People For Money Is *Strictly Prohibited*. Or i will stop this project forever.
<!--Url for Badges--> <!--Url for Badges-->
[license-shield]: https://img.shields.io/github/license/yasirarism/MissKatyPyro?labelColor=D8D8D8&color=04B4AE [license-shield]: https://img.shields.io/github/license/yasirarism/MissKatyPyro?labelColor=D8D8D8&color=04B4AE
[repository-size-shield]: https://img.shields.io/github/repo-size/yasirarism/MissKatyPyro?labelColor=D8D8D8&color=BE81F7 [repository-size-shield]: https://img.shields.io/github/repo-size/yasirarism/MissKatyPyro?labelColor=D8D8D8&color=BE81F7
[issue-closed-shield]: https://img.shields.io/github/issues-closed/yasirarism/MissKatyPyro?labelColor=D8D8D8&color=FE9A2E [issue-closed-shield]: https://img.shields.io/github/issues-closed/yasirarism/MissKatyPyro?labelColor=D8D8D8&color=FE9A2E
<!--Url for Buttons--> <!--Url for Buttons-->
[readme-ko-shield]: https://img.shields.io/badge/-readme%20in%20Indonesian-2E2E2E?style=for-the-badge [readme-ko-shield]: https://img.shields.io/badge/-readme%20in%20Indonesian-2E2E2E?style=for-the-badge
[view-demo-shield]: https://img.shields.io/badge/-%F0%9F%98%8E%20view%20demo-F3F781?style=for-the-badge [view-demo-shield]: https://img.shields.io/badge/-%F0%9F%98%8E%20view%20demo-F3F781?style=for-the-badge
[view-demo-url]: https://t.me/MissKatyBot [view-demo-url]: https://t.me/MissKatyBot
[report-bug-shield]: https://img.shields.io/badge/-%F0%9F%90%9E%20report%20bug-F5A9A9?style=for-the-badge [report-bug-shield]: https://img.shields.io/badge/-%F0%9F%90%9E%20report%20bug-F5A9A9?style=for-the-badge
[report-bug-url]: https://github.com/yasirarism/MissKatyPyro/issues [report-bug-url]: https://github.com/yasirarism/MissKatyPyro/issues
[request-feature-shield]: https://img.shields.io/badge/-%E2%9C%A8%20request%20feature-A9D0F5?style=for-the-badge [request-feature-shield]: https://img.shields.io/badge/-%E2%9C%A8%20request%20feature-A9D0F5?style=for-the-badge
[request-feature-url]: https://github.com/yasirarism/MissKatyPyro/issues [request-feature-url]: https://github.com/yasirarism/MissKatyPyro/issues
<!--URLS--> <!--URLS-->
[readme-ko-url]: README.id.md [readme-ko-url]: README.id.md
[kofi-url]: https://ko-fi.com/yasirarism [kofi-url]: https://ko-fi.com/yasirarism
[paypal-url]: https://paypal.me/yasirarism [paypal-url]: https://paypal.me/yasirarism
[qris-url]: https://img.yasirweb.eu.org/file/ee74ce527fb8264b54691.jpg [qris-url]: https://img.yasirweb.eu.org/file/ee74ce527fb8264b54691.jpg
[mayar]: https://yasirarism.mayar.link/payme [mayar]: https://yasirarism.mayar.link/payme
[sociabuzz-url]: https://sociabuzz.com/yasirarism/tribe [sociabuzz-url]: https://sociabuzz.com/yasirarism/tribe
[saweria-url]: https://saweria.co/yasirarism [saweria-url]: https://saweria.co/yasirarism
[trakteer-url]: https://trakteer.id/yasir-aris-sp7cn [trakteer-url]: https://trakteer.id/yasir-aris-sp7cn

View file

@ -46,7 +46,7 @@ MOD_NOLOAD = ["subscene_dl"]
HELPABLE = {} HELPABLE = {}
cleanmode = {} cleanmode = {}
botStartTime = time.time() botStartTime = time.time()
misskaty_version = "v2.14" misskaty_version = "v2.15"
uvloop.install() uvloop.install()
faulthandler_enable() faulthandler_enable()

View file

@ -1,78 +1,78 @@
import json import json
import re import re
from .http import fetch from .http import fetch
def html_builder(title: str, text: str) -> str: def html_builder(title: str, text: str) -> str:
""" """
Make proper html with css from given content. Make proper html with css from given content.
""" """
heading = "<span class='container heading'><b>{content}</b></span>" heading = "<span class='container heading'><b>{content}</b></span>"
subheading = "<span class='container subheading'><b>{content}</b></span>" subheading = "<span class='container subheading'><b>{content}</b></span>"
infobox = "<span class='container infobox'>" infobox = "<span class='container infobox'>"
subtitlebox = "<span class='container subtitlebox'>" subtitlebox = "<span class='container subtitlebox'>"
icon = "<img class='icons' src={icon_url} width='35px' height='35px' alt='' >" icon = "<img class='icons' src={icon_url} width='35px' height='35px' alt='' >"
html_msg = f"<body>{heading.format(content=title)}" html_msg = f"<body>{heading.format(content=title)}"
for line in text.splitlines(): for line in text.splitlines():
if ":" not in line and bool(line): if ":" not in line and bool(line):
if "Text #" in line: if "Text #" in line:
if bool(re.search("Text #1$", line)): if bool(re.search("Text #1$", line)):
subtitle_count = len(re.findall("Text #", text)) subtitle_count = len(re.findall("Text #", text))
html_msg += icon.format( html_msg += icon.format(
icon_url="https://te.legra.ph/file/9d4a676445544d0f2d6db.png" icon_url="https://te.legra.ph/file/9d4a676445544d0f2d6db.png"
) )
html_msg += subheading.format( html_msg += subheading.format(
content=f"Subtitles ({subtitle_count} subtitle)" content=f"Subtitles ({subtitle_count} subtitle)"
) )
html_msg += "<span style='padding: 10px 0vw;' class='subtitle'>" html_msg += "<span style='padding: 10px 0vw;' class='subtitle'>"
elif "General" in line: elif "General" in line:
html_msg += icon.format( html_msg += icon.format(
icon_url="https://te.legra.ph/file/638fb0416f2600e7c5aa3.png" icon_url="https://te.legra.ph/file/638fb0416f2600e7c5aa3.png"
) )
html_msg += subheading.format(content="General") html_msg += subheading.format(content="General")
elif "Video" in line: elif "Video" in line:
html_msg += icon.format( html_msg += icon.format(
icon_url="https://te.legra.ph/file/fbc30d71cf71c9a54e59d.png" icon_url="https://te.legra.ph/file/fbc30d71cf71c9a54e59d.png"
) )
html_msg += subheading.format(content="Video") html_msg += subheading.format(content="Video")
elif "Audio" in line: elif "Audio" in line:
html_msg += icon.format( html_msg += icon.format(
icon_url="https://te.legra.ph/file/a3c431be457fedbae2286.png" icon_url="https://te.legra.ph/file/a3c431be457fedbae2286.png"
) )
html_msg += subheading.format(content=f"{line.strip()}") html_msg += subheading.format(content=f"{line.strip()}")
elif "Menu" in line: elif "Menu" in line:
html_msg += "</span>" html_msg += "</span>"
html_msg += icon.format( html_msg += icon.format(
icon_url="https://te.legra.ph/file/3023b0c2bc202ec9d6d0d.png" icon_url="https://te.legra.ph/file/3023b0c2bc202ec9d6d0d.png"
) )
html_msg += subheading.format(content="Chapters") html_msg += subheading.format(content="Chapters")
else: else:
html_msg += subheading.format(content=f"{line.strip()}") html_msg += subheading.format(content=f"{line.strip()}")
html_msg += subtitlebox if "Text #" in line else infobox html_msg += subtitlebox if "Text #" in line else infobox
elif ":" in line: elif ":" in line:
if "Attachments" not in line and "ErrorDetectionType" not in line: if "Attachments" not in line and "ErrorDetectionType" not in line:
html_msg += f"<div><code>{line.strip()}</code></div>" html_msg += f"<div><code>{line.strip()}</code></div>"
else: else:
html_msg += "</span>" html_msg += "</span>"
html_msg += "</span>" html_msg += "</span>"
return html_msg return html_msg
async def mediainfo_paste(text: str, title: str) -> str: async def mediainfo_paste(text: str, title: str) -> str:
html_content = html_builder(title, text) html_content = html_builder(title, text)
URL = "https://yasirr.eu.org/mediainfo" URL = "https://yasirr.eu.org/mediainfo"
response = await fetch.post(URL, data={"content": html_content}) response = await fetch.post(URL, data={"content": html_content})
return ( return (
f"https://yasirr.eu.org/mediainfo-{json.loads(response.content)['key']}" f"https://yasirr.eu.org/mediainfo-{json.loads(response.content)['key']}"
) )

View file

@ -1,140 +1,140 @@
# * @author Yasir Aris M <yasiramunandar@gmail.com> # * @author Yasir Aris M <yasiramunandar@gmail.com>
# * @date 2023-06-21 22:12:27 # * @date 2023-06-21 22:12:27
# * @projectName MissKatyPyro # * @projectName MissKatyPyro
# * Copyright ©YasirPedia All rights reserved # * Copyright ©YasirPedia All rights reserved
import asyncio import asyncio
import html import html
import privatebinapi import privatebinapi
from cachetools import TTLCache from cachetools import TTLCache
from openai import APIConnectionError, APIStatusError, AsyncOpenAI, RateLimitError from openai import APIConnectionError, APIStatusError, AsyncOpenAI, RateLimitError
from pyrogram import filters from pyrogram import filters
from pyrogram.errors import MessageTooLong from pyrogram.errors import MessageTooLong
from pyrogram.types import Message from pyrogram.types import Message
from misskaty import app from misskaty import app
from misskaty.core import pyro_cooldown from misskaty.core import pyro_cooldown
from misskaty.helper import check_time_gap, post_to_telegraph, use_chat_lang from misskaty.helper import check_time_gap, post_to_telegraph, use_chat_lang
from misskaty.vars import COMMAND_HANDLER, GOOGLEAI_KEY, OPENAI_KEY, SUDO from misskaty.vars import COMMAND_HANDLER, GOOGLEAI_KEY, OPENAI_KEY, SUDO
__MODULE__ = "ChatBot" __MODULE__ = "ChatBot"
__HELP__ = """ __HELP__ = """
/ai - Generate text response from AI using Gemini AI By Google. /ai - Generate text response from AI using Gemini AI By Google.
/ask - Generate text response from AI using OpenAI. /ask - Generate text response from AI using OpenAI.
""" """
gptai_conversations = TTLCache(maxsize=4000, ttl=24*60*60) gptai_conversations = TTLCache(maxsize=4000, ttl=24*60*60)
gemini_conversations = TTLCache(maxsize=4000, ttl=24*60*60) gemini_conversations = TTLCache(maxsize=4000, ttl=24*60*60)
async def get_openai_stream_response(is_stream, key, base_url, model, messages, bmsg, strings): async def get_openai_stream_response(is_stream, key, base_url, model, messages, bmsg, strings):
ai = AsyncOpenAI(api_key=key, base_url=base_url) ai = AsyncOpenAI(api_key=key, base_url=base_url)
answer = "" answer = ""
num = 0 num = 0
try: try:
response = await ai.chat.completions.create( response = await ai.chat.completions.create(
model=model, model=model,
messages=messages, messages=messages,
temperature=0.7, temperature=0.7,
stream=is_stream, stream=is_stream,
) )
if not is_stream: if not is_stream:
answer += response.choices[0].message.content answer += response.choices[0].message.content
if len(answer) > 4000: if len(answer) > 4000:
answerlink = await privatebinapi.send_async("https://bin.yasirweb.eu.org", text=answer, expiration="1week", formatting="markdown") answerlink = await privatebinapi.send_async("https://bin.yasirweb.eu.org", text=answer, expiration="1week", formatting="markdown")
await bmsg.edit_msg( await bmsg.edit_msg(
strings("answers_too_long").format(answerlink=answerlink.get("full_url")), strings("answers_too_long").format(answerlink=answerlink.get("full_url")),
disable_web_page_preview=True, disable_web_page_preview=True,
) )
else: else:
await bmsg.edit_msg(f"{html.escape(answer)}\n<b>Powered by:</b> <code>Gemini 1.5 Flash</code>") await bmsg.edit_msg(f"{html.escape(answer)}\n<b>Powered by:</b> <code>Gemini 1.5 Flash</code>")
else: else:
async for chunk in response: async for chunk in response:
if not chunk.choices or not chunk.choices[0].delta.content: if not chunk.choices or not chunk.choices[0].delta.content:
continue continue
num += 1 num += 1
answer += chunk.choices[0].delta.content answer += chunk.choices[0].delta.content
if num == 30 and len(answer) < 4000: if num == 30 and len(answer) < 4000:
await bmsg.edit_msg(html.escape(answer)) await bmsg.edit_msg(html.escape(answer))
await asyncio.sleep(1.5) await asyncio.sleep(1.5)
num = 0 num = 0
if len(answer) > 4000: if len(answer) > 4000:
answerlink = await privatebinapi.send_async("https://bin.yasirweb.eu.org", text=answer, expiration="1week", formatting="markdown") answerlink = await privatebinapi.send_async("https://bin.yasirweb.eu.org", text=answer, expiration="1week", formatting="markdown")
await bmsg.edit_msg( await bmsg.edit_msg(
strings("answers_too_long").format(answerlink=answerlink.get("full_url")), strings("answers_too_long").format(answerlink=answerlink.get("full_url")),
disable_web_page_preview=True, disable_web_page_preview=True,
) )
else: else:
await bmsg.edit_msg(f"{html.escape(answer)}\n\n<b>Powered by:</b> <code>GPT 4o</code>") await bmsg.edit_msg(f"{html.escape(answer)}\n\n<b>Powered by:</b> <code>GPT 4o</code>")
except APIConnectionError as e: except APIConnectionError as e:
await bmsg.edit_msg(f"The server could not be reached because {e.__cause__}") await bmsg.edit_msg(f"The server could not be reached because {e.__cause__}")
return None return None
except RateLimitError as e: except RateLimitError as e:
if "billing details" in str(e): if "billing details" in str(e):
return await bmsg.edit_msg( return await bmsg.edit_msg(
"This openai key from this bot has expired, please give openai key donation for bot owner." "This openai key from this bot has expired, please give openai key donation for bot owner."
) )
await bmsg.edit_msg("You're got rate limit, please try again later.") await bmsg.edit_msg("You're got rate limit, please try again later.")
return None return None
except APIStatusError as e: except APIStatusError as e:
await bmsg.edit_msg( await bmsg.edit_msg(
f"Another {e.status_code} status code was received with response {e.response}" f"Another {e.status_code} status code was received with response {e.response}"
) )
return None return None
except Exception as e: except Exception as e:
await bmsg.edit_msg(f"ERROR: {e}") await bmsg.edit_msg(f"ERROR: {e}")
return None return None
return answer return answer
@app.on_message(filters.command("ai", COMMAND_HANDLER) & pyro_cooldown.wait(10)) @app.on_message(filters.command("ai", COMMAND_HANDLER) & pyro_cooldown.wait(10))
@app.on_bot_business_message( @app.on_bot_business_message(
filters.command("ai", COMMAND_HANDLER) & pyro_cooldown.wait(10) filters.command("ai", COMMAND_HANDLER) & pyro_cooldown.wait(10)
) )
@use_chat_lang() @use_chat_lang()
async def gemini_chatbot(_, ctx: Message, strings): async def gemini_chatbot(_, ctx: Message, strings):
if len(ctx.command) == 1: if len(ctx.command) == 1:
return await ctx.reply_msg( return await ctx.reply_msg(
strings("no_question").format(cmd=ctx.command[0]), quote=True, del_in=5 strings("no_question").format(cmd=ctx.command[0]), quote=True, del_in=5
) )
if not GOOGLEAI_KEY: if not GOOGLEAI_KEY:
return await ctx.reply_msg("GOOGLEAI_KEY env is missing!!!") return await ctx.reply_msg("GOOGLEAI_KEY env is missing!!!")
uid = ctx.from_user.id if ctx.from_user else ctx.sender_chat.id uid = ctx.from_user.id if ctx.from_user else ctx.sender_chat.id
msg = await ctx.reply_msg(strings("find_answers_str"), quote=True) msg = await ctx.reply_msg(strings("find_answers_str"), quote=True)
if uid not in gemini_conversations: if uid not in gemini_conversations:
gemini_conversations[uid] = [{"role": "system", "content": "Kamu adalah AI dengan karakter mirip kucing bernama MissKaty AI yang diciptakan oleh Yasir untuk membantu manusia mencari informasi."}, {"role": "user", "content": ctx.input}] gemini_conversations[uid] = [{"role": "system", "content": "Kamu adalah AI dengan karakter mirip kucing bernama MissKaty AI yang diciptakan oleh Yasir untuk membantu manusia mencari informasi."}, {"role": "user", "content": ctx.input}]
else: else:
gemini_conversations[uid].append({"role": "user", "content": ctx.input}) gemini_conversations[uid].append({"role": "user", "content": ctx.input})
ai_response = await get_openai_stream_response(False, GOOGLEAI_KEY, "https://gemini.yasirapi.eu.org/v1", "gemini-1.5-flash", gemini_conversations[uid], msg, strings) ai_response = await get_openai_stream_response(False, GOOGLEAI_KEY, "https://gemini.yasirapi.eu.org/v1", "gemini-1.5-flash", gemini_conversations[uid], msg, strings)
if not ai_response: if not ai_response:
gemini_conversations[uid].pop() gemini_conversations[uid].pop()
if len(gemini_conversations[uid]) == 1: if len(gemini_conversations[uid]) == 1:
gemini_conversations.pop(uid) gemini_conversations.pop(uid)
return return
gemini_conversations[uid].append({"role": "assistant", "content": ai_response}) gemini_conversations[uid].append({"role": "assistant", "content": ai_response})
@app.on_message(filters.command("ask", COMMAND_HANDLER) & pyro_cooldown.wait(10)) @app.on_message(filters.command("ask", COMMAND_HANDLER) & pyro_cooldown.wait(10))
@use_chat_lang() @use_chat_lang()
async def openai_chatbot(self, ctx: Message, strings): async def openai_chatbot(self, ctx: Message, strings):
if len(ctx.command) == 1: if len(ctx.command) == 1:
return await ctx.reply_msg( return await ctx.reply_msg(
strings("no_question").format(cmd=ctx.command[0]), quote=True, del_in=5 strings("no_question").format(cmd=ctx.command[0]), quote=True, del_in=5
) )
if not OPENAI_KEY: if not OPENAI_KEY:
return await ctx.reply_msg("OPENAI_KEY env is missing!!!") return await ctx.reply_msg("OPENAI_KEY env is missing!!!")
uid = ctx.from_user.id if ctx.from_user else ctx.sender_chat.id uid = ctx.from_user.id if ctx.from_user else ctx.sender_chat.id
is_in_gap, _ = await check_time_gap(uid) is_in_gap, _ = await check_time_gap(uid)
if is_in_gap and (uid not in SUDO): if is_in_gap and (uid not in SUDO):
return await ctx.reply_msg(strings("dont_spam"), del_in=5) return await ctx.reply_msg(strings("dont_spam"), del_in=5)
pertanyaan = ctx.input pertanyaan = ctx.input
msg = await ctx.reply_msg(strings("find_answers_str"), quote=True) msg = await ctx.reply_msg(strings("find_answers_str"), quote=True)
if uid not in gptai_conversations: if uid not in gptai_conversations:
gptai_conversations[uid] = [{"role": "system", "content": "Kamu adalah AI dengan karakter mirip kucing bernama MissKaty AI yang diciptakan oleh Yasir untuk membantu manusia mencari informasi."}, {"role": "user", "content": pertanyaan}] gptai_conversations[uid] = [{"role": "system", "content": "Kamu adalah AI dengan karakter mirip kucing bernama MissKaty AI yang diciptakan oleh Yasir untuk membantu manusia mencari informasi."}, {"role": "user", "content": pertanyaan}]
else: else:
gptai_conversations[uid].append({"role": "user", "content": pertanyaan}) gptai_conversations[uid].append({"role": "user", "content": pertanyaan})
ai_response = await get_openai_stream_response(True, OPENAI_KEY, "https://models.inference.ai.azure.com" if uid in SUDO else "https://duckai.yasirapi.eu.org/v1", "gpt-4o" if uid in SUDO else "gpt-4o-mini", gptai_conversations[uid], msg, strings) ai_response = await get_openai_stream_response(True, OPENAI_KEY, "https://models.inference.ai.azure.com" if uid in SUDO else "https://duckai.yasirapi.eu.org/v1", "gpt-4o" if uid in SUDO else "gpt-4o-mini", gptai_conversations[uid], msg, strings)
if not ai_response: if not ai_response:
gptai_conversations[uid].pop() gptai_conversations[uid].pop()
if len(gptai_conversations[uid]) == 1: if len(gptai_conversations[uid]) == 1:
gptai_conversations.pop(uid) gptai_conversations.pop(uid)
return return
gptai_conversations[uid].append({"role": "assistant", "content": ai_response}) gptai_conversations[uid].append({"role": "assistant", "content": ai_response})

File diff suppressed because it is too large Load diff

View file

@ -1,455 +1,455 @@
""" """
* @author Yasir Aris M <yasiramunandar@gmail.com> * @author Yasir Aris M <yasiramunandar@gmail.com>
* @created 2022-12-01 09:12:27 * @created 2022-12-01 09:12:27
* @projectName MissKatyPyro * @projectName MissKatyPyro
* Copyright @YasirPedia All rights reserved * Copyright @YasirPedia All rights reserved
""" """
import privatebinapi import privatebinapi
from json import loads as json_loads from json import loads as json_loads
from os import remove from os import remove
from re import compile as compiles from re import compile as compiles
from pyrogram import filters from pyrogram import filters
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from misskaty import app from misskaty import app
from misskaty.helper import fetch, post_to_telegraph, rentry from misskaty.helper import fetch, post_to_telegraph, rentry
from misskaty.vars import COMMAND_HANDLER from misskaty.vars import COMMAND_HANDLER
__MODULE__ = "Paste" __MODULE__ = "Paste"
__HELP__ = """ __HELP__ = """
/paste [Text/Reply To Message] - Post text to My Pastebin. /paste [Text/Reply To Message] - Post text to My Pastebin.
/sbin [Text/Reply To Message] - Post text to Spacebin. /sbin [Text/Reply To Message] - Post text to Spacebin.
/neko [Text/Reply To Message] - Post text to Nekobin. /neko [Text/Reply To Message] - Post text to Nekobin.
/tgraph [Text/Reply To Message] - Post text to Telegraph. /tgraph [Text/Reply To Message] - Post text to Telegraph.
/imgbb [Images] - Upload image to ImgBB. /imgbb [Images] - Upload image to ImgBB.
/rentry [Text/Reply To Message] - Post text to Rentry using markdown style. /rentry [Text/Reply To Message] - Post text to Rentry using markdown style.
""" """
# Size Checker for Limit # Size Checker for Limit
def humanbytes(size: int): def humanbytes(size: int):
"""Convert Bytes To Bytes So That Human Can Read It""" """Convert Bytes To Bytes So That Human Can Read It"""
if not isinstance(size, int): if not isinstance(size, int):
try: try:
pass pass
except ValueError: except ValueError:
size = None size = None
if not size: if not size:
return "0 B" return "0 B"
size = int(size) size = int(size)
power = 2**10 power = 2**10
raised_to_pow = 0 raised_to_pow = 0
dict_power_n = { dict_power_n = {
0: "", 0: "",
1: "K", 1: "K",
2: "M", 2: "M",
3: "G", 3: "G",
4: "T", 4: "T",
5: "P", 5: "P",
6: "E", 6: "E",
7: "Z", 7: "Z",
8: "Y", 8: "Y",
} }
while size > power: while size > power:
size /= power size /= power
raised_to_pow += 1 raised_to_pow += 1
try: try:
real_size = f"{str(round(size, 2))} {dict_power_n[raised_to_pow]}B" real_size = f"{str(round(size, 2))} {dict_power_n[raised_to_pow]}B"
except KeyError: except KeyError:
real_size = "Can't Define Real Size !" real_size = "Can't Define Real Size !"
return real_size return real_size
# Pattern if extension supported, PR if want to add more # Pattern if extension supported, PR if want to add more
pattern = compiles(r"^text/|json$|yaml$|xml$|toml$|x-sh$|x-shellscript$|x-subrip$") pattern = compiles(r"^text/|json$|yaml$|xml$|toml$|x-sh$|x-shellscript$|x-subrip$")
@app.on_message(filters.command(["tgraph"], COMMAND_HANDLER)) @app.on_message(filters.command(["tgraph"], COMMAND_HANDLER))
async def telegraph_paste(_, message): async def telegraph_paste(_, message):
reply = message.reply_to_message reply = message.reply_to_message
if not reply and len(message.command) < 2: if not reply and len(message.command) < 2:
return await message.reply_msg( return await message.reply_msg(
f"**Reply To A Message With /{message.command[0]} or with command**", f"**Reply To A Message With /{message.command[0]} or with command**",
del_in=6, del_in=6,
) )
if message.from_user: if message.from_user:
if message.from_user.username: if message.from_user.username:
uname = f"@{message.from_user.username} [{message.from_user.id}]" uname = f"@{message.from_user.username} [{message.from_user.id}]"
else: else:
uname = f"[{message.from_user.first_name}](tg://user?id={message.from_user.id}) [{message.from_user.id}]" uname = f"[{message.from_user.first_name}](tg://user?id={message.from_user.id}) [{message.from_user.id}]"
else: else:
uname = message.sender_chat.title uname = message.sender_chat.title
msg = await message.reply_msg("`Pasting to Telegraph...`") msg = await message.reply_msg("`Pasting to Telegraph...`")
data = "" data = ""
limit = 1024 * 1024 limit = 1024 * 1024
if reply and not (reply.text or reply.document): if reply and not (reply.text or reply.document):
return await msg.edit_msg("**Telegraph upload has been disabled by Durov, use ImgBB command instead.**") return await msg.edit_msg("**Telegraph upload has been disabled by Durov, use ImgBB command instead.**")
if reply and reply.document: if reply and reply.document:
if reply.document.file_size > limit: if reply.document.file_size > limit:
return await msg.edit_msg( return await msg.edit_msg(
f"**You can only paste files smaller than {humanbytes(limit)}.**" f"**You can only paste files smaller than {humanbytes(limit)}.**"
) )
if not pattern.search(reply.document.mime_type): if not pattern.search(reply.document.mime_type):
return await msg.edit_msg("**Only text files can be pasted.**") return await msg.edit_msg("**Only text files can be pasted.**")
file = await reply.download() file = await reply.download()
title = ( title = (
message.text.split(None, 1)[1] message.text.split(None, 1)[1]
if len(message.command) > 1 if len(message.command) > 1
else "MissKaty Paste" else "MissKaty Paste"
) )
try: try:
with open(file, "r") as text: with open(file, "r") as text:
data = text.read() data = text.read()
remove(file) remove(file)
except UnicodeDecodeError: except UnicodeDecodeError:
try: try:
remove(file) remove(file)
except: except:
pass pass
return await msg.edit_msg("`File Not Supported !`") return await msg.edit_msg("`File Not Supported !`")
elif reply and (reply.text or reply.caption): elif reply and (reply.text or reply.caption):
title = ( title = (
message.text.split(None, 1)[1] message.text.split(None, 1)[1]
if len(message.command) > 1 if len(message.command) > 1
else "MissKaty Paste" else "MissKaty Paste"
) )
data = reply.text.html.replace("\n", "<br>") or reply.caption.html.replace( data = reply.text.html.replace("\n", "<br>") or reply.caption.html.replace(
"\n", "<br>" "\n", "<br>"
) )
elif not reply and len(message.command) >= 2: elif not reply and len(message.command) >= 2:
title = "MissKaty Paste" title = "MissKaty Paste"
data = message.text.split(None, 1)[1] data = message.text.split(None, 1)[1]
try: try:
url = await post_to_telegraph(False, title, data) url = await post_to_telegraph(False, title, data)
except Exception as e: except Exception as e:
return await msg.edit_msg(f"ERROR: {e}") return await msg.edit_msg(f"ERROR: {e}")
if not url: if not url:
return await msg.edit_msg("Text Too Short Or File Problems") return await msg.edit_msg("Text Too Short Or File Problems")
button = [ button = [
[InlineKeyboardButton("Open Link", url=url)], [InlineKeyboardButton("Open Link", url=url)],
[ [
InlineKeyboardButton( InlineKeyboardButton(
"Share Link", url=f"https://telegram.me/share/url?url={url}" "Share Link", url=f"https://telegram.me/share/url?url={url}"
) )
], ],
] ]
pasted = f"**Successfully pasted your data to Telegraph<a href='{url}'>.</a>\n\nPaste by {uname}**" pasted = f"**Successfully pasted your data to Telegraph<a href='{url}'>.</a>\n\nPaste by {uname}**"
await msg.edit_msg(pasted, reply_markup=InlineKeyboardMarkup(button)) await msg.edit_msg(pasted, reply_markup=InlineKeyboardMarkup(button))
@app.on_message(filters.command(["paste"], COMMAND_HANDLER)) @app.on_message(filters.command(["paste"], COMMAND_HANDLER))
async def wastepaste(_, message): async def wastepaste(_, message):
reply = message.reply_to_message reply = message.reply_to_message
target = str(message.command[0]).split("@", maxsplit=1)[0] target = str(message.command[0]).split("@", maxsplit=1)[0]
if not reply and len(message.command) < 2: if not reply and len(message.command) < 2:
return await message.reply_msg( return await message.reply_msg(
f"**Reply To A Message With /{target} or with command**", del_in=6 f"**Reply To A Message With /{target} or with command**", del_in=6
) )
msg = await message.reply_msg("`Pasting to YasirBin...`") msg = await message.reply_msg("`Pasting to YasirBin...`")
data = "" data = ""
limit = 1024 * 1024 limit = 1024 * 1024
if reply and reply.document: if reply and reply.document:
if reply.document.file_size > limit: if reply.document.file_size > limit:
return await msg.edit_msg( return await msg.edit_msg(
f"**You can only paste files smaller than {humanbytes(limit)}.**" f"**You can only paste files smaller than {humanbytes(limit)}.**"
) )
if not pattern.search(reply.document.mime_type): if not pattern.search(reply.document.mime_type):
return await msg.edit_msg("**Only text files can be pasted.**") return await msg.edit_msg("**Only text files can be pasted.**")
file = await reply.download() file = await reply.download()
try: try:
with open(file, "r") as text: with open(file, "r") as text:
data = text.read() data = text.read()
remove(file) remove(file)
except UnicodeDecodeError: except UnicodeDecodeError:
try: try:
remove(file) remove(file)
except: except:
pass pass
return await msg.edit_msg("`File Not Supported !`") return await msg.edit_msg("`File Not Supported !`")
elif reply and (reply.text or reply.caption): elif reply and (reply.text or reply.caption):
data = reply.text or reply.caption data = reply.text or reply.caption
elif not reply and len(message.command) >= 2: elif not reply and len(message.command) >= 2:
data = message.text.split(None, 1)[1] data = message.text.split(None, 1)[1]
if message.from_user: if message.from_user:
if message.from_user.username: if message.from_user.username:
uname = f"@{message.from_user.username} [{message.from_user.id}]" uname = f"@{message.from_user.username} [{message.from_user.id}]"
else: else:
uname = f"[{message.from_user.first_name}](tg://user?id={message.from_user.id}) [{message.from_user.id}]" uname = f"[{message.from_user.first_name}](tg://user?id={message.from_user.id}) [{message.from_user.id}]"
else: else:
uname = message.sender_chat.title uname = message.sender_chat.title
try: try:
url = await privatebinapi.send_async("https://bin.yasirweb.eu.org", text=data, expiration="1week", formatting="markdown") url = await privatebinapi.send_async("https://bin.yasirweb.eu.org", text=data, expiration="1week", formatting="markdown")
except Exception as e: except Exception as e:
return await msg.edit_msg(f"ERROR: {e}") return await msg.edit_msg(f"ERROR: {e}")
if not url: if not url:
return await msg.edit_msg("Text Too Short Or File Problems") return await msg.edit_msg("Text Too Short Or File Problems")
button = [ button = [
[InlineKeyboardButton("Open Link", url=url["full_url"])], [InlineKeyboardButton("Open Link", url=url["full_url"])],
[ [
InlineKeyboardButton( InlineKeyboardButton(
"Share Link", url=f"https://telegram.me/share/url?url={url['full_url']}" "Share Link", url=f"https://telegram.me/share/url?url={url['full_url']}"
) )
], ],
] ]
pasted = f"**Successfully pasted your data to YasirBin<a href='{url}'>.</a>\n\nPaste by {uname}**" pasted = f"**Successfully pasted your data to YasirBin<a href='{url}'>.</a>\n\nPaste by {uname}**"
await msg.edit_msg(pasted, reply_markup=InlineKeyboardMarkup(button)) await msg.edit_msg(pasted, reply_markup=InlineKeyboardMarkup(button))
# Nekobin Paste # Nekobin Paste
@app.on_message(filters.command(["neko"], COMMAND_HANDLER)) @app.on_message(filters.command(["neko"], COMMAND_HANDLER))
async def nekopaste(_, message): async def nekopaste(_, message):
reply = message.reply_to_message reply = message.reply_to_message
target = str(message.command[0]).split("@", maxsplit=1)[0] target = str(message.command[0]).split("@", maxsplit=1)[0]
if not reply and len(message.command) < 2: if not reply and len(message.command) < 2:
return await message.reply_msg( return await message.reply_msg(
f"**Reply To A Message With /{target} or with command**", del_in=6 f"**Reply To A Message With /{target} or with command**", del_in=6
) )
msg = await message.reply_msg("`Pasting to Nekobin...`") msg = await message.reply_msg("`Pasting to Nekobin...`")
data = "" data = ""
limit = 1024 * 1024 limit = 1024 * 1024
if reply and reply.document: if reply and reply.document:
if reply.document.file_size > limit: if reply.document.file_size > limit:
return await message.edit_msg( return await message.edit_msg(
f"**You can only paste files smaller than {humanbytes(limit)}.**" f"**You can only paste files smaller than {humanbytes(limit)}.**"
) )
if not pattern.search(reply.document.mime_type): if not pattern.search(reply.document.mime_type):
return await message.edit_msg("**Only text files can be pasted.**") return await message.edit_msg("**Only text files can be pasted.**")
file = await reply.download() file = await reply.download()
try: try:
with open(file, "r") as text: with open(file, "r") as text:
data = text.read() data = text.read()
remove(file) remove(file)
except UnicodeDecodeError: except UnicodeDecodeError:
try: try:
remove(file) remove(file)
except: except:
pass pass
return await message.edit_msg("`File Not Supported !`") return await message.edit_msg("`File Not Supported !`")
elif reply and (reply.text or reply.caption): elif reply and (reply.text or reply.caption):
data = reply.text.html or reply.caption.html data = reply.text.html or reply.caption.html
elif not reply and len(message.command) >= 2: elif not reply and len(message.command) >= 2:
data = message.text.split(None, 1)[1] data = message.text.split(None, 1)[1]
if message.from_user: if message.from_user:
if message.from_user.username: if message.from_user.username:
uname = f"@{message.from_user.username}" uname = f"@{message.from_user.username}"
else: else:
uname = ( uname = (
f"[{message.from_user.first_name}](tg://user?id={message.from_user.id})" f"[{message.from_user.first_name}](tg://user?id={message.from_user.id})"
) )
else: else:
uname = message.sender_chat.title uname = message.sender_chat.title
try: try:
x = ( x = (
await fetch.post( await fetch.post(
"https://bin.mayuri.my.id/api/documents", json={"content": data} "https://bin.mayuri.my.id/api/documents", json={"content": data}
) )
).json() ).json()
url = f"https://bin.mayuri.my.id/{x['result']['key']}" url = f"https://bin.mayuri.my.id/{x['result']['key']}"
except Exception as e: except Exception as e:
return await msg.edit_msg(f"ERROR: {e}") return await msg.edit_msg(f"ERROR: {e}")
if not url: if not url:
return await msg.edit_msg("Text Too Short Or File Problems") return await msg.edit_msg("Text Too Short Or File Problems")
button = [ button = [
[InlineKeyboardButton("Open Link", url=url)], [InlineKeyboardButton("Open Link", url=url)],
[ [
InlineKeyboardButton( InlineKeyboardButton(
"Share Link", url=f"https://telegram.me/share/url?url={url}" "Share Link", url=f"https://telegram.me/share/url?url={url}"
) )
], ],
] ]
pasted = f"**Successfully pasted your data to Nekobin<a href='{url}'>.</a>\n\nPaste by {uname}**" pasted = f"**Successfully pasted your data to Nekobin<a href='{url}'>.</a>\n\nPaste by {uname}**"
await msg.edit_msg(pasted, reply_markup=InlineKeyboardMarkup(button)) await msg.edit_msg(pasted, reply_markup=InlineKeyboardMarkup(button))
# Paste as spacebin # Paste as spacebin
@app.on_message(filters.command(["sbin"], COMMAND_HANDLER)) @app.on_message(filters.command(["sbin"], COMMAND_HANDLER))
async def spacebinn(_, message): async def spacebinn(_, message):
reply = message.reply_to_message reply = message.reply_to_message
target = str(message.command[0]).split("@", maxsplit=1)[0] target = str(message.command[0]).split("@", maxsplit=1)[0]
if not reply and len(message.command) < 2: if not reply and len(message.command) < 2:
return await message.reply_msg( return await message.reply_msg(
f"**Reply To A Message With /{target} or with command**", del_in=6 f"**Reply To A Message With /{target} or with command**", del_in=6
) )
msg = await message.reply_msg("`Pasting to Spacebin...`") msg = await message.reply_msg("`Pasting to Spacebin...`")
data = "" data = ""
limit = 1024 * 1024 limit = 1024 * 1024
if reply and reply.document: if reply and reply.document:
if reply.document.file_size > limit: if reply.document.file_size > limit:
return await msg.edit_msg( return await msg.edit_msg(
f"**You can only paste files smaller than {humanbytes(limit)}.**" f"**You can only paste files smaller than {humanbytes(limit)}.**"
) )
if not pattern.search(reply.document.mime_type): if not pattern.search(reply.document.mime_type):
return await msg.edit_msg("**Only text files can be pasted.**") return await msg.edit_msg("**Only text files can be pasted.**")
file = await reply.download() file = await reply.download()
try: try:
with open(file, "r") as text: with open(file, "r") as text:
data = text.read() data = text.read()
remove(file) remove(file)
except UnicodeDecodeError: except UnicodeDecodeError:
try: try:
remove(file) remove(file)
except: except:
pass pass
return await msg.edit_msg("`File Not Supported !`") return await msg.edit_msg("`File Not Supported !`")
elif reply and (reply.text or reply.caption): elif reply and (reply.text or reply.caption):
data = reply.text.html or reply.caption.html data = reply.text.html or reply.caption.html
elif not reply and len(message.command) >= 2: elif not reply and len(message.command) >= 2:
data = message.text.split(None, 1)[1] data = message.text.split(None, 1)[1]
if message.from_user: if message.from_user:
if message.from_user.username: if message.from_user.username:
uname = f"@{message.from_user.username}" uname = f"@{message.from_user.username}"
else: else:
uname = ( uname = (
f"[{message.from_user.first_name}](tg://user?id={message.from_user.id})" f"[{message.from_user.first_name}](tg://user?id={message.from_user.id})"
) )
else: else:
uname = message.sender_chat.title uname = message.sender_chat.title
try: try:
siteurl = "https://spaceb.in/api/" siteurl = "https://spaceb.in/api/"
response = await fetch.post(siteurl, json={"content": data, "extension": "txt"}) response = await fetch.post(siteurl, json={"content": data, "extension": "txt"})
response = response.json() response = response.json()
url = "https://spaceb.in/" + response["payload"]["id"] url = "https://spaceb.in/" + response["payload"]["id"]
except Exception as e: except Exception as e:
return await msg.edit_msg(f"ERROR: {e}") return await msg.edit_msg(f"ERROR: {e}")
if not url: if not url:
return await msg.edit_msg("Text Too Short Or File Problems") return await msg.edit_msg("Text Too Short Or File Problems")
button = [ button = [
[InlineKeyboardButton("Open Link", url=url)], [InlineKeyboardButton("Open Link", url=url)],
[ [
InlineKeyboardButton( InlineKeyboardButton(
"Share Link", url=f"https://telegram.me/share/url?url={url}" "Share Link", url=f"https://telegram.me/share/url?url={url}"
) )
], ],
] ]
pasted = f"**Successfully pasted your data to Spacebin<a href='{url}'>.</a>\n\nPaste by {uname}**" pasted = f"**Successfully pasted your data to Spacebin<a href='{url}'>.</a>\n\nPaste by {uname}**"
await msg.edit_msg(pasted, reply_markup=InlineKeyboardMarkup(button)) await msg.edit_msg(pasted, reply_markup=InlineKeyboardMarkup(button))
# Rentry paste # Rentry paste
@app.on_message(filters.command(["rentry"], COMMAND_HANDLER)) @app.on_message(filters.command(["rentry"], COMMAND_HANDLER))
async def rentrypaste(_, message): async def rentrypaste(_, message):
reply = message.reply_to_message reply = message.reply_to_message
target = str(message.command[0]).split("@", maxsplit=1)[0] target = str(message.command[0]).split("@", maxsplit=1)[0]
if not reply and len(message.command) < 2: if not reply and len(message.command) < 2:
return await message.reply_msg( return await message.reply_msg(
f"**Reply To A Message With /{target} or with command**", del_in=6 f"**Reply To A Message With /{target} or with command**", del_in=6
) )
msg = await message.reply_msg("`Pasting to Rentry...`") msg = await message.reply_msg("`Pasting to Rentry...`")
data = "" data = ""
limit = 1024 * 1024 limit = 1024 * 1024
if reply and reply.document: if reply and reply.document:
if reply.document.file_size > limit: if reply.document.file_size > limit:
return await msg.edit_msg( return await msg.edit_msg(
f"**You can only paste files smaller than {humanbytes(limit)}.**" f"**You can only paste files smaller than {humanbytes(limit)}.**"
) )
if not pattern.search(reply.document.mime_type): if not pattern.search(reply.document.mime_type):
return await msg.edit_msg("**Only text files can be pasted.**") return await msg.edit_msg("**Only text files can be pasted.**")
file = await reply.download() file = await reply.download()
try: try:
with open(file, "r") as text: with open(file, "r") as text:
data = text.read() data = text.read()
remove(file) remove(file)
except UnicodeDecodeError: except UnicodeDecodeError:
try: try:
remove(file) remove(file)
except: except:
pass pass
return await msg.edit_msg("`File Not Supported !`") return await msg.edit_msg("`File Not Supported !`")
elif reply and (reply.text or reply.caption): elif reply and (reply.text or reply.caption):
data = reply.text.markdown or reply.caption.markdown data = reply.text.markdown or reply.caption.markdown
elif not reply and len(message.command) >= 2: elif not reply and len(message.command) >= 2:
data = message.text.split(None, 1)[1] data = message.text.split(None, 1)[1]
if message.from_user: if message.from_user:
if message.from_user.username: if message.from_user.username:
uname = f"@{message.from_user.username}" uname = f"@{message.from_user.username}"
else: else:
uname = ( uname = (
f"[{message.from_user.first_name}](tg://user?id={message.from_user.id})" f"[{message.from_user.first_name}](tg://user?id={message.from_user.id})"
) )
else: else:
uname = message.sender_chat.title uname = message.sender_chat.title
try: try:
url = await rentry(data) url = await rentry(data)
except Exception as e: except Exception as e:
return await msg.edit(f"`{e}`") return await msg.edit(f"`{e}`")
if not url: if not url:
return await msg.edit_msg("Text Too Short Or File Problems") return await msg.edit_msg("Text Too Short Or File Problems")
button = [ button = [
[InlineKeyboardButton("Open Link", url=url)], [InlineKeyboardButton("Open Link", url=url)],
[ [
InlineKeyboardButton( InlineKeyboardButton(
"Share Link", url=f"https://telegram.me/share/url?url={url}" "Share Link", url=f"https://telegram.me/share/url?url={url}"
) )
], ],
] ]
pasted = f"**Successfully pasted your data to Rentry<a href='{url}'>.</a>\n\nPaste by {uname}**" pasted = f"**Successfully pasted your data to Rentry<a href='{url}'>.</a>\n\nPaste by {uname}**"
await msg.edit_msg(pasted, reply_markup=InlineKeyboardMarkup(button)) await msg.edit_msg(pasted, reply_markup=InlineKeyboardMarkup(button))
# ImgBB Upload # ImgBB Upload
@app.on_message(filters.command(["imgbb"], COMMAND_HANDLER)) @app.on_message(filters.command(["imgbb"], COMMAND_HANDLER))
async def imgbb_upload(_, message): async def imgbb_upload(_, message):
reply = message.reply_to_message reply = message.reply_to_message
if not reply and len(message.command) == 1: if not reply and len(message.command) == 1:
return await message.edit_msg( return await message.edit_msg(
f"**Reply to a photo with /{message.command[0]} command to upload image on ImgBB.**", del_in=6 f"**Reply to a photo with /{message.command[0]} command to upload image on ImgBB.**", del_in=6
) )
if not (reply.photo or (reply.document and reply.document.mime_type.startswith("image"))): if not (reply.photo or (reply.document and reply.document.mime_type.startswith("image"))):
return await message.reply_msg("This command only support upload photo") return await message.reply_msg("This command only support upload photo")
msg = await message.reply_msg("`Uploading image to ImgBB...`") msg = await message.reply_msg("`Uploading image to ImgBB...`")
if message.from_user: if message.from_user:
if message.from_user.username: if message.from_user.username:
uname = f"@{message.from_user.username}" uname = f"@{message.from_user.username}"
else: else:
uname = ( uname = (
f"[{message.from_user.first_name}](tg://user?id={message.from_user.id})" f"[{message.from_user.first_name}](tg://user?id={message.from_user.id})"
) )
else: else:
uname = message.sender_chat.title uname = message.sender_chat.title
try: try:
path = await reply.download() path = await reply.download()
data = {"type": "file", "action": "upload"} data = {"type": "file", "action": "upload"}
files = {"source": (path, open(path, "rb"), "images/jpeg")} files = {"source": (path, open(path, "rb"), "images/jpeg")}
headers = {"origin": "https://imgbb.com", "referer": "https://imgbb.com/upload", "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.42"} headers = {"origin": "https://imgbb.com", "referer": "https://imgbb.com/upload", "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.42"}
res = await fetch.post("https://imgbb.com/json", files=files, data=data, headers=headers) res = await fetch.post("https://imgbb.com/json", files=files, data=data, headers=headers)
remove(path) remove(path)
url = f"https://ibb.co.com/{res.json()['image']['id_encoded']}" url = f"https://ibb.co.com/{res.json()['image']['id_encoded']}"
button = [ button = [
[InlineKeyboardButton("Open Link", url=url)], [InlineKeyboardButton("Open Link", url=url)],
[ [
InlineKeyboardButton( InlineKeyboardButton(
"Share Link", url=f"https://telegram.me/share/url?url={url}" "Share Link", url=f"https://telegram.me/share/url?url={url}"
) )
], ],
] ]
pasted = f"**Successfully pasted your images to ImgBB<a href='{url}'>.</a>\n\nPaste by {uname}**" pasted = f"**Successfully pasted your images to ImgBB<a href='{url}'>.</a>\n\nPaste by {uname}**"
await msg.edit_msg(pasted, reply_markup=InlineKeyboardMarkup(button)) await msg.edit_msg(pasted, reply_markup=InlineKeyboardMarkup(button))
except Exception as e: except Exception as e:
await msg.edit_msg(f"ERROR: {e}") await msg.edit_msg(f"ERROR: {e}")

File diff suppressed because it is too large Load diff

View file

@ -1,36 +1,36 @@
emoji emoji
git+https://github.com/yasirarism/pyrofork git+https://github.com/yasirarism/pyrofork
tgcrypto tgcrypto
async_pymongo async_pymongo
pymongo pymongo
python-dotenv python-dotenv
requests requests
beautifulsoup4 beautifulsoup4
aiohttp aiohttp
chevron chevron
cv-3 cv-3
gTTS gTTS
regex regex
apscheduler==3.10.4 apscheduler==3.10.4
pytz pytz
pykeyboard pykeyboard
pySmartDL pySmartDL
psutil psutil
python-dateutil python-dateutil
telegraph telegraph
hachoir hachoir
Pillow==10.4.0 Pillow==10.4.0
PrivateBinAPI PrivateBinAPI
httpx[http2] httpx[http2]
git+https://github.com/yasirarism/vcsi git+https://github.com/yasirarism/vcsi
git+https://github.com/yasirarism/iytdl git+https://github.com/yasirarism/iytdl
deep-translator deep-translator
telethon telethon
pyrate_limiter pyrate_limiter
cachetools cachetools
cloudscraper cloudscraper
openai==1.3.2 openai==1.3.2
GitPython GitPython
aiofiles aiofiles
uvloop==0.19.0 uvloop==0.19.0
lxml_html_clean lxml_html_clean