Updated ?

Nothing new but, looks like something changed ;) !
This commit is contained in:
Avi Patil
2023-12-10 03:22:07 +05:30
parent 1c2e6f31f5
commit 61b7dac2b7
44 changed files with 2197 additions and 1125 deletions

View File

@@ -0,0 +1,4 @@
from .keepalive import ping_server
from .time_format import get_readable_time
from .file_properties import get_name, get_file_ids
from .custom_dl import ByteStreamer

View File

@@ -0,0 +1,177 @@
from pyrogram.errors import UserNotParticipant
from pyrogram.enums.parse_mode import ParseMode
from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, Message
from FileStream.utils.translation import LANG
from FileStream.utils.database import Database
from FileStream.utils.human_readable import humanbytes
from FileStream.config import Telegram, Server
from FileStream.bot import FileStream
db = Database(Telegram.DATABASE_URL, Telegram.SESSION_NAME)
async def is_user_joined(bot, message: Message):
try:
user = await bot.get_chat_member(Telegram.UPDATES_CHANNEL, message.chat.id)
if user.status == "BANNED":
await message.reply_text(
text=LANG.BAN_TEXT.format(Telegram.OWNER_ID),
parse_mode=ParseMode.MARKDOWN,
disable_web_page_preview=True
)
return False
except UserNotParticipant:
await message.reply_text(
text = "<i>Jɪɴ ᴍʏ ᴜᴘᴅᴀᴛᴇ ᴄʜᴀɴɴᴇʟ ᴛᴏ sᴇ ᴍᴇ 🔐</i>",
reply_markup=InlineKeyboardMarkup(
[[
InlineKeyboardButton("Jɪɴ ɴᴏᴡ 🔓", url=f"https://t.me/{Telegram.UPDATES_CHANNEL}")
]]
),
parse_mode=ParseMode.HTML
)
return False
except Exception:
await message.reply_text(
text = f"<i>Sᴍᴇᴛʜɪɴɢ ᴡʀᴏɴɢ ᴄᴏɴᴛᴀᴄᴛ ᴍʏ ᴅᴇᴠᴇʟᴏᴘᴇʀ</i> <b><a href='https://t.me/{Telegram.UPDATES_CHANNEL}'>[ ᴄʟɪᴄᴋ ʜᴇʀᴇ ]</a></b>",
parse_mode=ParseMode.HTML,
disable_web_page_preview=True)
return False
return True
#---------------------[ PRIVATE GEN LINK + CALLBACK ]---------------------#
async def gen_link(_id):
file_info = await db.get_file(_id)
file_name = file_info['file_name']
file_size = humanbytes(file_info['file_size'])
mime_type = file_info['mime_type']
page_link = f"{Server.URL}watch/{_id}"
stream_link = f"{Server.URL}dl/{_id}"
file_link = f"https://t.me/{FileStream.username}?start=file_{_id}"
if "video" in mime_type:
stream_text = LANG.STREAM_TEXT.format(file_name, file_size, stream_link, page_link, file_link)
reply_markup = InlineKeyboardMarkup(
[
[InlineKeyboardButton("sᴛʀᴇᴀᴍ", url=page_link), InlineKeyboardButton("ᴅᴏᴡɴʟᴏᴀᴅ", url=stream_link)],
[InlineKeyboardButton("ɢᴇᴛ ғɪʟᴇ", url=file_link), InlineKeyboardButton("ʀᴇᴠᴏᴋᴇ ғɪʟᴇ", callback_data=f"msgdelpvt_{_id}")],
[InlineKeyboardButton("ʟsᴇ", callback_data="close")]
]
)
else:
stream_text = LANG.STREAM_TEXT_X.format(file_name, file_size, stream_link, file_link)
reply_markup = InlineKeyboardMarkup(
[
[InlineKeyboardButton("ᴅᴏᴡɴʟᴏᴀᴅ", url=stream_link)],
[InlineKeyboardButton("ɢᴇᴛ ғɪʟᴇ", url=file_link), InlineKeyboardButton("ʀᴇᴠᴏᴋᴇ ғɪʟᴇ", callback_data=f"msgdelpvt_{_id}")],
[InlineKeyboardButton("ʟsᴇ", callback_data="close")]
]
)
return reply_markup, stream_text
#---------------------[ GEN STREAM LINKS FOR CHANNEL ]---------------------#
async def gen_linkx(m:Message , _id, name: list):
file_info = await db.get_file(_id)
file_name = file_info['file_name']
mime_type = file_info['mime_type']
file_size = humanbytes(file_info['file_size'])
page_link = f"{Server.URL}watch/{_id}"
stream_link = f"{Server.URL}dl/{_id}"
file_link = f"https://t.me/{FileStream.username}?start=file_{_id}"
if "video" in mime_type:
stream_text= LANG.STREAM_TEXT_X.format(file_name, file_size, stream_link, page_link)
reply_markup = InlineKeyboardMarkup(
[
[InlineKeyboardButton("sᴛʀᴇᴀᴍ", url=page_link), InlineKeyboardButton("ᴅᴏᴡɴʟᴏᴀᴅ", url=stream_link)]
]
)
else:
stream_text= LANG.STREAM_TEXT_X.format(file_name, file_size, stream_link, file_link)
reply_markup = InlineKeyboardMarkup(
[
[InlineKeyboardButton("ᴅᴏᴡɴʟᴏᴀᴅ", url=stream_link)]
]
)
return reply_markup, stream_text
#---------------------[ USER BANNED ]---------------------#
async def is_user_banned(message):
if await db.is_user_banned(message.from_user.id):
await message.reply_text(
text=LANG.BAN_TEXT.format(Telegram.OWNER_ID),
parse_mode=ParseMode.MARKDOWN,
disable_web_page_preview=True
)
return True
return False
#---------------------[ CHANNEL BANNED ]---------------------#
async def is_channel_banned(bot, message):
if await db.is_user_banned(message.chat.id):
await bot.edit_message_reply_markup(
chat_id=message.chat.id,
message_id=message.id,
reply_markup=InlineKeyboardMarkup([[
InlineKeyboardButton(f"ᴄʜᴀɴɴᴇʟ ɪs ʙᴀɴɴᴇᴅ", callback_data="N/A")]])
)
return True
return False
#---------------------[ USER AUTH ]---------------------#
async def is_user_authorized(message):
if hasattr(Telegram, 'AUTH_USERS') and Telegram.AUTH_USERS:
user_id = message.from_user.id
if user_id == Telegram.OWNER_ID:
return True
if not (user_id in Telegram.AUTH_USERS):
await message.reply_text(
text="You are not authorized to use this bot.",
parse_mode=ParseMode.MARKDOWN,
disable_web_page_preview=True
)
return False
return True
#---------------------[ USER EXIST ]---------------------#
async def is_user_exist(bot, message):
if not bool(await db.get_user(message.from_user.id)):
await db.add_user(message.from_user.id)
await bot.send_message(
Telegram.LOG_CHANNEL,
f"**#NᴇUsᴇʀ**\n**⬩ sᴇʀ ɴᴀᴍᴇ :** [{message.from_user.first_name}](tg://user?id={message.from_user.id})\n**⬩ sᴇʀ ɪᴅ :** `{message.from_user.id}`"
)
async def is_channel_exist(bot, message):
if not bool(await db.get_user(message.chat.id)):
await db.add_user(message.chat.id)
members = await bot.get_chat_members_count(message.chat.id)
await bot.send_message(
Telegram.LOG_CHANNEL,
f"**#NᴇCʜᴀɴɴᴇʟ** \n**⬩ ᴄʜᴀᴛ ɴᴀᴍᴇ :** `{message.chat.title}`\n**⬩ ᴄʜᴀᴛ ɪᴅ :** `{message.chat.id}`\n**⬩ ᴛᴏᴛᴀʟ ᴍᴇᴍʙᴇʀs :** `{members}`"
)
async def verify_user(bot, message):
if not await is_user_authorized(message):
return False
if await is_user_banned(message):
return False
await is_user_exist(bot, message)
if Telegram.FORCE_UPDATES_CHANNEL:
if not await is_user_joined(bot, message):
return False
return True

View File

@@ -0,0 +1,19 @@
import asyncio
import traceback
from pyrogram.errors import FloodWait, InputUserDeactivated, UserIsBlocked, PeerIdInvalid
async def send_msg(user_id, message):
try:
await message.copy(chat_id=user_id)
return 200, None
except FloodWait as e:
await asyncio.sleep(e.value)
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"

View File

@@ -0,0 +1,214 @@
import asyncio
import logging
from typing import Dict, Union
from FileStream.bot import work_loads
from pyrogram import Client, utils, raw
from .file_properties import get_file_ids
from pyrogram.session import Session, Auth
from pyrogram.errors import AuthBytesInvalid
from pyrogram.file_id import FileId, FileType, ThumbnailSource
from pyrogram.types import Message
class ByteStreamer:
def __init__(self, client: Client):
self.clean_timer = 30 * 60
self.client: Client = client
self.cached_file_ids: Dict[str, FileId] = {}
asyncio.create_task(self.clean_cache())
async def get_file_properties(self, db_id: str, multi_clients) -> FileId:
"""
Returns the properties of a media of a specific message in a FIleId class.
if the properties are cached, then it'll return the cached results.
or it'll generate the properties from the Message ID and cache them.
"""
if not db_id in self.cached_file_ids:
logging.debug("Before Calling generate_file_properties")
await self.generate_file_properties(db_id, multi_clients)
logging.debug(f"Cached file properties for file with ID {db_id}")
return self.cached_file_ids[db_id]
async def generate_file_properties(self, db_id: str, multi_clients) -> FileId:
"""
Generates the properties of a media file on a specific message.
returns ths properties in a FIleId class.
"""
logging.debug("Before calling get_file_ids")
file_id = await get_file_ids(self.client, db_id, multi_clients, Message)
logging.debug(f"Generated file ID and Unique ID for file with ID {db_id}")
self.cached_file_ids[db_id] = file_id
logging.debug(f"Cached media file with ID {db_id}")
return self.cached_file_ids[db_id]
async def generate_media_session(self, client: Client, file_id: FileId) -> Session:
"""
Generates the media session for the DC that contains the media file.
This is required for getting the bytes from Telegram servers.
"""
media_session = client.media_sessions.get(file_id.dc_id, None)
if media_session is None:
if file_id.dc_id != await client.storage.dc_id():
media_session = Session(
client,
file_id.dc_id,
await Auth(
client, file_id.dc_id, await client.storage.test_mode()
).create(),
await client.storage.test_mode(),
is_media=True,
)
await media_session.start()
for _ in range(6):
exported_auth = await client.invoke(
raw.functions.auth.ExportAuthorization(dc_id=file_id.dc_id)
)
try:
await media_session.invoke(
raw.functions.auth.ImportAuthorization(
id=exported_auth.id, bytes=exported_auth.bytes
)
)
break
except AuthBytesInvalid:
logging.debug(
f"Invalid authorization bytes for DC {file_id.dc_id}"
)
continue
else:
await media_session.stop()
raise AuthBytesInvalid
else:
media_session = Session(
client,
file_id.dc_id,
await client.storage.auth_key(),
await client.storage.test_mode(),
is_media=True,
)
await media_session.start()
logging.debug(f"Created media session for DC {file_id.dc_id}")
client.media_sessions[file_id.dc_id] = media_session
else:
logging.debug(f"Using cached media session for DC {file_id.dc_id}")
return media_session
@staticmethod
async def get_location(file_id: FileId) -> Union[raw.types.InputPhotoFileLocation,
raw.types.InputDocumentFileLocation,
raw.types.InputPeerPhotoFileLocation,]:
"""
Returns the file location for the media file.
"""
file_type = file_id.file_type
if file_type == FileType.CHAT_PHOTO:
if file_id.chat_id > 0:
peer = raw.types.InputPeerUser(
user_id=file_id.chat_id, access_hash=file_id.chat_access_hash
)
else:
if file_id.chat_access_hash == 0:
peer = raw.types.InputPeerChat(chat_id=-file_id.chat_id)
else:
peer = raw.types.InputPeerChannel(
channel_id=utils.get_channel_id(file_id.chat_id),
access_hash=file_id.chat_access_hash,
)
location = raw.types.InputPeerPhotoFileLocation(
peer=peer,
volume_id=file_id.volume_id,
local_id=file_id.local_id,
big=file_id.thumbnail_source == ThumbnailSource.CHAT_PHOTO_BIG,
)
elif file_type == FileType.PHOTO:
location = raw.types.InputPhotoFileLocation(
id=file_id.media_id,
access_hash=file_id.access_hash,
file_reference=file_id.file_reference,
thumb_size=file_id.thumbnail_size,
)
else:
location = raw.types.InputDocumentFileLocation(
id=file_id.media_id,
access_hash=file_id.access_hash,
file_reference=file_id.file_reference,
thumb_size=file_id.thumbnail_size,
)
return location
async def yield_file(
self,
file_id: FileId,
index: int,
offset: int,
first_part_cut: int,
last_part_cut: int,
part_count: int,
chunk_size: int,
) -> Union[str, None]:
"""
Custom generator that yields the bytes of the media file.
Modded from <https://github.com/eyaadh/megadlbot_oss/blob/master/mega/telegram/utils/custom_download.py#L20>
Thanks to Eyaadh <https://github.com/eyaadh>
"""
client = self.client
work_loads[index] += 1
logging.debug(f"Starting to yielding file with client {index}.")
media_session = await self.generate_media_session(client, file_id)
current_part = 1
location = await self.get_location(file_id)
try:
r = await media_session.invoke(
raw.functions.upload.GetFile(
location=location, offset=offset, limit=chunk_size
),
)
if isinstance(r, raw.types.upload.File):
while True:
chunk = r.bytes
if not chunk:
break
elif part_count == 1:
yield chunk[first_part_cut:last_part_cut]
elif current_part == 1:
yield chunk[first_part_cut:]
elif current_part == part_count:
yield chunk[:last_part_cut]
else:
yield chunk
current_part += 1
offset += chunk_size
if current_part > part_count:
break
r = await media_session.invoke(
raw.functions.upload.GetFile(
location=location, offset=offset, limit=chunk_size
),
)
except (TimeoutError, AttributeError):
pass
finally:
logging.debug(f"Finished yielding file with {current_part} parts.")
work_loads[index] -= 1
async def clean_cache(self) -> None:
"""
function to clean the cache to reduce memory usage
"""
while True:
await asyncio.sleep(self.clean_timer)
self.cached_file_ids.clear()
logging.debug("Cleaned the cache")

View File

@@ -0,0 +1,136 @@
import pymongo
import time
import motor.motor_asyncio
from bson.objectid import ObjectId
from bson.errors import InvalidId
from FileStream.server.exceptions import FIleNotFound
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
self.black = self.db.blacklist
self.file = self.db.file
#---------------------[ NEW USER ]---------------------#
def new_user(self, id):
return dict(
id=id,
join_date=time.time(),
agreed_to_tos=False,
Links=0,
Plan="Free"
)
# ---------------------[ ADD USER ]---------------------#
async def add_user(self, id):
user = self.new_user(id)
await self.col.insert_one(user)
# ---------------------[ GET USER ]---------------------#
async def get_user(self, id):
user = await self.col.find_one({'id': int(id)})
return user
# ---------------------[ CHECK USER ]---------------------#
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
# ---------------------[ REMOVE USER ]---------------------#
async def delete_user(self, user_id):
await self.col.delete_many({'id': int(user_id)})
# ---------------------[ BAN, UNBAN USER ]---------------------#
def black_user(self, id):
return dict(
id=id,
ban_date=time.time()
)
async def ban_user(self, id):
user = self.black_user(id)
await self.black.insert_one(user)
async def unban_user(self, id):
await self.black.delete_one({'id': int(id)})
async def is_user_banned(self, id):
user = await self.black.find_one({'id': int(id)})
return True if user else False
async def total_banned_users_count(self):
count = await self.black.count_documents({})
return count
# ---------------------[ ADD FILE TO DB ]---------------------#
async def add_file(self, file_info):
file_info["time"] = time.time()
fetch_old = await self.get_file_by_fileuniqueid(file_info["user_id"], file_info["file_unique_id"])
if fetch_old:
return fetch_old["_id"]
await self.count_links(file_info["user_id"], "+")
return (await self.file.insert_one(file_info)).inserted_id
# ---------------------[ FIND FILE IN DB ]---------------------#
async def find_files(self, user_id, range):
user_files=self.file.find({"user_id": user_id})
user_files.skip(range[0] - 1)
user_files.limit(range[1] - range[0] + 1)
user_files.sort('_id', pymongo.DESCENDING)
total_files = await self.file.count_documents({"user_id": user_id})
return user_files, total_files
async def get_file(self, _id):
try:
file_info=await self.file.find_one({"_id": ObjectId(_id)})
if not file_info:
raise FIleNotFound
return file_info
except InvalidId:
raise FIleNotFound
async def get_file_by_fileuniqueid(self, id, file_unique_id, many=False):
if many:
return self.file.find({"file_unique_id": file_unique_id})
else:
file_info=await self.file.find_one({"user_id": id, "file_unique_id": file_unique_id})
if file_info:
return file_info
return False
# ---------------------[ TOTAL FILES ]---------------------#
async def total_files(self, id=None):
if id:
return await self.file.count_documents({"user_id": id})
return await self.file.count_documents({})
# ---------------------[ DELETE FILES ]---------------------#
async def delete_one_file(self, _id):
await self.file.delete_one({'_id': ObjectId(_id)})
# ---------------------[ UPDATE FILES ]---------------------#
async def update_file_ids(self, _id, file_ids: dict):
await self.file.update_one({"_id": ObjectId(_id)}, {"$set": {"file_ids": file_ids}})
# ---------------------[ PAID SYS ]---------------------#
async def link_available(self, id):
user = await self.col.find_one({"id": id})
if user.get("Plan") == "Plus":
return "Plus"
elif user.get("Plan") == "Free":
files = await self.file.count_documents({"user_id": id})
if files < 11:
return True
return False
async def count_links(self, id, operation: str):
if operation == "-":
await self.col.update_one({"id": id}, {"$inc": {"Links": -1}})
elif operation == "+":
await self.col.update_one({"id": id}, {"$inc": {"Links": 1}})

View File

@@ -0,0 +1,146 @@
from __future__ import annotations
import logging
from datetime import datetime
from pyrogram import Client
from typing import Any, Optional
from pyrogram.enums import ParseMode, ChatType
from pyrogram.types import Message
from pyrogram.file_id import FileId
from FileStream.bot import FileStream
from FileStream.utils.database import Database
from FileStream.config import Telegram, Server
db = Database(Telegram.DATABASE_URL, Telegram.SESSION_NAME)
async def get_file_ids(client: Client | bool, db_id: str, multi_clients, message) -> Optional[FileId]:
logging.debug("Starting of get_file_ids")
file_info = await db.get_file(db_id)
if (not "file_ids" in file_info) or not client:
logging.debug("Storing file_id of all clients in DB")
log_msg = await send_file(FileStream, db_id, file_info['file_id'], message)
await db.update_file_ids(db_id, await update_file_id(log_msg.id, multi_clients))
logging.debug("Stored file_id of all clients in DB")
if not client:
return
file_info = await db.get_file(db_id)
file_id_info = file_info.setdefault("file_ids", {})
if not str(client.id) in file_id_info:
logging.debug("Storing file_id in DB")
log_msg = await send_file(FileStream, db_id, file_info['file_id'], message)
msg = await client.get_messages(Telegram.LOG_CHANNEL, log_msg.id)
media = get_media_from_message(msg)
file_id_info[str(client.id)] = getattr(media, "file_id", "")
await db.update_file_ids(db_id, file_id_info)
logging.debug("Stored file_id in DB")
logging.debug("Middle of get_file_ids")
file_id = FileId.decode(file_id_info[str(client.id)])
setattr(file_id, "file_size", file_info['file_size'])
setattr(file_id, "mime_type", file_info['mime_type'])
setattr(file_id, "file_name", file_info['file_name'])
setattr(file_id, "unique_id", file_info['file_unique_id'])
logging.debug("Ending of get_file_ids")
return file_id
def get_media_from_message(message: "Message") -> Any:
media_types = (
"audio",
"document",
"photo",
"sticker",
"animation",
"video",
"voice",
"video_note",
)
for attr in media_types:
media = getattr(message, attr, None)
if media:
return media
def get_media_file_size(m):
media = get_media_from_message(m)
return getattr(media, "file_size", "None")
def get_name(media_msg: Message | FileId) -> str:
if isinstance(media_msg, Message):
media = get_media_from_message(media_msg)
file_name = getattr(media, "file_name", "")
elif isinstance(media_msg, FileId):
file_name = getattr(media_msg, "file_name", "")
if not file_name:
if isinstance(media_msg, Message) and media_msg.media:
media_type = media_msg.media.value
elif media_msg.file_type:
media_type = media_msg.file_type.name.lower()
else:
media_type = "file"
formats = {
"photo": "jpg", "audio": "mp3", "voice": "ogg",
"video": "mp4", "animation": "mp4", "video_note": "mp4",
"sticker": "webp"
}
ext = formats.get(media_type)
ext = "." + ext if ext else ""
date = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
file_name = f"{media_type}-{date}{ext}"
return file_name
def get_file_info(message):
media = get_media_from_message(message)
if message.chat.type == ChatType.PRIVATE:
user_idx = message.from_user.id
else:
user_idx = message.chat.id
return {
"user_id": user_idx,
"file_id": getattr(media, "file_id", ""),
"file_unique_id": getattr(media, "file_unique_id", ""),
"file_name": get_name(message),
"file_size": getattr(media, "file_size", 0),
"mime_type": getattr(media, "mime_type", "None/unknown")
}
async def update_file_id(msg_id, multi_clients):
file_ids = {}
for client_id, client in multi_clients.items():
log_msg = await client.get_messages(Telegram.LOG_CHANNEL, msg_id)
media = get_media_from_message(log_msg)
file_ids[str(client.id)] = getattr(media, "file_id", "")
return file_ids
async def send_file(client: Client, db_id, file_id: str, message):
file_caption = message.caption
if file_caption is None:
file_caption = message.file_name
log_msg = await client.send_cached_media(chat_id=Telegram.LOG_CHANNEL, file_id=file_id,
caption=f'**{file_caption}**')
if message.chat.type == ChatType.PRIVATE:
await log_msg.reply_text(
text=f"**RᴇQᴛᴇᴅ ʙʏ :** [{message.from_user.first_name}](tg://user?id={message.from_user.id})\n**Uᴇʀ ɪᴅ :** `{message.from_user.id}`\n**Fɪʟᴇ ɪᴅ :** `{db_id}`",
disable_web_page_preview=True, parse_mode=ParseMode.MARKDOWN, quote=True)
else:
await log_msg.reply_text(
text=f"**RᴇQᴛᴇᴅ ʙʏ :** {message.chat.title} \n**Cʜᴀɴɴᴇʟ ɪᴅ :** `{message.chat.id}`\n**Fɪʟᴇ ɪᴅ :** `{db_id}`",
disable_web_page_preview=True, parse_mode=ParseMode.MARKDOWN, quote=True)
return log_msg
# return await client.send_cached_media(Telegram.BIN_CHANNEL, file_id)

View File

@@ -0,0 +1,10 @@
def humanbytes(size):
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'

View File

@@ -0,0 +1,20 @@
import asyncio
import logging
import aiohttp
import traceback
from FileStream.config import Server
async def ping_server():
sleep_time = Server.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(Server.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()

View File

@@ -0,0 +1,25 @@
import aiohttp
import aiofiles
import urllib.parse
from FileStream.config import Telegram, Server
from FileStream.utils.database import Database
from FileStream.utils.human_readable import humanbytes
db = Database(Telegram.DATABASE_URL, Telegram.SESSION_NAME)
async def render_page(db_id):
file_data=await db.get_file(db_id)
src = urllib.parse.urljoin(Server.URL, f'dl/{file_data["_id"]}')
if str((file_data['mime_type']).split('/')[0].strip()) == 'video':
async with aiofiles.open('FileStream/template/stream.html') as r:
heading = 'Watch {}'.format(file_data['file_name'])
html_template = await r.read()
html = html_template.replace('streamMediaLink', src).replace('streamHeading', heading)
else:
async with aiofiles.open('FileStream/template/dl.html') as r:
async with aiohttp.ClientSession() as s:
async with s.get(src) as u:
heading = 'Download {}'.format(file_data['file_name'])
file_size = humanbytes(int(u.headers.get('Content-Length')))
html = (await r.read()) % (heading, file_data['file_name'], src, file_size)
return html

View File

@@ -0,0 +1,22 @@
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

View File

@@ -0,0 +1,72 @@
from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton
from FileStream.config import Telegram
class LANG(object):
START_TEXT = """
<b>👋 Hᴇʏ, </b>{}\n
<b>I'ᴍ ᴛᴇʟᴇɢʀᴀᴍ ғɪʟᴇs sᴛʀᴇᴀᴍɪɴɢ ʙᴏᴛ ᴀs ᴡᴇʟʟ ᴅɪʀᴇᴄᴛ ʟɪɴᴋs ɢᴇɴᴇʀᴀᴛᴏʀ</b>\n
<b>ᴡᴏʀᴋɪɴɢ ᴏɴ ʜᴀɴɴᴇʟs ᴀɴᴅ ᴘʀɪᴠᴀᴛᴇ ᴄʜᴀᴛ</b>\n
<b>💕 @{}</b>\n"""
HELP_TEXT = """
<b>- ᴀᴅᴅ ᴍᴇ ᴀs ᴀɴ ᴀᴅᴍɪɴ ᴏɴ ᴛʜᴇ ᴄʜᴀɴɴᴇʟ</b>
<b>- sᴇɴᴅ ᴍᴇ ᴀɴʏ ᴅᴏᴄᴜᴍᴇɴᴛ ᴏʀ ᴍᴇᴅɪᴀ</b>
<b>- ɪ'ʟʟ ᴘʀᴏᴠɪᴅᴇ sᴛʀᴇᴀᴍᴀʙʟᴇ ʟɪɴᴋ</b>\n
<b>🔞 ᴀᴅᴜʟᴛ ᴄᴏɴᴛᴇɴᴛ sᴛʀɪᴛʟʏ ᴘʀᴏʜɪʙɪᴛᴇᴅ.</b>\n
<i><b> ʀᴇᴘᴏʀᴛ ʙɢs ᴛᴏ <a href='https://telegram.me/AvishkarPatil'>ᴅᴇᴠᴇʟᴏᴘᴇʀ</a></b></i>"""
ABOUT_TEXT = """
<b>⚜ ᴍʏ ɴᴀᴍᴇ : {}</b>\n
<b>✦ ᴇʀsɪɴ : {}</b>
<b>✦ ᴜᴘᴅᴀᴛᴇᴅ ᴏɴ : 19-November-2023</b>
<b>✦ ᴅᴇᴠᴇʟᴏᴘᴇʀ : <a href='https://telegram.me/AvishkarPatil'>Avishkar Patil</a></b>\n
"""
STREAM_TEXT = """
<i><u>𝗬𝗼𝘂𝗿 𝗟𝗶𝗻𝗸 𝗚𝗲𝗻𝗲𝗿𝗮𝘁𝗲𝗱 !</u></i>\n
<b>📂 Fɪʟᴇ ɴᴀᴍᴇ :</b> <b>{}</b>\n
<b>📦 Fɪʟᴇ ꜱɪᴢᴇ :</b> <code>{}</code>\n
<b>📥 Dɴʟᴀᴅ :</b> <code>{}</code>\n
<b>🖥 Wᴀᴛʜ :</b> <code>{}</code>\n
<b>🔗 Sʜᴀʀᴇ :</b> <code>{}</code>\n"""
STREAM_TEXT_X = """
<i><u>𝗬𝗼𝘂𝗿 𝗟𝗶𝗻𝗸 𝗚𝗲𝗻𝗲𝗿𝗮𝘁𝗲𝗱 !</u></i>\n
<b>📂 Fɪʟᴇ ɴᴀᴍᴇ :</b> <b>{}</b>\n
<b>📦 Fɪʟᴇ ꜱɪᴢᴇ :</b> <code>{}</code>\n
<b>📥 Dɴʟᴀᴅ :</b> <code>{}</code>\n
<b>🔗 Sʜᴀʀᴇ :</b> <code>{}</code>\n"""
BAN_TEXT = "__Sʀʀʏ Sɪʀ, Y ᴀʀᴇ Bᴀɴɴᴇᴅ ᴛᴏ sᴇ ᴍᴇ.__\n\n**[Cɴᴛᴀᴛ Dᴇᴇʟᴘᴇʀ](tg://user?id={}) Tʜᴇʏ Wɪʟʟ Hᴇʟᴘ Y**"
class BUTTON(object):
START_BUTTONS = InlineKeyboardMarkup(
[[
InlineKeyboardButton('ʜᴇʟᴘ', callback_data='help'),
InlineKeyboardButton('ᴀʙᴏᴜᴛ', callback_data='about'),
InlineKeyboardButton('ʟsᴇ', callback_data='close')
],
[InlineKeyboardButton("📢 ᴜᴘᴅᴀᴛᴇ ᴄʜᴀɴɴᴇʟ", url=f'https://t.me/{Telegram.UPDATES_CHANNEL}')]
]
)
HELP_BUTTONS = InlineKeyboardMarkup(
[[
InlineKeyboardButton('ʜᴏᴍᴇ', callback_data='home'),
InlineKeyboardButton('ᴀʙᴏᴜᴛ', callback_data='about'),
InlineKeyboardButton('ʟsᴇ', callback_data='close'),
],
[InlineKeyboardButton("📢 ᴜᴘᴅᴀᴛᴇ ᴄʜᴀɴɴᴇʟ", url=f'https://t.me/{Telegram.UPDATES_CHANNEL}')]
]
)
ABOUT_BUTTONS = InlineKeyboardMarkup(
[[
InlineKeyboardButton('ʜᴏᴍᴇ', callback_data='home'),
InlineKeyboardButton('ʜᴇʟᴘ', callback_data='help'),
InlineKeyboardButton('ʟsᴇ', callback_data='close'),
],
[InlineKeyboardButton("📢 ᴜᴘᴅᴀᴛᴇ ᴄʜᴀɴɴᴇʟ", url=f'https://t.me/{Telegram.UPDATES_CHANNEL}')]
]
)