Skip to content

Commit

Permalink
update web ui and deps
Browse files Browse the repository at this point in the history
  • Loading branch information
aahnik committed Dec 9, 2023
1 parent a0a4750 commit 72c576e
Show file tree
Hide file tree
Showing 13 changed files with 2,378 additions and 1,792 deletions.
3,153 changes: 1,749 additions & 1,404 deletions poetry.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion tgcf/bot/live_bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ async def style_command_handler(event):
_valid = [item.value for item in Style]
if args not in _valid:
raise ValueError(f"Invalid style. Choose from {_valid}")
CONFIG.plugins.fmt.style = args
CONFIG.plugin_cfgs.fmt.style = args
await event.respond("Success")
write_config(CONFIG)
except ValueError as err:
Expand Down
89 changes: 50 additions & 39 deletions tgcf/plugins/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
from telethon.tl.custom.message import Message

from tgcf.config import CONFIG
from tgcf.plugin_models import FileType, ASYNC_PLUGIN_IDS
from tgcf.plugin_models import ASYNC_PLUGIN_IDS, FileType
from tgcf.utils import cleanup, stamp

PLUGINS = CONFIG.plugins
# PLUGINS = CONFIG.plugin_cfgs


class TgcfMessage:
Expand Down Expand Up @@ -66,58 +66,69 @@ def modify(self, tm: TgcfMessage) -> TgcfMessage:
return tm


def load_plugins() -> Dict[str, TgcfPlugin]:
def load_plugins() -> Dict[int, Dict[str, TgcfPlugin]]:
"""Load the plugins specified in config."""
_plugins = {}
for item in PLUGINS:
plugin_id = item[0]
if item[1].check == False:
continue

plugin_class_name = f"Tgcf{plugin_id.title()}"

try: # try to load first party plugin
plugin_module = import_module("tgcf.plugins." + plugin_id)
except ModuleNotFoundError:
logging.error(
f"{plugin_id} is not a first party plugin. Third party plugins are not supported."
)
else:
logging.info(f"First party plugin {plugin_id} loaded!")
_plugins: Dict = {}
# plugin_cfg_id: { plugin_id: plugin }
for pcfg_id, cfg in enumerate(CONFIG.plugin_cfgs):

try:
plugin_class = getattr(plugin_module, plugin_class_name)
if not issubclass(plugin_class, TgcfPlugin):
logging.error(
f"Plugin class {plugin_class_name} does not inherit TgcfPlugin"
)
_plugins[pcfg_id] = {}
for item in cfg:
if item[0] == "alias":
continue
plugin: TgcfPlugin = plugin_class(item[1])
if not plugin.id_ == plugin_id:
logging.error(f"Plugin id for {plugin_id} does not match expected id.")

plugin_id = item[0]
if item[1].check == False:
continue
except AttributeError:
logging.error(f"Found plugin {plugin_id}, but plugin class not found.")
else:
logging.info(f"Loaded plugin {plugin_id}")
_plugins.update({plugin.id_: plugin})

plugin_class_name = f"Tgcf{plugin_id.title()}"

try: # try to load first party plugin
plugin_module = import_module("tgcf.plugins." + plugin_id)
except ModuleNotFoundError:
logging.error(
f"{plugin_id} is not a first party plugin. Third party plugins are not supported."
)
else:
logging.info(f"First party plugin {plugin_id} loaded!")

try:
plugin_class = getattr(plugin_module, plugin_class_name)
if not issubclass(plugin_class, TgcfPlugin):
logging.error(
f"Plugin class {plugin_class_name} does not inherit TgcfPlugin"
)
continue
plugin: TgcfPlugin = plugin_class(item[1])
if not plugin.id_ == plugin_id:
logging.error(
f"Plugin id for {plugin_id} does not match expected id."
)
continue
except AttributeError:
logging.error(f"Found plugin {plugin_id}, but plugin class not found.")
else:
logging.info(f"Loaded plugin {plugin_id}")
_plugins[pcfg_id].update({plugin.id_: plugin})
return _plugins


async def load_async_plugins() -> None:
"""Load async plugins specified plugin_models."""
if plugins:
for id in ASYNC_PLUGIN_IDS:
if id in plugins:
await plugins[id].__ainit__()
logging.info(f"Plugin {id} asynchronously loaded")
for pcfg_id, cfg in plugins.items():
for _id in ASYNC_PLUGIN_IDS:
if _id in plugins[pcfg_id].keys():
await plugins[pcfg_id][_id].__ainit__()
logging.info(f"Plugin {_id} asynchronously loaded")


async def apply_plugins(message: Message) -> TgcfMessage:
async def apply_plugins(pcfg_id: int, message: Message) -> TgcfMessage:
"""Apply all loaded plugins to a message."""
tm = TgcfMessage(message)
pcfg = plugins[pcfg_id]

for _id, plugin in plugins.items():
for _id, plugin in pcfg.items():
try:
if inspect.iscoroutinefunction(plugin.modify):
ntm = await plugin.modify(tm)
Expand Down
20 changes: 12 additions & 8 deletions tgcf/plugins/sender.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
import logging
import sys

from tgcf.plugins import TgcfMessage, TgcfPlugin
from tgcf.config import CONFIG, get_SESSION
from telethon import TelegramClient

from tgcf.config import CONFIG, get_SESSION
from tgcf.plugins import TgcfMessage, TgcfPlugin


class TgcfSender(TgcfPlugin):
id_ = "sender"

async def __ainit__(self) -> None:
sender = TelegramClient(
get_SESSION(CONFIG.plugins.sender, 'tgcf_sender'),
CONFIG.login.API_ID,
CONFIG.login.API_HASH,
get_SESSION(CONFIG.plugin_cfgs.sender, "tgcf_sender"),
CONFIG.login_cfg.API_ID,
CONFIG.login_cfg.API_HASH,
)
if self.data.user_type == 0:
if self.data.BOT_TOKEN == "":
logging.warning("[Sender] Bot token not found, but login type is set to bot.")
logging.warning(
"[Sender] Bot token not found, but login type is set to bot."
)
sys.exit()
await sender.start(bot_token=self.data.BOT_TOKEN)
else:
Expand All @@ -28,4 +32,4 @@ async def modify(self, tm: TgcfMessage) -> TgcfMessage:
if tm.file_type != "nofile":
tm.new_file = await tm.get_file()
tm.cleanup = True
return tm
return tm
4 changes: 2 additions & 2 deletions tgcf/web_ui/0_👋_Hello.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import streamlit as st

from tgcf.web_ui.utils import hide_st, switch_theme
from tgcf.config import read_config
from tgcf.web_ui.utils import hide_st, switch_theme

CONFIG = read_config()

Expand All @@ -10,7 +10,7 @@
page_icon="👋",
)
hide_st(st)
switch_theme(st,CONFIG)
switch_theme(st, CONFIG)
st.write("# Welcome to tgcf 👋")

html = """
Expand Down
126 changes: 95 additions & 31 deletions tgcf/web_ui/pages/1_🔑_Telegram_Login.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import streamlit as st

from tgcf.config import CONFIG, read_config, write_config
from tgcf.config import (
CONFIG,
AgentForwardingConfig,
AgentLoginConfig,
read_config,
write_config,
)
from tgcf.web_ui.password import check_password
from tgcf.web_ui.utils import hide_st, switch_theme

Expand All @@ -11,50 +17,108 @@
page_icon="🔑",
)
hide_st(st)
switch_theme(st,CONFIG)
switch_theme(st, CONFIG)
if check_password(st):
CONFIG.login.API_ID = int(
st.text_input("API ID", value=str(CONFIG.login.API_ID), type="password")
CONFIG.login_cfg.tg.API_ID = int(
st.text_input("API ID", value=str(CONFIG.login_cfg.tg.API_ID), type="password")
)
CONFIG.login.API_HASH = st.text_input(
"API HASH", value=CONFIG.login.API_HASH, type="password"
CONFIG.login_cfg.tg.API_HASH = st.text_input(
"API HASH", value=CONFIG.login_cfg.tg.API_HASH, type="password"
)
st.write("You can get api id and api hash from https://my.telegram.org.")

user_type = st.radio(
"Choose account type", ["Bot", "User"], index=CONFIG.login.user_type
)
if user_type == "Bot":
CONFIG.login.user_type = 0
CONFIG.login.BOT_TOKEN = st.text_input(
"Enter bot token", value=CONFIG.login.BOT_TOKEN, type="password"
)
else:
CONFIG.login.user_type = 1
CONFIG.login.SESSION_STRING = st.text_input(
"Enter session string", value=CONFIG.login.SESSION_STRING, type="password"
)
with st.expander("How to get session string ?"):
st.markdown(
"""
add_new = st.button("Add new Forwarding Agent")

Link to repl: https://replit.com/@aahnik/tg-login?v=1
if add_new:
CONFIG.login_cfg.agents.append(AgentLoginConfig())
CONFIG.agent_fwd_cfg.append(AgentForwardingConfig())
write_config(CONFIG)

_Click on the above link and enter api id, api hash, and phone no to generate session string._
num = len(CONFIG.login_cfg.agents)

**Note from developer:**
tab_strs = []

Due some issues logging in with a user account using a phone no is not supported in this web interface.
for i in range(num):
agent = CONFIG.login_cfg.agents[i]
if agent.alias:
label = agent.alias
else:
label = "Agent " + str(i + 1)
agent.alias = label
write_config(CONFIG)
tab_strs.append(label)

I have built a command-line program named tg-login (https://github.com/aahnik/tg-login) that can generate the session string for you.
tabs = st.tabs(list(tab_strs))

You can run tg-login on your computer, or securely in this repl. tg-login is open source, and you can also inspect the bash script running in the repl.
for i in range(num):
with tabs[i]:
# todo: implement delete agent
# when you are deleting agent from login config
# you must also delete agent from forwarding config

What is a session string ?
https://docs.telethon.dev/en/stable/concepts/sessions.html#string-sessions
agent = CONFIG.login_cfg.agents[i]
agent.alias = st.text_input(
"Agent Name", key=f"agent {i}", value=agent.alias
)

"""
user_type = st.radio(
"Choose account type",
["Bot", "User"],
index=agent.user_type,
key=f"user_type {i}",
)
if user_type == "Bot":
agent.user_type = 0
agent.BOT_TOKEN = st.text_input(
"Enter bot token",
value=agent.BOT_TOKEN,
type="password",
key=f"bot_token {i}",
)
else:
agent.user_type = 1
agent.SESSION_STRING = st.text_input(
"Enter session string",
value=agent.SESSION_STRING,
type="password",
key=f"session_string {i}",
)
with st.expander("How to get session string ?"):
st.markdown(
"""
Link to repl: https://replit.com/@aahnik/tg-login?v=1
_Click on the above link and enter api id, api hash, and phone no to generate session string._
**Note from developer:**
Due some issues logging in with a user account using a phone no is not supported in this web interface.
I have built a command-line program named tg-login (https://github.com/aahnik/tg-login) that can generate the session string for you.
You can run tg-login on your computer, or securely in this repl. tg-login is open source, and you can also inspect the bash script running in the repl.
What is a session string ?
https://docs.telethon.dev/en/stable/concepts/sessions.html#string-sessions
"""
)
with st.expander("Delete this agent"):
if i != 0:
st.warning(
f"Clicking the 'Remove' button will **delete** this agent: **{agent.alias}**. This action cannot be reversed once done.",
icon="⚠️",
)
if st.button(
f"Remove agent **{agent.alias}**", key=f"remove_btn {i}"
):
del CONFIG.login_cfg.agents[i]
del CONFIG.agent_fwd_cfg[i]
write_config(CONFIG)
st.experimental_rerun()
else:
st.warning("This is the default agent and cannot be deleted!")

if st.button("Save"):
write_config(CONFIG)
2 changes: 1 addition & 1 deletion tgcf/web_ui/pages/2_⭐_Admins.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
page_icon="⭐",
)
hide_st(st)
switch_theme(st,CONFIG)
switch_theme(st, CONFIG)
if check_password(st):

CONFIG.admins = get_list(st.text_area("Admins", value=get_string(CONFIG.admins)))
Expand Down
21 changes: 18 additions & 3 deletions tgcf/web_ui/pages/3_🔗_Connections.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
page_icon="🔗",
)
hide_st(st)
switch_theme(st,CONFIG)
switch_theme(st, CONFIG)
if check_password(st):
add_new = st.button("Add new connection")
if add_new:
Expand Down Expand Up @@ -49,8 +49,8 @@
if name:
label = f"{con} [{name}]"
else:
label = con
with st.expander("Modify Metadata"):
label = str(con)
with st.expander("Core Settings"):
st.write(f"Connection ID: **{con}**")
CONFIG.forwards[i].con_name = st.text_input(
"Name of this connection",
Expand All @@ -66,6 +66,21 @@
value=CONFIG.forwards[i].use_this,
key=f"use {con}",
)
CONFIG.forwards[i].agent = st.selectbox(
"Agent",
options=range(len(CONFIG.login_cfg.agents)),
key=f"agentfwd {i}",
format_func=lambda x: CONFIG.login_cfg.agents[x].alias,
index=CONFIG.forwards[i].agent,
)

CONFIG.forwards[i].plugin_cfg = st.selectbox(
"Plugin Config",
options=range(len(CONFIG.plugin_cfgs)),
key=f"pcfg {i}",
format_func=lambda x: CONFIG.plugin_cfgs[x].alias,
index=CONFIG.forwards[i].plugin_cfg,
)
with st.expander("Source and Destination"):
st.write(f"Configure connection {label}")

Expand Down
Loading

0 comments on commit 72c576e

Please sign in to comment.