From 3f57f6191c75da169d9fa8c61db8e217242d683f Mon Sep 17 00:00:00 2001 From: Gauthamram Ravichandran <20rgr12@gmail.com> Date: Thu, 4 Jun 2020 23:19:13 +0530 Subject: [PATCH 001/181] minor-fix --- stdplugins/download.py | 19 ++++++++++--------- stdplugins/tb_button.py | 2 +- stdplugins/telegraph.py | 2 +- uniborg/util.py | 4 ++-- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/stdplugins/download.py b/stdplugins/download.py index 153cad8acd..f67df16743 100644 --- a/stdplugins/download.py +++ b/stdplugins/download.py @@ -47,7 +47,7 @@ async def _(event): file_name = os.path.basename(url) to_download_directory = Config.TMP_DOWNLOAD_DIRECTORY if "|" in input_str: - url, file_name = input_str.split("|") + url, file_name = input_str.split("|", maxsplit = 1) url = url.strip() file_name = file_name.strip() downloaded_file_name = os.path.join(to_download_directory, file_name) @@ -64,17 +64,18 @@ async def _(event): speed = downloader.get_speed() elapsed_time = round(diff) * 1000 progress_str = "[{0}{1}]\nProgress: {2}%".format( - ''.join(["█" for i in range(math.floor(percentage / 5))]), - ''.join(["░" for i in range(20 - math.floor(percentage / 5))]), + ''.join(["█" for _ in range(math.floor(percentage / 5))]), + ''.join(["░" for _ in range(20 - math.floor(percentage / 5))]), round(percentage, 2)) estimated_total_time = downloader.get_eta(human=True) try: - current_message = f"trying to download\n" - current_message += f"URL: {url}\n" - current_message += f"File Name: {file_name}\n" - current_message += f"{progress_str}\n" - current_message += f"{humanbytes(downloaded)} of {humanbytes(total_length)}\n" - current_message += f"ETA: {estimated_total_time}" + current_message = f"trying to download\n"\ + f"URL: {url}\n"\ + f"File Name: {file_name}\n" \ + f"Speed: {speed}"\ + f"{progress_str}\n"\ + f"{humanbytes(downloaded)} of {humanbytes(total_length)}\n"\ + f"ETA: {estimated_total_time}" if round(diff % 10.00) == 0 and current_message != display_message: await mone.edit(current_message) display_message = current_message diff --git a/stdplugins/tb_button.py b/stdplugins/tb_button.py index a1950f3d95..7bb139a743 100644 --- a/stdplugins/tb_button.py +++ b/stdplugins/tb_button.py @@ -39,7 +39,7 @@ async def _(event): # if even, not escaped -> create button if n_escapes % 2 == 0: - # create a thruple with button label, url, and newline status + # create a tuple with button label, url, and newline status buttons.append((match.group(2), match.group(3), bool(match.group(4)))) note_data += markdown_note[prev:match.start(1)] prev = match.end(1) diff --git a/stdplugins/telegraph.py b/stdplugins/telegraph.py index 9c5d29611f..c207a1eb1f 100644 --- a/stdplugins/telegraph.py +++ b/stdplugins/telegraph.py @@ -67,7 +67,7 @@ async def _(event): r_message, Config.TMP_DOWNLOAD_DIRECTORY ) - m_list = None + m_list = '' with open(downloaded_file_name, "rb") as fd: m_list = fd.readlines() for m in m_list: diff --git a/uniborg/util.py b/uniborg/util.py index 44e4888709..2d908452e1 100644 --- a/uniborg/util.py +++ b/uniborg/util.py @@ -95,8 +95,8 @@ async def progress(current, total, event, start, type_of_ps): time_to_completion = round((total - current) / speed) * 1000 estimated_total_time = elapsed_time + time_to_completion progress_str = "[{0}{1}]\nPercent: {2}%\n".format( - ''.join(["█" for i in range(math.floor(percentage / 5))]), - ''.join(["░" for i in range(20 - math.floor(percentage / 5))]), + ''.join(["█" for _ in range(math.floor(percentage / 5))]), + ''.join(["░" for _ in range(20 - math.floor(percentage / 5))]), round(percentage, 2)) tmp = progress_str + \ "{0} of {1}\nETA: {2}".format( From 96ad1e2ba6487b1ad862c22a13833234a9874767 Mon Sep 17 00:00:00 2001 From: "M.Furkan" Date: Sat, 6 Jun 2020 13:24:32 +0300 Subject: [PATCH 002/181] Update download.py --- stdplugins/download.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stdplugins/download.py b/stdplugins/download.py index f67df16743..8a9c99eb0e 100644 --- a/stdplugins/download.py +++ b/stdplugins/download.py @@ -64,8 +64,8 @@ async def _(event): speed = downloader.get_speed() elapsed_time = round(diff) * 1000 progress_str = "[{0}{1}]\nProgress: {2}%".format( - ''.join(["█" for _ in range(math.floor(percentage / 5))]), - ''.join(["░" for _ in range(20 - math.floor(percentage / 5))]), + ''.join("█" for _ in range(math.floor(percentage / 5))), + ''.join("░" for _ in range(20 - math.floor(percentage / 5))), round(percentage, 2)) estimated_total_time = downloader.get_eta(human=True) try: From a92180b800ea339150939efa77ebc3c18cc556ac Mon Sep 17 00:00:00 2001 From: Shrimadhav U K Date: Sun, 7 Jun 2020 12:52:15 +0530 Subject: [PATCH 003/181] Add DeezLoader plugin --- stdplugins/deezload.py | 177 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 stdplugins/deezload.py diff --git a/stdplugins/deezload.py b/stdplugins/deezload.py new file mode 100644 index 0000000000..a4e2dacf01 --- /dev/null +++ b/stdplugins/deezload.py @@ -0,0 +1,177 @@ +# UniBorg (telegram userbot) +# Copyright (C) 2020 The Authors + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. + +# DeezLoader is an attempt to archive songs and +# to serve the poor who can't afford legal copy of the songs. +# If you are capable of buying and +# spending money on songs in legal ways, please do so. + +# The Author(s) of this module are not responsible +# for the usage of this program by other people. + +# The Author(s) of this module do not recommend +# doing it illegally or against Deezer's Terms of Service + +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +# requires: deezloader hachoir Pillow + +import deezloader +import os +import shutil +import time + +from uniborg.util import admin_cmd +from hachoir.metadata import extractMetadata +from hachoir.parser import createParser +# from PIL import Image +from telethon.tl.types import DocumentAttributeAudio + +@borg.on(admin_cmd(pattern="deezload (.+?|) --(FLAC|MP3\_320|MP3\_256|MP3\_128)")) +async def _(event): + """DeezLoader by @An0nimia + Ported for UniBorg by @SpEcHlDe""" + if event.fwd_from: + return + + strings = { + "name": "DeezLoad", + "arl_token_cfg_doc": "ARL Token for Deezer", + "invalid_arl_token": "please set the required variables for this module", + "wrong_cmd_syntax": "bruh, now i think how far should we go. please terminate my Session 🥺", + "server_error": "We're experiencing technical difficulties.", + "processing": "checking received input ?" + } + + ARL_TOKEN = Config.DEEZER_ARL_TOKEN + + if ARL_TOKEN is None: + await event.edit(strings["invalid_arl_token"]) + return + + try: + loader = deezloader.Login(ARL_TOKEN) + except Exception as er: + await event.edit(str(er)) + return + + temp_dl_path = os.path.join(Config.TMP_DOWNLOAD_DIRECTORY, str(time.time())) + if not os.path.exists(temp_dl_path): + os.makedirs(temp_dl_path) + + required_link = event.pattern_match.group(1) + required_qty = event.pattern_match.group(2) + + await event.edit(strings["processing"]) + + if "spotify" in required_link: + if "track" in required_link: + required_track = loader.download_trackspo( + required_link, + output=temp_dl_path, + quality=required_qty, + recursive_quality=True, + recursive_download=True, + not_interface=True + ) + await upload_track(required_track, event) + shutil.rmtree(temp_dl_path) + await event.delete() + + elif "album" in required_link: + reqd_albums = loader.download_albumspo( + required_link, + output=temp_dl_path, + quality=required_qty, + recursive_quality=True, + recursive_download=True, + not_interface=True, + zips=False + ) + for required_track in reqd_albums: + await upload_track(required_track, event) + shutil.rmtree(temp_dl_path) + await event.delete() + + elif "deezer" in required_link: + if "track" in required_link: + required_track = loader.download_trackdee( + required_link, + output=temp_dl_path, + quality=required_qty, + recursive_quality=True, + recursive_download=True, + not_interface=True + ) + await upload_track(required_track, event) + shutil.rmtree(temp_dl_path) + await event.delete() + + elif "album" in required_link: + reqd_albums = loader.download_albumdee( + required_link, + output=temp_dl_path, + quality=required_qty, + recursive_quality=True, + recursive_download=True, + not_interface=True, + zips=False + ) + for required_track in reqd_albums: + await upload_track(required_track, event) + shutil.rmtree(temp_dl_path) + await event.delete() + + else: + await event.edit(strings["wrong_cmd_syntax"]) + + +async def upload_track(track_location, message): + metadata = extractMetadata(createParser(track_location)) + duration = 0 + title = "" + performer = "" + if metadata.has("duration"): + duration = metadata.get("duration").seconds + if metadata.has("title"): + title = metadata.get("title") + if metadata.has("artist"): + performer = metadata.get("artist") + document_attributes = [ + DocumentAttributeAudio( + duration=duration, + voice=False, + title=title, + performer=performer, + waveform=None + ) + ] + supports_streaming = True + force_document = False + caption_rts = os.path.basename(track_location) + await message.client.send_file( + message.chat_id, + track_location, + caption=caption_rts, + force_document=force_document, + supports_streaming=supports_streaming, + allow_cache=False, + # reply_to=message.id, + # thumb=thumb, + attributes=document_attributes, + # progress_callback=lambda d, t: asyncio.get_event_loop().create_task( + # progress(d, t, event, c_time, "trying to upload") + # ) + ) + os.remove(track_location) From 48fd464d308235a52b52cfc8eb2de6be62ce00a5 Mon Sep 17 00:00:00 2001 From: Shrimadhav U K Date: Sun, 7 Jun 2020 12:52:49 +0530 Subject: [PATCH 004/181] Add deezloader dependancy --- requirements-stdborg.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements-stdborg.txt b/requirements-stdborg.txt index d5b314d631..09e8277397 100644 --- a/requirements-stdborg.txt +++ b/requirements-stdborg.txt @@ -5,6 +5,7 @@ beautifulsoup4 cfscrape coffeehouse cryptg +deezloader emoji googletrans google_images_download==2.8.0 From 56c2ec6626a7d041101560e8dbcb12ed7c01ade0 Mon Sep 17 00:00:00 2001 From: Shrimadhav U K Date: Sun, 7 Jun 2020 12:53:44 +0530 Subject: [PATCH 005/181] Add DEEZER_ARL_TOKEN to sample_config --- sample_config.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sample_config.py b/sample_config.py index 0edf12b14d..f6b4d823da 100644 --- a/sample_config.py +++ b/sample_config.py @@ -108,6 +108,8 @@ class Config(object): # define the "types" that should be uplaoded as streamable TL_VID_STREAM_TYPES = ("MP4", "WEBM") TL_MUS_STREAM_TYPES = ("MP3", "WAV", "FLAC") + # Deeer ARL Token + DEEZER_ARL_TOKEN = os.environ.get("DEEZER_ARL_TOKEN", None) class Production(Config): From a57191cbc3aa6cf03196bd3934b3319f8baa426b Mon Sep 17 00:00:00 2001 From: Shrimadhav U K Date: Sun, 7 Jun 2020 22:01:36 +0530 Subject: [PATCH 006/181] =?UTF-8?q?fix=20indentationError,=20maybe=20?= =?UTF-8?q?=F0=9F=98=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stdplugins/deezload.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdplugins/deezload.py b/stdplugins/deezload.py index a4e2dacf01..f6f7f7feb0 100644 --- a/stdplugins/deezload.py +++ b/stdplugins/deezload.py @@ -71,7 +71,7 @@ async def _(event): os.makedirs(temp_dl_path) required_link = event.pattern_match.group(1) - required_qty = event.pattern_match.group(2) + required_qty = event.pattern_match.group(2) await event.edit(strings["processing"]) From 77d80ce30127bb4a98652a59281c150a6495aee0 Mon Sep 17 00:00:00 2001 From: Shrimadhav U K Date: Tue, 9 Jun 2020 22:12:42 +0530 Subject: [PATCH 007/181] =?UTF-8?q?=F0=9F=A4=AE=F0=9F=A4=AE=20make=20it=20?= =?UTF-8?q?easier=20to=20copy=20session=20string=20=F0=9F=98=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- GenerateStringSession.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/GenerateStringSession.py b/GenerateStringSession.py index 4603ac6a77..4f0824128b 100644 --- a/GenerateStringSession.py +++ b/GenerateStringSession.py @@ -10,9 +10,16 @@ print("""Please go-to my.telegram.org Login using your Telegram account Click on API Development Tools -Create a new application, by entering the required details""") +Create a new application, by entering the required details + +if Telegram is blocked by your ISP, you can try the @useTGxBot""") APP_ID = int(input("Enter APP ID here: ")) API_HASH = input("Enter API HASH here: ") with TelegramClient(StringSession(), APP_ID, API_HASH) as client: - print(client.session.save()) + session_string = client.session.save() + saved_messages_template = """@UniBorg +HU_STRING_SESSION: {} + +⚠️ it is forbidden to pass this value to third parties""".format(session_string) + client.send_message("me", saved_messages_template, parse_mode="html") From de82c2c91d926fa32074f7e15587ac99d8022e5a Mon Sep 17 00:00:00 2001 From: ViruZs <52099763+TGExplore@users.noreply.github.com> Date: Fri, 10 Jul 2020 11:55:14 +0530 Subject: [PATCH 008/181] Changed heroku-postgresql Version Heroku Log : "An error was encountered when contacting the add-on partner to create heroku-postgresql:hobby-dev: Available versions are 9.6, 10, 11, 12 (the default is 12)" 12 (default) 11 10 9.6 9.5 - deprecating --- app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app.json b/app.json index 976ccda075..c65e5c90d5 100644 --- a/app.json +++ b/app.json @@ -142,7 +142,7 @@ "addons": [{ "plan": "heroku-postgresql", "options": { - "version": "9.5" + "version": "10" } }], "buildpacks": [{ From 0849249620ad93e9ca3d6efff30342a29fc27a1e Mon Sep 17 00:00:00 2001 From: Shrimadhav U K Date: Fri, 10 Jul 2020 12:03:36 +0530 Subject: [PATCH 009/181] update postgres version --- app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app.json b/app.json index c65e5c90d5..d4ffdf5066 100644 --- a/app.json +++ b/app.json @@ -142,7 +142,7 @@ "addons": [{ "plan": "heroku-postgresql", "options": { - "version": "10" + "version": "12" } }], "buildpacks": [{ From 677f15187acadc494422485d35f2874adbf29437 Mon Sep 17 00:00:00 2001 From: Shrimadhav U K Date: Sun, 12 Jul 2020 15:17:04 +0530 Subject: [PATCH 010/181] tests --- README.md | 6 +- app.json | 10 +--- helper_sign_in.py | 119 +++++++++++++++++++++++++++++++++++++++ requirements-stdborg.txt | 26 ++++++++- requirements.txt | 2 + sample_config.py | 4 +- stdborg.py | 41 +++++++++++--- 7 files changed, 185 insertions(+), 23 deletions(-) create mode 100644 helper_sign_in.py diff --git a/README.md b/README.md index fc645e6ced..a70bc9917f 100644 --- a/README.md +++ b/README.md @@ -6,16 +6,12 @@ Pluggable [``asyncio``](https://docs.python.org/3/library/asyncio.html) ## installing -#### The Easy Way - -[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy) - #### The Legacy Way Simply clone the repository and run the main file: ```sh git clone https://github.com/udf/uniborg.git cd uniborg -virtualenv -p /usr/bin/python3 venv +python3 -m venv venv . ./venv/bin/activate pip install -r requirements.txt # diff --git a/app.json b/app.json index d4ffdf5066..bfc03a54c1 100644 --- a/app.json +++ b/app.json @@ -25,10 +25,6 @@ "description": "Get this value from my.telegram.org! Please do not steal", "value": "" }, - "HU_STRING_SESSION": { - "description": "Get this value by running python3 GenerateStringSession.py locally", - "value": "" - }, "OPEN_WEATHER_MAP_APPID": { "description": "Get your own APPID from https://api.openweathermap.org/data/2.5/weather", "required": false @@ -81,12 +77,10 @@ "required": false }, "TG_BOT_TOKEN_BF_HER": { - "description": "Obtain a Telegram bot token by contacting @BotFather", - "required": false + "description": "Obtain a Telegram bot token by contacting @BotFather" }, "TG_BOT_USER_NAME_BF_HER": { - "description": "Obtain a Telegram bot @username by contacting @BotFather", - "required": false + "description": "Obtain a Telegram bot @username by contacting @BotFather" }, "REM_BG_API_KEY": { "description": "Get your own API key from https://www.remove.bg/ or feel free to use http://telegram.dog/Remove_BGBot", diff --git a/helper_sign_in.py b/helper_sign_in.py new file mode 100644 index 0000000000..300c51f598 --- /dev/null +++ b/helper_sign_in.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# UniBorg Telegram UseRBot +# Copyright (C) 2020 @UniBorg +# This code is licensed under +# the "you can't use this for anything - public or private, +# unless you know the two prime factors to the number below" license +# +# 76420267623546914285312953847595971404341698667641514250876752277272387319730719447944190236554292723287731288464885804750741761364327420735484520254795074034271100312534358762695139153809201139028342591690162180482749102700757709533577692364027644748874488672927686880394116645482754406114234995849466230628072343395577643542244898329670772406248890522958479425726186109846556166785296629623349390742033833661187669196367578138285625089404848643493377827537273669265993240595087539269421233264244215402846901329418276845584435165797641413600630197168449069124329071377882018664252635437935498247362577995000876370559921979986167467150242719108997966389358573614338347798942075025019524334410765076448079346402255279475454578911100171143362383701997345247071665044229776967047890105530288552675523382282543070978365198408375296102481704475022808512560332288875562645323407287276387630426464690604583020202716621432448074540765228575710411577376747565205168211778277438102839283208230298551765603915629876539090653002258100860161813070337131517342747019595180737118037884721995383231810660641212174692945512923696997890453647367133871298033535417493414711299792390309624922324695948156041420140711933411174201608157710806470205328887 +# +# https://github.com/udf/uniborg/raw/kate/stdplugins/sp_lonami_gay.py +# വിവരണം അടിച്ചുമാറ്റിക്കൊണ്ട് പോകുന്നവർ ക്രെഡിറ്റ് വെച്ചാൽ സന്തോഷമേ ഉള്ളു..! + +import logging +from telethon import TelegramClient +from telethon.sessions import StringSession +from telethon.errors.rpcerrorlist import ( + SessionPasswordNeededError, + PhoneCodeInvalidError +) + + +async def bleck_megick(event, config_jbo): + bot_me = await event.client.get_me() + print(bot_me.stringify()) + if bot_me.username.lower() == config_jbo.TG_BOT_USER_NAME_BF_HER.lower() and int(event.chat_id) == int(config_jbo.SUDO_USERS[0]): + # force int for Type checks + # 🤣🤣 validations + async with event.client.conversation(event.chat_id) as conv: + await conv.send_message( + "welcome **master**\n" + "please send me your Phone Number, to generate " + "`HU_STRING_SESSION` \n" + "Enter the Phone Number that you want to make awesome, " + "powered by @UniBorg" + ) + msg2 = await conv.get_response() + logging.info(msg2.stringify()) + phone = msg2.message.strip() + current_client = TelegramClient( + StringSession(), + api_id=config_jbo.APP_ID, + api_hash=config_jbo.API_HASH, + device_model="@UniBorg String Generator", + system_version="@UniBorg", + app_version="9.6.9", + lang_code="ml" + ) + await current_client.connect() + sent = await current_client.send_code_request(phone) + logging.info(sent) + if not sent: + await conv.send_message( + "This number is not registered on Telegram. " + "Please check your #karma by reading https://t.me/c/1220993104/28753" + ) + return + + await conv.send_message( + "This number is registered on Telegram. " + "Please input the verification code " + "that you receive from [Telegram](tg://user?id=777000) " + "seperated by space, " + "else a `PhoneCodeInvalidError` would be raised." + ) + msg4 = await conv.get_response() + + received_code = msg4.message.strip() + received_tfa_code = None + received_code = "".join(received_code.split(" ")) + + try: + await current_client.sign_in( + phone, + code=received_code, + password=received_tfa_code + ) + except PhoneCodeInvalidError: + await conv.send_message( + "Invalid Code Received. " + "Please re /start" + ) + return + except SessionPasswordNeededError: + await conv.send_message( + "The entered Telegram Number is protected with 2FA. " + "Please enter your second factor authentication code.\n" + "__This message " + "will only be used for generating your string session, " + "and will never be used for any other purposes " + "than for which it is asked.__" + "\n\n" + "The code is available for review at " + "https://github.com/SpEcHiDe/UniBorg/raw/master/helper_sign_in.py" + ) + msg6 = await conv.get_response() + received_tfa_code = msg6.message.strip() + await current_client.sign_in(password=received_tfa_code) + + # all done + # Getting information about yourself + current_client_me = await current_client.get_me() + # "me" is an User object. You can pretty-print + # any Telegram object with the "stringify" method: + logging.info(current_client_me.stringify()) + session_string = current_client.session.save() + + string_session_messeg = await conv.send_message( + f"{session_string}" + ) + await string_session_messeg.reply( + "now, " + "please turn of the application " + "and set the above variable to " + "`HU_STRING_SESSION` variable, " + "and restart application." + ) + else: + await event.reply("un authorized -_- user(s)") diff --git a/requirements-stdborg.txt b/requirements-stdborg.txt index 09e8277397..d0e94474d3 100644 --- a/requirements-stdborg.txt +++ b/requirements-stdborg.txt @@ -1,33 +1,55 @@ aiofiles aiohttp + aria2p + beautifulsoup4 cfscrape + coffeehouse -cryptg + deezloader + emoji + googletrans google_images_download==2.8.0 gtts + hachoir + Pillow + PyLyrics -psycopg2 + pySmartDL + python-barcode python-magic + qrcode + regex + requests + selenium + speedtest-cli + +psycopg2-binary sqlalchemy + telegraph + urbandict + wikipedia + youtube-dl + google-api-python-client==1.7.11 oauth2client==4.1.3 httplib2==0.13.1 + justwatch diff --git a/requirements.txt b/requirements.txt index 562071f39b..94009a5e6d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,4 @@ telethon +telethon-session-sqlalchemy +cryptg -r ./requirements-stdborg.txt diff --git a/sample_config.py b/sample_config.py index f6b4d823da..723ac2caaa 100644 --- a/sample_config.py +++ b/sample_config.py @@ -75,7 +75,9 @@ class Config(object): # specify list of users allowed to use bot # WARNING: be careful who you grant access to your bot. # malicious users could do ".exec rm -rf /*" - SUDO_USERS = set(int(x) for x in os.environ.get("SUDO_USERS", "").split()) + SUDO_USERS = list(set( + int(x) for x in os.environ.get("SUDO_USERS", "").split() + )) # VeryStream only supports video formats VERY_STREAM_LOGIN = os.environ.get("VERY_STREAM_LOGIN", None) VERY_STREAM_KEY = os.environ.get("VERY_STREAM_KEY", None) diff --git a/stdborg.py b/stdborg.py index 859ed4e8ff..a9ad5ba276 100644 --- a/stdborg.py +++ b/stdborg.py @@ -9,6 +9,7 @@ from uniborg import Uniborg from uniborg.storage import Storage from telethon.sessions import StringSession +from telethon import events, TelegramClient logging.basicConfig(level=logging.INFO) @@ -30,8 +31,11 @@ logging.warning("No DB_URI Found!") -if len(Config.SUDO_USERS) >= 0: - Config.SUDO_USERS.add("me") +if len(Config.SUDO_USERS) == 0: + logging.warning( + "'SUDO_USERS' should have atleast one value" + ) + sys.exit(1) if Config.HU_STRING_SESSION is not None: @@ -60,8 +64,31 @@ ) borg.run_until_disconnected() else: - # throw error - logging.error("USAGE EXAMPLE:\n" - "python3 -m stdborg " - "\n 👆👆 Please follow the above format to run your userbot." - "\n Bot quitting.") + if Config.TG_BOT_TOKEN_BF_HER: + # user defined 'TG_BOT_TOKEN_BF_HER' + # but did not define, 'HU_STRING_SESSION' + logging.info( + "[] did not provide / generate " + "'HU_STRING_SESSION', trying to work-around" + ) + temp_borg = TelegramClient( + "temp_bot_session", + api_id=Config.APP_ID, + api_hash=Config.API_HASH + ).start(bot_token=Config.TG_BOT_TOKEN_BF_HER) + @temp_borg.on(events.NewMessage()) + async def on_new_message(event): + from helper_sign_in import bleck_megick + await bleck_megick(event, Config) + logging.info( + f"please send /start to your '@{Config.TG_BOT_USER_NAME_BF_HER}'" + ) + temp_borg.run_until_disconnected() + else: + # throw error + logging.error( + "USAGE EXAMPLE:\n" + "python3 -m stdborg " + "\n 👆👆 Please follow the above format to run your userbot." + "\n Bot quitting." + ) From 04845f9b7bfe437ddad8fbaaf9351c6ea357e58e Mon Sep 17 00:00:00 2001 From: Shrimadhav U K Date: Sun, 12 Jul 2020 15:36:32 +0530 Subject: [PATCH 011/181] tests --- helper_sign_in.py | 12 ++++++++---- stdborg.py | 10 +++++++--- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/helper_sign_in.py b/helper_sign_in.py index 300c51f598..fa8028fe51 100644 --- a/helper_sign_in.py +++ b/helper_sign_in.py @@ -12,8 +12,9 @@ # വിവരണം അടിച്ചുമാറ്റിക്കൊണ്ട് പോകുന്നവർ ക്രെഡിറ്റ് വെച്ചാൽ സന്തോഷമേ ഉള്ളു..! import logging +import secrets from telethon import TelegramClient -from telethon.sessions import StringSession +from alchemysession import AlchemySessionContainer from telethon.errors.rpcerrorlist import ( SessionPasswordNeededError, PhoneCodeInvalidError @@ -37,8 +38,12 @@ async def bleck_megick(event, config_jbo): msg2 = await conv.get_response() logging.info(msg2.stringify()) phone = msg2.message.strip() + container = AlchemySessionContainer(config_jbo.DB_URI) + session_id = str(secrets.randbelow(1000000)) + session = container.new_session(session_id) + current_client = TelegramClient( - StringSession(), + session, api_id=config_jbo.APP_ID, api_hash=config_jbo.API_HASH, device_model="@UniBorg String Generator", @@ -103,10 +108,9 @@ async def bleck_megick(event, config_jbo): # "me" is an User object. You can pretty-print # any Telegram object with the "stringify" method: logging.info(current_client_me.stringify()) - session_string = current_client.session.save() string_session_messeg = await conv.send_message( - f"{session_string}" + f"{session_id}" ) await string_session_messeg.reply( "now, " diff --git a/stdborg.py b/stdborg.py index a9ad5ba276..80e4fadee4 100644 --- a/stdborg.py +++ b/stdborg.py @@ -8,7 +8,7 @@ from pathlib import Path from uniborg import Uniborg from uniborg.storage import Storage -from telethon.sessions import StringSession +from alchemysession import AlchemySessionContainer from telethon import events, TelegramClient @@ -40,9 +40,13 @@ if Config.HU_STRING_SESSION is not None: # for Running on Heroku - session_name = str(Config.HU_STRING_SESSION) + session_id = str(Config.HU_STRING_SESSION) + container = AlchemySessionContainer( + engine=Config.DB_URI, + session=session_id + ) borg = Uniborg( - StringSession(session_name), + container, n_plugin_path="stdplugins/", db_plugin_path="dbplugins/", api_config=Config, From da4d107076e6cf092b5bab5c7c5b88f596e3e683 Mon Sep 17 00:00:00 2001 From: Shrimadhav U K Date: Sun, 12 Jul 2020 16:12:57 +0530 Subject: [PATCH 012/181] update README, with disclaimer --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index a70bc9917f..29f3f4d254 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,13 @@ Pluggable [``asyncio``](https://docs.python.org/3/library/asyncio.html) [Telegram](https://telegram.org) userbot based on [Telethon](https://github.com/LonamiWebs/Telethon). +/** +// **DISCLAIMER** + +// multiple accounts are getting banned, +// hence, please do not deploy this REPOsitory + */ + ## installing #### The Legacy Way From b80c9f0493996e5e31a52bda6888e925db1c67d2 Mon Sep 17 00:00:00 2001 From: Shrimadhav U K Date: Sun, 12 Jul 2020 19:55:20 +0530 Subject: [PATCH 013/181] tests: maybe https://t.me/c/1279877202/2539 --- helper_sign_in.py | 5 ++--- uniborg/uniborg.py | 2 -- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/helper_sign_in.py b/helper_sign_in.py index fa8028fe51..cc7b4f76bd 100644 --- a/helper_sign_in.py +++ b/helper_sign_in.py @@ -46,9 +46,8 @@ async def bleck_megick(event, config_jbo): session, api_id=config_jbo.APP_ID, api_hash=config_jbo.API_HASH, - device_model="@UniBorg String Generator", - system_version="@UniBorg", - app_version="9.6.9", + device_model="GNU/Linux nonUI", + app_version="@UniBorg 2.0", lang_code="ml" ) await current_client.connect() diff --git a/uniborg/uniborg.py b/uniborg/uniborg.py index a245af2425..55aa6fb275 100644 --- a/uniborg/uniborg.py +++ b/uniborg/uniborg.py @@ -25,8 +25,6 @@ def __init__( self.config = api_config kwargs = { - "api_id": 6, - "api_hash": "eb06d4abfb49dc3eeb1aeb98ae0f581e", "device_model": "GNU/Linux nonUI", "app_version": "@UniBorg 2.0", "lang_code": "ml", From b69ff7cb4d7ab3aa75e5ea207568726d0bdbc0e3 Mon Sep 17 00:00:00 2001 From: Shrimadhav U K Date: Sun, 12 Jul 2020 20:20:55 +0530 Subject: [PATCH 014/181] tests --- stdborg.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stdborg.py b/stdborg.py index 80e4fadee4..7e27b74aa9 100644 --- a/stdborg.py +++ b/stdborg.py @@ -45,8 +45,9 @@ engine=Config.DB_URI, session=session_id ) + session = container.new_session(session_id) borg = Uniborg( - container, + session, n_plugin_path="stdplugins/", db_plugin_path="dbplugins/", api_config=Config, From 335607861532c1fd056264a2978a971beff6b3d2 Mon Sep 17 00:00:00 2001 From: Shrimadhav U K Date: Sun, 12 Jul 2020 20:28:52 +0530 Subject: [PATCH 015/181] tests: https://t.me/c/1279877202/3378 --- stdborg.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/stdborg.py b/stdborg.py index 7e27b74aa9..ac62dc9db8 100644 --- a/stdborg.py +++ b/stdborg.py @@ -42,8 +42,7 @@ # for Running on Heroku session_id = str(Config.HU_STRING_SESSION) container = AlchemySessionContainer( - engine=Config.DB_URI, - session=session_id + engine=Config.DB_URI ) session = container.new_session(session_id) borg = Uniborg( From 61e7d5ac1fb073fbcaf4a35dfcf610614140c618 Mon Sep 17 00:00:00 2001 From: Shrimadhav U K Date: Sun, 12 Jul 2020 20:43:13 +0530 Subject: [PATCH 016/181] add some LOGgers --- uniborg/uniborg.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/uniborg/uniborg.py b/uniborg/uniborg.py index 55aa6fb275..95f78a90e4 100644 --- a/uniborg/uniborg.py +++ b/uniborg/uniborg.py @@ -15,8 +15,15 @@ class Uniborg(TelegramClient): def __init__( - self, session, *, n_plugin_path="plugins", db_plugin_path="plugins", - bot_token=None, api_config=None, **kwargs): + self, + session, + *, + n_plugin_path="plugins", + db_plugin_path="plugins", + bot_token=None, + api_config=None, + **kwargs + ): self._name = "LoggedIn" self._logger = logging.getLogger("UniBorg") self._plugins = {} @@ -81,7 +88,10 @@ async def _async_init(self, **kwargs): self.me = await self.get_me() self.uid = telethon.utils.get_peer_id(self.me) - self._logger.info(f"Logged in as {self.uid}") + self._logger.info( + f"Logged in as {self.uid} " + f"Try {self.config.COMMAND_HAND_LER}helpme in any chat..!" + ) def load_plugin(self, shortname): From 1ceb804c3c038033e1faf699c338cf5f8467b68e Mon Sep 17 00:00:00 2001 From: Shrimadhav U K Date: Mon, 13 Jul 2020 19:24:09 +0530 Subject: [PATCH 017/181] fix is_admin condition check --- uniborg/util.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/uniborg/util.py b/uniborg/util.py index 2d908452e1..08e5609d17 100644 --- a/uniborg/util.py +++ b/uniborg/util.py @@ -148,6 +148,8 @@ def time_formatter(milliseconds: int) -> str: async def is_admin(client, chat_id, user_id): + if not str(chat_id).startswith("-100"): + return False req_jo = await client(GetParticipantRequest( channel=chat_id, user_id=user_id From cbffa61f0aa148f35a076fa2cb17f10cbaaf0cbc Mon Sep 17 00:00:00 2001 From: Shrimadhav U K Date: Mon, 13 Jul 2020 19:33:33 +0530 Subject: [PATCH 018/181] =?UTF-8?q?temporary=20removing.=20=E2=9C=8C?= =?UTF-8?q?=EF=B8=8F=20will=20be=20re-stored,=20soon=20=E2=84=A2=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dbplugins/antiflood.py | 71 ------ dbplugins/blacklist.py | 79 ------- dbplugins/filters.py | 106 --------- dbplugins/locks.py | 262 --------------------- dbplugins/lydia_ai_chat_bot.py | 126 ---------- dbplugins/notification_mtab_manager.py | 310 ------------------------- dbplugins/snip.py | 83 ------- dbplugins/warns.py | 88 ------- dbplugins/welcome.py | 74 ------ uniborg/uniborg.py | 2 +- 10 files changed, 1 insertion(+), 1200 deletions(-) delete mode 100644 dbplugins/antiflood.py delete mode 100644 dbplugins/blacklist.py delete mode 100644 dbplugins/filters.py delete mode 100644 dbplugins/locks.py delete mode 100644 dbplugins/lydia_ai_chat_bot.py delete mode 100644 dbplugins/notification_mtab_manager.py delete mode 100644 dbplugins/snip.py delete mode 100644 dbplugins/warns.py delete mode 100644 dbplugins/welcome.py diff --git a/dbplugins/antiflood.py b/dbplugins/antiflood.py deleted file mode 100644 index 4b727ec5b6..0000000000 --- a/dbplugins/antiflood.py +++ /dev/null @@ -1,71 +0,0 @@ -import asyncio -from telethon import events -from telethon.tl.functions.channels import EditBannedRequest -from telethon.tl.types import ChatBannedRights -from uniborg.util import admin_cmd, is_admin -import sql_helpers.antiflood_sql as sql - - -CHAT_FLOOD = sql.__load_flood_settings() -# warn mode for anti flood -ANTI_FLOOD_WARN_MODE = ChatBannedRights( - until_date=None, - view_messages=None, - send_messages=True -) - - -@borg.on(admin_cmd(incoming=True)) -async def _(event): - # logger.info(CHAT_FLOOD) - if not CHAT_FLOOD: - return - admin_c = await is_admin(event.client, event.chat_id, event.message.from_id) - if admin_c: - return - if not (str(event.chat_id) in CHAT_FLOOD): - return - should_ban = sql.update_flood(event.chat_id, event.message.from_id) - if not should_ban: - return - try: - await event.client(EditBannedRequest( - event.chat_id, - event.message.from_id, - ANTI_FLOOD_WARN_MODE - )) - except Exception as e: # pylint:disable=C0103,W0703 - no_admin_privilege_message = await event.client.send_message( - entity=event.chat_id, - message="""**Automatic AntiFlooder** -@admin [User](tg://user?id={}) is flooding this chat. - -`{}`""".format(event.message.from_id, str(e)), - reply_to=event.message.id - ) - await asyncio.sleep(10) - await no_admin_privilege_message.edit( - "https://t.me/keralagram/724970", - link_preview=False - ) - else: - await event.client.send_message( - entity=event.chat_id, - message="""**Automatic AntiFlooder** -[User](tg://user?id={}) has been automatically restricted -because he reached the defined flood limit.""".format(event.message.from_id), - reply_to=event.message.id - ) - - -@borg.on(admin_cmd(pattern="setflood (.*)")) -async def _(event): - if event.fwd_from: - return - input_str = event.pattern_match.group(1) - try: - sql.set_flood(event.chat_id, input_str) - CHAT_FLOOD = sql.__load_flood_settings() - await event.edit("Antiflood updated to {} in the current chat".format(input_str)) - except Exception as e: # pylint:disable=C0103,W0703 - await event.edit(str(e)) diff --git a/dbplugins/blacklist.py b/dbplugins/blacklist.py deleted file mode 100644 index 3b755ec4dd..0000000000 --- a/dbplugins/blacklist.py +++ /dev/null @@ -1,79 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -"""Filters -Available Commands: -.addblacklist -.listblacklist -.rmblacklist""" -import asyncio -import io -import re -import sql_helpers.blacklist_sql as sql -from telethon import events, utils -from telethon.tl import types, functions -from uniborg.util import admin_cmd, is_admin - - -@borg.on(admin_cmd(incoming=True)) -async def on_new_message(event): - if await is_admin(event.client, event.chat_id, event.from_id): - return - if borg.me.id == event.from_id: - return - name = event.raw_text - snips = sql.get_chat_blacklist(event.chat_id) - for snip in snips: - pattern = r"( |^|[^\w])" + re.escape(snip) + r"( |$|[^\w])" - if re.search(pattern, name, flags=re.IGNORECASE): - try: - await event.delete() - except Exception as e: - await event.reply("I do not have DELETE permission in this chat") - sql.rm_from_blacklist(event.chat_id, snip.lower()) - break - - -@borg.on(admin_cmd(pattern="addblacklist ((.|\n)*)")) -async def on_add_black_list(event): - text = event.pattern_match.group(1) - to_blacklist = list(set(trigger.strip() for trigger in text.split("\n") if trigger.strip())) - for trigger in to_blacklist: - sql.add_to_blacklist(event.chat_id, trigger.lower()) - await event.edit("Added {} triggers to the blacklist in the current chat".format(len(to_blacklist))) - - -@borg.on(admin_cmd(pattern="listblacklist")) -async def on_view_blacklist(event): - all_blacklisted = sql.get_chat_blacklist(event.chat_id) - OUT_STR = "Blacklists in the Current Chat:\n" - if len(all_blacklisted) > 0: - for trigger in all_blacklisted: - OUT_STR += f"👉 {trigger} \n" - else: - OUT_STR = "No BlackLists. Start Saving using `.addblacklist`" - if len(OUT_STR) > Config.MAX_MESSAGE_SIZE_LIMIT: - with io.BytesIO(str.encode(OUT_STR)) as out_file: - out_file.name = "blacklist.text" - await event.client.send_file( - event.chat_id, - out_file, - force_document=True, - allow_cache=False, - caption="BlackLists in the Current Chat", - reply_to=event - ) - await event.delete() - else: - await event.edit(OUT_STR) - - -@borg.on(admin_cmd(pattern="rmblacklist ((.|\n)*)")) -async def on_delete_blacklist(event): - text = event.pattern_match.group(1) - to_unblacklist = list(set(trigger.strip() for trigger in text.split("\n") if trigger.strip())) - successful = 0 - for trigger in to_unblacklist: - if sql.rm_from_blacklist(event.chat_id, trigger.lower()): - successful += 1 - await event.edit(f"Removed {successful} / {len(to_unblacklist)} from the blacklist") diff --git a/dbplugins/filters.py b/dbplugins/filters.py deleted file mode 100644 index 0032f295cf..0000000000 --- a/dbplugins/filters.py +++ /dev/null @@ -1,106 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -"""Filters -Available Commands: -.savefilter -.listfilters -.clearfilter""" -import asyncio -import re -from telethon import events, utils -from telethon.tl import types -from sql_helpers.filters_sql import get_filter, add_filter, remove_filter, get_all_filters, remove_all_filters -from uniborg.util import admin_cmd - - -DELETE_TIMEOUT = 300 -last_triggered_filters = {} - - -@borg.on(admin_cmd(incoming=True)) -async def on_snip(event): - name = event.raw_text - if event.chat_id in last_triggered_filters: - if name in last_triggered_filters[event.chat_id]: - # avoid userbot spam - # "I demand rights for us bots, we are equal to you humans." -Henri Koivuneva (t.me/UserbotTesting/2698) - return False - snips = get_all_filters(event.chat_id) - if snips: - for snip in snips: - pattern = r"( |^|[^\w])" + re.escape(snip.keyword) + r"( |$|[^\w])" - if re.search(pattern, name, flags=re.IGNORECASE): - msg_o = await event.client.get_messages( - entity=Config.PRIVATE_CHANNEL_BOT_API_ID, - ids=int(snip.f_mesg_id) - ) - message_id = event.message.id - if event.reply_to_msg_id: - message_id = event.reply_to_msg_id - await event.client.send_message( - event.chat_id, - msg_o.message, - reply_to=message_id, - file=msg_o.media - ) - if event.chat_id not in last_triggered_filters: - last_triggered_filters[event.chat_id] = [] - last_triggered_filters[event.chat_id].append(name) - await asyncio.sleep(DELETE_TIMEOUT) - last_triggered_filters[event.chat_id].remove(name) - - -@borg.on(admin_cmd(pattern="savefilter (.*)")) -async def on_snip_save(event): - name = event.pattern_match.group(1) - msg = await event.get_reply_message() - if msg: - msg_o = await event.client.forward_messages( - entity=Config.PRIVATE_CHANNEL_BOT_API_ID, - messages=msg, - from_peer=event.chat_id, - silent=True - ) - add_filter(event.chat_id, name, msg_o.id) - await event.edit(f"filter {name} saved successfully. Get it with {name}") - else: - await event.edit("Reply to a message with `savefilter keyword` to save the filter") - - -@borg.on(admin_cmd(pattern="listfilters")) -async def on_snip_list(event): - all_snips = get_all_filters(event.chat_id) - OUT_STR = "Available Filters in the Current Chat:\n" - if len(all_snips) > 0: - for a_snip in all_snips: - OUT_STR += f"👉 {a_snip.keyword} \n" - else: - OUT_STR = "No Filters. Start Saving using `.savefilter`" - if len(OUT_STR) > Config.MAX_MESSAGE_SIZE_LIMIT: - with io.BytesIO(str.encode(OUT_STR)) as out_file: - out_file.name = "filters.text" - await event.client.send_file( - event.chat_id, - out_file, - force_document=True, - allow_cache=False, - caption="Available Filters in the Current Chat", - reply_to=event - ) - await event.delete() - else: - await event.edit(OUT_STR) - - -@borg.on(admin_cmd(pattern="clearfilter (.*)")) -async def on_snip_delete(event): - name = event.pattern_match.group(1) - remove_filter(event.chat_id, name) - await event.edit(f"filter {name} deleted successfully") - - -@borg.on(admin_cmd(pattern="clearallfilters")) -async def on_all_snip_delete(event): - remove_all_filters(event.chat_id) - await event.edit(f"filters **in current chat** deleted successfully") diff --git a/dbplugins/locks.py b/dbplugins/locks.py deleted file mode 100644 index 95c8941fd1..0000000000 --- a/dbplugins/locks.py +++ /dev/null @@ -1,262 +0,0 @@ -"""Default Permission in Telegram 5.0.1 -Available Commands: .lock