diff --git a/repthon/sql_helper/DS_Store b/repthon/sql_helper/DS_Store new file mode 100644 index 0000000..e3967d2 Binary files /dev/null and b/repthon/sql_helper/DS_Store differ diff --git a/repthon/sql_helper/__init__.py b/repthon/sql_helper/__init__.py new file mode 100644 index 0000000..d8f5e7e --- /dev/null +++ b/repthon/sql_helper/__init__.py @@ -0,0 +1,34 @@ +import os + +from sqlalchemy import create_engine +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import scoped_session, sessionmaker + +# the secret configuration specific things +from ..Config import Config +from ..core.logger import logging + +LOGS = logging.getLogger(__name__) + + +def start() -> scoped_session: + database_url = ( + Config.DB_URI.replace("postgres:", "postgresql:") + if "postgres://" in Config.DB_URI + else Config.DB_URI + ) + engine = create_engine(database_url) + BASE.metadata.bind = engine + BASE.metadata.create_all(engine) + return scoped_session(sessionmaker(bind=engine, autoflush=False)) + + +try: + BASE = declarative_base() + SESSION = start() +except AttributeError as e: + # this is a dirty way for the work-around required for #23 + LOGS.error( + "DB_URI is not configured. Features depending on the database might have issues." + ) + LOGS.error(str(e)) diff --git a/repthon/sql_helper/antiflood_sql.py b/repthon/sql_helper/antiflood_sql.py new file mode 100644 index 0000000..3f550e8 --- /dev/null +++ b/repthon/sql_helper/antiflood_sql.py @@ -0,0 +1,98 @@ +import threading + +from sqlalchemy import Column, Integer, String + +from . import BASE, SESSION + +DEF_COUNT = 0 +DEF_LIMIT = 0 +DEF_OBJ = (None, DEF_COUNT, DEF_LIMIT) + + +class FloodControl(BASE): + __tablename__ = "antiflood" + chat_id = Column(String(14), primary_key=True) + user_id = Column(Integer) + count = Column(Integer, default=DEF_COUNT) + limit = Column(Integer, default=DEF_LIMIT) + + def __init__(self, chat_id): + self.chat_id = str(chat_id) # ensure string + + def __repr__(self): + return "" % self.chat_id + + +FloodControl.__table__.create(checkfirst=True) + +INSERTION_LOCK = threading.RLock() + + +class ANTIFLOOD_SQL: + def __init__(self): + self.CHAT_FLOOD = {} + + +ANTIFLOOD_SQL_ = ANTIFLOOD_SQL() + + +def set_flood(chat_id, amount): + with INSERTION_LOCK: + flood = SESSION.query(FloodControl).get(str(chat_id)) + if not flood: + flood = FloodControl(str(chat_id)) + + flood.user_id = None + flood.limit = amount + + ANTIFLOOD_SQL_.CHAT_FLOOD[str(chat_id)] = (None, DEF_COUNT, amount) + + SESSION.add(flood) + SESSION.commit() + + +def update_flood(chat_id: str, user_id) -> bool: + if str(chat_id) not in ANTIFLOOD_SQL_.CHAT_FLOOD: + return + curr_user_id, count, limit = ANTIFLOOD_SQL_.CHAT_FLOOD.get(str(chat_id), DEF_OBJ) + if limit == 0: # no antiflood + return False + if user_id != curr_user_id or user_id is None: # other user + ANTIFLOOD_SQL_.CHAT_FLOOD[str(chat_id)] = (user_id, DEF_COUNT + 1, limit) + return False + + count += 1 + if count > limit: # too many msgs, kick + ANTIFLOOD_SQL_.CHAT_FLOOD[str(chat_id)] = (None, DEF_COUNT, limit) + return True + + # default -> update + ANTIFLOOD_SQL_.CHAT_FLOOD[str(chat_id)] = (user_id, count, limit) + return False + + +def get_flood_limit(chat_id): + return ANTIFLOOD_SQL_.CHAT_FLOOD.get(str(chat_id), DEF_OBJ)[2] + + +def migrate_chat(old_chat_id, new_chat_id): + with INSERTION_LOCK: + if flood := SESSION.query(FloodControl).get(str(old_chat_id)): + ANTIFLOOD_SQL_.CHAT_FLOOD[str(new_chat_id)] = ANTIFLOOD_SQL_.CHAT_FLOOD.get( + str(old_chat_id), DEF_OBJ + ) + flood.chat_id = str(new_chat_id) + SESSION.commit() + + SESSION.close() + + +def __load_flood_settings(): + try: + all_chats = SESSION.query(FloodControl).all() + ANTIFLOOD_SQL_.CHAT_FLOOD = { + chat.chat_id: (None, DEF_COUNT, chat.limit) for chat in all_chats + } + finally: + SESSION.close() + return ANTIFLOOD_SQL_.CHAT_FLOOD diff --git a/repthon/sql_helper/autopost_sql.py b/repthon/sql_helper/autopost_sql.py new file mode 100644 index 0000000..0c0c20a --- /dev/null +++ b/repthon/sql_helper/autopost_sql.py @@ -0,0 +1,84 @@ +import threading +from sqlalchemy import Column, String, UnicodeText, distinct, func +from . import BASE, SESSION + + +class Post(BASE): + __tablename__ = "post" + target_chat_id = Column(String(14), primary_key=True) + to_post_chat_id = Column(String(14), primary_key=True, nullable=False) + + def __init__(self, target_chat_id, to_post_chat_id): + self.to_post_chat_id = str(to_post_chat_id) + self.target_chat_id = str(target_chat_id) + + def __repr__(self): + return "" % (self.target_chat_id, self.to_post_chat_id) + + def __eq__(self, other): + return bool( + isinstance(other, Post) + and self.target_chat_id == other.target_chat_id + and self.to_post_chat_id == other.to_post_chat_id + ) + + + + +Post.__table__.create(checkfirst=True) + +POST_FILTER_INSERTION_LOCK = threading.RLock() + +CHAT_POSTS = {} + +def add_post(target_chat_id: str, to_post_chat_id: str): + with POST_FILTER_INSERTION_LOCK: + blacklist_filt = Post(str(target_chat_id), str(to_post_chat_id)) + + SESSION.merge(blacklist_filt) + SESSION.commit() + CHAT_POSTS.setdefault(str(target_chat_id), set()).add(str(to_post_chat_id)) + + +def get_all_post(target_chat_id: str): + return CHAT_POSTS.get(str(target_chat_id), set()) + + +def is_post(target_chat_id, to_post_chat_id): + with POST_FILTER_INSERTION_LOCK: + broadcast_group = SESSION.query(Post).get((str(target_chat_id), str(to_post_chat_id))) + return bool(broadcast_group) + + +def remove_post(target_chat_id, to_post_chat_id): + with POST_FILTER_INSERTION_LOCK: + blacklist_filt = SESSION.query(Post).get((str(target_chat_id), str(to_post_chat_id))) + if blacklist_filt: + if str(to_post_chat_id) in CHAT_POSTS.get(str(target_chat_id), set()): # sanity check + CHAT_POSTS.get(str(target_chat_id), set()).remove(str(to_post_chat_id)) + + SESSION.delete(blacklist_filt) + SESSION.commit() + return True + + SESSION.close() + return False + +def __load_chat_channels(): + global CHAT_POSTS + try: + chats = SESSION.query(Post.target_chat_id).distinct().all() + for (target_chat_id,) in chats: + CHAT_POSTS[target_chat_id] = [] + + all_filters = SESSION.query(Post).all() + for x in all_filters: + CHAT_POSTS[x.target_chat_id] += [x.to_post_chat_id] + + CHAT_POSTS = {x: set(y) for x, y in CHAT_POSTS.items()} + + finally: + SESSION.close() + + +__load_chat_channels() diff --git a/repthon/sql_helper/blacklist_sql.py b/repthon/sql_helper/blacklist_sql.py new file mode 100644 index 0000000..de4498c --- /dev/null +++ b/repthon/sql_helper/blacklist_sql.py @@ -0,0 +1,115 @@ +import threading + +from sqlalchemy import Column, String, UnicodeText, distinct, func + +from . import BASE, SESSION + + +class BlackListFilters(BASE): + __tablename__ = "blacklist" + chat_id = Column(String(14), primary_key=True) + trigger = Column(UnicodeText, primary_key=True, nullable=False) + + def __init__(self, chat_id, trigger): + self.chat_id = str(chat_id) # ensure string + self.trigger = trigger + + def __repr__(self): + return "" % (self.trigger, self.chat_id) + + def __eq__(self, other): + return bool( + isinstance(other, BlackListFilters) + and self.chat_id == other.chat_id + and self.trigger == other.trigger + ) + + +BlackListFilters.__table__.create(checkfirst=True) + +BLACKLIST_FILTER_INSERTION_LOCK = threading.RLock() + + +class BLACKLIST_SQL: + def __init__(self): + self.CHAT_BLACKLISTS = {} + + +BLACKLIST_SQL_ = BLACKLIST_SQL() + + +def add_to_blacklist(chat_id, trigger): + with BLACKLIST_FILTER_INSERTION_LOCK: + blacklist_filt = BlackListFilters(str(chat_id), trigger) + + SESSION.merge(blacklist_filt) # merge to avoid duplicate key issues + SESSION.commit() + BLACKLIST_SQL_.CHAT_BLACKLISTS.setdefault(str(chat_id), set()).add(trigger) + + +def rm_from_blacklist(chat_id, trigger): + with BLACKLIST_FILTER_INSERTION_LOCK: + if blacklist_filt := SESSION.query(BlackListFilters).get( + (str(chat_id), trigger) + ): + if trigger in BLACKLIST_SQL_.CHAT_BLACKLISTS.get( + str(chat_id), set() + ): # sanity check + BLACKLIST_SQL_.CHAT_BLACKLISTS.get(str(chat_id), set()).remove(trigger) + + SESSION.delete(blacklist_filt) + SESSION.commit() + return True + + SESSION.close() + return False + + +def get_chat_blacklist(chat_id): + return BLACKLIST_SQL_.CHAT_BLACKLISTS.get(str(chat_id), set()) + + +def num_blacklist_filters(): + try: + return SESSION.query(BlackListFilters).count() + finally: + SESSION.close() + + +def num_blacklist_chat_filters(chat_id): + try: + return ( + SESSION.query(BlackListFilters.chat_id) + .filter(BlackListFilters.chat_id == str(chat_id)) + .count() + ) + finally: + SESSION.close() + + +def num_blacklist_filter_chats(): + try: + return SESSION.query(func.count(distinct(BlackListFilters.chat_id))).scalar() + finally: + SESSION.close() + + +def __load_chat_blacklists(): + try: + chats = SESSION.query(BlackListFilters.chat_id).distinct().all() + for (chat_id,) in chats: # remove tuple by ( ,) + BLACKLIST_SQL_.CHAT_BLACKLISTS[chat_id] = [] + + all_filters = SESSION.query(BlackListFilters).all() + for x in all_filters: + BLACKLIST_SQL_.CHAT_BLACKLISTS[x.chat_id] += [x.trigger] + + BLACKLIST_SQL_.CHAT_BLACKLISTS = { + x: set(y) for x, y in BLACKLIST_SQL_.CHAT_BLACKLISTS.items() + } + + finally: + SESSION.close() + + +__load_chat_blacklists() diff --git a/repthon/sql_helper/bot_blacklists.py b/repthon/sql_helper/bot_blacklists.py new file mode 100644 index 0000000..501267b --- /dev/null +++ b/repthon/sql_helper/bot_blacklists.py @@ -0,0 +1,70 @@ +from sqlalchemy import Column, String, UnicodeText + +from . import BASE, SESSION + + +class Bot_BlackList(BASE): + __tablename__ = "bot_blacklist" + chat_id = Column(String(14), primary_key=True) + first_name = Column(UnicodeText) + username = Column(UnicodeText) + reason = Column(UnicodeText) + date = Column(UnicodeText) + + def __init__(self, chat_id, first_name, username, reason, date): + self.chat_id = str(chat_id) + self.username = username + self.reason = reason + self.date = date + self.first_name = first_name + + def __repr__(self): + return "" % self.chat_id + + +Bot_BlackList.__table__.create(checkfirst=True) + + +def add_user_to_bl( + chat_id: int, first_name: str, username: str, reason: str, date: str +): + """add the user to the blacklist""" + to_check = check_is_black_list(chat_id) + if not to_check: + __user = Bot_BlackList(str(chat_id), first_name, username, reason, date) + SESSION.add(__user) + SESSION.commit() + rem = SESSION.query(Bot_BlackList).get(str(chat_id)) + SESSION.delete(rem) + SESSION.commit() + user = Bot_BlackList(str(chat_id), first_name, username, reason, date) + SESSION.add(user) + SESSION.commit() + return True + + +def check_is_black_list(chat_id: int): + """check if user_id is blacklisted""" + try: + return SESSION.query(Bot_BlackList).get(str(chat_id)) + finally: + SESSION.close() + + +def rem_user_from_bl(chat_id: int): + """remove the user from the blacklist""" + if s__ := SESSION.query(Bot_BlackList).get(str(chat_id)): + SESSION.delete(s__) + SESSION.commit() + return True + SESSION.close() + return False + + +def get_all_bl_users(): + try: + return SESSION.query(Bot_BlackList).all() + except BaseException: + return None + finally: + SESSION.close() diff --git a/repthon/sql_helper/bot_pms_sql.py b/repthon/sql_helper/bot_pms_sql.py new file mode 100644 index 0000000..4cb97d2 --- /dev/null +++ b/repthon/sql_helper/bot_pms_sql.py @@ -0,0 +1,100 @@ +from sqlalchemy import Column, Integer, String, UnicodeText + +from . import BASE, SESSION + + +class Bot_Users(BASE): + __tablename__ = "bot_pms_data" + # pm logger message id + message_id = Column(Integer, primary_key=True) + first_name = Column(UnicodeText) + chat_id = Column(String(14)) + # in opposite user message id + reply_id = Column(Integer) + # pm logger message reply id + logger_id = Column(Integer) + # pm opposite user reply message id + result_id = Column(Integer, primary_key=True) + + def __init__(self, message_id, first_name, chat_id, reply_id, logger_id, result_id): + self.message_id = message_id + self.first_name = first_name + self.chat_id = str(chat_id) + self.reply_id = reply_id + self.logger_id = logger_id + self.result_id = result_id + + +Bot_Users.__table__.create(checkfirst=True) + + +def add_user_to_db(message_id, first_name, chat_id, reply_id, logger_id, result_id): + user = Bot_Users( + message_id, first_name, str(chat_id), reply_id, logger_id, result_id + ) + SESSION.add(user) + SESSION.commit() + return True + + +def get_user_id(message_id): + try: + if _result := ( + SESSION.query(Bot_Users) + .filter(Bot_Users.message_id == str(message_id)) + .all() + ): + return _result + return None + finally: + SESSION.close() + + +def del_user_from_db(message_id): + try: + if _result := ( + SESSION.query(Bot_Users) + .filter(Bot_Users.message_id == str(message_id)) + .all() + ): + for rst in _result: + rem = SESSION.query(Bot_Users).get((str(rst.message_id), rst.result_id)) + SESSION.delete(rem) + SESSION.commit() + return True + return False + finally: + SESSION.close() + + +def get_user_reply(reply_id): + try: + if _result := ( + SESSION.query(Bot_Users).filter(Bot_Users.reply_id == str(reply_id)).all() + ): + return _result + return None + finally: + SESSION.close() + + +def get_user_results(result_id): + try: + if _result := ( + SESSION.query(Bot_Users).filter(Bot_Users.result_id == str(result_id)).all() + ): + return _result + return None + finally: + SESSION.close() + + +def get_user_logging(logger_id): + try: + if _result := ( + SESSION.query(Bot_Users).filter(Bot_Users.logger_id == str(logger_id)).all() + ): + return _result + return None + finally: + SESSION.close() diff --git a/repthon/sql_helper/bot_starters.py b/repthon/sql_helper/bot_starters.py new file mode 100644 index 0000000..beb829c --- /dev/null +++ b/repthon/sql_helper/bot_starters.py @@ -0,0 +1,69 @@ +from sqlalchemy import Column, String, UnicodeText + +from . import BASE, SESSION + + +class Bot_Starters(BASE): + __tablename__ = "bot_starters" + user_id = Column(String(14), primary_key=True) + first_name = Column(UnicodeText) + date = Column(UnicodeText) + username = Column(UnicodeText) + + def __init__(self, user_id, first_name, date, username): + self.user_id = str(user_id) + self.first_name = first_name + self.date = date + self.username = username + + +Bot_Starters.__table__.create(checkfirst=True) + + +def add_starter_to_db( + user_id, + first_name, + date, + username, +): + to_check = get_starter_details(user_id) + if not to_check: + user = Bot_Starters(str(user_id), first_name, date, username) + SESSION.add(user) + SESSION.commit() + return True + rem = SESSION.query(Bot_Starters).get(str(user_id)) + SESSION.delete(rem) + SESSION.commit() + user = Bot_Starters(str(user_id), first_name, date, username) + SESSION.add(user) + SESSION.commit() + return True + + +def del_starter_from_db(user_id): + to_check = get_starter_details(user_id) + if not to_check: + return False + rem = SESSION.query(Bot_Starters).get(str(user_id)) + SESSION.delete(rem) + SESSION.commit() + return True + + +def get_starter_details(user_id): + try: + if _result := SESSION.query(Bot_Starters).get(str(user_id)): + return _result + return None + finally: + SESSION.close() + + +def get_all_starters(): + try: + return SESSION.query(Bot_Starters).all() + except BaseException: + return None + finally: + SESSION.close() diff --git a/repthon/sql_helper/broadcast_sql.py b/repthon/sql_helper/broadcast_sql.py new file mode 100644 index 0000000..bea2418 --- /dev/null +++ b/repthon/sql_helper/broadcast_sql.py @@ -0,0 +1,140 @@ +import threading + +from sqlalchemy import Column, String, UnicodeText, distinct, func + +from . import BASE, SESSION + + +class CatBroadcast(BASE): + __tablename__ = "catbroadcast" + keywoard = Column(UnicodeText, primary_key=True) + group_id = Column(String(14), primary_key=True, nullable=False) + + def __init__(self, keywoard, group_id): + self.keywoard = keywoard + self.group_id = str(group_id) + + def __repr__(self): + return "" % (self.group_id, self.keywoard) + + def __eq__(self, other): + return bool( + isinstance(other, CatBroadcast) + and self.keywoard == other.keywoard + and self.group_id == other.group_id + ) + + +CatBroadcast.__table__.create(checkfirst=True) + +CATBROADCAST_INSERTION_LOCK = threading.RLock() + + +class BROADCAST_SQL: + def __init__(self): + self.BROADCAST_CHANNELS = {} + + +BROADCAST_SQL_ = BROADCAST_SQL() + + +def add_to_broadcastlist(keywoard, group_id): + with CATBROADCAST_INSERTION_LOCK: + broadcast_group = CatBroadcast(keywoard, str(group_id)) + + SESSION.merge(broadcast_group) + SESSION.commit() + BROADCAST_SQL_.BROADCAST_CHANNELS.setdefault(keywoard, set()).add(str(group_id)) + + +def rm_from_broadcastlist(keywoard, group_id): + with CATBROADCAST_INSERTION_LOCK: + if broadcast_group := SESSION.query(CatBroadcast).get( + (keywoard, str(group_id)) + ): + if str(group_id) in BROADCAST_SQL_.BROADCAST_CHANNELS.get(keywoard, set()): + BROADCAST_SQL_.BROADCAST_CHANNELS.get(keywoard, set()).remove( + str(group_id) + ) + + SESSION.delete(broadcast_group) + SESSION.commit() + return True + + SESSION.close() + return False + + +def is_in_broadcastlist(keywoard, group_id): + with CATBROADCAST_INSERTION_LOCK: + broadcast_group = SESSION.query(CatBroadcast).get((keywoard, str(group_id))) + return bool(broadcast_group) + + +def del_keyword_broadcastlist(keywoard): + with CATBROADCAST_INSERTION_LOCK: + broadcast_group = ( + SESSION.query(CatBroadcast.keywoard) + .filter(CatBroadcast.keywoard == keywoard) + .delete() + ) + BROADCAST_SQL_.BROADCAST_CHANNELS.pop(keywoard) + SESSION.commit() + + +def get_chat_broadcastlist(keywoard): + return BROADCAST_SQL_.BROADCAST_CHANNELS.get(keywoard, set()) + + +def get_broadcastlist_chats(): + try: + chats = SESSION.query(CatBroadcast.keywoard).distinct().all() + return [i[0] for i in chats] + finally: + SESSION.close() + + +def num_broadcastlist(): + try: + return SESSION.query(CatBroadcast).count() + finally: + SESSION.close() + + +def num_broadcastlist_chat(keywoard): + try: + return ( + SESSION.query(CatBroadcast.keywoard) + .filter(CatBroadcast.keywoard == keywoard) + .count() + ) + finally: + SESSION.close() + + +def num_broadcastlist_chats(): + try: + return SESSION.query(func.count(distinct(CatBroadcast.keywoard))).scalar() + finally: + SESSION.close() + + +def __load_chat_broadcastlists(): + try: + chats = SESSION.query(CatBroadcast.keywoard).distinct().all() + for (keywoard,) in chats: + BROADCAST_SQL_.BROADCAST_CHANNELS[keywoard] = [] + + all_groups = SESSION.query(CatBroadcast).all() + for x in all_groups: + BROADCAST_SQL_.BROADCAST_CHANNELS[x.keywoard] += [x.group_id] + + BROADCAST_SQL_.BROADCAST_CHANNELS = { + x: set(y) for x, y in BROADCAST_SQL_.BROADCAST_CHANNELS.items() + } + + finally: + SESSION.close() + + +__load_chat_broadcastlists() diff --git a/repthon/sql_helper/chatbot_sql.py b/repthon/sql_helper/chatbot_sql.py new file mode 100644 index 0000000..7cb5f49 --- /dev/null +++ b/repthon/sql_helper/chatbot_sql.py @@ -0,0 +1,100 @@ +from sqlalchemy import Column, String, UnicodeText + +from . import BASE, SESSION + + +class ChatBot(BASE): + __tablename__ = "chatbot" + chat_id = Column(String(14), primary_key=True) + user_id = Column(String(14), primary_key=True, nullable=False) + chat_name = Column(UnicodeText) + user_name = Column(UnicodeText) + user_username = Column(UnicodeText) + chat_type = Column(UnicodeText) + + def __init__( + self, chat_id, user_id, chat_name, user_name, user_username, chat_type + ): + self.chat_id = str(chat_id) + self.user_id = str(user_id) + self.chat_name = chat_name + self.user_name = user_name + self.user_username = user_username + self.chat_type = chat_type + + def __eq__(self, other): + return bool( + isinstance(other, ChatBot) + and self.chat_id == other.chat_id + and self.user_id == other.user_id + ) + + +ChatBot.__table__.create(checkfirst=True) + + +def is_added(chat_id, user_id): + try: + return SESSION.query(ChatBot).get((str(chat_id), str(user_id))) + except BaseException: + return None + finally: + SESSION.close() + + +def get_users(chat_id): + try: + return SESSION.query(ChatBot).filter(ChatBot.chat_id == str(chat_id)).all() + finally: + SESSION.close() + + +def get_all_users(): + try: + return SESSION.query(ChatBot).all() + except BaseException: + return None + finally: + SESSION.close() + + +def addai(chat_id, user_id, chat_name, user_name, user_username, chat_type): + to_check = is_added(chat_id, user_id) + if not to_check: + adder = ChatBot( + str(chat_id), str(user_id), chat_name, user_name, user_username, chat_type + ) + SESSION.add(adder) + SESSION.commit() + return True + rem = SESSION.query(ChatBot).get((str(chat_id), str(user_id))) + SESSION.delete(rem) + SESSION.commit() + adder = ChatBot( + str(chat_id), str(user_id), chat_name, user_name, user_username, chat_type + ) + SESSION.add(adder) + SESSION.commit() + return False + + +def remove_ai(chat_id, user_id): + to_check = is_added(chat_id, user_id) + if not to_check: + return False + rem = SESSION.query(ChatBot).get((str(chat_id), str(user_id))) + SESSION.delete(rem) + SESSION.commit() + return True + + +def remove_users(chat_id): + if saved_filter := SESSION.query(ChatBot).filter(ChatBot.chat_id == str(chat_id)): + saved_filter.delete() + SESSION.commit() + + +def remove_all_users(): + if saved_filter := SESSION.query(ChatBot): + saved_filter.delete() + SESSION.commit() diff --git a/repthon/sql_helper/echo_sql.py b/repthon/sql_helper/echo_sql.py new file mode 100644 index 0000000..b01d334 --- /dev/null +++ b/repthon/sql_helper/echo_sql.py @@ -0,0 +1,100 @@ +from sqlalchemy import Column, String, UnicodeText + +from . import BASE, SESSION + + +class Echos(BASE): + __tablename__ = "echos" + chat_id = Column(String(14), primary_key=True) + user_id = Column(String(14), primary_key=True, nullable=False) + chat_name = Column(UnicodeText) + user_name = Column(UnicodeText) + user_username = Column(UnicodeText) + chat_type = Column(UnicodeText) + + def __init__( + self, chat_id, user_id, chat_name, user_name, user_username, chat_type + ): + self.chat_id = str(chat_id) + self.user_id = str(user_id) + self.chat_name = chat_name + self.user_name = user_name + self.user_username = user_username + self.chat_type = chat_type + + def __eq__(self, other): + return bool( + isinstance(other, Echos) + and self.chat_id == other.chat_id + and self.user_id == other.user_id + ) + + +Echos.__table__.create(checkfirst=True) + + +def is_echo(chat_id, user_id): + try: + return SESSION.query(Echos).get((str(chat_id), str(user_id))) + except BaseException: + return None + finally: + SESSION.close() + + +def get_echos(chat_id): + try: + return SESSION.query(Echos).filter(Echos.chat_id == str(chat_id)).all() + finally: + SESSION.close() + + +def get_all_echos(): + try: + return SESSION.query(Echos).all() + except BaseException: + return None + finally: + SESSION.close() + + +def addecho(chat_id, user_id, chat_name, user_name, user_username, chat_type): + to_check = is_echo(chat_id, user_id) + if not to_check: + adder = Echos( + str(chat_id), str(user_id), chat_name, user_name, user_username, chat_type + ) + SESSION.add(adder) + SESSION.commit() + return True + rem = SESSION.query(Echos).get((str(chat_id), str(user_id))) + SESSION.delete(rem) + SESSION.commit() + adder = Echos( + str(chat_id), str(user_id), chat_name, user_name, user_username, chat_type + ) + SESSION.add(adder) + SESSION.commit() + return False + + +def remove_echo(chat_id, user_id): + to_check = is_echo(chat_id, user_id) + if not to_check: + return False + rem = SESSION.query(Echos).get((str(chat_id), str(user_id))) + SESSION.delete(rem) + SESSION.commit() + return True + + +def remove_echos(chat_id): + if saved_filter := SESSION.query(Echos).filter(Echos.chat_id == str(chat_id)): + saved_filter.delete() + SESSION.commit() + + +def remove_all_echos(): + if saved_filter := SESSION.query(Echos): + saved_filter.delete() + SESSION.commit() diff --git a/repthon/sql_helper/filter_sql.py b/repthon/sql_helper/filter_sql.py new file mode 100644 index 0000000..2f2214a --- /dev/null +++ b/repthon/sql_helper/filter_sql.py @@ -0,0 +1,73 @@ +from sqlalchemy import Column, Numeric, String, UnicodeText + +from . import BASE, SESSION + + +class Filter(BASE): + __tablename__ = "catfilters" + chat_id = Column(String(14), primary_key=True) + keyword = Column(UnicodeText, primary_key=True, nullable=False) + reply = Column(UnicodeText) + f_mesg_id = Column(Numeric) + + def __init__(self, chat_id, keyword, reply, f_mesg_id): + self.chat_id = str(chat_id) + self.keyword = keyword + self.reply = reply + self.f_mesg_id = f_mesg_id + + def __eq__(self, other): + return bool( + isinstance(other, Filter) + and self.chat_id == other.chat_id + and self.keyword == other.keyword + ) + + +Filter.__table__.create(checkfirst=True) + + +def get_filter(chat_id, keyword): + try: + return SESSION.query(Filter).get((str(chat_id), keyword)) + finally: + SESSION.close() + + +def get_filters(chat_id): + try: + return SESSION.query(Filter).filter(Filter.chat_id == str(chat_id)).all() + finally: + SESSION.close() + + +def add_filter(chat_id, keyword, reply, f_mesg_id): + to_check = get_filter(chat_id, keyword) + if not to_check: + adder = Filter(str(chat_id), keyword, reply, f_mesg_id) + SESSION.add(adder) + SESSION.commit() + return True + rem = SESSION.query(Filter).get((str(chat_id), keyword)) + SESSION.delete(rem) + SESSION.commit() + adder = Filter(str(chat_id), keyword, reply, f_mesg_id) + SESSION.add(adder) + SESSION.commit() + return False + + +def remove_filter(chat_id, keyword): + to_check = get_filter(chat_id, keyword) + if not to_check: + return False + rem = SESSION.query(Filter).get((str(chat_id), keyword)) + SESSION.delete(rem) + SESSION.commit() + return True + + +def remove_all_filters(chat_id): + if saved_filter := SESSION.query(Filter).filter(Filter.chat_id == str(chat_id)): + saved_filter.delete() + SESSION.commit() diff --git a/repthon/sql_helper/fsub_sql.py b/repthon/sql_helper/fsub_sql.py new file mode 100644 index 0000000..f4942cf --- /dev/null +++ b/repthon/sql_helper/fsub_sql.py @@ -0,0 +1,82 @@ +from sqlalchemy import Column, Numeric, String + +from . import BASE, SESSION + + +class forceSubscribe(BASE): + __tablename__ = "forceSubscribe" + chat_id = Column(Numeric, primary_key=True) + channel = Column(String) + + def __init__(self, chat_id, channel): + self.chat_id = chat_id + self.channel = channel + + +forceSubscribe.__table__.create(checkfirst=True) + + +def fs_settings(chat_id): + try: + return ( + SESSION.query(forceSubscribe) + .filter(forceSubscribe.chat_id == chat_id) + .one() + ) + except: + return None + finally: + SESSION.close() + + +def is_fsub(chat_id): + try: + return ( + SESSION.query(forceSubscribe) + .filter(forceSubscribe.chat_id == chat_id) + .one() + ) + except: + return None + finally: + SESSION.close() + + +def add_fsub(chat_id, channel): + adder = SESSION.query(forceSubscribe).get(chat_id) + if adder: + adder.channel = channel + else: + adder = forceSubscribe(chat_id, channel) + SESSION.add(adder) + SESSION.commit() + + +def rm_fsub(chat_id): + rem = SESSION.query(forceSubscribe).get(chat_id) + if rem: + SESSION.delete(rem) + SESSION.commit() + + +def all_fsub(): + rem = SESSION.query(forceSubscribe).all() + SESSION.close() + return rem + + +def add_channel(chat_id, channel): + adder = SESSION.query(forceSubscribe).get(chat_id) + if adder: + adder.channel = channel + else: + adder = forceSubscribe(chat_id, channel) + SESSION.add(adder) + SESSION.commit() + + +def disapprove(chat_id): + rem = SESSION.query(forceSubscribe).get(chat_id) + if rem: + SESSION.delete(rem) + SESSION.commit() diff --git a/repthon/sql_helper/gban_sql_helper.py b/repthon/sql_helper/gban_sql_helper.py new file mode 100644 index 0000000..4856364 --- /dev/null +++ b/repthon/sql_helper/gban_sql_helper.py @@ -0,0 +1,64 @@ +""" +credits to @mrconfused and @sandy1709 +""" +# Copyright (C) 2020 sandeep.n(π.$) +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +from sqlalchemy import Column, String + +from . import BASE, SESSION + + +class GBan(BASE): + __tablename__ = "gban" + chat_id = Column(String(14), primary_key=True) + reason = Column(String(127)) + + def __init__(self, chat_id, reason=""): + self.chat_id = chat_id + self.reason = reason + + +GBan.__table__.create(checkfirst=True) + + +def is_gbanned(chat_id): + try: + return SESSION.query(GBan).filter(GBan.chat_id == str(chat_id)).one() + except BaseException: + return None + finally: + SESSION.close() + + +def get_gbanuser(chat_id): + try: + return SESSION.query(GBan).get(str(chat_id)) + finally: + SESSION.close() + + +def catgban(chat_id, reason): + adder = GBan(str(chat_id), str(reason)) + SESSION.add(adder) + SESSION.commit() + + +def catungban(chat_id): + if rem := SESSION.query(GBan).get(str(chat_id)): + SESSION.delete(rem) + SESSION.commit() + + +def get_all_gbanned(): + rem = SESSION.query(GBan).all() + SESSION.close() + return rem diff --git a/repthon/sql_helper/gdrive_sql.py b/repthon/sql_helper/gdrive_sql.py new file mode 100644 index 0000000..a7ed005 --- /dev/null +++ b/repthon/sql_helper/gdrive_sql.py @@ -0,0 +1,60 @@ +""" +credits to @mrconfused and @sandy1709 +""" +# Copyright (C) 2020 sandeep.n(π.$) +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +from sqlalchemy import Column, String + +from . import BASE, SESSION + + +class Gdrive(BASE): + __tablename__ = "catgdrive" + cat = Column(String(50), primary_key=True) + + def __init__(self, cat): + self.cat = cat + + +Gdrive.__table__.create(checkfirst=True) + + +def is_folder(folder_id): + try: + return SESSION.query(Gdrive).filter(Gdrive.cat == str(folder_id)) + except BaseException: + return None + finally: + SESSION.close() + + +def gparent_id(folder_id): + adder = SESSION.query(Gdrive).get(folder_id) + if not adder: + adder = Gdrive(folder_id) + SESSION.add(adder) + SESSION.commit() + + +def get_parent_id(): + try: + return SESSION.query(Gdrive).all() + except BaseException: + return None + finally: + SESSION.close() + + +def rmparent_id(folder_id): + if note := SESSION.query(Gdrive).filter(Gdrive.cat == folder_id): + note.delete() + SESSION.commit() diff --git a/repthon/sql_helper/global_collection.py b/repthon/sql_helper/global_collection.py new file mode 100644 index 0000000..93f7562 --- /dev/null +++ b/repthon/sql_helper/global_collection.py @@ -0,0 +1,144 @@ +import threading + +from sqlalchemy import Column, PickleType, UnicodeText, distinct, func + +from . import BASE, SESSION + + +class Cat_GlobalCollection(BASE): + __tablename__ = "cat_globalcollection" + keywoard = Column(UnicodeText, primary_key=True) + contents = Column(PickleType, primary_key=True, nullable=False) + + def __init__(self, keywoard, contents): + self.keywoard = keywoard + self.contents = tuple(contents) + + def __repr__(self): + return "" % ( + self.contents, + self.keywoard, + ) + + def __eq__(self, other): + return bool( + isinstance(other, Cat_GlobalCollection) + and self.keywoard == other.keywoard + and self.contents == other.contents + ) + + +Cat_GlobalCollection.__table__.create(checkfirst=True) + +CAT_GLOBALCOLLECTION = threading.RLock() + + +class COLLECTION_SQL: + def __init__(self): + self.CONTENTS_LIST = {} + + +COLLECTION_SQL_ = COLLECTION_SQL() + + +def add_to_collectionlist(keywoard, contents): + with CAT_GLOBALCOLLECTION: + keyword_items = Cat_GlobalCollection(keywoard, tuple(contents)) + + SESSION.merge(keyword_items) + SESSION.commit() + COLLECTION_SQL_.CONTENTS_LIST.setdefault(keywoard, set()).add(tuple(contents)) + + +def rm_from_collectionlist(keywoard, contents): + with CAT_GLOBALCOLLECTION: + if keyword_items := SESSION.query(Cat_GlobalCollection).get( + (keywoard, tuple(contents)) + ): + if tuple(contents) in COLLECTION_SQL_.CONTENTS_LIST.get(keywoard, set()): + COLLECTION_SQL_.CONTENTS_LIST.get(keywoard, set()).remove( + tuple(contents) + ) + SESSION.delete(keyword_items) + SESSION.commit() + return True + + SESSION.close() + return False + + +def is_in_collectionlist(keywoard, contents): + with CAT_GLOBALCOLLECTION: + keyword_items = COLLECTION_SQL_.CONTENTS_LIST.get(keywoard, set()) + return any(tuple(contents) == list1 for list1 in keyword_items) + + +def del_keyword_collectionlist(keywoard): + with CAT_GLOBALCOLLECTION: + keyword_items = ( + SESSION.query(Cat_GlobalCollection.keywoard) + .filter(Cat_GlobalCollection.keywoard == keywoard) + .delete() + ) + COLLECTION_SQL_.CONTENTS_LIST.pop(keywoard) + SESSION.commit() + + +def get_item_collectionlist(keywoard): + return COLLECTION_SQL_.CONTENTS_LIST.get(keywoard, set()) + + +def get_collectionlist_items(): + try: + chats = SESSION.query(Cat_GlobalCollection.keywoard).distinct().all() + return [i[0] for i in chats] + finally: + SESSION.close() + + +def num_collectionlist(): + try: + return SESSION.query(Cat_GlobalCollection).count() + finally: + SESSION.close() + + +def num_collectionlist_item(keywoard): + try: + return ( + SESSION.query(Cat_GlobalCollection.keywoard) + .filter(Cat_GlobalCollection.keywoard == keywoard) + .count() + ) + finally: + SESSION.close() + + +def num_collectionlist_items(): + try: + return SESSION.query( + func.count(distinct(Cat_GlobalCollection.keywoard)) + ).scalar() + finally: + SESSION.close() + + +def __load_item_collectionlists(): + try: + chats = SESSION.query(Cat_GlobalCollection.keywoard).distinct().all() + for (keywoard,) in chats: + COLLECTION_SQL_.CONTENTS_LIST[keywoard] = [] + + all_groups = SESSION.query(Cat_GlobalCollection).all() + for x in all_groups: + COLLECTION_SQL_.CONTENTS_LIST[x.keywoard] += [x.contents] + + COLLECTION_SQL_.CONTENTS_LIST = { + x: set(y) for x, y in COLLECTION_SQL_.CONTENTS_LIST.items() + } + + finally: + SESSION.close() + + +__load_item_collectionlists() diff --git a/repthon/sql_helper/global_collectionjson.py b/repthon/sql_helper/global_collectionjson.py new file mode 100644 index 0000000..07b730d --- /dev/null +++ b/repthon/sql_helper/global_collectionjson.py @@ -0,0 +1,56 @@ +from sqlalchemy import Column, UnicodeText +from sqlalchemy_json import MutableJson, NestedMutableJson + +from . import BASE, SESSION + + +class Cat_GlobalCollection_Json(BASE): + __tablename__ = "cat_globalcollectionjson" + keywoard = Column(UnicodeText, primary_key=True) + json = Column(MutableJson) + njson = Column(NestedMutableJson) + + def __init__(self, keywoard, json, njson): + self.keywoard = keywoard + self.json = json + self.njson = njson + + +Cat_GlobalCollection_Json.__table__.create(checkfirst=True) + + +def get_collection(keywoard): + try: + return SESSION.query(Cat_GlobalCollection_Json).get(keywoard) + finally: + SESSION.close() + + +def add_collection(keywoard, json, njson=None): + if njson is None: + njson = {} + to_check = get_collection(keywoard) + if to_check: + keyword_items = SESSION.query(Cat_GlobalCollection_Json).get(keywoard) + SESSION.delete(keyword_items) + keyword_items = Cat_GlobalCollection_Json(keywoard, json, njson) + SESSION.add(keyword_items) + SESSION.commit() + return True + + +def del_collection(keywoard): + to_check = get_collection(keywoard) + if not to_check: + return False + keyword_items = SESSION.query(Cat_GlobalCollection_Json).get(keywoard) + SESSION.delete(keyword_items) + SESSION.commit() + return True + + +def get_collections(): + try: + return SESSION.query(Cat_GlobalCollection_Json).all() + finally: + SESSION.close() diff --git a/repthon/sql_helper/global_list.py b/repthon/sql_helper/global_list.py new file mode 100644 index 0000000..3d485fe --- /dev/null +++ b/repthon/sql_helper/global_list.py @@ -0,0 +1,138 @@ +import threading + +from sqlalchemy import Column, String, UnicodeText, distinct, func + +from . import BASE, SESSION + + +class CatGloballist(BASE): + __tablename__ = "catglobal_list" + keywoard = Column(UnicodeText, primary_key=True) + group_id = Column(String, primary_key=True, nullable=False) + + def __init__(self, keywoard, group_id): + self.keywoard = keywoard + self.group_id = str(group_id) + + def __repr__(self): + return "" % (self.group_id, self.keywoard) + + def __eq__(self, other): + return bool( + isinstance(other, CatGloballist) + and self.keywoard == other.keywoard + and self.group_id == other.group_id + ) + + +CatGloballist.__table__.create(checkfirst=True) + +CATGLOBALLIST_INSERTION_LOCK = threading.RLock() + + +class GLOBALLIST_SQL: + def __init__(self): + self.GLOBALLIST_VALUES = {} + + +GLOBALLIST_SQL_ = GLOBALLIST_SQL() + + +def add_to_list(keywoard, group_id): + with CATGLOBALLIST_INSERTION_LOCK: + broadcast_group = CatGloballist(keywoard, str(group_id)) + SESSION.merge(broadcast_group) + SESSION.commit() + GLOBALLIST_SQL_.GLOBALLIST_VALUES.setdefault(keywoard, set()).add(str(group_id)) + + +def rm_from_list(keywoard, group_id): + with CATGLOBALLIST_INSERTION_LOCK: + if broadcast_group := SESSION.query(CatGloballist).get( + (keywoard, str(group_id)) + ): + if str(group_id) in GLOBALLIST_SQL_.GLOBALLIST_VALUES.get(keywoard, set()): + GLOBALLIST_SQL_.GLOBALLIST_VALUES.get(keywoard, set()).remove( + str(group_id) + ) + + SESSION.delete(broadcast_group) + SESSION.commit() + return True + SESSION.close() + return False + + +def is_in_list(keywoard, group_id): + with CATGLOBALLIST_INSERTION_LOCK: + broadcast_group = SESSION.query(CatGloballist).get((keywoard, str(group_id))) + return bool(broadcast_group) + + +def del_keyword_list(keywoard): + with CATGLOBALLIST_INSERTION_LOCK: + broadcast_group = ( + SESSION.query(CatGloballist.keywoard) + .filter(CatGloballist.keywoard == keywoard) + .delete() + ) + GLOBALLIST_SQL_.GLOBALLIST_VALUES.pop(keywoard) + SESSION.commit() + + +def get_collection_list(keywoard): + return GLOBALLIST_SQL_.GLOBALLIST_VALUES.get(keywoard, set()) + + +def get_list_keywords(): + try: + chats = SESSION.query(CatGloballist.keywoard).distinct().all() + return [i[0] for i in chats] + finally: + SESSION.close() + + +def num_list(): + try: + return SESSION.query(CatGloballist).count() + finally: + SESSION.close() + + +def num_list_keyword(keywoard): + try: + return ( + SESSION.query(CatGloballist.keywoard) + .filter(CatGloballist.keywoard == keywoard) + .count() + ) + finally: + SESSION.close() + + +def num_list_keywords(): + try: + return SESSION.query(func.count(distinct(CatGloballist.keywoard))).scalar() + finally: + SESSION.close() + + +def __load_chat_lists(): + try: + chats = SESSION.query(CatGloballist.keywoard).distinct().all() + for (keywoard,) in chats: + GLOBALLIST_SQL_.GLOBALLIST_VALUES[keywoard] = [] + + all_groups = SESSION.query(CatGloballist).all() + for x in all_groups: + GLOBALLIST_SQL_.GLOBALLIST_VALUES[x.keywoard] += [x.group_id] + + GLOBALLIST_SQL_.GLOBALLIST_VALUES = { + x: set(y) for x, y in GLOBALLIST_SQL_.GLOBALLIST_VALUES.items() + } + + finally: + SESSION.close() + + +__load_chat_lists() diff --git a/repthon/sql_helper/globals.py b/repthon/sql_helper/globals.py new file mode 100644 index 0000000..028b46d --- /dev/null +++ b/repthon/sql_helper/globals.py @@ -0,0 +1,50 @@ +try: + from . import BASE, SESSION +except ImportError as e: + raise AttributeError from e +from sqlalchemy import Column, String, UnicodeText + + +class Globals(BASE): + __tablename__ = "globals" + variable = Column(String, primary_key=True, nullable=False) + value = Column(UnicodeText, primary_key=True, nullable=False) + + def __init__(self, variable, value): + self.variable = str(variable) + self.value = value + + +Globals.__table__.create(checkfirst=True) + + +def gvarstatus(variable): + try: + return ( + SESSION.query(Globals) + .filter(Globals.variable == str(variable)) + .first() + .value + ) + except BaseException: + return None + finally: + SESSION.close() + + +def addgvar(variable, value): + if SESSION.query(Globals).filter(Globals.variable == str(variable)).one_or_none(): + delgvar(variable) + adder = Globals(str(variable), value) + SESSION.add(adder) + SESSION.commit() + + +def delgvar(variable): + rem = ( + SESSION.query(Globals) + .filter(Globals.variable == str(variable)) + .delete(synchronize_session="fetch") + ) + if rem: + SESSION.commit() diff --git a/repthon/sql_helper/gmute_sql.py b/repthon/sql_helper/gmute_sql.py new file mode 100644 index 0000000..8d405d1 --- /dev/null +++ b/repthon/sql_helper/gmute_sql.py @@ -0,0 +1,38 @@ +try: + from . import BASE, SESSION +except ImportError as e: + raise Exception("Hello!") from e + +from sqlalchemy import Column, String + + +class GMute(BASE): + __tablename__ = "gmute" + sender = Column(String(14), primary_key=True) + + def __init__(self, sender): + self.sender = str(sender) + + +GMute.__table__.create(checkfirst=True) + + +def is_gmuted(sender_id): + try: + return SESSION.query(GMute).all() + except BaseException: + return None + finally: + SESSION.close() + + +def gmute(sender): + adder = GMute(str(sender)) + SESSION.add(adder) + SESSION.commit() + + +def ungmute(sender): + if rem := SESSION.query(GMute).get((str(sender))): + SESSION.delete(rem) + SESSION.commit() diff --git a/repthon/sql_helper/google_drive_sql.py b/repthon/sql_helper/google_drive_sql.py new file mode 100644 index 0000000..b61655d --- /dev/null +++ b/repthon/sql_helper/google_drive_sql.py @@ -0,0 +1,42 @@ +from sqlalchemy import Column, String, Text + +from . import BASE, SESSION + + +class GoogleDriveCreds(BASE): + __tablename__ = "gdrive" + user = Column(String, primary_key=True) + credentials = Column(Text, nullable=False) + + def __init__(self, user): + self.user = user + + +GoogleDriveCreds.__table__.create(checkfirst=True) + + +def save_credentials(user, credentials): + saved_credentials = SESSION.query(GoogleDriveCreds).get(user) + if not saved_credentials: + saved_credentials = GoogleDriveCreds(user) + + saved_credentials.credentials = credentials + + SESSION.add(saved_credentials) + SESSION.commit() + return True + + +def get_credentials(user): + try: + saved_credentials = SESSION.query(GoogleDriveCreds).get(user) + return saved_credentials.credentials if saved_credentials is not None else None + finally: + SESSION.close() + + +def clear_credentials(user): + if saved_credentials := SESSION.query(GoogleDriveCreds).get(user): + SESSION.delete(saved_credentials) + SESSION.commit() + return True diff --git a/repthon/sql_helper/locks_sql.py b/repthon/sql_helper/locks_sql.py new file mode 100644 index 0000000..4362112 --- /dev/null +++ b/repthon/sql_helper/locks_sql.py @@ -0,0 +1,259 @@ +# Zed-Thon +# Copyright (C) 2022 Zed-Thon . All Rights Reserved +# +# This file is a part of < https://github.com/Zed-Thon/ZelZal/ > +# PLease read the GNU Affero General Public License in +# . +from sqlalchemy import Column, String, Boolean + +from . import BASE, SESSION + + + +class Permissions(BASE): + __tablename__ = "permissions" + chat_id = Column(String(14), primary_key=True) + # Booleans are for "is this locked", _NOT_ "is this allowed" + audio = Column(Boolean, default=False) + voice = Column(Boolean, default=False) + contact = Column(Boolean, default=False) + video = Column(Boolean, default=False) + document = Column(Boolean, default=False) + photo = Column(Boolean, default=False) + sticker = Column(Boolean, default=False) + gif = Column(Boolean, default=False) + url = Column(Boolean, default=False) + bots = Column(Boolean, default=False) + forward = Column(Boolean, default=False) + game = Column(Boolean, default=False) + location = Column(Boolean, default=False) + rtl = Column(Boolean, default=False) + button = Column(Boolean, default=False) + egame = Column(Boolean, default=False) + inline = Column(Boolean, default=False) + + def __init__(self, chat_id): + self.chat_id = str(chat_id) # ensure string + self.audio = False + self.voice = False + self.contact = False + self.video = False + self.document = False + self.photo = False + self.sticker = False + self.gif = False + self.url = False + self.bots = False + self.forward = False + self.game = False + self.location = False + self.rtl = False + self.button = False + self.egame = False + self.inline = False + + def __repr__(self): + return "" % self.chat_id + + +class Restrictions(BASE): + __tablename__ = "restrictions" + chat_id = Column(String(14), primary_key=True) + # Booleans are for "is this restricted", _NOT_ "is this allowed" + messages = Column(Boolean, default=False) + media = Column(Boolean, default=False) + other = Column(Boolean, default=False) + preview = Column(Boolean, default=False) + + def __init__(self, chat_id): + self.chat_id = str(chat_id) # ensure string + self.messages = False + self.media = False + self.other = False + self.preview = False + + def __repr__(self): + return "" % self.chat_id + + +# For those who faced database error, Just uncomment the +# line below and run bot for 1 time & remove that line! + +Permissions.__table__.create(checkfirst=True) +# Permissions.__table__.drop() +Restrictions.__table__.create(checkfirst=True) + + + +def init_permissions(chat_id, reset=False): + curr_perm = SESSION.query(Permissions).get(str(chat_id)) + if reset: + SESSION.delete(curr_perm) + SESSION.flush() + perm = Permissions(str(chat_id)) + SESSION.add(perm) + SESSION.commit() + return perm + + +def init_restrictions(chat_id, reset=False): + curr_restr = SESSION.query(Restrictions).get(str(chat_id)) + if reset: + SESSION.delete(curr_restr) + SESSION.flush() + restr = Restrictions(str(chat_id)) + SESSION.add(restr) + SESSION.commit() + return restr + + +def update_lock(chat_id, lock_type, locked): + curr_perm = SESSION.query(Permissions).get(str(chat_id)) + if not curr_perm: + curr_perm = init_permissions(chat_id) + if lock_type == "audio": + curr_perm.audio = locked + elif lock_type == "voice": + curr_perm.voice = locked + elif lock_type == "contact": + curr_perm.contact = locked + elif lock_type == "video": + curr_perm.video = locked + elif lock_type == "document": + curr_perm.document = locked + elif lock_type == "photo": + curr_perm.photo = locked + elif lock_type == "sticker": + curr_perm.sticker = locked + elif lock_type == "gif": + curr_perm.gif = locked + elif lock_type == "url": + curr_perm.url = locked + elif lock_type == "bots": + curr_perm.bots = locked + elif lock_type == "forward": + curr_perm.forward = locked + elif lock_type == "game": + curr_perm.game = locked + elif lock_type == "location": + curr_perm.location = locked + elif lock_type == "rtl": + curr_perm.rtl = locked + elif lock_type == "button": + curr_perm.button = locked + elif lock_type == "egame": + curr_perm.egame = locked + elif lock_type == "inline": + curr_perm.inline = locked + SESSION.add(curr_perm) + SESSION.commit() + + +def update_restriction(chat_id, restr_type, locked): + curr_restr = SESSION.query(Restrictions).get(str(chat_id)) + if not curr_restr: + curr_restr = init_restrictions(chat_id) + if restr_type == "messages": + curr_restr.messages = locked + elif restr_type == "media": + curr_restr.media = locked + elif restr_type == "other": + curr_restr.other = locked + elif restr_type == "previews": + curr_restr.preview = locked + elif restr_type == "all": + curr_restr.messages = locked + curr_restr.media = locked + curr_restr.other = locked + curr_restr.preview = locked + SESSION.add(curr_restr) + SESSION.commit() + + +def is_locked(chat_id, lock_type): + curr_perm = SESSION.query(Permissions).get(str(chat_id)) + SESSION.close() + if not curr_perm: + return False + elif lock_type == "sticker": + return curr_perm.sticker + elif lock_type == "photo": + return curr_perm.photo + elif lock_type == "audio": + return curr_perm.audio + elif lock_type == "voice": + return curr_perm.voice + elif lock_type == "contact": + return curr_perm.contact + elif lock_type == "video": + return curr_perm.video + elif lock_type == "document": + return curr_perm.document + elif lock_type == "gif": + return curr_perm.gif + elif lock_type == "url": + return curr_perm.url + elif lock_type == "bots": + return curr_perm.bots + elif lock_type == "forward": + return curr_perm.forward + elif lock_type == "game": + return curr_perm.game + elif lock_type == "location": + return curr_perm.location + elif lock_type == "rtl": + return curr_perm.rtl + elif lock_type == "button": + return curr_perm.button + elif lock_type == "egame": + return curr_perm.egame + elif lock_type == "inline": + return curr_perm.inline + + +def is_restr_locked(chat_id, lock_type): + curr_restr = SESSION.query(Restrictions).get(str(chat_id)) + SESSION.close() + if not curr_restr: + return False + if lock_type == "messages": + return curr_restr.messages + elif lock_type == "media": + return curr_restr.media + elif lock_type == "other": + return curr_restr.other + elif lock_type == "previews": + return curr_restr.preview + elif lock_type == "all": + return ( + curr_restr.messages + and curr_restr.media + and curr_restr.other + and curr_restr.preview + ) + + +def get_locks(chat_id): + try: + return SESSION.query(Permissions).get(str(chat_id)) + finally: + SESSION.close() + + +def get_restr(chat_id): + try: + return SESSION.query(Restrictions).get(str(chat_id)) + finally: + SESSION.close() + + +def migrate_chat(old_chat_id, new_chat_id): + perms = SESSION.query(Permissions).get(str(old_chat_id)) + if perms: + perms.chat_id = str(new_chat_id) + SESSION.commit() + + rest = SESSION.query(Restrictions).get(str(old_chat_id)) + if rest: + rest.chat_id = str(new_chat_id) + SESSION.commit() diff --git a/repthon/sql_helper/mute_sql.py b/repthon/sql_helper/mute_sql.py new file mode 100644 index 0000000..cd3b7b2 --- /dev/null +++ b/repthon/sql_helper/mute_sql.py @@ -0,0 +1,35 @@ +try: + from . import BASE, SESSION +except ImportError as e: + raise Exception("Hello!") from e +from sqlalchemy import Column, String + + +class Mute(BASE): + __tablename__ = "mute" + sender = Column(String(14), primary_key=True) + chat_id = Column(String(14), primary_key=True) + + def __init__(self, sender, chat_id): + self.sender = str(sender) + self.chat_id = str(chat_id) + + +Mute.__table__.create(checkfirst=True) + + +def is_muted(sender, chat_id): + user = SESSION.query(Mute).get((str(sender), str(chat_id))) + return bool(user) + + +def mute(sender, chat_id): + adder = Mute(str(sender), str(chat_id)) + SESSION.add(adder) + SESSION.commit() + + +def unmute(sender, chat_id): + if rem := SESSION.query(Mute).get((str(sender), str(chat_id))): + SESSION.delete(rem) + SESSION.commit() diff --git a/repthon/sql_helper/no_log_pms_sql.py b/repthon/sql_helper/no_log_pms_sql.py new file mode 100644 index 0000000..d494ba6 --- /dev/null +++ b/repthon/sql_helper/no_log_pms_sql.py @@ -0,0 +1,35 @@ +from sqlalchemy import Column, Numeric + +from . import BASE, SESSION + + +class NOLogPMs(BASE): + __tablename__ = "no_log_pms" + chat_id = Column(Numeric, primary_key=True) + + def __init__(self, chat_id, reason=""): + self.chat_id = chat_id + + +NOLogPMs.__table__.create(checkfirst=True) + + +def is_approved(chat_id): + try: + return SESSION.query(NOLogPMs).filter(NOLogPMs.chat_id == chat_id).one() + except BaseException: + return None + finally: + SESSION.close() + + +def approve(chat_id): + adder = NOLogPMs(chat_id) + SESSION.add(adder) + SESSION.commit() + + +def disapprove(chat_id): + if rem := SESSION.query(NOLogPMs).get(chat_id): + SESSION.delete(rem) + SESSION.commit() diff --git a/repthon/sql_helper/pmpermit_sql.py b/repthon/sql_helper/pmpermit_sql.py new file mode 100644 index 0000000..18cad49 --- /dev/null +++ b/repthon/sql_helper/pmpermit_sql.py @@ -0,0 +1,77 @@ +from sqlalchemy import Column, String, UnicodeText + +from . import BASE, SESSION + + +class PmPermit_Sql(BASE): + __tablename__ = "pmpermit_sql" + user_id = Column(String(14), primary_key=True) + first_name = Column(UnicodeText) + date = Column(UnicodeText) + username = Column(UnicodeText) + reason = Column(UnicodeText) + + def __init__(self, user_id, first_name, date, username, reason): + self.user_id = str(user_id) + self.first_name = first_name + self.date = date + self.username = username + self.reason = reason + + +PmPermit_Sql.__table__.create(checkfirst=True) + + +def approve(user_id, first_name, date, username, reason): + to_check = is_approved(user_id) + if not to_check: + user = PmPermit_Sql(str(user_id), first_name, date, username, reason) + SESSION.add(user) + SESSION.commit() + return True + rem = SESSION.query(PmPermit_Sql).get(str(user_id)) + SESSION.delete(rem) + SESSION.commit() + user = PmPermit_Sql(str(user_id), first_name, date, username, reason) + SESSION.add(user) + SESSION.commit() + return True + + +def disapprove(user_id): + to_check = is_approved(user_id) + if not to_check: + return False + rem = SESSION.query(PmPermit_Sql).get(str(user_id)) + SESSION.delete(rem) + SESSION.commit() + return True + + +def is_approved(user_id): + try: + if _result := SESSION.query(PmPermit_Sql).get(str(user_id)): + return _result + return None + finally: + SESSION.close() + + +def get_all_approved(): + try: + return SESSION.query(PmPermit_Sql).all() + except BaseException: + return None + finally: + SESSION.close() + + +def disapprove_all(): + try: + SESSION.query(PmPermit_Sql).delete() + SESSION.commit() + return True + except BaseException: + return False + finally: + SESSION.close() diff --git a/repthon/sql_helper/snip_sql.py b/repthon/sql_helper/snip_sql.py new file mode 100644 index 0000000..2c4c720 --- /dev/null +++ b/repthon/sql_helper/snip_sql.py @@ -0,0 +1,58 @@ +from sqlalchemy import Column, Numeric, UnicodeText + +from . import BASE, SESSION + + +class Note(BASE): + __tablename__ = "catsnip" + keyword = Column(UnicodeText, primary_key=True, nullable=False) + reply = Column(UnicodeText) + f_mesg_id = Column(Numeric) + + def __init__(self, keyword, reply, f_mesg_id): + self.keyword = keyword + self.reply = reply + self.f_mesg_id = f_mesg_id + + +Note.__table__.create(checkfirst=True) + + +def get_note(keyword): + try: + return SESSION.query(Note).get(keyword) + finally: + SESSION.close() + + +def get_notes(): + try: + return SESSION.query(Note).all() + finally: + SESSION.close() + + +def add_note(keyword, reply, f_mesg_id): + to_check = get_note(keyword) + if not to_check: + adder = Note(keyword, reply, f_mesg_id) + SESSION.add(adder) + SESSION.commit() + return True + rem = SESSION.query(Note).get(keyword) + SESSION.delete(rem) + SESSION.commit() + adder = Note(keyword, reply, f_mesg_id) + SESSION.add(adder) + SESSION.commit() + return False + + +def rm_note(keyword): + to_check = get_note(keyword) + if not to_check: + return False + rem = SESSION.query(Note).get(keyword) + SESSION.delete(rem) + SESSION.commit() + return True diff --git a/repthon/sql_helper/warns_sql.py b/repthon/sql_helper/warns_sql.py new file mode 100644 index 0000000..bebfc71 --- /dev/null +++ b/repthon/sql_helper/warns_sql.py @@ -0,0 +1,139 @@ +import threading + +from sqlalchemy import Boolean, Column, Integer, String, UnicodeText, distinct, func + +from . import BASE, SESSION + + +class Warns(BASE): + __tablename__ = "warns" + user_id = Column(Integer, primary_key=True) + chat_id = Column(String(14), primary_key=True) + num_warns = Column(Integer, default=0) + reasons = Column(UnicodeText) + + def __init__(self, user_id, chat_id): + self.user_id = user_id + self.chat_id = str(chat_id) + self.num_warns = 0 + self.reasons = "" + + def __repr__(self): + return "<{} warns for {} in {} for reasons {}>".format( + self.num_warns, self.user_id, self.chat_id, self.reasons + ) + + +class WarnSettings(BASE): + __tablename__ = "warn_settings" + chat_id = Column(String(14), primary_key=True) + warn_limit = Column(Integer, default=3) + soft_warn = Column(Boolean, default=False) + + def __init__(self, chat_id, warn_limit=3, soft_warn=False): + self.chat_id = str(chat_id) + self.warn_limit = warn_limit + self.soft_warn = soft_warn + + def __repr__(self): + return "<{} has {} possible warns.>".format(self.chat_id, self.warn_limit) + + +Warns.__table__.create(checkfirst=True) +WarnSettings.__table__.create(checkfirst=True) + +WARN_INSERTION_LOCK = threading.RLock() +WARN_SETTINGS_LOCK = threading.RLock() + + +def warn_user(user_id, chat_id, reason=None): + with WARN_INSERTION_LOCK: + warned_user = SESSION.query(Warns).get((user_id, str(chat_id))) + if not warned_user: + warned_user = Warns(user_id, str(chat_id)) + warned_user.num_warns += 1 + if reason: + warned_user.reasons = warned_user.reasons + "\r\n\r\n" + reason + reasons = warned_user.reasons + num = warned_user.num_warns + SESSION.add(warned_user) + SESSION.commit() + return num, reasons + + +def remove_warn(user_id, chat_id): + with WARN_INSERTION_LOCK: + removed = False + warned_user = SESSION.query(Warns).get((user_id, str(chat_id))) + if warned_user and warned_user.num_warns > 0: + warned_user.num_warns -= 1 + SESSION.add(warned_user) + SESSION.commit() + removed = True + SESSION.close() + return removed + + +def reset_warns(user_id, chat_id): + with WARN_INSERTION_LOCK: + if warned_user := SESSION.query(Warns).get((user_id, str(chat_id))): + warned_user.num_warns = 0 + warned_user.reasons = "" + SESSION.add(warned_user) + SESSION.commit() + SESSION.close() + + +def get_warns(user_id, chat_id): + try: + user = SESSION.query(Warns).get((user_id, str(chat_id))) + if not user: + return None + reasons = user.reasons + num = user.num_warns + return num, reasons + finally: + SESSION.close() + + +def set_warn_limit(chat_id, warn_limit): + with WARN_SETTINGS_LOCK: + curr_setting = SESSION.query(WarnSettings).get(str(chat_id)) + if not curr_setting: + curr_setting = WarnSettings(chat_id, warn_limit=warn_limit) + curr_setting.warn_limit = warn_limit + SESSION.add(curr_setting) + SESSION.commit() + + +def set_warn_strength(chat_id, soft_warn): + with WARN_SETTINGS_LOCK: + curr_setting = SESSION.query(WarnSettings).get(str(chat_id)) + if not curr_setting: + curr_setting = WarnSettings(chat_id, soft_warn=soft_warn) + curr_setting.soft_warn = soft_warn + SESSION.add(curr_setting) + SESSION.commit() + + +def get_warn_setting(chat_id): + try: + if setting := SESSION.query(WarnSettings).get(str(chat_id)): + return setting.warn_limit, setting.soft_warn + return 3, False + finally: + SESSION.close() + + +def num_warns(): + try: + return SESSION.query(func.sum(Warns.num_warns)).scalar() or 0 + finally: + SESSION.close() + + +def num_warn_chats(): + try: + return SESSION.query(func.count(distinct(Warns.chat_id))).scalar() + finally: + SESSION.close() diff --git a/repthon/sql_helper/welcome_sql.py b/repthon/sql_helper/welcome_sql.py new file mode 100644 index 0000000..6ebbc8e --- /dev/null +++ b/repthon/sql_helper/welcome_sql.py @@ -0,0 +1,70 @@ +try: + from . import BASE, SESSION +except ImportError as e: + raise AttributeError from e + +from sqlalchemy import BigInteger, Column, Numeric, String, UnicodeText + + +class Welcome(BASE): + __tablename__ = "catwelcome" + chat_id = Column(String(14), primary_key=True) + previous_welcome = Column(BigInteger) + reply = Column(UnicodeText) + f_mesg_id = Column(Numeric) + + def __init__(self, chat_id, previous_welcome, reply, f_mesg_id): + self.chat_id = str(chat_id) + self.previous_welcome = previous_welcome + self.reply = reply + self.f_mesg_id = f_mesg_id + + +Welcome.__table__.create(checkfirst=True) + + +def get_welcome(chat_id): + try: + return SESSION.query(Welcome).get(str(chat_id)) + finally: + SESSION.close() + + +def get_current_welcome_settings(chat_id): + try: + return SESSION.query(Welcome).filter(Welcome.chat_id == str(chat_id)).one() + except BaseException: + return None + finally: + SESSION.close() + + +def add_welcome_setting(chat_id, previous_welcome, reply, f_mesg_id): + to_check = get_welcome(chat_id) + if not to_check: + adder = Welcome(chat_id, previous_welcome, reply, f_mesg_id) + SESSION.add(adder) + SESSION.commit() + return True + rem = SESSION.query(Welcome).get(str(chat_id)) + SESSION.delete(rem) + SESSION.commit() + adder = Welcome(chat_id, previous_welcome, reply, f_mesg_id) + SESSION.commit() + return False + + +def rm_welcome_setting(chat_id): + try: + if rem := SESSION.query(Welcome).get(str(chat_id)): + SESSION.delete(rem) + SESSION.commit() + return True + except BaseException: + return False + + +def update_previous_welcome(chat_id, previous_welcome): + row = SESSION.query(Welcome).get(str(chat_id)) + row.previous_welcome = previous_welcome + SESSION.commit() diff --git a/repthon/sql_helper/welcomesql.py b/repthon/sql_helper/welcomesql.py new file mode 100644 index 0000000..1209d92 --- /dev/null +++ b/repthon/sql_helper/welcomesql.py @@ -0,0 +1,72 @@ +try: + from . import BASE, SESSION +except ImportError as e: + raise AttributeError from e + +from sqlalchemy import BigInteger, Column, Numeric, String, UnicodeText + + +class JoinWelcome(BASE): + __tablename__ = "joinwelcome" + chat_id = Column(String(14), primary_key=True) + previous_welcome = Column(BigInteger) + reply = Column(UnicodeText) + f_mesg_id = Column(Numeric) + + def __init__(self, chat_id, previous_welcome, reply, f_mesg_id): + self.chat_id = str(chat_id) + self.previous_welcome = previous_welcome + self.reply = reply + self.f_mesg_id = f_mesg_id + + +JoinWelcome.__table__.create(checkfirst=True) + + +def getwelcome(chat_id): + try: + return SESSION.query(JoinWelcome).get(str(chat_id)) + finally: + SESSION.close() + + +def getcurrent_welcome_settings(chat_id): + try: + return ( + SESSION.query(JoinWelcome).filter(JoinWelcome.chat_id == str(chat_id)).one() + ) + except BaseException: + return None + finally: + SESSION.close() + + +def addwelcome_setting(chat_id, previous_welcome, reply, f_mesg_id): + to_check = getwelcome(chat_id) + if not to_check: + adder = JoinWelcome(chat_id, previous_welcome, reply, f_mesg_id) + SESSION.add(adder) + SESSION.commit() + return True + rem = SESSION.query(JoinWelcome).get(str(chat_id)) + SESSION.delete(rem) + SESSION.commit() + adder = JoinWelcome(chat_id, previous_welcome, reply, f_mesg_id) + SESSION.commit() + return False + + +def rmwelcome_setting(chat_id): + try: + if rem := SESSION.query(JoinWelcome).get(str(chat_id)): + SESSION.delete(rem) + SESSION.commit() + return True + except BaseException: + return False + + +def updateprevious_welcome(chat_id, previous_welcome): + row = SESSION.query(JoinWelcome).get(str(chat_id)) + row.previous_welcome = previous_welcome + SESSION.commit() diff --git a/repthon/sql_helper/zed.txt b/repthon/sql_helper/zed.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/repthon/sql_helper/zed.txt @@ -0,0 +1 @@ +