import os import random import shutil import subprocess import sys from threading import Thread import time import traceback import schedule from modules.logging import logWrite from modules.utils import configGet, jsonLoad, jsonSave pid = os.getpid() if "--move-sent" in sys.argv: for entry in jsonLoad(configGet("index", "locations"))["sent"]: try: shutil.move(configGet("queue", "locations")+os.sep+entry, configGet("sent", "locations")+os.sep+entry) except FileNotFoundError: logWrite(f"File '{entry}' is already moved or does not exist") except Exception as exp: logWrite(f"Could not move sent file '{entry}' to '{configGet('sent', 'locations')}' due to {exp}") if "--cleanup" in sys.argv: if "--confirm" in sys.argv: for entry in jsonLoad(configGet("index", "locations"))["sent"]: try: try: os.remove(configGet("queue", "locations")+os.sep+entry) except FileNotFoundError: pass try: os.remove(configGet("sent", "locations")+os.sep+entry) except FileNotFoundError: pass except Exception as exp: logWrite(f"Could not remove '{entry}' due to {exp}") else: logWrite(f"Requested cleanup of sent files but not authorized. Please pass '--confirm' to perform that") if "--norun" in sys.argv: logWrite("Argument --norun passed, not running the main script") sys.exit() try: from pyrogram import Client, filters, idle # type: ignore from pyrogram.types import ChatPermissions, ReplyKeyboardMarkup, InlineKeyboardMarkup, InlineKeyboardButton, BotCommand, BotCommandScopeChat # type: ignore except ModuleNotFoundError: print(f"Module pyrogram is not installed. Run 'pip3 install -r requirements.txt' and restart the program.", flush=True) sys.exit() app = Client("duptsiaposter", bot_token=configGet("bot_token", "bot"), api_id=configGet("api_id", "bot"), api_hash=configGet("api_hash", "bot")) def send_content(): try: list_sent = jsonLoad(configGet("index", "locations")) list_queue = os.listdir(configGet("queue", "locations")) for file in list_queue: if not file in list_sent["sent"]: ext_match = False for ext in configGet("photo", "posting", "extensions"): if file.endswith(ext): ext_match = True ext_type = "photo" break for ext in configGet("video", "posting", "extensions"): if file.endswith(ext): ext_match = True ext_type = "video" break if not ext_match: list_queue.remove(file) else: list_queue.remove(file) if len(list_queue) > 0: candidate_file = random.choice(list_queue) candidate = configGet("queue", "locations")+os.sep+candidate_file else: logWrite(f"Could not send content due to queue folder empty with allowed extensions") if configGet("error", "reports"): app.send_message(configGet("admin", "reports"), f"Could not send content: `Queue folder is empty or contains only unsupported or already sent files.`") # type: ignore return if ext_type == "photo": # type: ignore if configGet("enabled", "caption"): if configGet("link", "caption") != None: sent = app.send_photo(configGet("channel", "posting"), candidate, caption=f"[{configGet('text', 'caption')}]({configGet('link', 'caption')})", disable_notification=configGet("silent", "posting")) # type: ignore else: sent = app.send_photo(configGet("channel", "posting"), candidate, caption=configGet('text', 'caption'), disable_notification=configGet("silent", "posting")) # type: ignore else: sent = app.send_photo(configGet("channel", "posting"), candidate, disable_notification=configGet("silent", "posting")) # type: ignore elif ext_type == "video": # type: ignore if configGet("enabled", "caption"): if configGet("link", "caption") != None: sent = app.send_video(configGet("channel", "posting"), candidate, caption=f"[{configGet('text', 'caption')}]({configGet('link', 'caption')})", disable_notification=configGet("silent", "posting")) # type: ignore else: sent = app.send_video(configGet("channel", "posting"), candidate, caption=configGet('text', 'caption'), disable_notification=configGet("silent", "posting")) # type: ignore else: sent = app.send_video(configGet("channel", "posting"), candidate, disable_notification=configGet("silent", "posting")) # type: ignore list_sent["sent"].append(candidate_file) jsonSave(list_sent, configGet("index", "locations")) if configGet("move_sent", "posting"): shutil.move(candidate, configGet("sent", "locations")+os.sep+candidate_file) if configGet("sent", "reports"): app.send_message(configGet("admin", "reports"), f"Posted `{candidate_file}`", disable_web_page_preview=True, reply_markup=InlineKeyboardMarkup([ [InlineKeyboardButton("View in channel", url=sent.link)] # type: ignore ])) # type: ignore except Exception as exp: logWrite(f"Could not send content due to {exp}") if configGet("error", "reports"): app.send_message(configGet("admin", "reports"), f"Could not send content due to `{exp}`\n\nTraceback:\n```{traceback.format_exc()}```") # type: ignore @app.on_message(~ filters.scheduled & filters.command(["kill", "die", "reboot"], prefixes=["", "/"])) def kill(app, msg): if msg.from_user.id == configGet("admin", "reports"): msg.reply_text(f"Shutting down bot with pid `{pid}`") os.system('kill -9 '+str(pid)) for entry in configGet("time", "posting"): schedule.every().day.at(entry).do(send_content) def background_task(): try: while True: try: schedule.run_pending() time.sleep(1) except: pass except Exception as exp: logWrite(f"Exception {exp} happened on task execution") except KeyboardInterrupt: logWrite('\nShutting down...') app.send_message(configGet("admin", "reports"), f"Shutting down with PID `{pid}`") # type: ignore os.system('kill -9 '+str(pid)) if __name__ == "__main__": logWrite(f'Starting with PID {pid}') app.start() # type: ignore app.send_message(configGet("admin", "reports"), f"Starting with pid `{pid}`") # type: ignore t = Thread(target=background_task) t.start() app.set_bot_commands([ # type: ignore BotCommand("reboot", "Reboot the bot"), ], scope=BotCommandScopeChat(chat_id=configGet("admin", "reports"))) idle() app.send_message(configGet("admin", "reports"), f"Shutting down with pid `{pid}`") # type: ignore logWrite(f'Shutting down with PID {pid}') subprocess.call(f'kill -9 {pid}', shell=True) # type: ignore