- direct_link_generator: add letsupload.io, feurl.com, pixeldrain.com support
- Block Drive & YouTube link using /mirror command
- Remove racaty.net because have firewall
- Remove anime & stickers module, because not related in mirror bot
- Some update in aria.sh
- Tidying Up

NOTE: Redeploy Recommended.

Co-authored-by: Ncode2014 <Ncode2014@users.noreply.github.com>
Co-authored-by: FA Tulloh <77918734+yourtulloh@users.noreply.github.com>
This commit is contained in:
Hafitz Setya 2021-06-15 05:20:22 +07:00 committed by GitHub
parent 90b9c452f7
commit a0132487e8
Signed by untrusted user: GitHub
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 66 additions and 750 deletions

View File

@ -29,13 +29,12 @@
- Custom image support
- Counting file/folder
- Shell and Executor
- Stickers module
- View Link button
- Direct links supported:
```
racaty.net, hxfile.co, anonfiles.com, fembed.com, femax20.com, layarkacaxxi.icu,
letsupload.io, hxfile.co, anonfiles.com, fembed.com, femax20.com, layarkacaxxi.icu,
naniplay.com, naniplay.nanime.in, naniplay.nanime.biz, sbembed.com, streamsb.net,
uptobox.com (Uptobox account must be premium),
feurl.com, pixeldrain.com, uptobox.com (Uptobox account must be premium),
1drv.ms (Only works for file not folder or busines account)
```
## From Original Repos
@ -104,7 +103,7 @@ pip3 install -r requirements-cli.txt
**2. Using Heroku PostgreSQL**
<p><a href="https://dev.to/prisma/how-to-setup-a-free-postgresql-database-on-heroku-1dc1"> <img src="https://img.shields.io/badge/see%20on%20dev.to-black?style=for-the-badge&logo=dev-dot-to" width="190""/></a></p>
**NOTE**: If you deploying on Heroku, no need to generate database manually, because it will automatic generate database when first deploying
**NOTE**: If you deploying on Heroku using Heroku button, no need to generate database manually, because it will automatic generate database when first deploying
</details>
@ -125,7 +124,7 @@ Fill up rest of the fields. Meaning of each fields are discussed below:
- **TELEGRAM_API**: This is to authenticate to your Telegram account for downloading Telegram files. You can get this from https://my.telegram.org DO NOT put this in quotes.
- **TELEGRAM_HASH**: This is to authenticate to your Telegram account for downloading Telegram files. You can get this from https://my.telegram.org
- **OWNER_ID**: The Telegram user ID (not username) of the Owner of the bot
- **DATABASE_URL**: Your Database URL. See [Generate Database](https://github.com/breakdowns/slam-mirrorbot/tree/master#generate-database) to generate database. (**NOTE**: If you deploying on Heroku, no need to generate database manually, because it will automatic generate database when first deploying)
- **DATABASE_URL**: Your Database URL. See [Generate Database](https://github.com/breakdowns/slam-mirrorbot/tree/master#generate-database) to generate database. (**NOTE**: If you deploying on Heroku using Heroku button, no need to generate database manually, because it will automatic generate database when first deploying)
- **GDRIVE_FOLDER_ID**: This is the folder ID of the Google Drive Folder to which you want to upload all the mirrors.
- **DOWNLOAD_DIR**: The path to the local folder where the downloads should be downloaded to
- **DOWNLOAD_STATUS_UPDATE_INTERVAL**: A short interval of time in seconds after which the Mirror progress message is updated. (I recommend to keep it `5` seconds at least)
@ -214,7 +213,7 @@ sudo docker run mirrorbot
## Deploying on Heroku with heroku-cli and Goorm IDE
<p><a href="https://telegra.ph/How-to-Deploy-a-Mirror-Bot-to-Heroku-with-CLI-05-06"> <img src="https://img.shields.io/badge/see%20on%20telegraph-grey?style=for-the-badge" width="190""/></a></p>
## Video Tutorial
## Video Tutorial deploying slam-mirrorbot on Heroku
<p><a href="https://www.youtube.com/watch?v=WIhL0TrisfQ&t=1s"> <img src="https://img.shields.io/badge/See%20On%20Youtube-black?style=for-the-badge&logo=youtube" width="200""/></a></p>
**NOTE**: Recommended to generate **token.pickle** manually. [Read here](https://github.com/breakdowns/slam-mirrorbot#getting-google-oauth-api-credential-file)
@ -304,5 +303,6 @@ Thanks to:
- [magneto261290](https://github.com/magneto261290/) for some features
- [SVR666](https://github.com/SVR666/) for some features & fixes
- [anasty17](https://github.com/anasty17) for some features & help
- [breakdowns](https://github.com/breakdowns) for Slam
And many more people who aren't mentioned here, but may be found in [Contributors](https://github.com/breakdowns/slam-mirrorbot/graphs/contributors).

View File

@ -1,5 +1,5 @@
export MAX_DOWNLOAD_SPEED=0
tracker_list=$(curl -Ns https://raw.githubusercontent.com/XIU2/TrackersListCollection/master/all.txt --next https://ngosang.github.io/trackerslist/trackers_all_http.txt --next https://newtrackon.com/api/all --next https://raw.githubusercontent.com/DeSireFire/animeTrackerList/master/AT_all.txt --next https://raw.githubusercontent.com/hezhijie0327/Trackerslist/main/trackerslist_tracker.txt --next https://raw.githubusercontent.com/hezhijie0327/Trackerslist/main/trackerslist_exclude.txt | awk '$1' | tr '\n\n' ',')
tracker_list=$(curl -Ns https://raw.githubusercontent.com/XIU2/TrackersListCollection/master/all.txt https://ngosang.github.io/trackerslist/trackers_all_http.txt https://newtrackon.com/api/all https://raw.githubusercontent.com/DeSireFire/animeTrackerList/master/AT_all.txt https://raw.githubusercontent.com/hezhijie0327/Trackerslist/main/trackerslist_tracker.txt https://raw.githubusercontent.com/hezhijie0327/Trackerslist/main/trackerslist_exclude.txt | awk '$0' | tr '\n\n' ',')
export MAX_CONCURRENT_DOWNLOADS=7
aria2c --enable-rpc --rpc-listen-all=false --rpc-listen-port 6800 --check-certificate=false \
@ -8,7 +8,7 @@ aria2c --enable-rpc --rpc-listen-all=false --rpc-listen-port 6800 --check-certif
--follow-torrent=mem --split=10 \
--daemon=true --allow-overwrite=true --max-overall-download-limit=$MAX_DOWNLOAD_SPEED \
--max-overall-upload-limit=1K --max-concurrent-downloads=$MAX_CONCURRENT_DOWNLOADS \
--peer-id-prefix=-qB4350- --user-agent=qBittorrent/4.3.5 --peer-agent=qBittorrent/4.3.5 \
--peer-id-prefix=-TR3000- --peer-agent=Transmission/3.00 \
--disk-cache=64M --file-allocation=prealloc --continue=true \
--max-file-not-found=5 --max-tries=20 --auto-file-renaming=true \
--bt-enable-lpd=true --seed-time=0.01 --seed-ratio=1.0 \

View File

@ -18,7 +18,7 @@ from bot.helper.telegram_helper.message_utils import *
from .helper.ext_utils.bot_utils import get_readable_file_size, get_readable_time
from .helper.telegram_helper.filters import CustomFilters
from bot.helper.telegram_helper import button_build
from .modules import authorize, list, cancel_mirror, mirror_status, mirror, clone, watch, shell, eval, anime, stickers, search, delete, speedtest, usage, mediainfo, count
from .modules import authorize, list, cancel_mirror, mirror_status, mirror, clone, watch, shell, eval, search, delete, speedtest, usage, mediainfo, count
now=datetime.now(pytz.timezone('Asia/Jakarta'))
@ -58,9 +58,10 @@ Type /{BotCommands.HelpCommand} to get a list of available commands
buttons.buildbutton("Support Group", "https://t.me/SlamMirrorSupport")
reply_markup = InlineKeyboardMarkup(buttons.build_menu(2))
LOGGER.info('UID: {} - UN: {} - MSG: {}'.format(update.message.chat.id, update.message.chat.username, update.message.text))
uptime = get_readable_time((time.time() - botStartTime))
if CustomFilters.authorized_user(update) or CustomFilters.authorized_chat(update):
if update.message.chat.type == "private" :
sendMessage(f"Hey I'm Alive 🙂", context.bot, update)
sendMessage(f"Hey I'm Alive 🙂\nSince: <code>{uptime}</code>", context.bot, update)
else :
update.effective_message.reply_photo(IMAGE_URL, start_string, parse_mode=ParseMode.MARKDOWN, reply_markup=reply_markup)
else :
@ -69,7 +70,6 @@ Type /{BotCommands.HelpCommand} to get a list of available commands
def restart(update, context):
restart_message = sendMessage("Restarting, Please wait!", context.bot, update)
LOGGER.info(f'Restarting the Bot...')
# Save restart message object in order to reply to it after restarting
with open(".restartmsg", "w") as f:
f.truncate(0)
@ -138,10 +138,6 @@ def bot_help(update, context):
/mediainfo: Get detailed info about replied media (Only for Telegram file).
/tshelp: Get help for Torrent search module.
/weebhelp: Get help for Anime, Manga, and Character module.
/stickerhelp: Get help for Stickers module.
'''
help_string = f'''
@ -174,10 +170,6 @@ def bot_help(update, context):
/mediainfo: Get detailed info about replied media (Only for Telegram file).
/tshelp: Get help for Torrent search module.
/weebhelp: Get help for Anime, Manga, and Character module.
/stickerhelp: Get help for Stickers module.
'''
if CustomFilters.sudo_user(update) or CustomFilters.owner_filter(update):

View File

@ -24,7 +24,7 @@ from bs4 import BeautifulSoup
from js2py import EvalJs
from lk21.extractors.bypasser import Bypass
from base64 import standard_b64encode
from bot.helper.telegram_helper.bot_commands import BotCommands
from bot.helper.ext_utils.exceptions import DirectDownloadLinkException
@ -32,6 +32,10 @@ def direct_link_generator(link: str):
""" direct links generator """
if not link:
raise DirectDownloadLinkException("`No links found!`")
elif 'youtube.com' in link or 'youtu.be' in link:
raise DirectDownloadLinkException(f"Youtube Link use /{BotCommands.WatchCommand} or /{BotCommands.TarWatchCommand}")
elif 'drive.google.com' in link:
raise DirectDownloadLinkException(f"G-Drive Link use /{BotCommands.CloneCommand}")
elif 'zippyshare.com' in link:
return zippy_share(link)
elif 'yadi.sk' in link:
@ -46,16 +50,18 @@ def direct_link_generator(link: str):
return osdn(link)
elif 'github.com' in link:
return github(link)
elif 'racaty.net' in link:
return racaty(link)
elif 'hxfile.co' in link:
return hxfile(link)
elif 'anonfiles.com' in link:
return anon(link)
elif 'letsupload.io' in link:
return letsupload(link)
elif 'fembed.com' in link:
return fembed(link)
elif 'femax20.com' in link:
return fembed(link)
elif 'feurl.com' in link:
return fembed(link)
elif 'naniplay.nanime.in' in link:
return fembed(link)
elif 'naniplay.nanime.biz' in link:
@ -70,11 +76,15 @@ def direct_link_generator(link: str):
return sbembed(link)
elif '1drv.ms' in link:
return onedrive(link)
elif 'pixeldrain.com' in link:
return pixeldrain(link)
else:
raise DirectDownloadLinkException(f'No Direct link function found for {link}')
def zippy_share(url: str) -> str:
""" ZippyShare direct links generator
Based on https://github.com/KenHV/Mirror-Bot """
link = re.findall("https:/.(.*?).zippyshare", url)[0]
response_content = (requests.get(url)).content
bs_obj = BeautifulSoup(response_content, "lxml")
@ -203,24 +213,6 @@ def github(url: str) -> str:
raise DirectDownloadLinkException("`Error: Can't extract the link`\n")
def racaty(url: str) -> str:
""" Racaty direct links generator
based on https://github.com/breakdowns/slam-mirrorbot """
dl_url = ''
try:
link = re.findall(r'\bhttps?://.*racaty\.net\S+', url)[0]
except IndexError:
raise DirectDownloadLinkException("`No Racaty links found`\n")
reqs=requests.get(link)
bss=BeautifulSoup(reqs.text,'html.parser')
op=bss.find('input',{'name':'op'})['value']
id=bss.find('input',{'name':'id'})['value']
rep=requests.post(link,data={'op':op,'id':id})
bss2=BeautifulSoup(rep.text,'html.parser')
dl_url=bss2.find('a',{'id':'uniqueExpirylink'})['href']
return dl_url
def hxfile(url: str) -> str:
""" Hxfile direct links generator
based on https://github.com/breakdowns/slam-mirrorbot """
@ -247,6 +239,19 @@ def anon(url: str) -> str:
return dl_url
def letsupload(url: str) -> str:
""" Letsupload direct link generator
Based on https://github.com/breakdowns/slam-mirrorbot """
dl_url = ''
try:
link = re.findall(r'\bhttps?://.*letsupload\.io\S+', url)[0]
except IndexError:
raise DirectDownloadLinkException("`No Letsupload links found`\n")
bypasser = lk21.Bypass()
dl_url=bypasser.bypass_url(link)
return dl_url
def fembed(link: str) -> str:
""" Fembed direct link generator
Based on https://github.com/breakdowns/slam-mirrorbot """
@ -257,6 +262,8 @@ def fembed(link: str) -> str:
for i in dl_url:
lst_link.append(dl_url[i])
return lst_link[count-1]
except:
raise DirectDownloadLinkException("ERROR: Can't download file, double check your Fembed link.")
def sbembed(link: str) -> str:
@ -269,6 +276,8 @@ def sbembed(link: str) -> str:
for i in dl_url:
lst_link.append(dl_url[i])
return lst_link[count-1]
except:
raise DirectDownloadLinkException("ERROR: Can't download file, double check your Sbembed/Streamsb link.")
def onedrive(link: str) -> str:
@ -286,6 +295,19 @@ def onedrive(link: str) -> str:
return dl_link
def pixeldrain(url: str) -> str:
""" Based on https://github.com/yash-dk/TorToolkit-Telegram """
url = url.strip("/ ")
file_id = url.split("/")[-1]
info_link = f"https://pixeldrain.com/api/file/{file_id}/info"
dl_link = f"https://pixeldrain.com/api/file/{file_id}"
resp = requests.get(info_link).json()
if resp["success"]:
return dl_link
else:
raise DirectDownloadLinkException("ERROR: Cant't download due {}.".format(resp.text["value"]))
def useragent():
"""
useragent random setter

View File

@ -27,7 +27,7 @@ from bot.helper.ext_utils.fs_utils import get_mime_type, get_path_size
LOGGER = logging.getLogger(__name__)
logging.getLogger('googleapiclient.discovery').setLevel(logging.ERROR)
SERVICE_ACCOUNT_INDEX = 0
TELEGRAPHLIMIT = 95
TELEGRAPHLIMIT = 80
class GoogleDriveHelper:
def __init__(self, name=None, listener=None):

View File

@ -1,270 +0,0 @@
import datetime
import html
import textwrap
import bs4
import requests
from telegram import InlineKeyboardMarkup, InlineKeyboardButton, ParseMode
from telegram.ext import CommandHandler
from bot.helper.telegram_helper.filters import CustomFilters
from bot import dispatcher, IMAGE_URL
def shorten(description, info = 'anilist.co'):
msg = ""
if len(description) > 700:
description = description[0:500] + '....'
msg += f"\n*Description*: _{description}_[Read More]({info})"
else:
msg += f"\n*Description*:_{description}_"
return msg
#time formatter from uniborg
def t(milliseconds: int) -> str:
"""Inputs time in milliseconds, to get beautified time,
as string"""
seconds, milliseconds = divmod(int(milliseconds), 1000)
minutes, seconds = divmod(seconds, 60)
hours, minutes = divmod(minutes, 60)
days, hours = divmod(hours, 24)
tmp = ((str(days) + " Days, ") if days else "") + \
((str(hours) + " Hours, ") if hours else "") + \
((str(minutes) + " Minutes, ") if minutes else "") + \
((str(seconds) + " Seconds, ") if seconds else "") + \
((str(milliseconds) + " ms, ") if milliseconds else "")
return tmp[:-2]
airing_query = '''
query ($id: Int,$search: String) {
Media (id: $id, type: ANIME,search: $search) {
id
episodes
title {
romaji
english
native
}
nextAiringEpisode {
airingAt
timeUntilAiring
episode
}
}
}
'''
fav_query = """
query ($id: Int) {
Media (id: $id, type: ANIME) {
id
title {
romaji
english
native
}
}
}
"""
anime_query = '''
query ($id: Int,$search: String) {
Media (id: $id, type: ANIME,search: $search) {
id
title {
romaji
english
native
}
description (asHtml: false)
startDate{
year
}
episodes
season
type
format
status
duration
siteUrl
studios{
nodes{
name
}
}
trailer{
id
site
thumbnail
}
averageScore
genres
bannerImage
}
}
'''
character_query = """
query ($query: String) {
Character (search: $query) {
id
name {
first
last
full
}
siteUrl
image {
large
}
description
}
}
"""
manga_query = """
query ($id: Int,$search: String) {
Media (id: $id, type: MANGA,search: $search) {
id
title {
romaji
english
native
}
description (asHtml: false)
startDate{
year
}
type
format
status
siteUrl
averageScore
genres
bannerImage
}
}
"""
url = 'https://graphql.anilist.co'
def anime(update, context):
message = update.effective_message
search = message.text.split(' ', 1)
if len(search) == 1: return
else: search = search[1]
variables = {'search' : search}
json = requests.post(url, json={'query': anime_query, 'variables': variables}).json()['data'].get('Media', None)
if json:
msg = f"*{json['title']['romaji']}*(`{json['title']['native']}`)\n*Type*: {json['format']}\n*Status*: {json['status']}\n*Episodes*: {json.get('episodes', 'N/A')}\n*Duration*: {json.get('duration', 'N/A')} Per Ep.\n*Score*: {json['averageScore']}\n*Genres*: `"
for x in json['genres']: msg += f"{x}, "
msg = msg[:-2] + '`\n'
msg += "*Studios*: `"
for x in json['studios']['nodes']: msg += f"{x['name']}, "
msg = msg[:-2] + '`\n'
info = json.get('siteUrl')
trailer = json.get('trailer', None)
if trailer:
trailer_id = trailer.get('id', None)
site = trailer.get('site', None)
if site == "youtube": trailer = 'https://youtu.be/' + trailer_id
description = json.get('description', 'N/A').replace('<i>', '').replace('</i>', '').replace('<br>', '')
msg += shorten(description, info)
image = json.get('bannerImage', None)
if trailer:
buttons = [
[InlineKeyboardButton("More Info", url=info),
InlineKeyboardButton("Trailer 🎬", url=trailer)]
]
else:
buttons = [
[InlineKeyboardButton("More Info", url=info)]
]
if image:
try:
update.effective_message.reply_photo(photo = image, caption = msg, parse_mode=ParseMode.MARKDOWN, reply_markup=InlineKeyboardMarkup(buttons))
except:
msg += f" [〽️]({image})"
update.effective_message.reply_text(msg, parse_mode=ParseMode.MARKDOWN, reply_markup=InlineKeyboardMarkup(buttons))
else:
update.effective_message.reply_text(msg, parse_mode=ParseMode.MARKDOWN, reply_markup=InlineKeyboardMarkup(buttons))
def character(update, _):
message = update.effective_message
search = message.text.split(' ', 1)
if len(search) == 1:
update.effective_message.reply_text('Format : /character < character name >')
return
search = search[1]
variables = {'query': search}
json = requests.post(url, json={'query': character_query, 'variables': variables}).json()['data'].get('Character', None)
if json:
msg = f"*{json.get('name').get('full')}*(`{json.get('name').get('native')}`)\n"
description = f"{json['description']}"
site_url = json.get('siteUrl')
msg += shorten(description, site_url)
image = json.get('image', None)
if image:
image = image.get('large')
update.effective_message.reply_photo(photo = image, caption = msg, parse_mode=ParseMode.MARKDOWN)
else: update.effective_message.reply_text(msg, parse_mode=ParseMode.MARKDOWN)
def manga(update, _):
message = update.effective_message
search = message.text.split(' ', 1)
if len(search) == 1:
update.effective_message.reply_text('Format : /manga < manga name >')
return
search = search[1]
variables = {'search': search}
json = requests.post(url, json={'query': manga_query, 'variables': variables}).json()['data'].get('Media', None)
msg = ''
if json:
title, title_native = json['title'].get('romaji', False), json['title'].get('native', False)
start_date, status, score = json['startDate'].get('year', False), json.get('status', False), json.get('averageScore', False)
if title:
msg += f"*{title}*"
if title_native:
msg += f"(`{title_native}`)"
if start_date: msg += f"\n*Start Date* - `{start_date}`"
if status: msg += f"\n*Status* - `{status}`"
if score: msg += f"\n*Score* - `{score}`"
msg += '\n*Genres* - '
for x in json.get('genres', []): msg += f"{x}, "
msg = msg[:-2]
info = json['siteUrl']
buttons = [
[InlineKeyboardButton("More Info", url=info)]
]
image = json.get("bannerImage", False)
msg += f"_{json.get('description', None)}_"
if image:
try:
update.effective_message.reply_photo(photo = image, caption = msg, parse_mode=ParseMode.MARKDOWN, reply_markup=InlineKeyboardMarkup(buttons))
except:
msg += f" [〽️]({image})"
update.effective_message.reply_text(msg, parse_mode=ParseMode.MARKDOWN, reply_markup=InlineKeyboardMarkup(buttons))
else: update.effective_message.reply_text(msg, parse_mode=ParseMode.MARKDOWN, reply_markup=InlineKeyboardMarkup(buttons))
def weebhelp(update, context):
help_string = '''
`/anime`*:* Search Anime
`/character`*:* Search Character
`/manga`*:* Search Manga
'''
update.effective_message.reply_photo(IMAGE_URL, help_string, parse_mode=ParseMode.MARKDOWN)
ANIME_HANDLER = CommandHandler("anime", anime, filters=CustomFilters.authorized_chat | CustomFilters.authorized_user, run_async=True)
CHARACTER_HANDLER = CommandHandler("character", character, filters=CustomFilters.authorized_chat | CustomFilters.authorized_user, run_async=True)
MANGA_HANDLER = CommandHandler("manga", manga, filters=CustomFilters.authorized_chat | CustomFilters.authorized_user, run_async=True)
WEEBHELP_HANDLER = CommandHandler("weebhelp", weebhelp, filters=CustomFilters.authorized_chat | CustomFilters.authorized_user, run_async=True)
dispatcher.add_handler(ANIME_HANDLER)
dispatcher.add_handler(CHARACTER_HANDLER)
dispatcher.add_handler(MANGA_HANDLER)
dispatcher.add_handler(WEEBHELP_HANDLER)

View File

@ -17,7 +17,7 @@ def cancel_mirror(update, context):
gid = args[1]
dl = getDownloadByGid(gid)
if not dl:
sendMessage(f"GID: <u>{gid}</u> not found.", context.bot, update)
sendMessage(f"GID: <code>{gid}</code> not found.", context.bot, update)
return
with download_dict_lock:
keys = list(download_dict.keys())
@ -30,7 +30,7 @@ def cancel_mirror(update, context):
keys = list(download_dict.keys())
dl = download_dict[mirror_message.message_id]
except:
sendMessage("It's not your msg, reply to your mirrror msg which was used to start the download to cancel.", context.bot, update)
sendMessage("It's not your msg, reply to your mirror msg which was used to start the download to cancel.", context.bot, update)
return
if not update.message.reply_to_message:
pass
@ -46,7 +46,6 @@ def cancel_mirror(update, context):
sendMessage("Extract in progress, can't cancel.", context.bot, update)
return
else:
sendMessage("Download canceled.", context.bot, update)
dl.download().cancel_download()
sleep(1) # Wait a Second For Aria2 To free Resources.
clean_download(f'{DOWNLOAD_DIR}{mirror_message.message_id}/')

View File

@ -288,6 +288,15 @@ def _mirror(bot, update, isTar=False, extract=False):
link = direct_link_generator(link)
except DirectDownloadLinkException as e:
LOGGER.info(f'{link}: {e}')
if "ERROR:" in str(e):
sendMessage(f"{e}", bot, update)
return
if "G-Drive" in str(e):
sendMessage(f"ERROR: {e}", bot, update)
return
if "Youtube" in str(e):
sendMessage(f"ERROR: {e}", bot, update)
return
listener = MirrorListener(bot, update, pswd, isTar, tag, extract)
if bot_utils.is_mega_link(link):
link_type = get_mega_link_type(link)

View File

@ -1,433 +0,0 @@
import math
import os
import urllib.request as urllib
from PIL import Image
from html import escape
from bot.helper.telegram_helper.filters import CustomFilters
from telegram import ParseMode, InlineKeyboardMarkup, InlineKeyboardButton
from telegram import TelegramError
from telegram.ext import CommandHandler
from telegram.utils.helpers import mention_html
from bot import dispatcher, IMAGE_URL
def stickerid(update, context):
msg = update.effective_message
if msg.reply_to_message and msg.reply_to_message.sticker:
update.effective_message.reply_text(
"Hello " +
f"{mention_html(msg.from_user.id, msg.from_user.first_name)}" +
", The sticker id you are replying is :\n <code>" +
escape(msg.reply_to_message.sticker.file_id) + "</code>",
parse_mode=ParseMode.HTML,
)
else:
update.effective_message.reply_text(
"Hello " +
f"{mention_html(msg.from_user.id, msg.from_user.first_name)}" +
", Please reply to sticker message to get id sticker",
parse_mode=ParseMode.HTML,
)
def getsticker(update, context):
bot = context.bot
msg = update.effective_message
chat_id = update.effective_chat.id
if msg.reply_to_message and msg.reply_to_message.sticker:
file_id = msg.reply_to_message.sticker.file_id
new_file = bot.get_file(file_id)
new_file.download("sticker.png")
bot.send_document(chat_id, document=open("sticker.png", "rb"))
os.remove("sticker.png")
else:
update.effective_message.reply_text(
"Please reply to a sticker for me to upload its PNG.")
def kang(update, context):
msg = update.effective_message
user = update.effective_user
args = context.args
packnum = 0
packname = "a" + str(user.id) + "_by_" + context.bot.username
packname_found = 0
max_stickers = 120
while packname_found == 0:
try:
stickerset = context.bot.get_sticker_set(packname)
if len(stickerset.stickers) >= max_stickers:
packnum += 1
packname = ("a" + str(packnum) + "_" + str(user.id) + "_by_" +
context.bot.username)
else:
packname_found = 1
except TelegramError as e:
if e.message == "Stickerset_invalid":
packname_found = 1
kangsticker = "kangsticker.png"
is_animated = False
file_id = ""
if msg.reply_to_message:
if msg.reply_to_message.sticker:
if msg.reply_to_message.sticker.is_animated:
is_animated = True
file_id = msg.reply_to_message.sticker.file_id
elif msg.reply_to_message.photo:
file_id = msg.reply_to_message.photo[-1].file_id
elif msg.reply_to_message.document:
file_id = msg.reply_to_message.document.file_id
else:
msg.reply_text("Yea, I can't kang that.")
kang_file = context.bot.get_file(file_id)
if not is_animated:
kang_file.download("kangsticker.png")
else:
kang_file.download("kangsticker.tgs")
if args:
sticker_emoji = str(args[0])
elif msg.reply_to_message.sticker and msg.reply_to_message.sticker.emoji:
sticker_emoji = msg.reply_to_message.sticker.emoji
else:
sticker_emoji = "🤔"
if not is_animated:
try:
im = Image.open(kangsticker)
maxsize = (512, 512)
if (im.width and im.height) < 512:
size1 = im.width
size2 = im.height
if im.width > im.height:
scale = 512 / size1
size1new = 512
size2new = size2 * scale
else:
scale = 512 / size2
size1new = size1 * scale
size2new = 512
size1new = math.floor(size1new)
size2new = math.floor(size2new)
sizenew = (size1new, size2new)
im = im.resize(sizenew)
else:
im.thumbnail(maxsize)
if not msg.reply_to_message.sticker:
im.save(kangsticker, "PNG")
context.bot.add_sticker_to_set(
user_id=user.id,
name=packname,
png_sticker=open("kangsticker.png", "rb"),
emojis=sticker_emoji,
)
msg.reply_text(
f"Sticker successfully added to [pack](t.me/addstickers/{packname})"
+ f"\nEmoji is: {sticker_emoji}",
parse_mode=ParseMode.MARKDOWN,
)
except OSError as e:
msg.reply_text("I can only kang images m8.")
print(e)
return
except TelegramError as e:
if e.message == "Stickerset_invalid":
makepack_internal(
update,
context,
msg,
user,
sticker_emoji,
packname,
packnum,
png_sticker=open("kangsticker.png", "rb"),
)
elif e.message == "Sticker_png_dimensions":
im.save(kangsticker, "PNG")
context.bot.add_sticker_to_set(
user_id=user.id,
name=packname,
png_sticker=open("kangsticker.png", "rb"),
emojis=sticker_emoji,
)
msg.reply_text(
f"Sticker successfully added to [pack](t.me/addstickers/{packname})"
+ f"\nEmoji is: {sticker_emoji}",
parse_mode=ParseMode.MARKDOWN,
)
elif e.message == "Invalid sticker emojis":
msg.reply_text("Invalid emoji(s).")
elif e.message == "Stickers_too_much":
msg.reply_text(
"Max packsize reached. Press F to pay respecc.")
elif e.message == "Internal Server Error: sticker set not found (500)":
msg.reply_text(
"Sticker successfully added to [pack](t.me/addstickers/%s)"
% packname + "\n"
"Emoji is:" + " " + sticker_emoji,
parse_mode=ParseMode.MARKDOWN,
)
print(e)
else:
packname = "animated" + str(user.id) + "_by_" + context.bot.username
packname_found = 0
max_stickers = 50
while packname_found == 0:
try:
stickerset = context.bot.get_sticker_set(packname)
if len(stickerset.stickers) >= max_stickers:
packnum += 1
packname = ("animated" + str(packnum) + "_" +
str(user.id) + "_by_" +
context.bot.username)
else:
packname_found = 1
except TelegramError as e:
if e.message == "Stickerset_invalid":
packname_found = 1
try:
context.bot.add_sticker_to_set(
user_id=user.id,
name=packname,
tgs_sticker=open("kangsticker.tgs", "rb"),
emojis=sticker_emoji,
)
msg.reply_text(
f"Sticker successfully added to [pack](t.me/addstickers/{packname})"
+ f"\nEmoji is: {sticker_emoji}",
parse_mode=ParseMode.MARKDOWN,
)
except TelegramError as e:
if e.message == "Stickerset_invalid":
makepack_internal(
update,
context,
msg,
user,
sticker_emoji,
packname,
packnum,
tgs_sticker=open("kangsticker.tgs", "rb"),
)
elif e.message == "Invalid sticker emojis":
msg.reply_text("Invalid emoji(s).")
elif e.message == "Internal Server Error: sticker set not found (500)":
msg.reply_text(
"Sticker successfully added to [pack](t.me/addstickers/%s)"
% packname + "\n"
"Emoji is:" + " " + sticker_emoji,
parse_mode=ParseMode.MARKDOWN,
)
print(e)
elif args:
try:
try:
urlemoji = msg.text.split(" ")
png_sticker = urlemoji[1]
sticker_emoji = urlemoji[2]
except IndexError:
sticker_emoji = "🤔"
urllib.urlretrieve(png_sticker, kangsticker)
im = Image.open(kangsticker)
maxsize = (512, 512)
if (im.width and im.height) < 512:
size1 = im.width
size2 = im.height
if im.width > im.height:
scale = 512 / size1
size1new = 512
size2new = size2 * scale
else:
scale = 512 / size2
size1new = size1 * scale
size2new = 512
size1new = math.floor(size1new)
size2new = math.floor(size2new)
sizenew = (size1new, size2new)
im = im.resize(sizenew)
else:
im.thumbnail(maxsize)
im.save(kangsticker, "PNG")
msg.reply_photo(photo=open("kangsticker.png", "rb"))
context.bot.add_sticker_to_set(
user_id=user.id,
name=packname,
png_sticker=open("kangsticker.png", "rb"),
emojis=sticker_emoji,
)
msg.reply_text(
f"Sticker successfully added to [pack](t.me/addstickers/{packname})"
+ f"\nEmoji is: {sticker_emoji}",
parse_mode=ParseMode.MARKDOWN,
)
except OSError as e:
msg.reply_text("I can only kang images m8.")
print(e)
return
except TelegramError as e:
if e.message == "Stickerset_invalid":
makepack_internal(
update,
context,
msg,
user,
sticker_emoji,
packname,
packnum,
png_sticker=open("kangsticker.png", "rb"),
)
elif e.message == "Sticker_png_dimensions":
im.save(kangsticker, "PNG")
context.bot.add_sticker_to_set(
user_id=user.id,
name=packname,
png_sticker=open("kangsticker.png", "rb"),
emojis=sticker_emoji,
)
msg.reply_text(
"Sticker successfully added to [pack](t.me/addstickers/%s)"
% packname + "\n" + "Emoji is:" + " " + sticker_emoji,
parse_mode=ParseMode.MARKDOWN,
)
elif e.message == "Invalid sticker emojis":
msg.reply_text("Invalid emoji(s).")
elif e.message == "Stickers_too_much":
msg.reply_text("Max packsize reached. Press F to pay respecc.")
elif e.message == "Internal Server Error: sticker set not found (500)":
msg.reply_text(
"Sticker successfully added to [pack](t.me/addstickers/%s)"
% packname + "\n"
"Emoji is:" + " " + sticker_emoji,
parse_mode=ParseMode.MARKDOWN,
)
print(e)
else:
packs = "Please reply to a sticker, or image to kang it!\nOh, by the way. here are your packs:\n"
if packnum > 0:
firstpackname = "a" + str(user.id) + "_by_" + context.bot.username
for i in range(0, packnum + 1):
if i == 0:
packs += f"[pack](t.me/addstickers/{firstpackname})\n"
else:
packs += f"[pack{i}](t.me/addstickers/{packname})\n"
else:
packs += f"[pack](t.me/addstickers/{packname})"
msg.reply_text(packs, parse_mode=ParseMode.MARKDOWN)
if os.path.isfile("kangsticker.png"):
os.remove("kangsticker.png")
elif os.path.isfile("kangsticker.tgs"):
os.remove("kangsticker.tgs")
def makepack_internal(
update,
context,
msg,
user,
emoji,
packname,
packnum,
png_sticker=None,
tgs_sticker=None,
):
name = user.first_name
name = name[:50]
try:
extra_version = ""
if packnum > 0:
extra_version = " " + str(packnum)
if png_sticker:
success = context.bot.create_new_sticker_set(
user.id,
packname,
f"{name}s kang pack" + extra_version,
png_sticker=png_sticker,
emojis=emoji,
)
if tgs_sticker:
success = context.bot.create_new_sticker_set(
user.id,
packname,
f"{name}s animated kang pack" + extra_version,
tgs_sticker=tgs_sticker,
emojis=emoji,
)
except TelegramError as e:
print(e)
if e.message == "Sticker set name is already occupied":
msg.reply_text(
"Your pack can be found [here](t.me/addstickers/%s)" % packname,
parse_mode=ParseMode.MARKDOWN,
)
elif e.message in ("Peer_id_invalid", "bot was blocked by the user"):
msg.reply_text(
"Contact me in PM first.",
reply_markup=InlineKeyboardMarkup([[
InlineKeyboardButton(
text="Start", url=f"t.me/{context.bot.username}")
]]),
)
elif e.message == "Internal Server Error: created sticker set not found (500)":
msg.reply_text(
"Sticker pack successfully created. Get it [here](t.me/addstickers/%s)"
% packname,
parse_mode=ParseMode.MARKDOWN,
)
return
if success:
msg.reply_text(
"Sticker pack successfully created. Get it [here](t.me/addstickers/%s)"
% packname,
parse_mode=ParseMode.MARKDOWN,
)
else:
msg.reply_text(
"Failed to create sticker pack. Possibly due to blek mejik.")
def delsticker(update, context):
msg = update.effective_message
if msg.reply_to_message and msg.reply_to_message.sticker:
file_id = msg.reply_to_message.sticker.file_id
context.bot.delete_sticker_from_set(file_id)
msg.reply_text(
"Sticker deleted!"
)
else:
update.effective_message.reply_text(
"Please reply to sticker message to del sticker"
)
def stickhelp(update, context):
help_string = '''
`/stickerid`*:* Reply to a Sticker to me to tell you its file ID.
`/getsticker`*:* Reply to a Sticker to me to upload its raw PNG file.
`/kang`*:* Reply to a Sticker to add it to your pack.
`/remove`*:* Replay to a Sticker to remove Sticker from an existing pack.
'''
update.effective_message.reply_photo(IMAGE_URL, help_string, parse_mode=ParseMode.MARKDOWN)
STICKERID_HANDLER = CommandHandler("stickerid", stickerid, filters=CustomFilters.authorized_chat | CustomFilters.authorized_user, run_async=True)
GETSTICKER_HANDLER = CommandHandler("getsticker", getsticker, filters=CustomFilters.authorized_chat | CustomFilters.authorized_user, run_async=True)
KANG_HANDLER = CommandHandler("kang", kang, filters=CustomFilters.authorized_chat | CustomFilters.authorized_user, run_async=True)
DEL_HANDLER = CommandHandler("remove", delsticker, filters=CustomFilters.authorized_chat | CustomFilters.authorized_user, run_async=True)
STICKHELP_HANDLER = CommandHandler("stickerhelp", stickhelp, filters=CustomFilters.authorized_chat | CustomFilters.authorized_user, run_async=True)
dispatcher.add_handler(STICKERID_HANDLER)
dispatcher.add_handler(GETSTICKER_HANDLER)
dispatcher.add_handler(KANG_HANDLER)
dispatcher.add_handler(DEL_HANDLER)
dispatcher.add_handler(STICKHELP_HANDLER)

View File

@ -2,7 +2,6 @@ aiohttp
aria2p
appdirs
beautifulsoup4
bs4
feedparser
google-api-python-client
google-auth-httplib2
@ -13,8 +12,6 @@ js2py
lk21
lxml
messages
natsort
Pillow
psutil
psycopg2-binary
pybase64