From c4dd7f6b7e189d2120a3b923c8d4d89e9786e9a4 Mon Sep 17 00:00:00 2001 From: AbirHasan2005 Date: Tue, 20 Apr 2021 15:14:57 +0600 Subject: [PATCH] New Update & Features! --- README.md | 45 +++--- WebStreamer/__main__.py | 2 +- WebStreamer/bot/__init__.py | 2 +- WebStreamer/bot/plugins/admin.py | 89 ++++++++++++ WebStreamer/bot/plugins/start.py | 191 ++++++++++++++++++++++++-- WebStreamer/bot/plugins/stream.py | 126 +++++++++++++++-- WebStreamer/utils/broadcast_helper.py | 22 +++ WebStreamer/utils/database.py | 36 +++++ WebStreamer/utils/human_readable.py | 15 ++ WebStreamer/vars.py | 17 ++- app.json | 25 +++- requirements.txt | 5 +- 12 files changed, 512 insertions(+), 63 deletions(-) create mode 100644 WebStreamer/bot/plugins/admin.py create mode 100644 WebStreamer/utils/broadcast_helper.py create mode 100644 WebStreamer/utils/database.py create mode 100644 WebStreamer/utils/human_readable.py diff --git a/README.md b/README.md index f978842..5032b2c 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,16 @@ -

Telegram File Stream Bot

+

Telegram File Stream Bot

- - Cover Image + + Cover Image

A Telegram bot to stream files to web
- Demo Bot ยป + Demo Bot ยป
- Report a Bug + Report a Bug | - Request Feature + Request Feature

@@ -47,7 +47,7 @@ ## About This Bot

- + Telegram Logo

@@ -65,7 +65,7 @@ Either you could locally host or deploy on [Heroku](https://heroku.com) ### Deploy on Heroku -Press the below button to Fast deply to Heroky +Press the below button to Fast deploy on Heroku [![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy) @@ -74,7 +74,7 @@ then goto the variables tab for more info on setti ### Host it on VPS or Locally ```sh -git clone https://github.com/EverythingSuckz/TG-FileStreamBot +git clone https://github.com/AbirHasan2005/Pyro-FileStreamBot cd TG-FileStreamBot virtualenv -p /usr/bin/python3 venv . ./venv/bin/activate @@ -97,7 +97,9 @@ API_HASH=esx576f8738x883f3sfzx83 BOT_TOKEN=55838383:yourtbottokenhere BIN_CHANNEL=-100 PORT=8080 -FQDN=yourserverip +FQDN=your_server_ip +OWNER_ID=your_user_id +DATABASE_URL=mongodb_uri ``` ### Mandatory Vars @@ -110,9 +112,16 @@ FQDN=yourserverip `BIN_CHANNEL` : Create a new channel (private/public), add [@missrose_bot](https://telegram.dog/MissRose_bot) as admin to the channel and type /id. Now copy paste the ID into this field. +`OWNER_ID` : Your Telegram User ID + +`DATABASE_URL` : MongoDB URI for saving User IDs when they first Start the Bot. We will use that for Broadcasting to them. I will try to add more features related with Database. If you need help to get the URI you can ask in [Support Group](https://t.me/linux_repo). ### Optional Vars +`UPDATES_CHANNEL` : Put a Public Channel Username, so every user have to Join that channel to use the bot. Must add bot to channel as Admin to work properly. + +`BANNED_CHANNELS` : Put IDs of Banned Channels where bot will not work. You can add multiple IDs & separate with Space. + `SLEEP_THRESHOLD` : Set a sleep threshold for flood wait exceptions happening globally in this telegram bot instance, below which any request that raises a flood wait will be automatically invoked again after sleeping for the required amount of time. Flood wait exceptions requiring higher waiting times will be raised. Defaults to 60 seconds. `WORKERS` : Number of maximum concurrent workers for handling incoming updates. Defaults to `3` @@ -127,25 +136,17 @@ FQDN=yourserverip ## How to use the bot -:warning: **Before using the bot, don't forget to add the bot to the `BIN_CHANNEL` as an admin** +:warning: **Before using the bot, don't forget to add the bot to the `BIN_CHANNEL` as an Admin** `/start` : To check if the bot is alive or not. To get an instant stream link, just forward any media to the bot and boom, its fast af. -## Contributing - -Feel free to contribute to this project if you have any further ideas - -## Contact me - -[![Telegram Channel](https://img.shields.io/static/v1?label=Join&message=Telegram%20Channel&color=blueviolet&style=for-the-badge&logo=telegram&logoColor=violet)](https://xn--r1a.click/WhySooSerious) -[![Telegram Group](https://img.shields.io/static/v1?label=Join&message=Telegram%20Group&color=blueviolet&style=for-the-badge&logo=telegram&logoColor=violet)](https://xn--r1a.click/WhyThisUsername) - -You can contact either via my [Telegram Chat](https://xn--r1a.click/WhyThisUsername) or you can PM me on [@EverythingSuckz](https://xn--r1a.click/EverythingSuckz) +### Channel Support +Bot also Supported with Channels. Just add bot Channel as Admin. If any new file comes in Channel it will edit it with **Get Download Link** Button. ## Credits -- Me +- [@EverythingSuckz](https://github.com/EverythingSuckz) & [@AbirHasan2005](https://github.com/AbirHasan2005) - [eyaadh](https://github.com/eyaadh) for his awesome [Megatron Bot](https://github.com/eyaadh/megadlbot_oss) - [Dan Tรจs](https://telegram.dog/haskell) for his [Pyrogram Library](https://github.com/pyrogram/pyrogram) \ No newline at end of file diff --git a/WebStreamer/__main__.py b/WebStreamer/__main__.py index 31830fb..fdff484 100644 --- a/WebStreamer/__main__.py +++ b/WebStreamer/__main__.py @@ -1,5 +1,5 @@ # This file is a part of TG-FileStreamBot -# Coding : Jyothis Jayanth [@EverythingSuckz] +# Coding: @EverythingSuckz & @AbirHasan2005 import os import sys diff --git a/WebStreamer/bot/__init__.py b/WebStreamer/bot/__init__.py index 1d39c78..4cf9cbd 100644 --- a/WebStreamer/bot/__init__.py +++ b/WebStreamer/bot/__init__.py @@ -5,7 +5,7 @@ from pyrogram import Client from ..vars import Var StreamBot = Client( - session_name= 'Web Streamer', + session_name='Web Streamer', api_id=Var.API_ID, api_hash=Var.API_HASH, bot_token=Var.BOT_TOKEN, diff --git a/WebStreamer/bot/plugins/admin.py b/WebStreamer/bot/plugins/admin.py new file mode 100644 index 0000000..5410c37 --- /dev/null +++ b/WebStreamer/bot/plugins/admin.py @@ -0,0 +1,89 @@ +# (c) @AbirHasan2005 + +import os +import time +import string +import random +import asyncio +import aiofiles +import datetime +from WebStreamer.utils.broadcast_helper import send_msg +from WebStreamer.utils.database import Database +from WebStreamer.bot import StreamBot +from WebStreamer.vars import Var +from pyrogram import filters, Client +from pyrogram.types import Message +db = Database(Var.DATABASE_URL, Var.SESSION_NAME) +broadcast_ids = {} + + +@StreamBot.on_message(filters.command("status") & filters.private & filters.user(Var.OWNER_ID) & ~filters.edited) +async def sts(c: Client, m: Message): + total_users = await db.total_users_count() + await m.reply_text(text=f"**Total Users in DB:** `{total_users}`", parse_mode="Markdown", quote=True) + + +@StreamBot.on_message(filters.command("broadcast") & filters.private & filters.user(Var.OWNER_ID) & filters.reply & ~filters.edited) +async def broadcast_(c, m): + all_users = await db.get_all_users() + broadcast_msg = m.reply_to_message + while True: + broadcast_id = ''.join([random.choice(string.ascii_letters) for i in range(3)]) + if not broadcast_ids.get(broadcast_id): + break + out = await m.reply_text( + text=f"Broadcast initiated! You will be notified with log file when all the users are notified." + ) + start_time = time.time() + total_users = await db.total_users_count() + done = 0 + failed = 0 + success = 0 + broadcast_ids[broadcast_id] = dict( + total=total_users, + current=done, + failed=failed, + success=success + ) + async with aiofiles.open('broadcast.txt', 'w') as broadcast_log_file: + async for user in all_users: + sts, msg = await send_msg( + user_id=int(user['id']), + message=broadcast_msg + ) + if msg is not None: + await broadcast_log_file.write(msg) + if sts == 200: + success += 1 + else: + failed += 1 + if sts == 400: + await db.delete_user(user['id']) + done += 1 + if broadcast_ids.get(broadcast_id) is None: + break + else: + broadcast_ids[broadcast_id].update( + dict( + current=done, + failed=failed, + success=success + ) + ) + if broadcast_ids.get(broadcast_id): + broadcast_ids.pop(broadcast_id) + completed_in = datetime.timedelta(seconds=int(time.time() - start_time)) + await asyncio.sleep(3) + await out.delete() + if failed == 0: + await m.reply_text( + text=f"broadcast completed in `{completed_in}`\n\nTotal users {total_users}.\nTotal done {done}, {success} success and {failed} failed.", + quote=True + ) + else: + await m.reply_document( + document='broadcast.txt', + caption=f"broadcast completed in `{completed_in}`\n\nTotal users {total_users}.\nTotal done {done}, {success} success and {failed} failed.", + quote=True + ) + os.remove('broadcast.txt') \ No newline at end of file diff --git a/WebStreamer/bot/plugins/start.py b/WebStreamer/bot/plugins/start.py index a2fc6de..fbcb19d 100644 --- a/WebStreamer/bot/plugins/start.py +++ b/WebStreamer/bot/plugins/start.py @@ -1,21 +1,182 @@ -# This file is a part of TG-FileStreamBot -# Coding : Jyothis Jayanth [@EverythingSuckz] +# (c) @EverythingSuckz | @AbirHasan2005 from WebStreamer.bot import StreamBot from WebStreamer.vars import Var -from pyrogram import filters, emoji +from WebStreamer.utils.human_readable import humanbytes +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) -@StreamBot.on_message(filters.command(['start', 'help'])) + +@StreamBot.on_message(filters.command('start') & filters.private & ~filters.edited) async def start(b, m): - await m.reply('Hi, Send me a file to get an instant stream link.', - reply_markup=InlineKeyboardMarkup( - [ - [ - InlineKeyboardButton( - f'{emoji.STAR} Source {emoji.STAR}', - url='https://github.com/EverythingSuckz/TG-FileStreamBot' - ) - ] - ] - )) \ No newline at end of file + if not await db.is_user_exist(m.from_user.id): + await db.add_user(m.from_user.id) + await b.send_message( + Var.BIN_CHANNEL, + f"#NEW_USER: \n\nNew User [{m.from_user.first_name}](tg://user?id={m.from_user.id}) Started !!" + ) + usr_cmd = m.text.split("_")[-1] + if usr_cmd == "/start": + if Var.UPDATES_CHANNEL is not None: + try: + user = await b.get_chat_member(Var.UPDATES_CHANNEL, m.chat.id) + if user.status == "kicked": + await b.send_message( + chat_id=m.chat.id, + text="Sorry Sir, You are Banned to use me. Contact my [Support Group](https://t.me/linux_repo).", + parse_mode="markdown", + disable_web_page_preview=True + ) + return + except UserNotParticipant: + await b.send_message( + chat_id=m.chat.id, + text="**Please Join My Updates Channel to use this Bot!**\n\nDue to Overload, Only Channel Subscribers can use the Bot!", + reply_markup=InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton("๐Ÿค– Join Updates Channel", url=f"https://t.me/{Var.UPDATES_CHANNEL}") + ] + ] + ), + parse_mode="markdown" + ) + return + except Exception: + await b.send_message( + chat_id=m.chat.id, + text="Something went Wrong. Contact my [Support Group](https://t.me/linux_repo).", + parse_mode="markdown", + disable_web_page_preview=True) + return + await m.reply_text( + text='๐Ÿ™‹ Hey Bruh!!\nI am Instant Telegram File to Link Generator Bot.\n\nSend me any file & see the magic!', + reply_markup=InlineKeyboardMarkup( + [ + [InlineKeyboardButton('Bots Channel', url='https://t.me/Discovery_Updates'), InlineKeyboardButton('Support Group', url='https://t.me/linux_repo')], + [InlineKeyboardButton('Developer', url='https://t.me/AbirHasan2005')] + ] + ), + disable_web_page_preview=True + ) + else: + if Var.UPDATES_CHANNEL is not None: + try: + user = await b.get_chat_member(Var.UPDATES_CHANNEL, m.chat.id) + if user.status == "kicked": + await b.send_message( + chat_id=m.chat.id, + text="Sorry Sir, You are Banned to use me. Contact my [Support Group](https://t.me/linux_repo).", + parse_mode="markdown", + disable_web_page_preview=True + ) + return + except UserNotParticipant: + await b.send_message( + chat_id=m.chat.id, + text="**Please Join My Updates Channel to use this Bot!**\n\nDue to Overload, Only Channel Subscribers can use the Bot!", + reply_markup=InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton("๐Ÿค– Join Updates Channel", url=f"https://t.me/{Var.UPDATES_CHANNEL}") + ], + [ + InlineKeyboardButton("๐Ÿ”„ Refresh / Try Again", + url=f"https://t.me/AH_File2Link_Bot?start=AbirHasan2005_{usr_cmd}") + ] + ] + ), + parse_mode="markdown" + ) + return + except Exception: + await b.send_message( + chat_id=m.chat.id, + text="Something went Wrong. Contact my [Support Group](https://t.me/linux_repo).", + parse_mode="markdown", + disable_web_page_preview=True) + return + + get_msg = await b.get_messages(chat_id=Var.BIN_CHANNEL, message_ids=int(usr_cmd)) + + 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, + Var.PORT, + get_msg.message_id) + + msg_text = "Bruh! ๐Ÿ˜\nYour Link Generated! ๐Ÿค“\n\n๐Ÿ“‚ **File Name:** `{}`\n**File Size:** `{}`\n\n๐Ÿ“ฅ **Download Link:** `{}`" + await m.reply_text( + text=msg_text.format(file_name, file_size, stream_link) + ) + + +@StreamBot.on_message(filters.command('help') & filters.private & ~filters.edited) +async def help_handler(bot, message): + if not await db.is_user_exist(message.from_user.id): + await db.add_user(message.from_user.id) + await bot.send_message( + Var.BIN_CHANNEL, + f"#NEW_USER: \n\nNew User [{message.from_user.first_name}](tg://user?id={message.from_user.id}) Started !!" + ) + if Var.UPDATES_CHANNEL is not None: + try: + user = await bot.get_chat_member(Var.UPDATES_CHANNEL, message.chat.id) + if user.status == "kicked": + await bot.send_message( + chat_id=message.chat.id, + text="Sorry Sir, You are Banned to use me. Contact my [Support Group](https://t.me/linux_repo).", + parse_mode="markdown", + disable_web_page_preview=True + ) + return + except UserNotParticipant: + await bot.send_message( + chat_id=message.chat.id, + text="**Please Join My Updates Channel to use this Bot!**\n\nDue to Overload, Only Channel Subscribers can use the Bot!", + reply_markup=InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton("๐Ÿค– Join Updates Channel", url=f"https://t.me/{Var.UPDATES_CHANNEL}") + ] + ] + ), + parse_mode="markdown" + ) + return + except Exception: + await bot.send_message( + chat_id=message.chat.id, + text="Something went Wrong. Contact my [Support Group](https://t.me/linux_repo).", + parse_mode="markdown", + disable_web_page_preview=True) + return + await message.reply_text( + text="Send me any File I will provide External Direct Download Link!\n\nAlso I am Supported in Channels. Add me to Channel as Admin to Make Me Workable!", + parse_mode="Markdown", + disable_web_page_preview=True, + reply_markup=InlineKeyboardMarkup( + [ + [InlineKeyboardButton("Support Group", url="https://t.me/linux_repo"), InlineKeyboardButton("Bots Channel", url="https://t.me/Discovery_Updates")], + [InlineKeyboardButton("Developer", url="https://t.me/AbirHasan2005")] + ] + ) + ) \ No newline at end of file diff --git a/WebStreamer/bot/plugins/stream.py b/WebStreamer/bot/plugins/stream.py index 4c0e089..1862d21 100644 --- a/WebStreamer/bot/plugins/stream.py +++ b/WebStreamer/bot/plugins/stream.py @@ -1,20 +1,118 @@ -# This file is a part of TG-FileStreamBot -# Coding : Jyothis Jayanth [@EverythingSuckz] +# (c) @EverythingSuckz | @AbirHasan2005 +import asyncio from WebStreamer.bot import StreamBot +from WebStreamer.utils.database import Database +from WebStreamer.utils.human_readable import humanbytes from WebStreamer.vars import Var -from pyrogram import filters, Client, emoji +from pyrogram import filters, Client +from pyrogram.errors import FloodWait, UserNotParticipant from pyrogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton +db = Database(Var.DATABASE_URL, Var.SESSION_NAME) -@StreamBot.on_message(filters.private & (filters.document | filters.video | filters.audio), group=4) -async def media_receive_handler(c: Client, m: Message): - log_msg = await m.copy(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, - Var.PORT, - log_msg.message_id) - await m.reply_text( - text="`{}`".format(stream_link), - quote=True - ) \ No newline at end of file +@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): + await db.add_user(m.from_user.id) + await c.send_message( + Var.BIN_CHANNEL, + f"#NEW_USER: \n\nNew User [{m.from_user.first_name}](tg://user?id={m.from_user.id}) Started !!" + ) + if Var.UPDATES_CHANNEL is not None: + try: + user = await c.get_chat_member(Var.UPDATES_CHANNEL, m.chat.id) + if user.status == "kicked": + await c.send_message( + chat_id=m.chat.id, + text="Sorry Sir, You are Banned to use me. Contact my [Support Group](https://t.me/linux_repo).", + parse_mode="markdown", + disable_web_page_preview=True + ) + return + except UserNotParticipant: + await c.send_message( + chat_id=m.chat.id, + text="**Please Join My Updates Channel to use this Bot!**\n\nDue to Overload, Only Channel Subscribers can use the Bot!", + reply_markup=InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton("๐Ÿค– Join Updates Channel", url=f"https://t.me/{Var.UPDATES_CHANNEL}") + ] + ] + ), + parse_mode="markdown" + ) + return + except Exception: + await c.send_message( + chat_id=m.chat.id, + text="Something went Wrong. Contact my [Support Group](https://t.me/linux_repo).", + parse_mode="markdown", + disable_web_page_preview=True) + 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, + 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}" + + msg_text = "Bruh! ๐Ÿ˜\nYour Link Generated! ๐Ÿค“\n\n๐Ÿ“‚ **File Name:** `{}`\n**File Size:** `{}`\n\n๐Ÿ“ฅ **Download Link:** `{}`" + await log_msg.reply_text(text=f"Requested by [{m.from_user.first_name}](tg://user?id={m.from_user.id})\n**User ID:** `{m.from_user.id}`\n**Download Link:** {stream_link}", disable_web_page_preview=True, parse_mode="Markdown", quote=True) + await m.reply_text( + text=msg_text.format(file_name, file_size, stream_link), + reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("Download Now", url=stream_link)]]), + quote=True + ) + except FloodWait as e: + print(f"Sleeping for {str(e.x)}s") + await asyncio.sleep(e.x) + await c.send_message(chat_id=Var.BIN_CHANNEL, text=f"Got FloodWait of {str(e.x)}s from [{m.from_user.first_name}](tg://user?id={m.from_user.id})\n\n**User ID:** `{str(m.from_user.id)}`", disable_web_page_preview=True, parse_mode="Markdown") + + +@StreamBot.on_message(filters.channel & (filters.document | filters.video) & ~filters.edited, group=-1) +async def channel_receive_handler(bot, broadcast): + if int(broadcast.chat.id) in Var.BANNED_CHANNELS: + await bot.leave_chat(broadcast.chat.id) + return + try: + log_msg = await broadcast.forward(chat_id=Var.BIN_CHANNEL) + await log_msg.reply_text( + text=f"**Channel Name:** `{broadcast.chat.title}`\n**Channel ID:** `{broadcast.chat.id}`\n**Link:** https://t.me/AH_File2Link_Bot?start=AbirHasan2005_{str(log_msg.message_id)}", + quote=True, + parse_mode="Markdown" + ) + await bot.edit_message_reply_markup( + chat_id=broadcast.chat.id, + message_id=broadcast.message_id, + reply_markup=InlineKeyboardMarkup( + [ + [InlineKeyboardButton("Get Direct Download Link", url=f"https://t.me/AH_File2Link_Bot?start=AbirHasan2005_{str(log_msg.message_id)}")] + ] + ) + ) + except FloodWait as w: + print(f"Sleeping for {str(w.x)}s") + await asyncio.sleep(w.x) + await bot.send_message(chat_id=Var.BIN_CHANNEL, + text=f"Got FloodWait of {str(w.x)}s from {broadcast.chat.title}\n\n**Channel ID:** `{str(broadcast.chat.id)}`", + disable_web_page_preview=True, parse_mode="Markdown") + except Exception as e: + await bot.send_message(chat_id=Var.BIN_CHANNEL, text=f"#ERROR_TRACEBACK: `{e}`", disable_web_page_preview=True, parse_mode="Markdown") + print(f"Can't Edit Broadcast Message!\nError: {e}") \ No newline at end of file diff --git a/WebStreamer/utils/broadcast_helper.py b/WebStreamer/utils/broadcast_helper.py new file mode 100644 index 0000000..fe2de17 --- /dev/null +++ b/WebStreamer/utils/broadcast_helper.py @@ -0,0 +1,22 @@ +# (c) @AbirHasan2005 + +import asyncio +import traceback +from pyrogram.errors import FloodWait, InputUserDeactivated, UserIsBlocked, PeerIdInvalid + + +async def send_msg(user_id, message): + try: + await message.forward(chat_id=user_id) + return 200, None + except FloodWait as e: + await asyncio.sleep(e.x) + return send_msg(user_id, message) + except InputUserDeactivated: + return 400, f"{user_id} : deactivated\n" + except UserIsBlocked: + return 400, f"{user_id} : blocked the bot\n" + 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 diff --git a/WebStreamer/utils/database.py b/WebStreamer/utils/database.py new file mode 100644 index 0000000..ed35369 --- /dev/null +++ b/WebStreamer/utils/database.py @@ -0,0 +1,36 @@ +# (c) @AbirHasan2005 + +import datetime +import motor.motor_asyncio + + +class Database: + def __init__(self, uri, database_name): + self._client = motor.motor_asyncio.AsyncIOMotorClient(uri) + self.db = self._client[database_name] + self.col = self.db.users + + def new_user(self, id): + return dict( + id=id, + join_date=datetime.date.today().isoformat() + ) + + async def add_user(self, id): + user = self.new_user(id) + await self.col.insert_one(user) + + async def is_user_exist(self, id): + user = await self.col.find_one({'id': int(id)}) + return True if user else False + + async def total_users_count(self): + count = await self.col.count_documents({}) + return count + + async def get_all_users(self): + all_users = self.col.find({}) + return all_users + + async def delete_user(self, user_id): + await self.col.delete_many({'id': int(user_id)}) diff --git a/WebStreamer/utils/human_readable.py b/WebStreamer/utils/human_readable.py new file mode 100644 index 0000000..10bec75 --- /dev/null +++ b/WebStreamer/utils/human_readable.py @@ -0,0 +1,15 @@ +# (c) @AbirHasan2005 + + +def humanbytes(size): + # https://stackoverflow.com/a/49361727/4723940 + # 2**10 = 1024 + if not size: + return "" + power = 2**10 + n = 0 + Dic_powerN = {0: ' ', 1: 'Ki', 2: 'Mi', 3: 'Gi', 4: 'Ti'} + while size > power: + size /= power + n += 1 + return str(round(size, 2)) + " " + Dic_powerN[n] + 'B' \ No newline at end of file diff --git a/WebStreamer/vars.py b/WebStreamer/vars.py index 3ede535..d08a3e8 100644 --- a/WebStreamer/vars.py +++ b/WebStreamer/vars.py @@ -1,25 +1,30 @@ -# This file is a part of TG-FileStreamBot -# Coding : Jyothis Jayanth [@EverythingSuckz] +# (c) @EverythingSuckz | @AbirHasan2005 from os import getenv, environ from dotenv import load_dotenv load_dotenv() + 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', 'AHFile2LinkBot')) SLEEP_THRESHOLD = int(getenv('SLEEP_THRESHOLD', '60')) - WORKERS = int(getenv('WORKERS', '3')) - BIN_CHANNEL = int(getenv('BIN_CHANNEL', None)) + 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')) #TODO + OWNER_ID = int(getenv('OWNER_ID', '1445283714')) NO_PORT = bool(getenv('NO_PORT', False)) + APP_NAME = None if 'DYNO' in environ: ON_HEROKU = True APP_NAME = str(getenv('APP_NAME')) else: ON_HEROKU = False - FQDN = str(getenv('FQDN', BIND_ADRESS)) if not ON_HEROKU else APP_NAME+'.herokuapp.com' \ No newline at end of file + FQDN = str(getenv('FQDN', BIND_ADRESS)) if not ON_HEROKU else APP_NAME+'.herokuapp.com' + 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())) \ No newline at end of file diff --git a/app.json b/app.json index cf2aa41..7cc8c39 100644 --- a/app.json +++ b/app.json @@ -1,5 +1,5 @@ { - "name": "TG-FileStreamBot", + "name": "Pyro-FileStreamBot", "description": "A Pyrogram Telegram bot to Stream Telegram files to web.", "keywords": [ "telegram", @@ -12,7 +12,7 @@ "modular", "media" ], - "repository": "https://github.com/EverythingSuckz/TG-FileStreamBot", + "repository": "https://github.com/AbirHasan2005/Pyro-FileStreamBot", "success_url": "/", "logo": "https://telegra.ph/file/9d63060a06c6fc6def1da.png", "website": "stream.wrench.gq", @@ -36,6 +36,20 @@ "BIN_CHANNEL": { "description": "The BIN Channel ID. Read the readme for more info about this var" }, + "DATABASE_URL": { + "description": "MongoDB URI for saving User IDs when they first Start the Bot. We will use that for Broadcasting to them. I will try to add more features related with Database. If you need help to get the URI you can ask in Support Group: https://t.me/linux_repo" + }, + "OWNER_ID": { + "description": "Your Telegram User ID" + }, + "BANNED_CHANNELS": { + "description": "Put IDs of Banned Channels where bot will not work. You can add multiple IDs & separate with Space.", + "required": false + }, + "UPDATES_CHANNEL": { + "description": "Put a Public Channel Username, so every user have to Join that channel to use the bot. Must add bot to channel as Admin to work properly.", + "required": false + }, "SLEEP_THRESHOLD": { "description": "Floodwait Sleep timer. Read the readme for more info about this var", "required": false @@ -60,7 +74,12 @@ "FQDN": { "description": "Read the readme for more info about this var", "required": false - } + }, + "SESSION_NAME": { + "description": "Any Session Name for Bot", + "required": false + }, + }, "buildpacks": [{ "url": "heroku/python" diff --git a/requirements.txt b/requirements.txt index 2c40272..946e976 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,7 @@ pyrogram tgcrypto aiohttp -python-dotenv \ No newline at end of file +python-dotenv +motor +aiofiles +dnspython \ No newline at end of file