diff --git a/.gitignore b/.gitignore index 4875859..9b9d0a4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -# Byte-compiled / optimized / DLL file +# Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class @@ -114,4 +114,4 @@ dmypy.json .pyre/ #session files -*.session +*.session \ No newline at end of file diff --git a/.replit b/.replit new file mode 100644 index 0000000..75cf641 --- /dev/null +++ b/.replit @@ -0,0 +1,2 @@ +language = "bash" +run = "pip3 install -r requirements.txt; python3 -m WebStreamer" \ No newline at end of file diff --git a/Procfile b/Procfile index 034b858..9a79e65 100644 --- a/Procfile +++ b/Procfile @@ -1 +1 @@ -web: python -m WebStreamer +web: python -m WebStreamer \ No newline at end of file diff --git a/WebStreamer/__init__.py b/WebStreamer/__init__.py index 2c34819..ff0636f 100644 --- a/WebStreamer/__init__.py +++ b/WebStreamer/__init__.py @@ -1,5 +1 @@ - -# Maintained By : Avishkar Patil [ @Avishkarpatil ] [ Telegram ] - -import time -StartTime = time.time() +# This file is a part of avipatilpro/FileStreamBot diff --git a/WebStreamer/__main__.py b/WebStreamer/__main__.py index 88c7e1e..b6192a8 100644 --- a/WebStreamer/__main__.py +++ b/WebStreamer/__main__.py @@ -1,3 +1,4 @@ + import os import sys import glob @@ -11,14 +12,6 @@ from .vars import Var from aiohttp import web from .server import web_server from .utils.keepalive import ping_server -from apscheduler.schedulers.background import BackgroundScheduler - -logging.basicConfig( - level=logging.INFO, - format="%(asctime)s - %(name)s - %(levelname)s - %(message)s" -) -logging.getLogger("pyrogram").setLevel(logging.WARNING) -logging.getLogger("apscheduler").setLevel(logging.WARNING) ppath = "WebStreamer/bot/plugins/*.py" files = glob.glob(ppath) @@ -30,9 +23,10 @@ async def start_services(): print('\n') print('------------------- Initalizing Telegram Bot -------------------') await StreamBot.start() - print('----------------------------- DONE -----------------------------') print('\n') - print('--------------------------- Importing ---------------------------') + print('---------------------- DONE ----------------------') + print('\n') + print('------------------- Importing -------------------') for name in files: with open(name) as a: patt = Path(a.name) @@ -44,24 +38,22 @@ async def start_services(): spec.loader.exec_module(load) sys.modules["WebStreamer.bot.plugins." + plugin_name] = load print("Imported => " + plugin_name) - if Var.ON_HEROKU: - print('------------------ Starting Keep Alive Service ------------------') - print('\n') - scheduler = BackgroundScheduler() - scheduler.add_job(ping_server, "interval", seconds=1200) - scheduler.start() - print('-------------------- Initalizing Web Server --------------------') + print('\n') + print('------------------- Initalizing Web Server -------------------') app = web.AppRunner(await web_server()) await app.setup() bind_address = "0.0.0.0" if Var.ON_HEROKU else Var.FQDN await web.TCPSite(app, bind_address, Var.PORT).start() - print('----------------------------- DONE -----------------------------') print('\n') print('----------------------- Service Started -----------------------') print(' bot =>> {}'.format((await StreamBot.get_me()).first_name)) print(' server ip =>> {}:{}'.format(bind_address, Var.PORT)) if Var.ON_HEROKU: print(' app runnng on =>> {}'.format(Var.FQDN)) + if Var.ON_HEROKU: + print('------------------ Starting Keep Alive Service ------------------') + print('\n') + await asyncio.create_task(ping_server()) print('---------------------------------------------------------------') await idle() @@ -69,4 +61,4 @@ if __name__ == '__main__': try: loop.run_until_complete(start_services()) except KeyboardInterrupt: - logging.info('----------------------- Service Stopped -----------------------') + print('----------------------- Service Stopped -----------------------') diff --git a/WebStreamer/bot/__init__.py b/WebStreamer/bot/__init__.py index 4cf9cbd..dd02cd1 100644 --- a/WebStreamer/bot/__init__.py +++ b/WebStreamer/bot/__init__.py @@ -1,5 +1,3 @@ -# This file is a part of TG-FileStreamBot -# Coding : Jyothis Jayanth [@EverythingSuckz] from pyrogram import Client from ..vars import Var @@ -11,4 +9,4 @@ StreamBot = Client( bot_token=Var.BOT_TOKEN, sleep_threshold=Var.SLEEP_THRESHOLD, workers=Var.WORKERS -) \ No newline at end of file +) diff --git a/WebStreamer/bot/plugins/admin.py b/WebStreamer/bot/plugins/admin.py index 850dfbe..15dbbe1 100644 --- a/WebStreamer/bot/plugins/admin.py +++ b/WebStreamer/bot/plugins/admin.py @@ -1,4 +1,4 @@ -# (c) @Avishkarpatil | @AbirHasan2005 +# (c) @Avishkarpatil import os import time diff --git a/WebStreamer/bot/plugins/start.py b/WebStreamer/bot/plugins/start.py index 3412186..bfbe2bc 100644 --- a/WebStreamer/bot/plugins/start.py +++ b/WebStreamer/bot/plugins/start.py @@ -1,5 +1,4 @@ -# © @AvishkarPatil [ Telegram ] - +import urllib.parse from WebStreamer.bot import StreamBot from WebStreamer.vars import Var from WebStreamer.utils.human_readable import humanbytes @@ -7,6 +6,7 @@ from WebStreamer.utils.database import Database from pyrogram import filters from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton from pyrogram.errors import UserNotParticipant + db = Database(Var.DATABASE_URL, Var.SESSION_NAME) START_TEXT = """ @@ -79,6 +79,21 @@ async def cb_data(bot, update): else: await update.message.delete() +def get_media_file_size(m): + media = m.video or m.audio or m.document + if media and media.file_size: + return media.file_size + else: + return None + + +def get_media_file_name(m): + media = m.video or m.document or m.audio + if media and media.file_name: + return urllib.parse.quote_plus(media.file_name) + else: + return None + @StreamBot.on_message(filters.command('start') & filters.private & ~filters.edited) async def start(b, m): @@ -146,8 +161,10 @@ async def start(b, m): text="**Pʟᴇᴀsᴇ Jᴏɪɴ Mʏ Uᴘᴅᴀᴛᴇs Cʜᴀɴɴᴇʟ ᴛᴏ ᴜsᴇ ᴛʜɪs Bᴏᴛ**!\n\n**Dᴜᴇ ᴛᴏ Oᴠᴇʀʟᴏᴀᴅ, Oɴʟʏ Cʜᴀɴɴᴇʟ Sᴜʙsᴄʀɪʙᴇʀs ᴄᴀɴ ᴜsᴇ ᴛʜᴇ Bᴏᴛ**!", reply_markup=InlineKeyboardMarkup( [[ - InlineKeyboardButton("🤖 Jᴏɪɴ Uᴘᴅᴀᴛᴇs Cʜᴀɴɴᴇʟ", url=f"https://t.me/{Var.UPDATES_CHANNEL}") - ]] + InlineKeyboardButton("🤖 Jᴏɪɴ Uᴘᴅᴀᴛᴇs Cʜᴀɴɴᴇʟ", url=f"https://t.me/{Var.UPDATES_CHANNEL}")], + [InlineKeyboardButton("🔄 Refresh / Try Again", url=f"https://t.me/{(await b.get_me()).username}?start=AvishkarPatil_{usr_cmd}") + + ]] ), parse_mode="markdown" ) @@ -161,27 +178,14 @@ async def start(b, m): return get_msg = await b.get_messages(chat_id=Var.BIN_CHANNEL, message_ids=int(usr_cmd)) + file_name = get_media_file_name(get_msg) + file_size = humanbytes(get_media_file_size(get_msg)) - file_size = None - if get_msg.video: - file_size = f"{humanbytes(get_msg.video.file_size)}" - elif get_msg.document: - file_size = f"{humanbytes(get_msg.document.file_size)}" - elif get_msg.audio: - file_size = f"{humanbytes(get_msg.audio.file_size)}" - - file_name = None - if get_msg.video: - file_name = f"{get_msg.video.file_name}" - elif get_msg.document: - file_name = f"{get_msg.document.file_name}" - elif get_msg.audio: - file_name = f"{get_msg.audio.file_name}" - - stream_link = "https://{}/{}".format(Var.FQDN, get_msg.message_id) if Var.ON_HEROKU or Var.NO_PORT else \ - "http://{}:{}/{}".format(Var.FQDN, + stream_link = "https://{}/{}/{}".format(Var.FQDN, get_msg.message_id, file_name) if Var.ON_HEROKU or Var.NO_PORT else \ + "http://{}:{}/{}/{}".format(Var.FQDN, Var.PORT, - get_msg.message_id) + get_msg.message_id, + file_name) msg_text =""" 𝗬𝗼𝘂𝗿 𝗟𝗶𝗻𝗸 𝗚𝗲𝗻𝗲𝗿𝗮𝘁𝗲𝗱 !\n @@ -199,6 +203,7 @@ async def start(b, m): ) + @StreamBot.on_message(filters.private & filters.command(["about"])) async def start(bot, update): await update.reply_text( @@ -252,3 +257,4 @@ async def help_handler(bot, message): disable_web_page_preview=True, reply_markup=HELP_BUTTONS ) + diff --git a/WebStreamer/bot/plugins/stream.py b/WebStreamer/bot/plugins/stream.py index 9dc31a4..cd46dd1 100644 --- a/WebStreamer/bot/plugins/stream.py +++ b/WebStreamer/bot/plugins/stream.py @@ -1,7 +1,9 @@ # (c) @Avishkarpatil + import asyncio +import urllib.parse from WebStreamer.bot import StreamBot from WebStreamer.utils.database import Database from WebStreamer.utils.human_readable import humanbytes @@ -12,6 +14,22 @@ from pyrogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton db = Database(Var.DATABASE_URL, Var.SESSION_NAME) +def get_media_file_size(m): + media = m.video or m.audio or m.document + if media and media.file_size: + return media.file_size + else: + return None + + +def get_media_file_name(m): + media = m.video or m.document or m.audio + if media and media.file_name: + return urllib.parse.quote_plus(media.file_name) + else: + return None + + @StreamBot.on_message(filters.private & (filters.document | filters.video | filters.audio) & ~filters.edited, group=4) async def private_receive_handler(c: Client, m: Message): if not await db.is_user_exist(m.from_user.id): @@ -50,25 +68,13 @@ async def private_receive_handler(c: Client, m: Message): return try: log_msg = await m.forward(chat_id=Var.BIN_CHANNEL) - stream_link = "https://{}/{}".format(Var.FQDN, log_msg.message_id) if Var.ON_HEROKU or Var.NO_PORT else \ - "http://{}:{}/{}".format(Var.FQDN, + file_name = get_media_file_name(m) + file_size = humanbytes(get_media_file_size(m)) + stream_link = "https://{}/{}/{}".format(Var.FQDN, log_msg.message_id, file_name) if Var.ON_HEROKU or Var.NO_PORT else \ + "http://{}:{}/{}/{}".format(Var.FQDN, Var.PORT, - log_msg.message_id) - file_size = None - if m.video: - file_size = f"{humanbytes(m.video.file_size)}" - elif m.document: - file_size = f"{humanbytes(m.document.file_size)}" - elif m.audio: - file_size = f"{humanbytes(m.audio.file_size)}" - - file_name = None - if m.video: - file_name = f"{m.video.file_name}" - elif m.document: - file_name = f"{m.document.file_name}" - elif m.audio: - file_name = f"{m.audio.file_name}" + log_msg.message_id, + file_name) msg_text =""" 𝗬𝗼𝘂𝗿 𝗟𝗶𝗻𝗸 𝗚𝗲𝗻𝗲𝗿𝗮𝘁𝗲𝗱 !\n @@ -104,7 +110,7 @@ async def channel_receive_handler(bot, broadcast): Var.PORT, log_msg.message_id) await log_msg.reply_text( - text=f"**Cʜᴀɴɴᴇʟ Nᴀᴍᴇ:** `{broadcast.chat.title}`\n**Cʜᴀɴɴᴇʟ ID:** `{broadcast.chat.id}`\n**Rᴇǫᴜᴇsᴛ ᴜʀʟ:** {stream_link}", + text=f"**Cʜᴀɴɴᴇʟ Nᴀᴍᴇ:** `{broadcast.chat.title}`\n**Cʜᴀɴɴᴇʟ ID:** `{broadcast.chat.id}`\n**Rᴇǫᴜᴇsᴛ ᴜʀʟ:** https://t.me/{(await bot.get_me()).username}?start=AvishkarPatil_{str(log_msg.message_id)}", # text=f"**Cʜᴀɴɴᴇʟ Nᴀᴍᴇ:** `{broadcast.chat.title}`\n**Cʜᴀɴɴᴇʟ ID:** `{broadcast.chat.id}`\n**Rᴇǫᴜᴇsᴛ ᴜʀʟ:** https://t.me/FxStreamBot?start=AvishkarPatil_{str(log_msg.message_id)}", quote=True, parse_mode="Markdown" @@ -113,7 +119,7 @@ async def channel_receive_handler(bot, broadcast): chat_id=broadcast.chat.id, message_id=broadcast.message_id, reply_markup=InlineKeyboardMarkup( - [[InlineKeyboardButton("Dᴏᴡɴʟᴏᴀᴅ ʟɪɴᴋ 📥", url=stream_link)]]) + [[InlineKeyboardButton("Dᴏᴡɴʟᴏᴀᴅ ʟɪɴᴋ 📥", url=f"https://t.me/{(await bot.get_me()).username}?start=AvishkarPatil_{str(log_msg.message_id)}")]]) # [[InlineKeyboardButton("Dᴏᴡɴʟᴏᴀᴅ ʟɪɴᴋ 📥", url=f"https://t.me/FxStreamBot?start=AvishkarPatil_{str(log_msg.message_id)}")]]) ) except FloodWait as w: diff --git a/WebStreamer/server/__init__.py b/WebStreamer/server/__init__.py index d3bcb0b..a344be9 100644 --- a/WebStreamer/server/__init__.py +++ b/WebStreamer/server/__init__.py @@ -1,5 +1,3 @@ -# © Avishkar Patil [ @AvishkarPatil ] [ Telegram ] -# Coding : Jyothis Jayanth [@EverythingSuckz] from aiohttp import web from .stream_routes import routes diff --git a/WebStreamer/server/stream_routes.py b/WebStreamer/server/stream_routes.py index f67b902..e3a4638 100644 --- a/WebStreamer/server/stream_routes.py +++ b/WebStreamer/server/stream_routes.py @@ -1,4 +1,5 @@ -import time +# Avishkar Patil | AbirHasan2005 + import math import logging import secrets @@ -6,21 +7,23 @@ import mimetypes from ..vars import Var from aiohttp import web from ..bot import StreamBot -from WebStreamer import StartTime from ..utils.custom_dl import TGCustomYield, chunk_size, offset_fix -from ..utils.time_format import get_readable_time + routes = web.RouteTableDef() @routes.get("/", allow_head=True) async def root_route_handler(request): + bot_details = await StreamBot.get_me() return web.json_response({"status": "running", "maintained_by": "Avishkar_Patil", - "uptime": get_readable_time(time.time() - StartTime), - "telegram_bot": '@'+(await StreamBot.get_me()).username}) + "server_permission": "Open", + "Telegram_Bot": '@'+bot_details.username}) @routes.get("/{message_id}") +@routes.get("/{message_id}/") +@routes.get(r"/{message_id:\d+}/{name}") async def stream_handler(request): try: message_id = int(request.match_info['message_id']) diff --git a/WebStreamer/utils/__init__.py b/WebStreamer/utils/__init__.py index 99cd8d0..ff0636f 100644 --- a/WebStreamer/utils/__init__.py +++ b/WebStreamer/utils/__init__.py @@ -1,3 +1 @@ -# This file is a part of TG-FileStreamBot -# Coding : Jyothis Jayanth [@EverythingSuckz] -# Maintained By : Avishkar Patil [ @AvishkarPatil ] [ Telegram ] +# This file is a part of avipatilpro/FileStreamBot diff --git a/WebStreamer/utils/broadcast_helper.py b/WebStreamer/utils/broadcast_helper.py index fe2de17..b629741 100644 --- a/WebStreamer/utils/broadcast_helper.py +++ b/WebStreamer/utils/broadcast_helper.py @@ -1,4 +1,3 @@ -# (c) @AbirHasan2005 import asyncio import traceback @@ -19,4 +18,4 @@ async def send_msg(user_id, message): except PeerIdInvalid: return 400, f"{user_id} : user id invalid\n" except Exception as e: - return 500, f"{user_id} : {traceback.format_exc()}\n" \ No newline at end of file + return 500, f"{user_id} : {traceback.format_exc()}\n" diff --git a/WebStreamer/utils/custom_dl.py b/WebStreamer/utils/custom_dl.py index 8bfe050..1270d5b 100644 --- a/WebStreamer/utils/custom_dl.py +++ b/WebStreamer/utils/custom_dl.py @@ -1,5 +1,3 @@ -# Taken from megadlbot_oss -# Thanks to Eyaadh import math from typing import Union @@ -230,4 +228,4 @@ class TGCustomYield: ) ) - return m_file \ No newline at end of file + return m_file diff --git a/WebStreamer/utils/database.py b/WebStreamer/utils/database.py index ed35369..cf72f8d 100644 --- a/WebStreamer/utils/database.py +++ b/WebStreamer/utils/database.py @@ -1,4 +1,4 @@ -# (c) @AbirHasan2005 + import datetime import motor.motor_asyncio diff --git a/WebStreamer/utils/human_readable.py b/WebStreamer/utils/human_readable.py index 10bec75..c7f2fdb 100644 --- a/WebStreamer/utils/human_readable.py +++ b/WebStreamer/utils/human_readable.py @@ -1,5 +1,3 @@ -# (c) @AbirHasan2005 - def humanbytes(size): # https://stackoverflow.com/a/49361727/4723940 @@ -12,4 +10,4 @@ def humanbytes(size): while size > power: size /= power n += 1 - return str(round(size, 2)) + " " + Dic_powerN[n] + 'B' \ No newline at end of file + return str(round(size, 2)) + " " + Dic_powerN[n] + 'B' diff --git a/WebStreamer/utils/keepalive.py b/WebStreamer/utils/keepalive.py index 834e4d2..cfbd398 100644 --- a/WebStreamer/utils/keepalive.py +++ b/WebStreamer/utils/keepalive.py @@ -1,11 +1,21 @@ -# Bot Sleeping - +import asyncio import logging -import requests -from ..vars import Var -def ping_server(): - k = requests.get(f'https://ping-pong-sn.herokuapp.com/pingback?link={Var.URL}').json() - if not k.get('error'): - logging.info('KeepAliveService: Pinged {} with status {}'.format(Var.FQDN, k.get('Status'))) - else: - logging.error('Couldn\'t Ping the Server!') +import aiohttp +import traceback +from WebStreamer.vars import Var + +URL = f"https://{Var.FQDN}" + + +async def ping_server(): + sleep_time = Var.PING_INTERVAL + while True: + await asyncio.sleep(sleep_time) + try: + async with aiohttp.ClientSession(timeout=aiohttp.ClientTimeout(total=10)) as session: + async with session.get(Var.URL) as resp: + logging.info("Pinged server with response: {}".format(resp.status)) + except TimeoutError: + logging.warning("Couldn't connect to the site URL..!") + except Exception: + traceback.print_exc() diff --git a/WebStreamer/utils/time_format.py b/WebStreamer/utils/time_format.py deleted file mode 100644 index 0bd7790..0000000 --- a/WebStreamer/utils/time_format.py +++ /dev/null @@ -1,24 +0,0 @@ -# Bot Uptime - -def get_readable_time(seconds: int) -> str: - count = 0 - readable_time = "" - time_list = [] - time_suffix_list = ["s", "m", "h", " days"] - while count < 4: - count += 1 - if count < 3: - remainder, result = divmod(seconds, 60) - else: - remainder, result = divmod(seconds, 24) - if seconds == 0 and remainder == 0: - break - time_list.append(int(result)) - seconds = int(remainder) - for x in range(len(time_list)): - time_list[x] = str(time_list[x]) + time_suffix_list[x] - if len(time_list) == 4: - readable_time += time_list.pop() + ", " - time_list.reverse() - readable_time += ": ".join(time_list) - return readable_time diff --git a/WebStreamer/vars.py b/WebStreamer/vars.py index 1e01694..cdfe54a 100644 --- a/WebStreamer/vars.py +++ b/WebStreamer/vars.py @@ -10,13 +10,13 @@ class Var(object): API_ID = int(getenv('API_ID')) API_HASH = str(getenv('API_HASH')) BOT_TOKEN = str(getenv('BOT_TOKEN')) - SESSION_NAME = str(getenv('SESSION_NAME', 'F2LxBot')) + SESSION_NAME = str(getenv('SESSION_NAME', 'AviStreamBot')) SLEEP_THRESHOLD = int(getenv('SLEEP_THRESHOLD', '60')) WORKERS = int(getenv('WORKERS', '4')) BIN_CHANNEL = int(getenv('BIN_CHANNEL')) PORT = int(getenv('PORT', 8080)) BIND_ADRESS = str(getenv('WEB_SERVER_BIND_ADDRESS', '0.0.0.0')) - OWNER_ID = int(getenv('OWNER_ID', '1445283714')) + OWNER_ID = int(getenv('OWNER_ID', '797848243')) NO_PORT = bool(getenv('NO_PORT', False)) APP_NAME = None if 'DYNO' in environ: @@ -29,4 +29,4 @@ class Var(object): "http://{}:{}/".format(FQDN, PORT) DATABASE_URL = str(getenv('DATABASE_URL')) UPDATES_CHANNEL = str(getenv('UPDATES_CHANNEL', None)) - BANNED_CHANNELS = list(set(int(x) for x in str(getenv("BANNED_CHANNELS", "-1001362659779")).split())) + BANNED_CHANNELS = list(set(int(x) for x in str(getenv("BANNED_CHANNELS", "-1001296894100")).split())) \ No newline at end of file diff --git a/app.json b/app.json index 4a3286e..bc0e32d 100644 --- a/app.json +++ b/app.json @@ -15,7 +15,7 @@ "repository": "https://github.com/avipatilpro/FileStreamBot/", "success_url": "/", "logo": "https://i.ibb.co/ZJzJ9Hq/link-3x.png", - "website": "avipatilweb.me", + "website": "avipatilweb.ml", "env": { "ENV": { "description": "Set this to True if you don't want to crash the bot", diff --git a/requirements.txt b/requirements.txt index b54c967..946e976 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,6 +4,4 @@ aiohttp python-dotenv motor aiofiles -dnspython -apscheduler -requests +dnspython \ No newline at end of file