├── Dockerfile
├── Git_Pull.bat
├── Git_Push.bat
├── LICENSE
├── LaylaRobot
├── __init__.py
├── __main__.py
├── bsdk
│ ├── extras
│ │ └── lol.txt
│ └── fonts
│ │ ├── 1.ttf
│ │ ├── 10.ttf
│ │ ├── 2.ttf
│ │ ├── 4.ttf
│ │ ├── 5.ttf
│ │ ├── 6.ttf
│ │ ├── 7.ttf
│ │ ├── 8.ttf
│ │ └── 9.ttf
├── conf.py
├── events.py
├── helper_extra
│ ├── admin_rights.py
│ ├── aichat.py
│ └── badmedia.py
├── modules
│ ├── __aimultilanguage.py
│ ├── __core.py
│ ├── __country.py
│ ├── __encrypt.py
│ ├── __forcesubs.py
│ ├── __google.py
│ ├── __gps.py
│ ├── __heroku.py
│ ├── __imdb.py
│ ├── __init__.py
│ ├── __nightmode.py
│ ├── __shield.py
│ ├── __songs.py
│ ├── __speachtotext.py
│ ├── __telegraph.py
│ ├── __texttospeech.py
│ ├── __tools.py
│ ├── __weather.py
│ ├── __zip.py
│ ├── _pyrogithub.py
│ ├── admin.py
│ ├── afk.py
│ ├── anime.py
│ ├── antiflood.py
│ ├── approve.py
│ ├── backups.py
│ ├── bans.py
│ ├── blacklist.py
│ ├── blacklist_stickers.py
│ ├── blacklistusers.py
│ ├── cleaner.py
│ ├── connection.py
│ ├── cricketscore.py
│ ├── currency_converter.py
│ ├── cust_filters.py
│ ├── dbcleanup.py
│ ├── debug.py
│ ├── dev.py
│ ├── disable.py
│ ├── disasters.py
│ ├── error_handler.py
│ ├── eval.py
│ ├── fakeit.py
│ ├── feds.py
│ ├── fun.py
│ ├── fun_strings.py
│ ├── games.py
│ ├── get_common_chats.py
│ ├── gettime.py
│ ├── global_bans.py
│ ├── gtranslator.py
│ ├── helper_funcs
│ │ ├── __init__.py
│ │ ├── alternate.py
│ │ ├── chat_status.py
│ │ ├── extraction.py
│ │ ├── filters.py
│ │ ├── handlers.py
│ │ ├── misc.py
│ │ ├── msg_types.py
│ │ ├── regex_helper.py
│ │ ├── string_handling.py
│ │ ├── string_store.py
│ │ └── telethn
│ │ │ ├── __init__.py
│ │ │ └── chatstatus.py
│ ├── locks.py
│ ├── log_channel.py
│ ├── logomaker.py
│ ├── math.py
│ ├── misc.py
│ ├── modules.py
│ ├── music.py
│ ├── musicplayer.py
│ ├── muting.py
│ ├── notes.py
│ ├── nsfw.py
│ ├── paste.py
│ ├── ping.py
│ ├── purge.py
│ ├── reactions.py
│ ├── remote_cmds.py
│ ├── reporting.py
│ ├── rules.py
│ ├── shell.py
│ ├── speed_test.py
│ ├── sql
│ │ ├── __init__.py
│ │ ├── afk_sql.py
│ │ ├── aihelp_sql.py
│ │ ├── antiflood_sql.py
│ │ ├── approve_sql.py
│ │ ├── blacklist_sql.py
│ │ ├── blacklistusers_sql.py
│ │ ├── blsticker_sql.py
│ │ ├── chatbot_sql.py
│ │ ├── cleaner_sql.py
│ │ ├── connection_sql.py
│ │ ├── cust_filters_sql.py
│ │ ├── disable_sql.py
│ │ ├── feds_sql.py
│ │ ├── global_bans_sql.py
│ │ ├── locks_sql.py
│ │ ├── log_channel_sql.py
│ │ ├── notes_sql.py
│ │ ├── nsfw_sql.py
│ │ ├── reporting_sql.py
│ │ ├── rss_sql.py
│ │ ├── rules_sql.py
│ │ ├── userinfo_sql.py
│ │ ├── users_sql.py
│ │ ├── warns_sql.py
│ │ └── welcome_sql.py
│ ├── sql_extended
│ │ ├── forceSubscribe_sql.py
│ │ ├── night_mode_sql.py
│ │ └── nsfw_watch_sql.py
│ ├── stickers.py
│ ├── tagall.py
│ ├── truth_and_dare.py
│ ├── truth_and_dare_string.py
│ ├── ud.py
│ ├── userinfo.py
│ ├── users.py
│ ├── wallpaper.py
│ ├── warns.py
│ ├── welcome.py
│ ├── wiki.py
│ └── zombies.py
├── mongo.py
├── pyrogramee
│ ├── dark.py
│ ├── errors.py
│ ├── pluginshelper.py
│ └── telethonbasics.py
├── resources
│ ├── Chopsic.otf
│ ├── Maghrib.ttf
│ ├── blackbg.jpg
│ ├── hero.png
│ └── images.jpeg
├── sample_config.py
└── utils
│ ├── X
│ ├── __init__.py
│ ├── dbfunc.py
│ ├── errors.py
│ ├── exceptions.py
│ ├── my.py
│ ├── progress.py
│ └── tools.py
├── Procfile
├── README.md
├── Setup venv.bat
├── _config.yml
├── app.json
├── exp.sh
├── heroku.yml
├── profanity_wordlist.txt
├── requirements.txt
├── restart.bat
├── runtime.txt
├── start.bat
└── start_service.bat
/Dockerfile:
--------------------------------------------------------------------------------
1 | # We're using Debian Slim Buster image
2 | FROM python:3.8.5-slim-buster
3 |
4 | ENV PIP_NO_CACHE_DIR 1
5 |
6 | RUN sed -i.bak 's/us-west-2\.ec2\.//' /etc/apt/sources.list
7 |
8 | # Installing Required Packages
9 | RUN apt update && apt upgrade -y && \
10 | apt install --no-install-recommends -y \
11 | debian-keyring \
12 | debian-archive-keyring \
13 | bash \
14 | bzip2 \
15 | curl \
16 | figlet \
17 | git \
18 | util-linux \
19 | libffi-dev \
20 | libjpeg-dev \
21 | libjpeg62-turbo-dev \
22 | libwebp-dev \
23 | linux-headers-amd64 \
24 | musl-dev \
25 | musl \
26 | neofetch \
27 | php-pgsql \
28 | python3-lxml \
29 | postgresql \
30 | postgresql-client \
31 | python3-psycopg2 \
32 | libpq-dev \
33 | libcurl4-openssl-dev \
34 | libxml2-dev \
35 | libxslt1-dev \
36 | python3-pip \
37 | python3-requests \
38 | python3-sqlalchemy \
39 | python3-tz \
40 | python3-aiohttp \
41 | openssl \
42 | pv \
43 | jq \
44 | wget \
45 | python3 \
46 | python3-dev \
47 | libreadline-dev \
48 | libyaml-dev \
49 | gcc \
50 | sqlite3 \
51 | libsqlite3-dev \
52 | sudo \
53 | zlib1g \
54 | ffmpeg \
55 | libssl-dev \
56 | libgconf-2-4 \
57 | libxi6 \
58 | xvfb \
59 | unzip \
60 | libopus0 \
61 | libopus-dev \
62 | && rm -rf /var/lib/apt/lists /var/cache/apt/archives /tmp
63 |
64 | # Pypi package Repo upgrade
65 | RUN pip3 install --upgrade pip setuptools
66 |
67 | # Copy Python Requirements to /root/LaylaRobot
68 | RUN git clone -b shiken https://github.com/QueenArzoo/LaylaRobot /root/LaylaRobot
69 | WORKDIR /root/LaylaRobot
70 |
71 | #Copy config file to /root/LaylaRobot/LaylaRobot
72 | COPY ./LaylaRobot/sample_config.py ./LaylaRobot/config.py* /root/LaylaRobot/LaylaRobot/
73 |
74 | ENV PATH="/home/bot/bin:$PATH"
75 |
76 | # Install requirements
77 | RUN pip3 install -U -r requirements.txt
78 |
79 | # Starting Worker
80 | CMD ["python3","-m","LaylaRobot"]
81 |
--------------------------------------------------------------------------------
/Git_Pull.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | TITLE Github Quick-Pull
3 |
4 | :: Print the branch cause ..oooooo fancy!
5 | echo Pulling from branch:
6 | git branch
7 | echo.
8 | git pull
9 |
--------------------------------------------------------------------------------
/Git_Push.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | TITLE Github Quick-pushing
3 |
4 | :: Print the branch cause people like me push to wrong branches and cry about it later.
5 | echo Pushing to branch:
6 | git branch
7 | echo.
8 | :: Take input for comment and thats about it
9 | set /p commit_title="Enter Commit title (pushes with you as author): "
10 |
11 | :: If you are reading comments to understand this part then you can go back stab yourself.
12 | echo.
13 | git pull
14 | git add *
15 | git commit -m "%commit_title%"
16 | git push
17 |
18 |
19 | :: Hail Hydra
--------------------------------------------------------------------------------
/LaylaRobot/bsdk/extras/lol.txt:
--------------------------------------------------------------------------------
1 | @HEROGAMERS1
2 |
--------------------------------------------------------------------------------
/LaylaRobot/bsdk/fonts/1.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shiv-x/LaylaRobot/a899ec54e1fa4048a1a71fdaedba14f9e679d8fb/LaylaRobot/bsdk/fonts/1.ttf
--------------------------------------------------------------------------------
/LaylaRobot/bsdk/fonts/10.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shiv-x/LaylaRobot/a899ec54e1fa4048a1a71fdaedba14f9e679d8fb/LaylaRobot/bsdk/fonts/10.ttf
--------------------------------------------------------------------------------
/LaylaRobot/bsdk/fonts/2.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shiv-x/LaylaRobot/a899ec54e1fa4048a1a71fdaedba14f9e679d8fb/LaylaRobot/bsdk/fonts/2.ttf
--------------------------------------------------------------------------------
/LaylaRobot/bsdk/fonts/4.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shiv-x/LaylaRobot/a899ec54e1fa4048a1a71fdaedba14f9e679d8fb/LaylaRobot/bsdk/fonts/4.ttf
--------------------------------------------------------------------------------
/LaylaRobot/bsdk/fonts/5.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shiv-x/LaylaRobot/a899ec54e1fa4048a1a71fdaedba14f9e679d8fb/LaylaRobot/bsdk/fonts/5.ttf
--------------------------------------------------------------------------------
/LaylaRobot/bsdk/fonts/6.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shiv-x/LaylaRobot/a899ec54e1fa4048a1a71fdaedba14f9e679d8fb/LaylaRobot/bsdk/fonts/6.ttf
--------------------------------------------------------------------------------
/LaylaRobot/bsdk/fonts/7.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shiv-x/LaylaRobot/a899ec54e1fa4048a1a71fdaedba14f9e679d8fb/LaylaRobot/bsdk/fonts/7.ttf
--------------------------------------------------------------------------------
/LaylaRobot/bsdk/fonts/8.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shiv-x/LaylaRobot/a899ec54e1fa4048a1a71fdaedba14f9e679d8fb/LaylaRobot/bsdk/fonts/8.ttf
--------------------------------------------------------------------------------
/LaylaRobot/bsdk/fonts/9.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shiv-x/LaylaRobot/a899ec54e1fa4048a1a71fdaedba14f9e679d8fb/LaylaRobot/bsdk/fonts/9.ttf
--------------------------------------------------------------------------------
/LaylaRobot/conf.py:
--------------------------------------------------------------------------------
1 | from envparse import env
2 | from LaylaRobot import LOGGER
3 |
4 | DEFAULTS = {
5 | "LOAD_MODULES": True,
6 | }
7 |
8 | def get_str_key(name, required=False):
9 | if name in DEFAULTS:
10 | default = DEFAULTS[name]
11 | else:
12 | default = None
13 | if not (data := env.str(name, default=default)) and not required:
14 | LOGGER.warn("No str key: " + name)
15 | return None
16 | elif not data:
17 | LOGGER.critical("No str key: " + name)
18 | sys.exit(2)
19 | else:
20 | return data
21 |
22 | def get_int_key(name, required=False):
23 | if name in DEFAULTS:
24 | default = DEFAULTS[name]
25 | else:
26 | default = None
27 | if not (data := env.int(name, default=default)) and not required:
28 | LOGGER.warn("No int key: " + name)
29 | return None
30 | elif not data:
31 | LOGGER.critical("No int key: " + name)
32 | sys.exit(2)
33 | else:
34 | return data
--------------------------------------------------------------------------------
/LaylaRobot/events.py:
--------------------------------------------------------------------------------
1 | from telethon import events
2 | from LaylaRobot import telethn
3 |
4 |
5 | def register(**args):
6 | """ Registers a new message. """
7 | pattern = args.get("pattern", None)
8 |
9 | r_pattern = r"^[/!]"
10 |
11 | if pattern is not None and not pattern.startswith("(?i)"):
12 | args["pattern"] = "(?i)" + pattern
13 |
14 | args["pattern"] = pattern.replace("^/", r_pattern, 1)
15 |
16 | def decorator(func):
17 | telethn.add_event_handler(func, events.NewMessage(**args))
18 | return func
19 |
20 | return decorator
21 |
22 |
23 | def chataction(**args):
24 | """ Registers chat actions. """
25 |
26 | def decorator(func):
27 | telethn.add_event_handler(func, events.ChatAction(**args))
28 | return func
29 |
30 | return decorator
31 |
32 |
33 | def userupdate(**args):
34 | """ Registers user updates. """
35 |
36 | def decorator(func):
37 | telethn.add_event_handler(func, events.UserUpdate(**args))
38 | return func
39 |
40 | return decorator
41 |
42 |
43 | def inlinequery(**args):
44 | """ Registers inline query. """
45 | pattern = args.get("pattern", None)
46 |
47 | if pattern is not None and not pattern.startswith("(?i)"):
48 | args["pattern"] = "(?i)" + pattern
49 |
50 | def decorator(func):
51 | telethn.add_event_handler(func, events.InlineQuery(**args))
52 | return func
53 |
54 | return decorator
55 |
56 |
57 | def callbackquery(**args):
58 | """ Registers inline query. """
59 |
60 | def decorator(func):
61 | telethn.add_event_handler(func, events.CallbackQuery(**args))
62 | return func
63 |
64 | return decorator
65 |
66 |
--------------------------------------------------------------------------------
/LaylaRobot/helper_extra/admin_rights.py:
--------------------------------------------------------------------------------
1 | from telegram import User, Chat
2 |
3 |
4 | def user_can_promote(chat: Chat, user: User, bot_id: int) -> bool:
5 | return chat.get_member(user.id).can_promote_members
6 |
7 |
8 | def user_can_ban(chat: Chat, user: User, bot_id: int) -> bool:
9 | return chat.get_member(user.id).can_restrict_members
10 |
11 |
12 | def user_can_pin(chat: Chat, user: User, bot_id: int) -> bool:
13 | return chat.get_member(user.id).can_pin_messages
14 |
15 |
16 | def user_can_changeinfo(chat: Chat, user: User, bot_id: int) -> bool:
17 | return chat.get_member(user.id).can_change_info
18 |
--------------------------------------------------------------------------------
/LaylaRobot/helper_extra/aichat.py:
--------------------------------------------------------------------------------
1 | from LaylaRobot.mongo import client as db_x
2 |
3 | lydia = db_x["CAHTBOT"]
4 |
5 |
6 | def add_chat(chat_id):
7 | stark = lydia.find_one({"chat_id": chat_id})
8 | if stark:
9 | return False
10 | else:
11 | lydia.insert_one({"chat_id": chat_id})
12 | return True
13 |
14 |
15 | def remove_chat(chat_id):
16 | stark = lydia.find_one({"chat_id": chat_id})
17 | if not stark:
18 | return False
19 | else:
20 | lydia.delete_one({"chat_id": chat_id})
21 | return True
22 |
23 |
24 | def get_all_chats():
25 | r = list(lydia.find())
26 | if r:
27 | return r
28 | else:
29 | return False
30 |
31 |
32 | def get_session(chat_id):
33 | stark = lydia.find_one({"chat_id": chat_id})
34 | if not stark:
35 | return False
36 | else:
37 | return stark
--------------------------------------------------------------------------------
/LaylaRobot/helper_extra/badmedia.py:
--------------------------------------------------------------------------------
1 | from LaylaRobot import telethn as tbot
2 | import requests
3 | import time
4 |
5 |
6 |
7 | async def is_nsfw(event):
8 | lmao = event
9 | if not (
10 | lmao.gif
11 | or lmao.video
12 | or lmao.video_note
13 | or lmao.photo
14 | or lmao.sticker
15 | or lmao.media
16 | ):
17 | return False
18 | if lmao.video or lmao.video_note or lmao.sticker or lmao.gif:
19 | try:
20 | starkstark = event.client.download_media(lmao.media, thumb=-1)
21 | except:
22 | return False
23 | elif lmao.photo or lmao.sticker:
24 | try:
25 | starkstark = event.client.download_media(lmao.media)
26 | except:
27 | return False
28 | img = starkstark
29 | f = {"file": (img, open(img, "rb"))}
30 |
31 | r = requests.post("https://starkapi.herokuapp.com/nsfw/", files = f).json()
32 | if r.get("success") is False:
33 | is_nsfw = False
34 | elif r.get("is_nsfw") is True:
35 | is_nsfw = True
36 | elif r.get("is_nsfw") is False:
37 | is_nsfw = False
38 | return is_nsfw
39 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/__core.py:
--------------------------------------------------------------------------------
1 | from LaylaRobot import telethn as tbot
2 | from LaylaRobot.events import register
3 | import os
4 | import asyncio
5 | import os
6 | import time
7 | from datetime import datetime
8 | from LaylaRobot import OWNER_ID, DEV_USERS
9 | from LaylaRobot import TEMP_DOWNLOAD_DIRECTORY as path
10 | from LaylaRobot import TEMP_DOWNLOAD_DIRECTORY
11 | from datetime import datetime
12 | water = './LaylaRobot/resources/yone.jpg'
13 | client = tbot
14 |
15 | @register(pattern=r"^/send ?(.*)")
16 | async def Prof(event):
17 | if event.sender_id == OWNER_ID or event.sender_id == DEV_USERS:
18 | pass
19 | else:
20 | return
21 | thumb = water
22 | message_id = event.message.id
23 | input_str = event.pattern_match.group(1)
24 | the_plugin_file = "./LaylaRobot/modules/{}.py".format(input_str)
25 | if os.path.exists(the_plugin_file):
26 | message_id = event.message.id
27 | await event.client.send_file(
28 | event.chat_id,
29 | the_plugin_file,
30 | force_document=True,
31 | allow_cache=False,
32 | thumb=thumb,
33 | reply_to=message_id,
34 | )
35 | else:
36 | await event.reply("No File Found!")
37 |
38 |
39 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/__country.py:
--------------------------------------------------------------------------------
1 | from telethon.tl.functions.photos import GetUserPhotosRequest
2 | from telethon.tl.functions.users import GetFullUserRequest
3 | from telethon.tl.types import MessageEntityMentionName
4 | from telethon.utils import get_input_location
5 | import flag
6 | import html, os
7 | from countryinfo import CountryInfo
8 | from LaylaRobot import telethn as borg
9 | from LaylaRobot.events import register
10 |
11 |
12 | @register(pattern="^/country (.*)")
13 | async def msg(event):
14 | if event.fwd_from:
15 | return
16 | input_str = event.pattern_match.group(1)
17 | lol = input_str
18 | country = CountryInfo(lol)
19 | try:
20 | a = country.info()
21 | except:
22 | await event.reply("Country Not Avaiable Currently")
23 | name = a.get("name")
24 | bb= a.get("altSpellings")
25 | hu = ''
26 | for p in bb:
27 | hu += p+", "
28 |
29 | area = a.get("area")
30 | borders = ""
31 | hell = a.get("borders")
32 | for fk in hell:
33 | borders += fk+", "
34 |
35 | call = ""
36 | WhAt = a.get("callingCodes")
37 | for what in WhAt:
38 | call+= what+" "
39 |
40 | capital = a.get("capital")
41 | currencies = ""
42 | fker = a.get("currencies")
43 | for FKer in fker:
44 | currencies += FKer+", "
45 |
46 | HmM = a.get("demonym")
47 | geo = a.get("geoJSON")
48 | pablo = geo.get("features")
49 | Pablo = pablo[0]
50 | PAblo = Pablo.get("geometry")
51 | EsCoBaR= PAblo.get("type")
52 | iso = ""
53 | iSo = a.get("ISO")
54 | for hitler in iSo:
55 | po = iSo.get(hitler)
56 | iso += po+", "
57 | fla = iSo.get("alpha2")
58 | nox = fla.upper()
59 | okie = flag.flag(nox)
60 |
61 | languages = a.get("languages")
62 | lMAO=""
63 | for lmao in languages:
64 | lMAO += lmao+", "
65 |
66 | nonive = a.get("nativeName")
67 | waste = a.get("population")
68 | reg = a.get("region")
69 | sub = a.get("subregion")
70 | tik = a.get("timezones")
71 | tom =""
72 | for jerry in tik:
73 | tom+=jerry+", "
74 |
75 | GOT = a.get("tld")
76 | lanester = ""
77 | for targaryen in GOT:
78 | lanester+=targaryen+", "
79 |
80 | wiki = a.get("wiki")
81 |
82 | caption = f"""Information Gathered Successfully
83 |
84 | Country Name:- {name}
85 | Alternative Spellings:- {hu}
86 | Country Area:- {area} square kilometers
87 | Borders:- {borders}
88 | Calling Codes:- {call}
89 | Country's Capital:- {capital}
90 | Country's currency:- {currencies}
91 | Country's Flag:- {okie}
92 | Demonym:- {HmM}
93 | Country Type:- {EsCoBaR}
94 | ISO Names:- {iso}
95 | Languages:- {lMAO}
96 | Native Name:- {nonive}
97 | population:- {waste}
98 | Region:- {reg}
99 | Sub Region:- {sub}
100 | Time Zones:- {tom}
101 | Top Level Domain:- {lanester}
102 | wikipedia:- {wiki}
103 |
104 | Gathered By Layla.
105 | """
106 |
107 |
108 | await borg.send_message(
109 | event.chat_id,
110 | caption,
111 | parse_mode="HTML",
112 | )
113 |
114 | await event.delete()
115 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/__encrypt.py:
--------------------------------------------------------------------------------
1 | from LaylaRobot import telethn as tbot
2 | import os
3 | from LaylaRobot.events import register
4 | import secureme
5 |
6 | @register(pattern="^/encrypt ?(.*)")
7 | async def hmm(event):
8 | if event.reply_to_msg_id:
9 | lel = await event.get_reply_message()
10 | cmd = lel.text
11 | else:
12 | cmd = event.pattern_match.group(1)
13 | Text = cmd
14 | k = secureme.encrypt(Text)
15 | await event.reply(k)
16 |
17 | @register(pattern="^/decrypt ?(.*)")
18 | async def hmm(event):
19 | if event.reply_to_msg_id:
20 | lel = await event.get_reply_message()
21 | ok = lel.text
22 | else:
23 | ok = event.pattern_match.group(1)
24 | Text = ok
25 | k = secureme.decrypt(Text)
26 | await event.reply(k)
27 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/__gps.py:
--------------------------------------------------------------------------------
1 | import os
2 | from LaylaRobot import telethn as tbot
3 | from geopy.geocoders import Nominatim
4 | from LaylaRobot.events import register
5 | from LaylaRobot import *
6 | from telethon import *
7 | from telethon.tl import *
8 |
9 | GMAPS_LOC = "https://maps.googleapis.com/maps/api/geocode/json"
10 |
11 |
12 | @register(pattern="^/gps (.*)")
13 | async def _(event):
14 | args = event.pattern_match.group(1)
15 |
16 | try:
17 | geolocator = Nominatim(user_agent="SkittBot")
18 | location = args
19 | geoloc = geolocator.geocode(location)
20 | longitude = geoloc.longitude
21 | latitude = geoloc.latitude
22 | gm = "https://www.google.com/maps/search/{},{}".format(latitude, longitude)
23 | await tbot.send_file(
24 | event.chat_id,
25 | file=types.InputMediaGeoPoint(
26 | types.InputGeoPoint(float(latitude), float(longitude))
27 | ),
28 | )
29 | await event.reply(
30 | "Open with: [🌏Google Maps]({})".format(gm),
31 | link_preview=False,
32 | )
33 | except Exception as e:
34 | print(e)
35 | await event.reply("I can't find that")
36 |
37 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/__imdb.py:
--------------------------------------------------------------------------------
1 | from LaylaRobot import telethn as tbot
2 | import os
3 | import re
4 | import bs4
5 | import requests
6 | from telethon import types
7 | from telethon.tl import functions
8 | from LaylaRobot.events import register
9 |
10 | langi = "en"
11 |
12 |
13 | @register(pattern="^/imdb (.*)")
14 | async def imdb(e):
15 | if e.fwd_from:
16 | return
17 | try:
18 | movie_name = e.pattern_match.group(1)
19 | remove_space = movie_name.split(" ")
20 | final_name = "+".join(remove_space)
21 | page = requests.get(
22 | "https://www.imdb.com/find?ref_=nv_sr_fn&q=" + final_name + "&s=all"
23 | )
24 | str(page.status_code)
25 | soup = bs4.BeautifulSoup(page.content, "html.parser")
26 | odds = soup.findAll("tr", "odd")
27 | mov_title = odds[0].findNext("td").findNext("td").text
28 | mov_link = (
29 | "http://www.imdb.com/" + odds[0].findNext("td").findNext("td").a["href"]
30 | )
31 | page1 = requests.get(mov_link)
32 | soup = bs4.BeautifulSoup(page1.content, "lxml")
33 | if soup.find("div", "poster"):
34 | poster = soup.find("div", "poster").img["src"]
35 | else:
36 | poster = ""
37 | if soup.find("div", "title_wrapper"):
38 | pg = soup.find("div", "title_wrapper").findNext("div").text
39 | mov_details = re.sub(r"\s+", " ", pg)
40 | else:
41 | mov_details = ""
42 | credits = soup.findAll("div", "credit_summary_item")
43 | if len(credits) == 1:
44 | director = credits[0].a.text
45 | writer = "Not available"
46 | stars = "Not available"
47 | elif len(credits) > 2:
48 | director = credits[0].a.text
49 | writer = credits[1].a.text
50 | actors = []
51 | for x in credits[2].findAll("a"):
52 | actors.append(x.text)
53 | actors.pop()
54 | stars = actors[0] + "," + actors[1] + "," + actors[2]
55 | else:
56 | director = credits[0].a.text
57 | writer = "Not available"
58 | actors = []
59 | for x in credits[1].findAll("a"):
60 | actors.append(x.text)
61 | actors.pop()
62 | stars = actors[0] + "," + actors[1] + "," + actors[2]
63 | if soup.find("div", "inline canwrap"):
64 | story_line = soup.find("div", "inline canwrap").findAll("p")[0].text
65 | else:
66 | story_line = "Not available"
67 | info = soup.findAll("div", "txt-block")
68 | if info:
69 | mov_country = []
70 | mov_language = []
71 | for node in info:
72 | a = node.findAll("a")
73 | for i in a:
74 | if "country_of_origin" in i["href"]:
75 | mov_country.append(i.text)
76 | elif "primary_language" in i["href"]:
77 | mov_language.append(i.text)
78 | if soup.findAll("div", "ratingValue"):
79 | for r in soup.findAll("div", "ratingValue"):
80 | mov_rating = r.strong["title"]
81 | else:
82 | mov_rating = "Not available"
83 | await e.reply(
84 | ""
85 | "Title : "
86 | + mov_title
87 | + "
\n"
88 | + mov_details
89 | + "
\nRating : "
90 | + mov_rating
91 | + "
\nCountry : "
92 | + mov_country[0]
93 | + "
\nLanguage : "
94 | + mov_language[0]
95 | + "
\nDirector : "
96 | + director
97 | + "
\nWriter : "
98 | + writer
99 | + "
\nStars : "
100 | + stars
101 | + "
\nIMDB Url : "
102 | + mov_link
103 | + "\nStory Line : "
104 | + story_line,
105 | link_preview=True,
106 | parse_mode="HTML",
107 | )
108 | except IndexError:
109 | await e.reply("Plox enter **Valid movie name** kthx")
110 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/__init__.py:
--------------------------------------------------------------------------------
1 | from LaylaRobot import LOAD, LOGGER, NO_LOAD
2 |
3 |
4 | def __list_all_modules():
5 | import glob
6 | from os.path import basename, dirname, isfile
7 |
8 | # This generates a list of modules in this folder for the * in __main__ to work.
9 | mod_paths = glob.glob(dirname(__file__) + "/*.py")
10 | all_modules = [
11 | basename(f)[:-3]
12 | for f in mod_paths
13 | if isfile(f) and f.endswith(".py") and not f.endswith("__init__.py")
14 | ]
15 |
16 | if LOAD or NO_LOAD:
17 | to_load = LOAD
18 | if to_load:
19 | if not all(
20 | any(mod == module_name for module_name in all_modules)
21 | for mod in to_load
22 | ):
23 | LOGGER.error("Invalid loadorder names. Quitting.")
24 | quit(1)
25 |
26 | all_modules = sorted(set(all_modules) - set(to_load))
27 | to_load = list(all_modules) + to_load
28 |
29 | else:
30 | to_load = all_modules
31 |
32 | if NO_LOAD:
33 | LOGGER.info("Not loading: {}".format(NO_LOAD))
34 | return [item for item in to_load if item not in NO_LOAD]
35 |
36 | return to_load
37 |
38 | return all_modules
39 |
40 |
41 | ALL_MODULES = __list_all_modules()
42 | LOGGER.info("Modules to load: %s", str(ALL_MODULES))
43 | __all__ = ALL_MODULES + ["ALL_MODULES"]
44 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/__songs.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | #Saavn
4 |
5 | import requests
6 | import wget
7 | from pyrogram import filters
8 |
9 | from LaylaRobot import pbot as Jebot
10 | from LaylaRobot.pyrogramee.dark import get_arg
11 |
12 |
13 | @Jebot.on_message(filters.command("saavn"))
14 | async def song(client, message):
15 | message.chat.id
16 | message.from_user["id"]
17 | args = get_arg(message) + " " + "song"
18 | if args.startswith(" "):
19 | await message.reply("Enter song name❗")
20 | return ""
21 | m = await message.reply_text(
22 | "Downloading your song,\nPlz wait ⏳️"
23 | )
24 | try:
25 | r = requests.get(f"https://jostapi.herokuapp.com/saavn?query={args}")
26 | except Exception as e:
27 | await m.edit(str(e))
28 | return
29 | sname = r.json()[0]["song"]
30 | slink = r.json()[0]["media_url"]
31 | ssingers = r.json()[0]["singers"]
32 | file = wget.download(slink)
33 | ffile = file.replace("mp4", "m4a")
34 | os.rename(file, ffile)
35 | await message.reply_audio(audio=ffile, title=sname, performer=ssingers)
36 | os.remove(ffile)
37 | await m.delete()
38 |
39 |
40 | #deezer#
41 | # Credits for @TheHamkerCat
42 |
43 | import os
44 | import aiofiles
45 | import aiohttp
46 | from pyrogram import filters
47 | from LaylaRobot import pbot as Layla
48 |
49 | ARQ = "https://thearq.tech/"
50 |
51 | async def fetch(url):
52 | async with aiohttp.ClientSession() as session:
53 | async with session.get(url) as resp:
54 | try:
55 | data = await resp.json()
56 | except:
57 | data = await resp.text()
58 | return data
59 |
60 | async def download_song(url):
61 | song_name = f"asuna.mp3"
62 | async with aiohttp.ClientSession() as session:
63 | async with session.get(url) as resp:
64 | if resp.status == 200:
65 | f = await aiofiles.open(song_name, mode="wb")
66 | await f.write(await resp.read())
67 | await f.close()
68 | return song_name
69 |
70 |
71 | @Layla.on_message(filters.command("deezer"))
72 | async def deezer(_, message):
73 | if len(message.command) < 2:
74 | await message.reply_text("Download Now Deezer")
75 | return
76 | text = message.text.split(None, 1)[1]
77 | query = text.replace(" ", "%20")
78 | m = await message.reply_text("Searching...")
79 | try:
80 | r = await fetch(f"{ARQ}deezer?query={query}&count=1")
81 | title = r[0]["title"]
82 | url = r[0]["url"]
83 | artist = r[0]["artist"]
84 | except Exception as e:
85 | await m.edit(str(e))
86 | return
87 | await m.edit("Downloading...")
88 | song = await download_song(url)
89 | await m.edit("Uploading...")
90 | await message.reply_audio(audio=song, title=title, performer=artist)
91 | os.remove(song)
92 | await m.delete()
93 |
94 | #Deezer
95 | # Credits for @TheHamkerCat
96 |
97 | import os
98 | import aiofiles
99 | import aiohttp
100 | from pyrogram import filters
101 | from LaylaRobot import pbot as ASUNA
102 |
103 | ARQ = "https://thearq.tech/"
104 |
105 | async def fetch(url):
106 | async with aiohttp.ClientSession() as session:
107 | async with session.get(url) as resp:
108 | try:
109 | data = await resp.json()
110 | except:
111 | data = await resp.text()
112 | return data
113 |
114 | async def download_song(url):
115 | song_name = f"asuna.mp3"
116 | async with aiohttp.ClientSession() as session:
117 | async with session.get(url) as resp:
118 | if resp.status == 200:
119 | f = await aiofiles.open(song_name, mode="wb")
120 | await f.write(await resp.read())
121 | await f.close()
122 | return song_name
123 |
124 |
125 | @Layla.on_message(filters.command("deezer"))
126 | async def deezer(_, message):
127 | if len(message.command) < 2:
128 | await message.reply_text("Download Now Deezer")
129 | return
130 | text = message.text.split(None, 1)[1]
131 | query = text.replace(" ", "%20")
132 | m = await message.reply_text("Searching...")
133 | try:
134 | r = await fetch(f"{ARQ}deezer?query={query}&count=1")
135 | title = r[0]["title"]
136 | url = r[0]["url"]
137 | artist = r[0]["artist"]
138 | except Exception as e:
139 | await m.edit(str(e))
140 | return
141 | await m.edit("Downloading...")
142 | song = await download_song(url)
143 | await m.edit("Uploading...")
144 | await message.reply_audio(audio=song, title=title, performer=artist)
145 | os.remove(song)
146 | await m.delete()
147 |
148 |
149 | __mod_name__ = "◎Music"
150 |
151 | __help__ = """
152 | • `/song`** : download the song in it's best quality available.(API BASED)
153 | • `/video`** : download the video song in it's best quality available.
154 | • `/deezer`** : download from deezer
155 | • `/lyrics`** : sends the complete lyrics of the song provided as input
156 | • `/glyrics`** song name : This plugin searches for song lyrics with song name and artist.
157 | """
158 |
159 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/__speachtotext.py:
--------------------------------------------------------------------------------
1 | from LaylaRobot import telethn as tbot
2 | import os
3 | import urllib.request
4 | from datetime import datetime
5 | from typing import List
6 | from typing import Optional
7 | import requests
8 | from telethon import *
9 | from telethon import events
10 | from telethon.tl import functions
11 | from telethon.tl import types
12 | from telethon.tl.types import *
13 |
14 | from LaylaRobot import *
15 | from LaylaRobot.events import register
16 |
17 |
18 | async def is_register_admin(chat, user):
19 | if isinstance(chat, (types.InputPeerChannel, types.InputChannel)):
20 | return isinstance(
21 | (
22 | await tbot(functions.channels.GetParticipantRequest(chat, user))
23 | ).participant,
24 | (types.ChannelParticipantAdmin, types.ChannelParticipantCreator),
25 | )
26 | if isinstance(chat, types.InputPeerUser):
27 | return True
28 |
29 |
30 | @register(pattern="^/stt$")
31 | async def _(event):
32 | if event.fwd_from:
33 | return
34 | if event.is_group:
35 | if not (await is_register_admin(event.input_chat, event.message.sender_id)):
36 | await event.reply("🚨 Need Admin Pewer.. You can't use this command.. But you can use in my pm")
37 | return
38 |
39 | start = datetime.now()
40 | if not os.path.isdir(TEMP_DOWNLOAD_DIRECTORY):
41 | os.makedirs(TEMP_DOWNLOAD_DIRECTORY)
42 |
43 | if event.reply_to_msg_id:
44 | previous_message = await event.get_reply_message()
45 | required_file_name = await event.client.download_media(
46 | previous_message, TEMP_DOWNLOAD_DIRECTORY
47 | )
48 | if IBM_WATSON_CRED_URL is None or IBM_WATSON_CRED_PASSWORD is None:
49 | await event.reply(
50 | "You need to set the required ENV variables for this module. \nModule stopping"
51 | )
52 | else:
53 | # await event.reply("Starting analysis")
54 | headers = {
55 | "Content-Type": previous_message.media.document.mime_type,
56 | }
57 | data = open(required_file_name, "rb").read()
58 | response = requests.post(
59 | IBM_WATSON_CRED_URL + "/v1/recognize",
60 | headers=headers,
61 | data=data,
62 | auth=("apikey", IBM_WATSON_CRED_PASSWORD),
63 | )
64 | r = response.json()
65 | if "results" in r:
66 | # process the json to appropriate string format
67 | results = r["results"]
68 | transcript_response = ""
69 | transcript_confidence = ""
70 | for alternative in results:
71 | alternatives = alternative["alternatives"][0]
72 | transcript_response += " " + str(alternatives["transcript"])
73 | transcript_confidence += (
74 | " " + str(alternatives["confidence"]) + " + "
75 | )
76 | end = datetime.now()
77 | ms = (end - start).seconds
78 | if transcript_response != "":
79 | string_to_show = "TRANSCRIPT: `{}`\nTime Taken: {} seconds\nConfidence: `{}`".format(
80 | transcript_response, ms, transcript_confidence
81 | )
82 | else:
83 | string_to_show = "TRANSCRIPT: `Nil`\nTime Taken: {} seconds\n\n**No Results Found**".format(
84 | ms
85 | )
86 | await event.reply(string_to_show)
87 | else:
88 | await event.reply(r["error"])
89 | # now, remove the temporary file
90 | os.remove(required_file_name)
91 | else:
92 | await event.reply("Reply to a voice message, to get the text out of it.")
93 |
94 |
95 | __help__ = """
96 | I can convert text to voice and voice to text..
97 | ❍ /tts *:* Reply to any message to get text to speech output
98 | ❍ /stt*:* Type in reply to a voice message(support english only) to extract text from it.
99 | *Language Codes*
100 | `af,am,ar,az,be,bg,bn,bs,ca,ceb,co,cs,cy,da,de,el,en,eo,es,
101 | et,eu,fa,fi,fr,fy,ga,gd,gl,gu,ha,haw,hi,hmn,hr,ht,hu,hy,
102 | id,ig,is,it,iw,ja,jw,ka,kk,km,kn,ko,ku,ky,la,lb,lo,lt,lv,mg,mi,mk,
103 | ml,mn,mr,ms,mt,my,ne,nl,no,ny,pa,pl,ps,pt,ro,ru,sd,si,sk,sl,
104 | sm,sn,so,sq,sr,st,su,sv,sw,ta,te,tg,th,tl,tr,uk,ur,uz,
105 | vi,xh,yi,yo,zh,zh_CN,zh_TW,zu`
106 | """
107 |
108 | __mod_name__ = "TTS/STT"
--------------------------------------------------------------------------------
/LaylaRobot/modules/__telegraph.py:
--------------------------------------------------------------------------------
1 | from LaylaRobot.events import register
2 | from LaylaRobot import telethn as tbot
3 | TMP_DOWNLOAD_DIRECTORY = "./"
4 | from telethon import events
5 | import os
6 | from PIL import Image
7 | from datetime import datetime
8 | from telegraph import Telegraph, upload_file, exceptions
9 | Hero = "Layla"
10 | telegraph = Telegraph()
11 | r = telegraph.create_account(short_name=Hero)
12 | auth_url = r["auth_url"]
13 |
14 |
15 | @register(pattern="^/t(m|xt) ?(.*)")
16 | async def _(event):
17 | if event.fwd_from:
18 | return
19 | optional_title = event.pattern_match.group(2)
20 | if event.reply_to_msg_id:
21 | start = datetime.now()
22 | r_message = await event.get_reply_message()
23 | input_str = event.pattern_match.group(1)
24 | if input_str == "m":
25 | downloaded_file_name = await tbot.download_media(
26 | r_message,
27 | TMP_DOWNLOAD_DIRECTORY
28 | )
29 | end = datetime.now()
30 | ms = (end - start).seconds
31 | h = await event.reply("Downloaded to {} in {} seconds.".format(downloaded_file_name, ms))
32 | if downloaded_file_name.endswith((".webp")):
33 | resize_image(downloaded_file_name)
34 | try:
35 | start = datetime.now()
36 | media_urls = upload_file(downloaded_file_name)
37 | except exceptions.TelegraphException as exc:
38 | await h.edit("ERROR: " + str(exc))
39 | os.remove(downloaded_file_name)
40 | else:
41 | end = datetime.now()
42 | ms_two = (end - start).seconds
43 | os.remove(downloaded_file_name)
44 | await h.edit("Uploaded to https://telegra.ph{})".format(media_urls[0]), link_preview=True)
45 | elif input_str == "xt":
46 | user_object = await tbot.get_entity(r_message.sender_id)
47 | title_of_page = user_object.first_name # + " " + user_object.last_name
48 | # apparently, all Users do not have last_name field
49 | if optional_title:
50 | title_of_page = optional_title
51 | page_content = r_message.message
52 | if r_message.media:
53 | if page_content != "":
54 | title_of_page = page_content
55 | downloaded_file_name = await tbot.download_media(
56 | r_message,
57 | TMP_DOWNLOAD_DIRECTORY
58 | )
59 | m_list = None
60 | with open(downloaded_file_name, "rb") as fd:
61 | m_list = fd.readlines()
62 | for m in m_list:
63 | page_content += m.decode("UTF-8") + "\n"
64 | os.remove(downloaded_file_name)
65 | page_content = page_content.replace("\n", "
")
66 | response = telegraph.create_page(
67 | title_of_page,
68 | html_content=page_content
69 | )
70 | end = datetime.now()
71 | ms = (end - start).seconds
72 | await event.reply("Pasted to https://telegra.ph/{} in {} seconds.".format(response["path"], ms), link_preview=True)
73 | else:
74 | await event.reply("Reply to a message to get a permanent telegra.ph link.")
75 |
76 |
77 | def resize_image(image):
78 | im = Image.open(image)
79 | im.save(image, "PNG")
80 |
81 |
82 | __help__ = """
83 | I can upload files to Telegraph
84 | ❍ /tm :Get Telegraph Link Of Replied Media
85 | ❍ /txt :Get Telegraph Link of Replied Text
86 | """
87 |
88 | __mod_name__ = "Telegraph"
89 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/__texttospeech.py:
--------------------------------------------------------------------------------
1 | from LaylaRobot import telethn as tbot
2 | import os
3 |
4 | from gtts import gTTS
5 | from gtts import gTTSError
6 | from telethon import *
7 | from telethon.tl import functions
8 | from telethon.tl import types
9 | from telethon.tl.types import *
10 |
11 | from LaylaRobot import *
12 |
13 | from LaylaRobot.events import register
14 |
15 |
16 | async def is_register_admin(chat, user):
17 | if isinstance(chat, (types.InputPeerChannel, types.InputChannel)):
18 | return isinstance(
19 | (
20 | await tbot(functions.channels.GetParticipantRequest(chat, user))
21 | ).participant,
22 | (types.ChannelParticipantAdmin, types.ChannelParticipantCreator),
23 | )
24 | if isinstance(chat, types.InputPeerUser):
25 | return True
26 |
27 |
28 | @register(pattern="^/tts (.*)")
29 | async def _(event):
30 | if event.fwd_from:
31 | return
32 | if event.is_group:
33 | if not (await is_register_admin(event.input_chat, event.message.sender_id)):
34 | await event.reply("🚨 Need Admin Pewer.. You can't use this command.. But you can use in my pm")
35 | return
36 |
37 | input_str = event.pattern_match.group(1)
38 | reply_to_id = event.message.id
39 | if event.reply_to_msg_id:
40 | previous_message = await event.get_reply_message()
41 | text = previous_message.message
42 | lan = input_str
43 | elif "|" in input_str:
44 | lan, text = input_str.split("|")
45 | else:
46 | await event.reply(
47 | "Invalid Syntax\nFormat `/tts lang | text`\nFor eg: `/tts en | hello`"
48 | )
49 | return
50 | text = text.strip()
51 | lan = lan.strip()
52 | try:
53 | tts = gTTS(text, tld="com", lang=lan)
54 | tts.save("k.mp3")
55 | except AssertionError:
56 | await event.reply(
57 | "The text is empty.\n"
58 | "Nothing left to speak after pre-precessing, "
59 | "tokenizing and cleaning."
60 | )
61 | return
62 | except ValueError:
63 | await event.reply("Language is not supported.")
64 | return
65 | except RuntimeError:
66 | await event.reply("Error loading the languages dictionary.")
67 | return
68 | except gTTSError:
69 | await event.reply("Error in Google Text-to-Speech API request !")
70 | return
71 | with open("k.mp3", "r"):
72 | await tbot.send_file(
73 | event.chat_id, "k.mp3", voice_note=True, reply_to=reply_to_id
74 | )
75 | os.remove("k.mp3")
--------------------------------------------------------------------------------
/LaylaRobot/modules/__tools.py:
--------------------------------------------------------------------------------
1 | __mod_name__ = "◎Tools"
2 |
3 | __help__ = """
4 | *Fake Info*
5 | ❍ /fakegen*:* Generates Fake Information
6 | ❍ /picgen*:* Generate a fake pic
7 |
8 | *Date-time-Weather*
9 | ❍ /time *:* Gives information about a timezone.
10 | ❍ /weather *:* Get weather info in a particular place.
11 | ❍ /wttr *:* Advanced weather module, usage same as /weather
12 | ❍ /wttr moon*:* Get the current status of moon
13 |
14 | *Quotly*
15 | - /q : reply any message with this command to create a sticker.
16 |
17 | *Converts*
18 | ❍ /encrypt*:* Encrypts The Given Text
19 | ❍ /decrypt*:* Decrypts Previously Ecrypted Text
20 | ❍ /zip*:* reply to a telegram file to compress it in .zip format
21 | ❍ /unzip*:* reply to a telegram file to decompress it from the .zip format
22 | """
23 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/__weather.py:
--------------------------------------------------------------------------------
1 | from LaylaRobot import telethn as tbot
2 | import io
3 | import os
4 | import time
5 |
6 | import aiohttp
7 | from telethon import *
8 | from telethon.tl import functions
9 | from telethon.tl import types
10 | from telethon.tl.types import *
11 |
12 | from LaylaRobot import *
13 |
14 | from LaylaRobot.events import register
15 |
16 |
17 | async def is_register_admin(chat, user):
18 | if isinstance(chat, (types.InputPeerChannel, types.InputChannel)):
19 | return isinstance(
20 | (
21 | await tbot(functions.channels.GetParticipantRequest(chat, user))
22 | ).participant,
23 | (types.ChannelParticipantAdmin, types.ChannelParticipantCreator),
24 | )
25 | if isinstance(chat, types.InputPeerUser):
26 | return True
27 |
28 |
29 | @register(pattern="^/weather (.*)")
30 | async def _(event):
31 | if event.fwd_from:
32 | return
33 |
34 | sample_url = (
35 | "https://api.openweathermap.org/data/2.5/weather?q={}&APPID={}&units=metric"
36 | )
37 | input_str = event.pattern_match.group(1)
38 | async with aiohttp.ClientSession() as session:
39 | response_api_zero = await session.get(
40 | sample_url.format(input_str, OPENWEATHERMAP_ID)
41 | )
42 | response_api = await response_api_zero.json()
43 | if response_api["cod"] == 200:
44 | country_code = response_api["sys"]["country"]
45 | country_time_zone = int(response_api["timezone"])
46 | sun_rise_time = int(response_api["sys"]["sunrise"]) + country_time_zone
47 | sun_set_time = int(response_api["sys"]["sunset"]) + country_time_zone
48 | await event.reply(
49 | """**Location**: {}
50 | **Temperature**: {}°С
51 | __minimium__: {}°С
52 | __maximum__ : {}°С
53 | **Humidity**: {}%
54 | **Wind**: {}m/s
55 | **Clouds**: {}hpa
56 | **Sunrise**: {} {}
57 | **Sunset**: {} {}""".format(
58 | input_str,
59 | response_api["main"]["temp"],
60 | response_api["main"]["temp_min"],
61 | response_api["main"]["temp_max"],
62 | response_api["main"]["humidity"],
63 | response_api["wind"]["speed"],
64 | response_api["clouds"]["all"],
65 | # response_api["main"]["pressure"],
66 | time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(sun_rise_time)),
67 | country_code,
68 | time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(sun_set_time)),
69 | country_code,
70 | )
71 | )
72 | else:
73 | await event.reply(response_api["message"])
74 |
75 |
76 | @register(pattern="^/wttr (.*)")
77 | async def _(event):
78 | if event.fwd_from:
79 | return
80 |
81 | sample_url = "https://wttr.in/{}.png"
82 | # logger.info(sample_url)
83 | input_str = event.pattern_match.group(1)
84 | async with aiohttp.ClientSession() as session:
85 | response_api_zero = await session.get(sample_url.format(input_str))
86 | # logger.info(response_api_zero)
87 | response_api = await response_api_zero.read()
88 | with io.BytesIO(response_api) as out_file:
89 | await event.reply(file=out_file)
90 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/_pyrogithub.py:
--------------------------------------------------------------------------------
1 | # © @Mr_Dark_Prince
2 | import aiohttp
3 | from pyrogram import filters
4 | from LaylaRobot import pbot
5 | from LaylaRobot.pyrogramee.errors import capture_err
6 |
7 |
8 | __mod_name__ = "Github"
9 |
10 |
11 | @pbot.on_message(filters.command('github'))
12 | @capture_err
13 | async def github(_, message):
14 | if len(message.command) != 2:
15 | await message.reply_text("/git Username")
16 | return
17 | username = message.text.split(None, 1)[1]
18 | URL = f'https://api.github.com/users/{username}'
19 | async with aiohttp.ClientSession() as session:
20 | async with session.get(URL) as request:
21 | if request.status == 404:
22 | return await message.reply_text("404")
23 |
24 | result = await request.json()
25 | try:
26 | url = result['html_url']
27 | name = result['name']
28 | company = result['company']
29 | bio = result['bio']
30 | created_at = result['created_at']
31 | avatar_url = result['avatar_url']
32 | blog = result['blog']
33 | location = result['location']
34 | repositories = result['public_repos']
35 | followers = result['followers']
36 | following = result['following']
37 | caption = f"""**Info Of {name}**
38 | **Username:** `{username}`
39 | **Bio:** `{bio}`
40 | **Profile Link:** [Here]({url})
41 | **Company:** `{company}`
42 | **Created On:** `{created_at}`
43 | **Repositories:** `{repositories}`
44 | **Blog:** `{blog}`
45 | **Location:** `{location}`
46 | **Followers:** `{followers}`
47 | **Following:** `{following}`"""
48 | except Exception as e:
49 | print(str(e))
50 | pass
51 | await message.reply_photo(photo=avatar_url, caption=caption)
52 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/afk.py:
--------------------------------------------------------------------------------
1 | import random, html
2 |
3 | from LaylaRobot import dispatcher
4 | from LaylaRobot.modules.disable import (
5 | DisableAbleCommandHandler,
6 | DisableAbleMessageHandler,
7 | )
8 | from LaylaRobot.modules.sql import afk_sql as sql
9 | from LaylaRobot.modules.users import get_user_id
10 | from telegram import MessageEntity, Update
11 | from telegram.error import BadRequest
12 | from telegram.ext import CallbackContext, Filters, MessageHandler, run_async
13 |
14 | AFK_GROUP = 7
15 | AFK_REPLY_GROUP = 8
16 |
17 |
18 | @run_async
19 | def afk(update: Update, context: CallbackContext):
20 | args = update.effective_message.text.split(None, 1)
21 | user = update.effective_user
22 |
23 | if not user: # ignore channels
24 | return
25 |
26 | if user.id in [777000, 1087968824]:
27 | return
28 |
29 | notice = ""
30 | if len(args) >= 2:
31 | reason = args[1]
32 | if len(reason) > 100:
33 | reason = reason[:100]
34 | notice = "\nYour afk reason was shortened to 100 characters."
35 | else:
36 | reason = ""
37 |
38 | sql.set_afk(update.effective_user.id, reason)
39 | fname = update.effective_user.first_name
40 | try:
41 | update.effective_message.reply_text("{} is now away!{}".format(fname, notice))
42 | except BadRequest:
43 | pass
44 |
45 |
46 | @run_async
47 | def no_longer_afk(update: Update, context: CallbackContext):
48 | user = update.effective_user
49 | message = update.effective_message
50 |
51 | if not user: # ignore channels
52 | return
53 |
54 | res = sql.rm_afk(user.id)
55 | if res:
56 | if message.new_chat_members: # dont say msg
57 | return
58 | firstname = update.effective_user.first_name
59 | try:
60 | options = [
61 | "{} is here!",
62 | "{} is back!",
63 | "{} is now in the chat!",
64 | "{} is awake!",
65 | "{} is back online!",
66 | "{} is finally here!",
67 | "Welcome back! {}",
68 | "Where is {}?\nIn the chat!",
69 | ]
70 | chosen_option = random.choice(options)
71 | update.effective_message.reply_text(chosen_option.format(firstname))
72 | except:
73 | return
74 |
75 |
76 | @run_async
77 | def reply_afk(update: Update, context: CallbackContext):
78 | bot = context.bot
79 | message = update.effective_message
80 | userc = update.effective_user
81 | userc_id = userc.id
82 | if message.entities and message.parse_entities(
83 | [MessageEntity.TEXT_MENTION, MessageEntity.MENTION]
84 | ):
85 | entities = message.parse_entities(
86 | [MessageEntity.TEXT_MENTION, MessageEntity.MENTION]
87 | )
88 |
89 | chk_users = []
90 | for ent in entities:
91 | if ent.type == MessageEntity.TEXT_MENTION:
92 | user_id = ent.user.id
93 | fst_name = ent.user.first_name
94 |
95 | if user_id in chk_users:
96 | return
97 | chk_users.append(user_id)
98 |
99 | if ent.type != MessageEntity.MENTION:
100 | return
101 |
102 | user_id = get_user_id(message.text[ent.offset : ent.offset + ent.length])
103 | if not user_id:
104 | # Should never happen, since for a user to become AFK they must have spoken. Maybe changed username?
105 | return
106 |
107 | if user_id in chk_users:
108 | return
109 | chk_users.append(user_id)
110 |
111 | try:
112 | chat = bot.get_chat(user_id)
113 | except BadRequest:
114 | print("Error: Could not fetch userid {} for AFK module".format(user_id))
115 | return
116 | fst_name = chat.first_name
117 |
118 | check_afk(update, context, user_id, fst_name, userc_id)
119 |
120 | elif message.reply_to_message:
121 | user_id = message.reply_to_message.from_user.id
122 | fst_name = message.reply_to_message.from_user.first_name
123 | check_afk(update, context, user_id, fst_name, userc_id)
124 |
125 |
126 | def check_afk(update, context, user_id, fst_name, userc_id):
127 | if sql.is_afk(user_id):
128 | user = sql.check_afk_status(user_id)
129 | if int(userc_id) == int(user_id):
130 | return
131 | if not user.reason:
132 | res = "{} is afk".format(fst_name)
133 | update.effective_message.reply_text(res)
134 | else:
135 | res = "{} is afk.\nReason: {}
".format(
136 | html.escape(fst_name), html.escape(user.reason)
137 | )
138 | update.effective_message.reply_text(res, parse_mode="html")
139 |
140 |
141 |
142 | AFK_HANDLER = DisableAbleCommandHandler("afk", afk)
143 | AFK_REGEX_HANDLER = DisableAbleMessageHandler(
144 | Filters.regex(r"^(?i)brb(.*)$"), afk, friendly="afk"
145 | )
146 | NO_AFK_HANDLER = MessageHandler(Filters.all & Filters.group, no_longer_afk)
147 | AFK_REPLY_HANDLER = MessageHandler(Filters.all & Filters.group, reply_afk)
148 |
149 | dispatcher.add_handler(AFK_HANDLER, AFK_GROUP)
150 | dispatcher.add_handler(AFK_REGEX_HANDLER, AFK_GROUP)
151 | dispatcher.add_handler(NO_AFK_HANDLER, AFK_GROUP)
152 | dispatcher.add_handler(AFK_REPLY_HANDLER, AFK_REPLY_GROUP)
153 |
154 | __mod_name__ = "AFK"
155 | __command_list__ = ["afk"]
156 | __handlers__ = [
157 | (AFK_HANDLER, AFK_GROUP),
158 | (AFK_REGEX_HANDLER, AFK_GROUP),
159 | (NO_AFK_HANDLER, AFK_GROUP),
160 | (AFK_REPLY_HANDLER, AFK_REPLY_GROUP),
161 | ]
162 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/blacklistusers.py:
--------------------------------------------------------------------------------
1 | # Module to blacklist users and prevent them from using commands by @TheRealPhoenix
2 | import html
3 | import LaylaRobot.modules.sql.blacklistusers_sql as sql
4 | from LaylaRobot import (
5 | DEV_USERS,
6 | OWNER_ID,
7 | DRAGONS,
8 | DEMONS,
9 | TIGERS,
10 | WOLVES,
11 | dispatcher,
12 | )
13 | from LaylaRobot.modules.helper_funcs.chat_status import dev_plus
14 | from LaylaRobot.modules.helper_funcs.extraction import (
15 | extract_user,
16 | extract_user_and_text,
17 | )
18 | from LaylaRobot.modules.log_channel import gloggable
19 | from telegram import ParseMode, Update
20 | from telegram.error import BadRequest
21 | from telegram.ext import CallbackContext, CommandHandler, run_async
22 | from telegram.utils.helpers import mention_html
23 |
24 | BLACKLISTWHITELIST = [OWNER_ID] + DEV_USERS + DRAGONS + WOLVES + DEMONS
25 | BLABLEUSERS = [OWNER_ID] + DEV_USERS
26 |
27 |
28 | @run_async
29 | @dev_plus
30 | @gloggable
31 | def bl_user(update: Update, context: CallbackContext) -> str:
32 | message = update.effective_message
33 | user = update.effective_user
34 | bot, args = context.bot, context.args
35 | user_id, reason = extract_user_and_text(message, args)
36 |
37 | if not user_id:
38 | message.reply_text("I doubt that's a user.")
39 | return ""
40 |
41 | if user_id == bot.id:
42 | message.reply_text("How am I supposed to do my work if I am ignoring myself?")
43 | return ""
44 |
45 | if user_id in BLACKLISTWHITELIST:
46 | message.reply_text("No!\nNoticing Disasters is my job.")
47 | return ""
48 |
49 | try:
50 | target_user = bot.get_chat(user_id)
51 | except BadRequest as excp:
52 | if excp.message == "User not found":
53 | message.reply_text("I can't seem to find this user.")
54 | return ""
55 | else:
56 | raise
57 |
58 | sql.blacklist_user(user_id, reason)
59 | message.reply_text("I shall ignore the existence of this user!")
60 | log_message = (
61 | f"#BLACKLIST\n"
62 | f"Admin: {mention_html(user.id, html.escape(user.first_name))}\n"
63 | f"User: {mention_html(target_user.id, html.escape(target_user.first_name))}"
64 | )
65 | if reason:
66 | log_message += f"\nReason: {reason}"
67 |
68 | return log_message
69 |
70 |
71 | @run_async
72 | @dev_plus
73 | @gloggable
74 | def unbl_user(update: Update, context: CallbackContext) -> str:
75 | message = update.effective_message
76 | user = update.effective_user
77 | bot, args = context.bot, context.args
78 | user_id = extract_user(message, args)
79 |
80 | if not user_id:
81 | message.reply_text("I doubt that's a user.")
82 | return ""
83 |
84 | if user_id == bot.id:
85 | message.reply_text("I always notice myself.")
86 | return ""
87 |
88 | try:
89 | target_user = bot.get_chat(user_id)
90 | except BadRequest as excp:
91 | if excp.message == "User not found":
92 | message.reply_text("I can't seem to find this user.")
93 | return ""
94 | else:
95 | raise
96 |
97 | if sql.is_user_blacklisted(user_id):
98 |
99 | sql.unblacklist_user(user_id)
100 | message.reply_text("*notices user*")
101 | log_message = (
102 | f"#UNBLACKLIST\n"
103 | f"Admin: {mention_html(user.id, html.escape(user.first_name))}\n"
104 | f"User: {mention_html(target_user.id, html.escape(target_user.first_name))}"
105 | )
106 |
107 | return log_message
108 |
109 | else:
110 | message.reply_text("I am not ignoring them at all though!")
111 | return ""
112 |
113 |
114 | @run_async
115 | @dev_plus
116 | def bl_users(update: Update, context: CallbackContext):
117 | users = []
118 | bot = context.bot
119 | for each_user in sql.BLACKLIST_USERS:
120 | user = bot.get_chat(each_user)
121 | reason = sql.get_reason(each_user)
122 |
123 | if reason:
124 | users.append(
125 | f"• {mention_html(user.id, html.escape(user.first_name))} :- {reason}"
126 | )
127 | else:
128 | users.append(f"• {mention_html(user.id, html.escape(user.first_name))}")
129 |
130 | message = "Blacklisted Users\n"
131 | if not users:
132 | message += "Noone is being ignored as of yet."
133 | else:
134 | message += "\n".join(users)
135 |
136 | update.effective_message.reply_text(message, parse_mode=ParseMode.HTML)
137 |
138 |
139 | def __user_info__(user_id):
140 | is_blacklisted = sql.is_user_blacklisted(user_id)
141 |
142 | text = "Blacklisted: {}"
143 | if user_id in [777000, 1087968824]:
144 | return ""
145 | if user_id == dispatcher.bot.id:
146 | return ""
147 | if int(user_id) in DRAGONS + TIGERS + WOLVES:
148 | return ""
149 | if is_blacklisted:
150 | text = text.format("Yes")
151 | reason = sql.get_reason(user_id)
152 | if reason:
153 | text += f"\nReason: {reason}
"
154 | else:
155 | text = text.format("No")
156 |
157 | return text
158 |
159 |
160 | BL_HANDLER = CommandHandler("ignore", bl_user)
161 | UNBL_HANDLER = CommandHandler("notice", unbl_user)
162 | BLUSERS_HANDLER = CommandHandler("ignoredlist", bl_users)
163 |
164 | dispatcher.add_handler(BL_HANDLER)
165 | dispatcher.add_handler(UNBL_HANDLER)
166 | dispatcher.add_handler(BLUSERS_HANDLER)
167 |
168 | __mod_name__ = "Blacklisting Users"
169 | __handlers__ = [BL_HANDLER, UNBL_HANDLER, BLUSERS_HANDLER]
170 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/cricketscore.py:
--------------------------------------------------------------------------------
1 | import urllib.request
2 |
3 | from bs4 import BeautifulSoup
4 | from telethon import events
5 | from LaylaRobot import telethn as tbot
6 | from telethon.tl import functions, types
7 | from telethon.tl.types import *
8 |
9 |
10 | async def is_register_admin(chat, user):
11 | if isinstance(chat, (types.InputPeerChannel, types.InputChannel)):
12 | return isinstance(
13 | (
14 | await tbot(functions.channels.GetParticipantRequest(chat, user))
15 | ).participant,
16 | (types.ChannelParticipantAdmin, types.ChannelParticipantCreator),
17 | )
18 | if isinstance(chat, types.InputPeerUser):
19 | return True
20 |
21 |
22 | @tbot.on(events.NewMessage(pattern="/cs$"))
23 | async def _(event):
24 | if event.fwd_from:
25 | return
26 | if event.is_group:
27 | if not (await is_register_admin(event.input_chat, event.message.sender_id)):
28 | await event.reply("🚨 Need Admin Pewer.. You can't use this command.. But you can use in my pm")
29 | return
30 |
31 | score_page = "http://static.cricinfo.com/rss/livescores.xml"
32 | page = urllib.request.urlopen(score_page)
33 | soup = BeautifulSoup(page, "html.parser")
34 | result = soup.find_all("description")
35 | Sed = ""
36 | for match in result:
37 | Sed += match.get_text() + "\n\n"
38 | await event.reply(
39 | f"Match information gathered successful\n\n\n{Sed}
",
40 | parse_mode="HTML",
41 | )
42 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/currency_converter.py:
--------------------------------------------------------------------------------
1 | import requests
2 | from LaylaRobot import CASH_API_KEY, dispatcher
3 | from telegram import Update, ParseMode
4 | from telegram.ext import CallbackContext, CommandHandler, run_async
5 |
6 |
7 | @run_async
8 | def convert(update: Update, context: CallbackContext):
9 | args = update.effective_message.text.split(" ")
10 |
11 | if len(args) == 4:
12 | try:
13 | orig_cur_amount = float(args[1])
14 |
15 | except ValueError:
16 | update.effective_message.reply_text("Invalid Amount Of Currency")
17 | return
18 |
19 | orig_cur = args[2].upper()
20 |
21 | new_cur = args[3].upper()
22 |
23 | request_url = (
24 | f"https://www.alphavantage.co/query"
25 | f"?function=CURRENCY_EXCHANGE_RATE"
26 | f"&from_currency={orig_cur}"
27 | f"&to_currency={new_cur}"
28 | f"&apikey={CASH_API_KEY}"
29 | )
30 | response = requests.get(request_url).json()
31 | try:
32 | current_rate = float(
33 | response["Realtime Currency Exchange Rate"]["5. Exchange Rate"]
34 | )
35 | except KeyError:
36 | update.effective_message.reply_text("Currency Not Supported.")
37 | return
38 | new_cur_amount = round(orig_cur_amount * current_rate, 5)
39 | update.effective_message.reply_text(
40 | f"{orig_cur_amount} {orig_cur} = {new_cur_amount} {new_cur}"
41 | )
42 |
43 | elif len(args) == 1:
44 | update.effective_message.reply_text(__help__, parse_mode=ParseMode.MARKDOWN)
45 |
46 | else:
47 | update.effective_message.reply_text(
48 | f"*Invalid Args!!:* Required 3 But Passed {len(args) -1}",
49 | parse_mode=ParseMode.MARKDOWN,
50 | )
51 |
52 |
53 | CONVERTER_HANDLER = CommandHandler("cash", convert)
54 |
55 | dispatcher.add_handler(CONVERTER_HANDLER)
56 |
57 | __command_list__ = ["cash"]
58 | __handlers__ = [CONVERTER_HANDLER]
59 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/dbcleanup.py:
--------------------------------------------------------------------------------
1 | from time import sleep
2 |
3 | import LaylaRobot.modules.sql.global_bans_sql as gban_sql
4 | import LaylaRobot.modules.sql.users_sql as user_sql
5 | from LaylaRobot import DEV_USERS, OWNER_ID, dispatcher
6 | from LaylaRobot.modules.helper_funcs.chat_status import dev_plus
7 | from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
8 | from telegram.error import BadRequest, Unauthorized
9 | from telegram.ext import (
10 | CallbackContext,
11 | CallbackQueryHandler,
12 | CommandHandler,
13 | run_async,
14 | )
15 |
16 |
17 | def get_invalid_chats(update: Update, context: CallbackContext, remove: bool = False):
18 | bot = context.bot
19 | chat_id = update.effective_chat.id
20 | chats = user_sql.get_all_chats()
21 | kicked_chats, progress = 0, 0
22 | chat_list = []
23 | progress_message = None
24 |
25 | for chat in chats:
26 |
27 | if ((100 * chats.index(chat)) / len(chats)) > progress:
28 | progress_bar = f"{progress}% completed in getting invalid chats."
29 | if progress_message:
30 | try:
31 | bot.editMessageText(
32 | progress_bar, chat_id, progress_message.message_id
33 | )
34 | except:
35 | pass
36 | else:
37 | progress_message = bot.sendMessage(chat_id, progress_bar)
38 | progress += 5
39 |
40 | cid = chat.chat_id
41 | sleep(0.1)
42 | try:
43 | bot.get_chat(cid, timeout=60)
44 | except (BadRequest, Unauthorized):
45 | kicked_chats += 1
46 | chat_list.append(cid)
47 | except:
48 | pass
49 |
50 | try:
51 | progress_message.delete()
52 | except:
53 | pass
54 |
55 | if not remove:
56 | return kicked_chats
57 | else:
58 | for muted_chat in chat_list:
59 | sleep(0.1)
60 | user_sql.rem_chat(muted_chat)
61 | return kicked_chats
62 |
63 |
64 | def get_invalid_gban(update: Update, context: CallbackContext, remove: bool = False):
65 | bot = context.bot
66 | banned = gban_sql.get_gban_list()
67 | ungbanned_users = 0
68 | ungban_list = []
69 |
70 | for user in banned:
71 | user_id = user["user_id"]
72 | sleep(0.1)
73 | try:
74 | bot.get_chat(user_id)
75 | except BadRequest:
76 | ungbanned_users += 1
77 | ungban_list.append(user_id)
78 | except:
79 | pass
80 |
81 | if not remove:
82 | return ungbanned_users
83 | else:
84 | for user_id in ungban_list:
85 | sleep(0.1)
86 | gban_sql.ungban_user(user_id)
87 | return ungbanned_users
88 |
89 |
90 | @run_async
91 | @dev_plus
92 | def dbcleanup(update: Update, context: CallbackContext):
93 | msg = update.effective_message
94 |
95 | msg.reply_text("Getting invalid chat count ...")
96 | invalid_chat_count = get_invalid_chats(update, context)
97 |
98 | msg.reply_text("Getting invalid gbanned count ...")
99 | invalid_gban_count = get_invalid_gban(update, context)
100 |
101 | reply = f"Total invalid chats - {invalid_chat_count}\n"
102 | reply += f"Total invalid gbanned users - {invalid_gban_count}"
103 |
104 | buttons = [[InlineKeyboardButton("Cleanup DB", callback_data="db_cleanup")]]
105 |
106 | update.effective_message.reply_text(
107 | reply, reply_markup=InlineKeyboardMarkup(buttons)
108 | )
109 |
110 |
111 | @run_async
112 | def callback_button(update: Update, context: CallbackContext):
113 | bot = context.bot
114 | query = update.callback_query
115 | message = query.message
116 | chat_id = update.effective_chat.id
117 | query_type = query.data
118 |
119 | admin_list = [OWNER_ID] + DEV_USERS
120 |
121 | bot.answer_callback_query(query.id)
122 |
123 | if query_type == "db_leave_chat":
124 | if query.from_user.id in admin_list:
125 | bot.editMessageText("Leaving chats ...", chat_id, message.message_id)
126 | chat_count = get_muted_chats(update, context, True)
127 | bot.sendMessage(chat_id, f"Left {chat_count} chats.")
128 | else:
129 | query.answer("You are not allowed to use this.")
130 | elif query_type == "db_cleanup":
131 | if query.from_user.id in admin_list:
132 | bot.editMessageText("Cleaning up DB ...", chat_id, message.message_id)
133 | invalid_chat_count = get_invalid_chats(update, context, True)
134 | invalid_gban_count = get_invalid_gban(update, context, True)
135 | reply = "Cleaned up {} chats and {} gbanned users from db.".format(
136 | invalid_chat_count, invalid_gban_count
137 | )
138 | bot.sendMessage(chat_id, reply)
139 | else:
140 | query.answer("You are not allowed to use this.")
141 |
142 |
143 | DB_CLEANUP_HANDLER = CommandHandler("dbcleanup", dbcleanup)
144 | BUTTON_HANDLER = CallbackQueryHandler(callback_button, pattern="db_.*")
145 |
146 | dispatcher.add_handler(DB_CLEANUP_HANDLER)
147 | dispatcher.add_handler(BUTTON_HANDLER)
148 |
149 | __mod_name__ = "DB Cleanup"
150 | __handlers__ = [DB_CLEANUP_HANDLER, BUTTON_HANDLER]
151 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/debug.py:
--------------------------------------------------------------------------------
1 | import os
2 | import datetime
3 |
4 | from telethon import events
5 | from telegram import Update
6 | from telegram.ext import CallbackContext, CommandHandler, run_async
7 |
8 | from LaylaRobot import telethn, dispatcher
9 | from LaylaRobot.modules.helper_funcs.chat_status import dev_plus
10 |
11 | DEBUG_MODE = False
12 |
13 |
14 | @run_async
15 | @dev_plus
16 | def debug(update: Update, context: CallbackContext):
17 | global DEBUG_MODE
18 | args = update.effective_message.text.split(None, 1)
19 | message = update.effective_message
20 | print(DEBUG_MODE)
21 | if len(args) > 1:
22 | if args[1] in ("yes", "on"):
23 | DEBUG_MODE = True
24 | message.reply_text("Debug mode is now on.")
25 | elif args[1] in ("no", "off"):
26 | DEBUG_MODE = False
27 | message.reply_text("Debug mode is now off.")
28 | else:
29 | if DEBUG_MODE:
30 | message.reply_text("Debug mode is currently on.")
31 | else:
32 | message.reply_text("Debug mode is currently off.")
33 |
34 |
35 | @telethn.on(events.NewMessage(pattern="[/!].*"))
36 | async def i_do_nothing_yes(event):
37 | global DEBUG_MODE
38 | if DEBUG_MODE:
39 | print(f"-{event.from_id} ({event.chat_id}) : {event.text}")
40 | if os.path.exists("updates.txt"):
41 | with open("updates.txt", "r") as f:
42 | text = f.read()
43 | with open("updates.txt", "w+") as f:
44 | f.write(text + f"\n-{event.from_id} ({event.chat_id}) : {event.text}")
45 | else:
46 | with open("updates.txt", "w+") as f:
47 | f.write(
48 | f"- {event.from_id} ({event.chat_id}) : {event.text} | {datetime.datetime.now()}"
49 | )
50 |
51 |
52 | support_chat = os.getenv("SUPPORT_CHAT")
53 |
54 |
55 | @run_async
56 | @dev_plus
57 | def logs(update: Update, context: CallbackContext):
58 | user = update.effective_user
59 | with open("log.txt", "rb") as f:
60 | context.bot.send_document(document=f, filename=f.name, chat_id=user.id)
61 |
62 |
63 | LOG_HANDLER = CommandHandler("logs", logs)
64 | dispatcher.add_handler(LOG_HANDLER)
65 |
66 | DEBUG_HANDLER = CommandHandler("debug", debug)
67 | dispatcher.add_handler(DEBUG_HANDLER)
68 |
69 | __mod_name__ = "Debug"
70 | __command_list__ = ["debug"]
71 | __handlers__ = [DEBUG_HANDLER]
72 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/dev.py:
--------------------------------------------------------------------------------
1 | import os
2 | import subprocess
3 | import sys
4 |
5 | from contextlib import suppress
6 | from time import sleep
7 |
8 | import LaylaRobot
9 |
10 | from LaylaRobot import dispatcher
11 | from LaylaRobot.modules.helper_funcs.chat_status import dev_plus
12 | from telegram import TelegramError, Update
13 | from telegram.error import Unauthorized
14 | from telegram.ext import CallbackContext, CommandHandler, run_async
15 |
16 | @run_async
17 | @dev_plus
18 | def allow_groups(update: Update, context: CallbackContext):
19 | args = context.args
20 | if not args:
21 | update.effective_message.reply_text(f"Current state: {LaylaRobot.ALLOW_CHATS}")
22 | return
23 | if args[0].lower() in ["off", "no"]:
24 | LaylaRobot.ALLOW_CHATS = True
25 | elif args[0].lower() in ["yes", "on"]:
26 | LaylaRobot.ALLOW_CHATS = False
27 | else:
28 | update.effective_message.reply_text("Format: /lockdown Yes/No or Off/On")
29 | return
30 | update.effective_message.reply_text("Done! Lockdown value toggled.")
31 |
32 | @run_async
33 | @dev_plus
34 | def leave(update: Update, context: CallbackContext):
35 | bot = context.bot
36 | args = context.args
37 | if args:
38 | chat_id = str(args[0])
39 | try:
40 | bot.leave_chat(int(chat_id))
41 | except TelegramError:
42 | update.effective_message.reply_text(
43 | "Beep boop, I could not leave that group(dunno why tho)."
44 | )
45 | return
46 | with suppress(Unauthorized):
47 | update.effective_message.reply_text("Beep boop, I left that soup!.")
48 | else:
49 | update.effective_message.reply_text("Send a valid chat ID")
50 |
51 |
52 | @run_async
53 | @dev_plus
54 | def gitpull(update: Update, context: CallbackContext):
55 | sent_msg = update.effective_message.reply_text(
56 | "Pulling all changes from remote and then attempting to restart."
57 | )
58 | subprocess.Popen("git pull", stdout=subprocess.PIPE, shell=True)
59 |
60 | sent_msg_text = sent_msg.text + "\n\nChanges pulled...I guess.. Restarting in "
61 |
62 | for i in reversed(range(5)):
63 | sent_msg.edit_text(sent_msg_text + str(i + 1))
64 | sleep(1)
65 |
66 | sent_msg.edit_text("Restarted.")
67 |
68 | os.system("restart.bat")
69 | os.execv("start.bat", sys.argv)
70 |
71 |
72 | @run_async
73 | @dev_plus
74 | def restart(update: Update, context: CallbackContext):
75 | update.effective_message.reply_text(
76 | "Starting a new instance and shutting down this one"
77 | )
78 |
79 | os.system("restart.bat")
80 | os.execv("start.bat", sys.argv)
81 |
82 |
83 | LEAVE_HANDLER = CommandHandler("leave", leave)
84 | GITPULL_HANDLER = CommandHandler("gitpull", gitpull)
85 | RESTART_HANDLER = CommandHandler("reboot", restart)
86 | ALLOWGROUPS_HANDLER = CommandHandler("lockdown", allow_groups)
87 |
88 | dispatcher.add_handler(ALLOWGROUPS_HANDLER)
89 | dispatcher.add_handler(LEAVE_HANDLER)
90 | dispatcher.add_handler(GITPULL_HANDLER)
91 | dispatcher.add_handler(RESTART_HANDLER)
92 |
93 | __mod_name__ = "Devs"
94 | __handlers__ = [LEAVE_HANDLER, GITPULL_HANDLER, RESTART_HANDLER, ALLOWGROUPS_HANDLER]
95 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/error_handler.py:
--------------------------------------------------------------------------------
1 | import traceback
2 |
3 | import requests
4 | import html
5 | import random
6 | import traceback
7 | import sys
8 | import pretty_errors
9 | import io
10 | from telegram import Update, InlineKeyboardMarkup, InlineKeyboardButton
11 | from telegram.ext import CallbackContext, CommandHandler
12 | from LaylaRobot import dispatcher, DEV_USERS, OWNER_ID
13 |
14 | pretty_errors.mono()
15 |
16 |
17 | class ErrorsDict(dict):
18 | "A custom dict to store errors and their count"
19 |
20 | def __init__(self, *args, **kwargs):
21 | self.raw = []
22 | super().__init__(*args, **kwargs)
23 |
24 | def __contains__(self, error):
25 | self.raw.append(error)
26 | error.identifier = "".join(random.choices("ABCDEFGHIJKLMNOPQRSTUVWXYZ", k=5))
27 | for e in self:
28 | if type(e) is type(error) and e.args == error.args:
29 | self[e] += 1
30 | return True
31 | self[error] = 0
32 | return False
33 |
34 | def __len__(self):
35 | return len(self.raw)
36 |
37 |
38 | errors = ErrorsDict()
39 |
40 |
41 | def error_callback(update: Update, context: CallbackContext):
42 | if not update:
43 | return
44 | if context.error in errors:
45 | return
46 | try:
47 | stringio = io.StringIO()
48 | pretty_errors.output_stderr = stringio
49 | output = pretty_errors.excepthook(
50 | type(context.error), context.error, context.error.__traceback__
51 | )
52 | pretty_errors.output_stderr = sys.stderr
53 | pretty_error = stringio.getvalue()
54 | stringio.close()
55 | except:
56 | pretty_error = "Failed to create pretty error."
57 | tb_list = traceback.format_exception(
58 | None, context.error, context.error.__traceback__
59 | )
60 | tb = "".join(tb_list)
61 | pretty_message = (
62 | "{}\n"
63 | "-------------------------------------------------------------------------------\n"
64 | "An exception was raised while handling an update\n"
65 | "User: {}\n"
66 | "Chat: {} {}\n"
67 | "Callback data: {}\n"
68 | "Message: {}\n\n"
69 | "Full Traceback: {}"
70 | ).format(
71 | pretty_error,
72 | update.effective_user.id,
73 | update.effective_chat.title if update.effective_chat else "",
74 | update.effective_chat.id if update.effective_chat else "",
75 | update.callback_query.data if update.callback_query else "None",
76 | update.effective_message.text if update.effective_message else "No message",
77 | tb,
78 | )
79 | key = requests.post(
80 | "https://nekobin.com/api/documents", json={"content": pretty_message}
81 | ).json()
82 | e = html.escape(f"{context.error}")
83 | if not key.get("result", {}).get("key"):
84 | with open("error.txt", "w+") as f:
85 | f.write(pretty_message)
86 | context.bot.send_document(
87 | OWNER_ID,
88 | open("error.txt", "rb"),
89 | caption=f"#{context.error.identifier}\nAn unknown error occured:\n{e}
",
90 | parse_mode="html",
91 | )
92 | return
93 | key = key.get("result").get("key")
94 | url = f"https://nekobin.com/{key}.py"
95 | context.bot.send_message(
96 | OWNER_ID,
97 | text=f"#{context.error.identifier}\nAn unknown error occured:\n{e}
",
98 | reply_markup=InlineKeyboardMarkup(
99 | [[InlineKeyboardButton("Nekobin", url=url)]]
100 | ),
101 | parse_mode="html",
102 | )
103 |
104 |
105 | def list_errors(update: Update, context: CallbackContext):
106 | if update.effective_user.id not in DEV_USERS:
107 | return
108 | e = {
109 | k: v for k, v in sorted(errors.items(), key=lambda item: item[1], reverse=True)
110 | }
111 | msg = "Errors List:\n"
112 | for x in e:
113 | msg += f"• {x}:
{e[x]} #{x.identifier}\n"
114 | msg += f"{len(errors)} have occurred since startup."
115 | if len(msg) > 4096:
116 | with open("errors_msg.txt", "w+") as f:
117 | f.write(msg)
118 | context.bot.send_document(
119 | update.effective_chat.id,
120 | open("errors_msg.txt", "rb"),
121 | caption=f"Too many errors have occured..",
122 | parse_mode="html",
123 | )
124 | return
125 | update.effective_message.reply_text(msg, parse_mode="html")
126 |
127 |
128 | dispatcher.add_error_handler(error_callback)
129 | dispatcher.add_handler(CommandHandler("errors", list_errors))
130 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/eval.py:
--------------------------------------------------------------------------------
1 | import io
2 | import os
3 |
4 | # Common imports for eval
5 | import textwrap
6 | import traceback
7 | from contextlib import redirect_stdout
8 |
9 | from LaylaRobot import LOGGER, dispatcher
10 | from LaylaRobot.modules.helper_funcs.chat_status import dev_plus
11 | from telegram import ParseMode, Update
12 | from telegram.ext import CallbackContext, CommandHandler, run_async
13 |
14 | namespaces = {}
15 |
16 |
17 | def namespace_of(chat, update, bot):
18 | if chat not in namespaces:
19 | namespaces[chat] = {
20 | "__builtins__": globals()["__builtins__"],
21 | "bot": bot,
22 | "effective_message": update.effective_message,
23 | "effective_user": update.effective_user,
24 | "effective_chat": update.effective_chat,
25 | "update": update,
26 | }
27 |
28 | return namespaces[chat]
29 |
30 |
31 | def log_input(update):
32 | user = update.effective_user.id
33 | chat = update.effective_chat.id
34 | LOGGER.info(f"IN: {update.effective_message.text} (user={user}, chat={chat})")
35 |
36 |
37 | def send(msg, bot, update):
38 | if len(str(msg)) > 2000:
39 | with io.BytesIO(str.encode(msg)) as out_file:
40 | out_file.name = "output.txt"
41 | bot.send_document(chat_id=update.effective_chat.id, document=out_file)
42 | else:
43 | LOGGER.info(f"OUT: '{msg}'")
44 | bot.send_message(
45 | chat_id=update.effective_chat.id,
46 | text=f"`{msg}`",
47 | parse_mode=ParseMode.MARKDOWN,
48 | )
49 |
50 |
51 | @dev_plus
52 | @run_async
53 | def evaluate(update: Update, context: CallbackContext):
54 | bot = context.bot
55 | send(do(eval, bot, update), bot, update)
56 |
57 |
58 | @dev_plus
59 | @run_async
60 | def execute(update: Update, context: CallbackContext):
61 | bot = context.bot
62 | send(do(exec, bot, update), bot, update)
63 |
64 |
65 | def cleanup_code(code):
66 | if code.startswith("```") and code.endswith("```"):
67 | return "\n".join(code.split("\n")[1:-1])
68 | return code.strip("` \n")
69 |
70 |
71 | def do(func, bot, update):
72 | log_input(update)
73 | content = update.message.text.split(" ", 1)[-1]
74 | body = cleanup_code(content)
75 | env = namespace_of(update.message.chat_id, update, bot)
76 |
77 | os.chdir(os.getcwd())
78 | with open(
79 | os.path.join(os.getcwd(), "LaylaRobot/modules/helper_funcs/temp.txt"), "w"
80 | ) as temp:
81 | temp.write(body)
82 |
83 | stdout = io.StringIO()
84 |
85 | to_compile = f'def func():\n{textwrap.indent(body, " ")}'
86 |
87 | try:
88 | exec(to_compile, env)
89 | except Exception as e:
90 | return f"{e.__class__.__name__}: {e}"
91 |
92 | func = env["func"]
93 |
94 | try:
95 | with redirect_stdout(stdout):
96 | func_return = func()
97 | except Exception as e:
98 | value = stdout.getvalue()
99 | return f"{value}{traceback.format_exc()}"
100 | else:
101 | value = stdout.getvalue()
102 | result = None
103 | if func_return is None:
104 | if value:
105 | result = f"{value}"
106 | else:
107 | try:
108 | result = f"{repr(eval(body, env))}"
109 | except:
110 | pass
111 | else:
112 | result = f"{value}{func_return}"
113 | if result:
114 | return result
115 |
116 |
117 | @dev_plus
118 | @run_async
119 | def clear(update: Update, context: CallbackContext):
120 | bot = context.bot
121 | log_input(update)
122 | global namespaces
123 | if update.message.chat_id in namespaces:
124 | del namespaces[update.message.chat_id]
125 | send("Cleared locals.", bot, update)
126 |
127 |
128 | EVAL_HANDLER = CommandHandler(("e", "ev", "eva", "eval"), evaluate)
129 | EXEC_HANDLER = CommandHandler(("x", "ex", "exe", "exec", "py"), execute)
130 | CLEAR_HANDLER = CommandHandler("clearlocals", clear)
131 |
132 | dispatcher.add_handler(EVAL_HANDLER)
133 | dispatcher.add_handler(EXEC_HANDLER)
134 | dispatcher.add_handler(CLEAR_HANDLER)
135 |
136 | __mod_name__ = "Eval Module"
137 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/fakeit.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | import requests
4 | from faker import Faker
5 | from faker.providers import internet
6 | from telethon import events
7 |
8 | from LaylaRobot.pyrogramee.telethonbasics import is_admin
9 | from LaylaRobot import telethn as tbot
10 |
11 | @tbot.on(events.NewMessage(pattern="/fakegen$"))
12 | async def hi(event):
13 | if event.fwd_from:
14 | return
15 | if event.is_group:
16 | if not await is_admin(event, event.message.sender_id):
17 | await event.reply("`You Should Be Admin To Do This!`")
18 | return
19 | fake = Faker()
20 | print("FAKE DETAILS GENERATED\n")
21 | name = str(fake.name())
22 | fake.add_provider(internet)
23 | address = str(fake.address())
24 | ip = fake.ipv4_private()
25 | cc = fake.credit_card_full()
26 | email = fake.ascii_free_email()
27 | job = fake.job()
28 | android = fake.android_platform_token()
29 | pc = fake.chrome()
30 | await event.reply(
31 | f" Fake Information Generated\nName :-{name}
\n\nAddress:-{address}
\n\nIP ADDRESS:-{ip}
\n\ncredit card:-{cc}
\n\nEmail Id:-{email}
\n\nJob:-{job}
\n\nandroid user agent:-{android}
\n\nPc user agent:-{pc}
",
32 | parse_mode="HTML",
33 | )
34 |
35 |
36 | @tbot.on(events.NewMessage(pattern="/picgen$"))
37 | async def _(event):
38 | if event.fwd_from:
39 | return
40 | if await is_admin(event, event.message.sender_id):
41 | url = "https://thispersondoesnotexist.com/image"
42 | response = requests.get(url)
43 | if response.status_code == 200:
44 | with open("FRIDAYOT.jpg", "wb") as f:
45 | f.write(response.content)
46 |
47 | captin = f"Fake Image powered by @AwesomeSupport."
48 | fole = "FRIDAYOT.jpg"
49 | await tbot.send_file(event.chat_id, fole, caption=captin)
50 | await event.delete()
51 | os.system("rm ./FRIDAYOT.jpg ")
52 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/games.py:
--------------------------------------------------------------------------------
1 | from telethon.tl.types import InputMediaDice
2 |
3 | from LaylaRobot.events import register
4 |
5 |
6 | @register(pattern="^/dice(?: |$)(.*)")
7 | async def _(event):
8 | if event.fwd_from:
9 | return
10 | input_str = event.pattern_match.group(1)
11 | r = await event.reply(file=InputMediaDice(""))
12 | input_int = int(input_str)
13 | if input_int > 6:
14 | await event.reply("hey nigga use number 1 to 6 only")
15 |
16 | else:
17 | try:
18 | required_number = input_int
19 | while r.media.value != required_number:
20 | await r.delete()
21 | r = await event.reply(file=InputMediaDice(""))
22 | except BaseException:
23 | pass
24 |
25 |
26 | @register(pattern="^/dart(?: |$)(.*)")
27 | async def _(event):
28 | if event.fwd_from:
29 | return
30 | input_str = event.pattern_match.group(1)
31 | r = await event.reply(file=InputMediaDice("🎯"))
32 | input_int = int(input_str)
33 | if input_int > 6:
34 | await event.reply("hey nigga use number 1 to 6 only")
35 |
36 | else:
37 | try:
38 | required_number = input_int
39 | while r.media.value != required_number:
40 | await r.delete()
41 | r = await event.reply(file=InputMediaDice("🎯"))
42 | except BaseException:
43 | pass
44 |
45 |
46 | @register(pattern="^/ball(?: |$)(.*)")
47 | async def _(event):
48 | if event.fwd_from:
49 | return
50 | input_str = event.pattern_match.group(1)
51 | r = await event.reply(file=InputMediaDice("🏀"))
52 | input_int = int(input_str)
53 | if input_int > 5:
54 | await event.reply("hey nigga use number 1 to 6 only")
55 |
56 | else:
57 | try:
58 | required_number = input_int
59 | while r.media.value != required_number:
60 | await r.delete()
61 | r = await event.reply(file=InputMediaDice("🏀"))
62 | except BaseException:
63 | pass
64 |
65 |
66 |
67 | __help__ = """
68 | *Play Game With Emojis:*
69 | - /dice or /dice 1 to 6 any value
70 | - /ball or /ball 1 to 5 any value
71 | - /dart or /dart 1 to 6 any value
72 | Usage: hahaha just a magic.
73 | warning: you would be in trouble if you input any other value than mentioned.
74 | *Truth And Dare:*
75 | - /Truth : for random truth.
76 | - /dare : for random dare.
77 | """
78 |
79 | __mod_name__ = "Game"
80 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/get_common_chats.py:
--------------------------------------------------------------------------------
1 | import os
2 | from time import sleep
3 |
4 | from LaylaRobot import OWNER_ID, dispatcher
5 | from LaylaRobot.modules.helper_funcs.extraction import extract_user
6 | from LaylaRobot.modules.sql.users_sql import get_user_com_chats
7 | from telegram import Update
8 | from telegram.error import BadRequest, RetryAfter, Unauthorized
9 | from telegram.ext import CallbackContext, CommandHandler, Filters
10 | from telegram.ext.dispatcher import run_async
11 |
12 |
13 | @run_async
14 | def get_user_common_chats(update: Update, context: CallbackContext):
15 | bot, args = context.bot, context.args
16 | msg = update.effective_message
17 | user = extract_user(msg, args)
18 | if not user:
19 | msg.reply_text("I share no common chats with the void.")
20 | return
21 | common_list = get_user_com_chats(user)
22 | if not common_list:
23 | msg.reply_text("No common chats with this user!")
24 | return
25 | name = bot.get_chat(user).first_name
26 | text = f"Common chats with {name}\n"
27 | for chat in common_list:
28 | try:
29 | chat_name = bot.get_chat(chat).title
30 | sleep(0.3)
31 | text += f"• {chat_name}
\n"
32 | except BadRequest:
33 | pass
34 | except Unauthorized:
35 | pass
36 | except RetryAfter as e:
37 | sleep(e.retry_after)
38 |
39 | if len(text) < 4096:
40 | msg.reply_text(text, parse_mode="HTML")
41 | else:
42 | with open("common_chats.txt", "w") as f:
43 | f.write(text)
44 | with open("common_chats.txt", "rb") as f:
45 | msg.reply_document(f)
46 | os.remove("common_chats.txt")
47 |
48 |
49 | COMMON_CHATS_HANDLER = CommandHandler(
50 | "getchats", get_user_common_chats, filters=Filters.user(OWNER_ID)
51 | )
52 |
53 | dispatcher.add_handler(COMMON_CHATS_HANDLER)
54 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/gettime.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | from typing import List
3 |
4 | import requests
5 | from LaylaRobot import TIME_API_KEY, dispatcher
6 | from LaylaRobot.modules.disable import DisableAbleCommandHandler
7 | from telegram import ParseMode, Update
8 | from telegram.ext import CallbackContext, run_async
9 |
10 |
11 | def generate_time(to_find: str, findtype: List[str]) -> str:
12 | data = requests.get(
13 | f"https://api.timezonedb.com/v2.1/list-time-zone"
14 | f"?key={TIME_API_KEY}"
15 | f"&format=json"
16 | f"&fields=countryCode,countryName,zoneName,gmtOffset,timestamp,dst"
17 | ).json()
18 |
19 | for zone in data["zones"]:
20 | for eachtype in findtype:
21 | if to_find in zone[eachtype].lower():
22 | country_name = zone["countryName"]
23 | country_zone = zone["zoneName"]
24 | country_code = zone["countryCode"]
25 |
26 | if zone["dst"] == 1:
27 | daylight_saving = "Yes"
28 | else:
29 | daylight_saving = "No"
30 |
31 | date_fmt = r"%d-%m-%Y"
32 | time_fmt = r"%H:%M:%S"
33 | day_fmt = r"%A"
34 | gmt_offset = zone["gmtOffset"]
35 | timestamp = datetime.datetime.now(
36 | datetime.timezone.utc
37 | ) + datetime.timedelta(seconds=gmt_offset)
38 | current_date = timestamp.strftime(date_fmt)
39 | current_time = timestamp.strftime(time_fmt)
40 | current_day = timestamp.strftime(day_fmt)
41 |
42 | break
43 |
44 | try:
45 | result = (
46 | f"Country: {country_name}
\n"
47 | f"Zone Name: {country_zone}
\n"
48 | f"Country Code: {country_code}
\n"
49 | f"Daylight saving: {daylight_saving}
\n"
50 | f"Day: {current_day}
\n"
51 | f"Current Time: {current_time}
\n"
52 | f"Current Date: {current_date}
\n"
53 | 'Timezones: List here'
54 | )
55 | except:
56 | result = None
57 |
58 | return result
59 |
60 |
61 | @run_async
62 | def gettime(update: Update, context: CallbackContext):
63 | message = update.effective_message
64 |
65 | try:
66 | query = message.text.strip().split(" ", 1)[1]
67 | except:
68 | message.reply_text("Provide a country name/abbreviation/timezone to find.")
69 | return
70 | send_message = message.reply_text(
71 | f"Finding timezone info for {query}", parse_mode=ParseMode.HTML
72 | )
73 |
74 | query_timezone = query.lower()
75 | if len(query_timezone) == 2:
76 | result = generate_time(query_timezone, ["countryCode"])
77 | else:
78 | result = generate_time(query_timezone, ["zoneName", "countryName"])
79 |
80 | if not result:
81 | send_message.edit_text(
82 | f"Timezone info not available for {query}\n"
83 | 'All Timezones: List here',
84 | parse_mode=ParseMode.HTML,
85 | disable_web_page_preview=True,
86 | )
87 | return
88 |
89 | send_message.edit_text(
90 | result, parse_mode=ParseMode.HTML, disable_web_page_preview=True
91 | )
92 |
93 |
94 | TIME_HANDLER = DisableAbleCommandHandler("time", gettime)
95 |
96 | dispatcher.add_handler(TIME_HANDLER)
97 |
98 | __mod_name__ = "TIME"
99 | __command_list__ = ["time"]
100 | __handlers__ = [TIME_HANDLER]
101 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/gtranslator.py:
--------------------------------------------------------------------------------
1 | from emoji import UNICODE_EMOJI
2 | from google_trans_new import LANGUAGES, google_translator
3 | from telegram import ParseMode, Update
4 | from telegram.ext import CallbackContext, run_async
5 |
6 | from LaylaRobot import dispatcher
7 | from LaylaRobot.modules.disable import DisableAbleCommandHandler
8 |
9 |
10 | @run_async
11 | def totranslate(update: Update, context: CallbackContext):
12 | message = update.effective_message
13 | problem_lang_code = []
14 | for key in LANGUAGES:
15 | if "-" in key:
16 | problem_lang_code.append(key)
17 |
18 | try:
19 | if message.reply_to_message:
20 | args = update.effective_message.text.split(None, 1)
21 | if message.reply_to_message.text:
22 | text = message.reply_to_message.text
23 | elif message.reply_to_message.caption:
24 | text = message.reply_to_message.caption
25 |
26 | try:
27 | source_lang = args[1].split(None, 1)[0]
28 | except (IndexError, AttributeError):
29 | source_lang = "en"
30 |
31 | else:
32 | args = update.effective_message.text.split(None, 2)
33 | text = args[2]
34 | source_lang = args[1]
35 |
36 | if source_lang.count("-") == 2:
37 | for lang in problem_lang_code:
38 | if lang in source_lang:
39 | if source_lang.startswith(lang):
40 | dest_lang = source_lang.rsplit("-", 1)[1]
41 | source_lang = source_lang.rsplit("-", 1)[0]
42 | else:
43 | dest_lang = source_lang.split("-", 1)[1]
44 | source_lang = source_lang.split("-", 1)[0]
45 | elif source_lang.count("-") == 1:
46 | for lang in problem_lang_code:
47 | if lang in source_lang:
48 | dest_lang = source_lang
49 | source_lang = None
50 | break
51 | if dest_lang is None:
52 | dest_lang = source_lang.split("-")[1]
53 | source_lang = source_lang.split("-")[0]
54 | else:
55 | dest_lang = source_lang
56 | source_lang = None
57 |
58 | exclude_list = UNICODE_EMOJI.keys()
59 | for emoji in exclude_list:
60 | if emoji in text:
61 | text = text.replace(emoji, "")
62 |
63 | trl = google_translator()
64 | if source_lang is None:
65 | detection = trl.detect(text)
66 | trans_str = trl.translate(text, lang_tgt=dest_lang)
67 | return message.reply_text(
68 | f"Translated from `{detection[0]}` to `{dest_lang}`:\n`{trans_str}`",
69 | parse_mode=ParseMode.MARKDOWN,
70 | )
71 | else:
72 | trans_str = trl.translate(text, lang_tgt=dest_lang, lang_src=source_lang)
73 | message.reply_text(
74 | f"Translated from `{source_lang}` to `{dest_lang}`:\n`{trans_str}`",
75 | parse_mode=ParseMode.MARKDOWN,
76 | )
77 |
78 | except IndexError:
79 | update.effective_message.reply_text(
80 | "Reply to messages or write messages from other languages for translating into the intended language\n\n"
81 | "Example: `/tr en-ml` to translate from English to Malayalam\n"
82 | "Or use: `/tr ml` for automatic detection and translating it into Malayalam.\n"
83 | "See [List of Language Codes](t.me/OnePunchSupport/12823) for a list of language codes.",
84 | parse_mode="markdown",
85 | disable_web_page_preview=True,
86 | )
87 | except ValueError:
88 | update.effective_message.reply_text("The intended language is not found!")
89 | else:
90 | return
91 |
92 |
93 | __help__ = """
94 | ❍ /tr or /tl (language code) as reply to a long message
95 | *Example:*
96 | ❍ /tr en*:* translates something to english
97 | ❍ /tr hi-en*:* translates hindi to english
98 |
99 | *Language Codes*
100 | `af,am,ar,az,be,bg,bn,bs,ca,ceb,co,cs,cy,da,de,el,en,eo,es,
101 | et,eu,fa,fi,fr,fy,ga,gd,gl,gu,ha,haw,hi,hmn,hr,ht,hu,hy,
102 | id,ig,is,it,iw,ja,jw,ka,kk,km,kn,ko,ku,ky,la,lb,lo,lt,lv,mg,mi,mk,
103 | ml,mn,mr,ms,mt,my,ne,nl,no,ny,pa,pl,ps,pt,ro,ru,sd,si,sk,sl,
104 | sm,sn,so,sq,sr,st,su,sv,sw,ta,te,tg,th,tl,tr,uk,ur,uz,
105 | vi,xh,yi,yo,zh,zh_CN,zh_TW,zu`
106 | """
107 |
108 | TRANSLATE_HANDLER = DisableAbleCommandHandler(["tr", "tl"], totranslate)
109 |
110 | dispatcher.add_handler(TRANSLATE_HANDLER)
111 |
112 | __mod_name__ = "G-Trans"
113 | __command_list__ = ["tr", "tl"]
114 | __handlers__ = [TRANSLATE_HANDLER]
115 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/helper_funcs/__init__.py:
--------------------------------------------------------------------------------
1 | """Helpers, also known as Utilities."""
2 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/helper_funcs/alternate.py:
--------------------------------------------------------------------------------
1 | from telegram.error import BadRequest
2 | from functools import wraps
3 | from telegram import ChatAction
4 |
5 |
6 | def send_message(message, text, *args, **kwargs):
7 | try:
8 | return message.reply_text(text, *args, **kwargs)
9 | except BadRequest as err:
10 | if str(err) == "Reply message not found":
11 | return message.reply_text(text, quote=False, *args, **kwargs)
12 |
13 |
14 | def typing_action(func):
15 | """Sends typing action while processing func command."""
16 |
17 | @wraps(func)
18 | def command_func(update, context, *args, **kwargs):
19 | context.bot.send_chat_action(
20 | chat_id=update.effective_chat.id, action=ChatAction.TYPING
21 | )
22 | return func(update, context, *args, **kwargs)
23 |
24 | return command_func
25 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/helper_funcs/filters.py:
--------------------------------------------------------------------------------
1 | from LaylaRobot import DEV_USERS, DRAGONS, DEMONS
2 | from telegram import Message
3 | from telegram.ext import BaseFilter
4 |
5 |
6 | class CustomFilters(object):
7 | class _Supporters(BaseFilter):
8 | def filter(self, message: Message):
9 | return bool(message.from_user and message.from_user.id in DEMONS)
10 |
11 | support_filter = _Supporters()
12 |
13 | class _Sudoers(BaseFilter):
14 | def filter(self, message: Message):
15 | return bool(message.from_user and message.from_user.id in DRAGONS)
16 |
17 | sudo_filter = _Sudoers()
18 |
19 | class _Developers(BaseFilter):
20 | def filter(self, message: Message):
21 | return bool(message.from_user and message.from_user.id in DEV_USERS)
22 |
23 | dev_filter = _Developers()
24 |
25 | class _MimeType(BaseFilter):
26 | def __init__(self, mimetype):
27 | self.mime_type = mimetype
28 | self.name = "CustomFilters.mime_type({})".format(self.mime_type)
29 |
30 | def filter(self, message: Message):
31 | return bool(
32 | message.document and message.document.mime_type == self.mime_type
33 | )
34 |
35 | mime_type = _MimeType
36 |
37 | class _HasText(BaseFilter):
38 | def filter(self, message: Message):
39 | return bool(
40 | message.text
41 | or message.sticker
42 | or message.photo
43 | or message.document
44 | or message.video
45 | )
46 |
47 | has_text = _HasText()
48 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/helper_funcs/handlers.py:
--------------------------------------------------------------------------------
1 | import LaylaRobot.modules.sql.blacklistusers_sql as sql
2 | from LaylaRobot import ALLOW_EXCL
3 | from LaylaRobot import DEV_USERS, DRAGONS, DEMONS, TIGERS, WOLVES
4 |
5 | from telegram import Update
6 | from telegram.ext import CommandHandler, MessageHandler, RegexHandler, Filters
7 | from pyrate_limiter import (
8 | BucketFullException,
9 | Duration,
10 | RequestRate,
11 | Limiter,
12 | MemoryListBucket,
13 | )
14 |
15 | if ALLOW_EXCL:
16 | CMD_STARTERS = ("/", "!")
17 | else:
18 | CMD_STARTERS = ("/",)
19 |
20 |
21 | class AntiSpam:
22 | def __init__(self):
23 | self.whitelist = (
24 | (DEV_USERS or [])
25 | + (DRAGONS or [])
26 | + (WOLVES or [])
27 | + (DEMONS or [])
28 | + (TIGERS or [])
29 | )
30 | # Values are HIGHLY experimental, its recommended you pay attention to our commits as we will be adjusting the values over time with what suits best.
31 | Duration.CUSTOM = 15 # Custom duration, 15 seconds
32 | self.sec_limit = RequestRate(6, Duration.CUSTOM) # 6 / Per 15 Seconds
33 | self.min_limit = RequestRate(20, Duration.MINUTE) # 20 / Per minute
34 | self.hour_limit = RequestRate(100, Duration.HOUR) # 100 / Per hour
35 | self.daily_limit = RequestRate(1000, Duration.DAY) # 1000 / Per day
36 | self.limiter = Limiter(
37 | self.sec_limit,
38 | self.min_limit,
39 | self.hour_limit,
40 | self.daily_limit,
41 | bucket_class=MemoryListBucket,
42 | )
43 |
44 | def check_user(self, user):
45 | """
46 | Return True if user is to be ignored else False
47 | """
48 | if user in self.whitelist:
49 | return False
50 | try:
51 | self.limiter.try_acquire(user)
52 | return False
53 | except BucketFullException:
54 | return True
55 |
56 |
57 | SpamChecker = AntiSpam()
58 | MessageHandlerChecker = AntiSpam()
59 |
60 |
61 | class CustomCommandHandler(CommandHandler):
62 | def __init__(self, command, callback, admin_ok=False, allow_edit=False, **kwargs):
63 | super().__init__(command, callback, **kwargs)
64 |
65 | if allow_edit is False:
66 | self.filters &= ~(
67 | Filters.update.edited_message | Filters.update.edited_channel_post
68 | )
69 |
70 | def check_update(self, update):
71 | if isinstance(update, Update) and update.effective_message:
72 | message = update.effective_message
73 |
74 | try:
75 | user_id = update.effective_user.id
76 | except:
77 | user_id = None
78 |
79 | if user_id:
80 | if sql.is_user_blacklisted(user_id):
81 | return False
82 |
83 | if message.text and len(message.text) > 1:
84 | fst_word = message.text.split(None, 1)[0]
85 | if len(fst_word) > 1 and any(
86 | fst_word.startswith(start) for start in CMD_STARTERS
87 | ):
88 |
89 | args = message.text.split()[1:]
90 | command = fst_word[1:].split("@")
91 | command.append(message.bot.username)
92 | if user_id == 1087968824:
93 | user_id = update.effective_chat.id
94 | if not (
95 | command[0].lower() in self.command
96 | and command[1].lower() == message.bot.username.lower()
97 | ):
98 | return None
99 | if SpamChecker.check_user(user_id):
100 | return None
101 | filter_result = self.filters(update)
102 | if filter_result:
103 | return args, filter_result
104 | else:
105 | return False
106 |
107 | def handle_update(self, update, dispatcher, check_result, context=None):
108 | if context:
109 | self.collect_additional_context(context, update, dispatcher, check_result)
110 | return self.callback(update, context)
111 | else:
112 | optional_args = self.collect_optional_args(dispatcher, update, check_result)
113 | return self.callback(dispatcher.bot, update, **optional_args)
114 |
115 | def collect_additional_context(self, context, update, dispatcher, check_result):
116 | if isinstance(check_result, bool):
117 | context.args = update.effective_message.text.split()[1:]
118 | else:
119 | context.args = check_result[0]
120 | if isinstance(check_result[1], dict):
121 | context.update(check_result[1])
122 |
123 |
124 | class CustomRegexHandler(RegexHandler):
125 | def __init__(self, pattern, callback, friendly="", **kwargs):
126 | super().__init__(pattern, callback, **kwargs)
127 |
128 |
129 | class CustomMessageHandler(MessageHandler):
130 | def __init__(self, filters, callback, friendly="", allow_edit=False, **kwargs):
131 | super().__init__(filters, callback, **kwargs)
132 | if allow_edit is False:
133 | self.filters &= ~(
134 | Filters.update.edited_message | Filters.update.edited_channel_post
135 | )
136 |
137 | def check_update(self, update):
138 | if isinstance(update, Update) and update.effective_message:
139 | return self.filters(update)
140 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/helper_funcs/misc.py:
--------------------------------------------------------------------------------
1 | from math import ceil
2 | from typing import Dict, List
3 |
4 | from LaylaRobot import NO_LOAD
5 | from telegram import MAX_MESSAGE_LENGTH, Bot, InlineKeyboardButton, ParseMode
6 | from telegram.error import TelegramError
7 |
8 |
9 | class EqInlineKeyboardButton(InlineKeyboardButton):
10 | def __eq__(self, other):
11 | return self.text == other.text
12 |
13 | def __lt__(self, other):
14 | return self.text < other.text
15 |
16 | def __gt__(self, other):
17 | return self.text > other.text
18 |
19 |
20 | def split_message(msg: str) -> List[str]:
21 | if len(msg) < MAX_MESSAGE_LENGTH:
22 | return [msg]
23 |
24 | lines = msg.splitlines(True)
25 | small_msg = ""
26 | result = []
27 | for line in lines:
28 | if len(small_msg) + len(line) < MAX_MESSAGE_LENGTH:
29 | small_msg += line
30 | else:
31 | result.append(small_msg)
32 | small_msg = line
33 | else:
34 | # Else statement at the end of the for loop, so append the leftover string.
35 | result.append(small_msg)
36 |
37 | return result
38 |
39 |
40 | def paginate_modules(page_n: int, module_dict: Dict, prefix, chat=None) -> List:
41 | if not chat:
42 | modules = sorted(
43 | [EqInlineKeyboardButton(x.__mod_name__,
44 | callback_data="{}_module({})".format(prefix, x.__mod_name__.lower())) for x
45 | in module_dict.values()])
46 | else:
47 | modules = sorted(
48 | [EqInlineKeyboardButton(x.__mod_name__,
49 | callback_data="{}_module({},{})".format(prefix, chat, x.__mod_name__.lower())) for x
50 | in module_dict.values()])
51 |
52 | pairs = [
53 | modules[i * 3:(i + 1) * 3] for i in range((len(modules) + 3 - 1) // 3)
54 | ]
55 |
56 | round_num = len(modules) / 3
57 | calc = len(modules) - round(round_num)
58 | if calc == 1:
59 | pairs.append((modules[-1], ))
60 | elif calc == 2:
61 | pairs.append((modules[-1], ))
62 |
63 | max_num_pages = ceil(len(pairs) / 10)
64 | modulo_page = page_n % max_num_pages
65 |
66 | # can only have a certain amount of buttons side by side
67 | if len(pairs) > 8:
68 | pairs = pairs[modulo_page * 8:8 * (modulo_page + 1)] + [
69 | (EqInlineKeyboardButton("⬅️", callback_data="{}_prev({})".format(prefix, modulo_page)),
70 | EqInlineKeyboardButton("Back", callback_data="layla_back"),
71 | EqInlineKeyboardButton("➡️", callback_data="{}_next({})".format(prefix, modulo_page)))]
72 |
73 | else:
74 | pairs += [[EqInlineKeyboardButton("Back", callback_data="layla_back")]]
75 |
76 | return pairs
77 |
78 |
79 | def send_to_list(
80 | bot: Bot, send_to: list, message: str, markdown=False, html=False
81 | ) -> None:
82 | if html and markdown:
83 | raise Exception("Can only send with either markdown or HTML!")
84 | for user_id in set(send_to):
85 | try:
86 | if markdown:
87 | bot.send_message(user_id, message, parse_mode=ParseMode.MARKDOWN)
88 | elif html:
89 | bot.send_message(user_id, message, parse_mode=ParseMode.HTML)
90 | else:
91 | bot.send_message(user_id, message)
92 | except TelegramError:
93 | pass # ignore users who fail
94 |
95 |
96 | def build_keyboard(buttons):
97 | keyb = []
98 | for btn in buttons:
99 | if btn.same_line and keyb:
100 | keyb[-1].append(InlineKeyboardButton(btn.name, url=btn.url))
101 | else:
102 | keyb.append([InlineKeyboardButton(btn.name, url=btn.url)])
103 |
104 | return keyb
105 |
106 |
107 | def revert_buttons(buttons):
108 | res = ""
109 | for btn in buttons:
110 | if btn.same_line:
111 | res += "\n[{}](buttonurl://{}:same)".format(btn.name, btn.url)
112 | else:
113 | res += "\n[{}](buttonurl://{})".format(btn.name, btn.url)
114 |
115 | return res
116 |
117 |
118 | def build_keyboard_parser(bot, chat_id, buttons):
119 | keyb = []
120 | for btn in buttons:
121 | if btn.url == "{rules}":
122 | btn.url = "http://t.me/{}?start={}".format(bot.username, chat_id)
123 | if btn.same_line and keyb:
124 | keyb[-1].append(InlineKeyboardButton(btn.name, url=btn.url))
125 | else:
126 | keyb.append([InlineKeyboardButton(btn.name, url=btn.url)])
127 |
128 | return keyb
129 |
130 |
131 | def is_module_loaded(name):
132 | return name not in NO_LOAD
133 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/helper_funcs/regex_helper.py:
--------------------------------------------------------------------------------
1 | import regex
2 |
3 |
4 | def regex_searcher(regex_string, string):
5 | try:
6 | search = regex.search(regex_string, string, timeout=6)
7 | except TimeoutError:
8 | return False
9 | except Exception:
10 | return False
11 | return search
12 |
13 |
14 | def infinite_loop_check(regex_string):
15 | loop_matches = [
16 | r"\((.{1,}[\+\*]){1,}\)[\+\*].",
17 | r"[\(\[].{1,}\{\d(,)?\}[\)\]]\{\d(,)?\}",
18 | r"\(.{1,}\)\{.{1,}(,)?\}\(.*\)(\+|\* |\{.*\})",
19 | ]
20 | for match in loop_matches:
21 | match_1 = regex.search(match, regex_string)
22 | if match_1:
23 | return True
24 | return False
25 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/helper_funcs/telethn/__init__.py:
--------------------------------------------------------------------------------
1 | from LaylaRobot import DEV_USERS, DRAGONS, DEMONS, TIGERS, WOLVES, telethn
2 |
3 | IMMUNE_USERS = DRAGONS + WOLVES + DEMONS + TIGERS + DEV_USERS
4 |
5 | IMMUNE_USERS = (
6 | list(DRAGONS) + list(WOLVES) + list(DEMONS) + list(TIGERS) + list(DEV_USERS)
7 | )
8 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/helper_funcs/telethn/chatstatus.py:
--------------------------------------------------------------------------------
1 | from LaylaRobot.modules.helper_funcs.telethn import IMMUNE_USERS, telethn
2 | from LaylaRobot import DRAGONS
3 | from telethon.tl.types import ChannelParticipantsAdmins
4 |
5 |
6 | async def user_is_ban_protected(user_id: int, message):
7 | status = False
8 | if message.is_private or user_id in (IMMUNE_USERS):
9 | return True
10 |
11 | async for user in telethn.iter_participants(
12 | message.chat_id, filter=ChannelParticipantsAdmins
13 | ):
14 | if user_id == user.id:
15 | status = True
16 | break
17 | return status
18 |
19 |
20 | async def user_is_admin(user_id: int, message):
21 | status = False
22 | if message.is_private:
23 | return True
24 |
25 | async for user in telethn.iter_participants(
26 | message.chat_id, filter=ChannelParticipantsAdmins
27 | ):
28 | if user_id == user.id or user_id in DRAGONS:
29 | status = True
30 | break
31 | return status
32 |
33 |
34 | async def is_user_admin(user_id: int, chat_id):
35 | status = False
36 | async for user in telethn.iter_participants(
37 | chat_id, filter=ChannelParticipantsAdmins
38 | ):
39 | if user_id == user.id or user_id in DRAGONS:
40 | status = True
41 | break
42 | return status
43 |
44 |
45 | async def yone_is_admin(chat_id: int):
46 | status = False
47 | yone = await telethn.get_me()
48 | async for user in telethn.iter_participants(
49 | chat_id, filter=ChannelParticipantsAdmins
50 | ):
51 | if yone.id == user.id:
52 | status = True
53 | break
54 | return status
55 |
56 |
57 | async def is_user_in_chat(chat_id: int, user_id: int):
58 | status = False
59 | async for user in telethn.iter_participants(chat_id):
60 | if user_id == user.id:
61 | status = True
62 | break
63 | return status
64 |
65 |
66 | async def can_change_info(message):
67 | status = False
68 | if message.chat.admin_rights:
69 | status = message.chat.admin_rights.change_info
70 | return status
71 |
72 |
73 | async def can_ban_users(message):
74 | status = False
75 | if message.chat.admin_rights:
76 | status = message.chat.admin_rights.ban_users
77 | return status
78 |
79 |
80 | async def can_pin_messages(message):
81 | status = False
82 | if message.chat.admin_rights:
83 | status = message.chat.admin_rights.pin_messages
84 | return status
85 |
86 |
87 | async def can_invite_users(message):
88 | status = False
89 | if message.chat.admin_rights:
90 | status = message.chat.admin_rights.invite_users
91 | return status
92 |
93 |
94 | async def can_add_admins(message):
95 | status = False
96 | if message.chat.admin_rights:
97 | status = message.chat.admin_rights.add_admins
98 | return status
99 |
100 |
101 | async def can_delete_messages(message):
102 |
103 | if message.is_private:
104 | return True
105 | elif message.chat.admin_rights:
106 | status = message.chat.admin_rights.delete_messages
107 | return status
108 | else:
109 | return False
110 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/math.py:
--------------------------------------------------------------------------------
1 | import math
2 |
3 | import pynewtonmath as newton
4 | from LaylaRobot import dispatcher
5 | from LaylaRobot.modules.disable import DisableAbleCommandHandler
6 | from telegram import Update
7 | from telegram.ext import CallbackContext, run_async
8 |
9 |
10 | @run_async
11 | def simplify(update: Update, context: CallbackContext):
12 | args = context.args
13 | message = update.effective_message
14 | message.reply_text(newton.simplify("{}".format(args[0])))
15 |
16 |
17 | @run_async
18 | def factor(update: Update, context: CallbackContext):
19 | args = context.args
20 | message = update.effective_message
21 | message.reply_text(newton.factor("{}".format(args[0])))
22 |
23 |
24 | @run_async
25 | def derive(update: Update, context: CallbackContext):
26 | args = context.args
27 | message = update.effective_message
28 | message.reply_text(newton.derive("{}".format(args[0])))
29 |
30 |
31 | @run_async
32 | def integrate(update: Update, context: CallbackContext):
33 | args = context.args
34 | message = update.effective_message
35 | message.reply_text(newton.integrate("{}".format(args[0])))
36 |
37 |
38 | @run_async
39 | def zeroes(update: Update, context: CallbackContext):
40 | args = context.args
41 | message = update.effective_message
42 | message.reply_text(newton.zeroes("{}".format(args[0])))
43 |
44 |
45 | @run_async
46 | def tangent(update: Update, context: CallbackContext):
47 | args = context.args
48 | message = update.effective_message
49 | message.reply_text(newton.tangent("{}".format(args[0])))
50 |
51 |
52 | @run_async
53 | def area(update: Update, context: CallbackContext):
54 | args = context.args
55 | message = update.effective_message
56 | message.reply_text(newton.area("{}".format(args[0])))
57 |
58 |
59 | @run_async
60 | def cos(update: Update, context: CallbackContext):
61 | args = context.args
62 | message = update.effective_message
63 | message.reply_text(math.cos(int(args[0])))
64 |
65 |
66 | @run_async
67 | def sin(update: Update, context: CallbackContext):
68 | args = context.args
69 | message = update.effective_message
70 | message.reply_text(math.sin(int(args[0])))
71 |
72 |
73 | @run_async
74 | def tan(update: Update, context: CallbackContext):
75 | args = context.args
76 | message = update.effective_message
77 | message.reply_text(math.tan(int(args[0])))
78 |
79 |
80 | @run_async
81 | def arccos(update: Update, context: CallbackContext):
82 | args = context.args
83 | message = update.effective_message
84 | message.reply_text(math.acos(int(args[0])))
85 |
86 |
87 | @run_async
88 | def arcsin(update: Update, context: CallbackContext):
89 | args = context.args
90 | message = update.effective_message
91 | message.reply_text(math.asin(int(args[0])))
92 |
93 |
94 | @run_async
95 | def arctan(update: Update, context: CallbackContext):
96 | args = context.args
97 | message = update.effective_message
98 | message.reply_text(math.atan(int(args[0])))
99 |
100 |
101 | @run_async
102 | def abs(update: Update, context: CallbackContext):
103 | args = context.args
104 | message = update.effective_message
105 | message.reply_text(math.fabs(int(args[0])))
106 |
107 |
108 | @run_async
109 | def log(update: Update, context: CallbackContext):
110 | args = context.args
111 | message = update.effective_message
112 | message.reply_text(math.log(int(args[0])))
113 |
114 |
115 |
116 | __mod_name__ = "Math"
117 |
118 | SIMPLIFY_HANDLER = DisableAbleCommandHandler("math", simplify)
119 | FACTOR_HANDLER = DisableAbleCommandHandler("factor", factor)
120 | DERIVE_HANDLER = DisableAbleCommandHandler("derive", derive)
121 | INTEGRATE_HANDLER = DisableAbleCommandHandler("integrate", integrate)
122 | ZEROES_HANDLER = DisableAbleCommandHandler("zeroes", zeroes)
123 | TANGENT_HANDLER = DisableAbleCommandHandler("tangent", tangent)
124 | AREA_HANDLER = DisableAbleCommandHandler("area", area)
125 | COS_HANDLER = DisableAbleCommandHandler("cos", cos)
126 | SIN_HANDLER = DisableAbleCommandHandler("sin", sin)
127 | TAN_HANDLER = DisableAbleCommandHandler("tan", tan)
128 | ARCCOS_HANDLER = DisableAbleCommandHandler("arccos", arccos)
129 | ARCSIN_HANDLER = DisableAbleCommandHandler("arcsin", arcsin)
130 | ARCTAN_HANDLER = DisableAbleCommandHandler("arctan", arctan)
131 | ABS_HANDLER = DisableAbleCommandHandler("abs", abs)
132 | LOG_HANDLER = DisableAbleCommandHandler("log", log)
133 |
134 | dispatcher.add_handler(SIMPLIFY_HANDLER)
135 | dispatcher.add_handler(FACTOR_HANDLER)
136 | dispatcher.add_handler(DERIVE_HANDLER)
137 | dispatcher.add_handler(INTEGRATE_HANDLER)
138 | dispatcher.add_handler(ZEROES_HANDLER)
139 | dispatcher.add_handler(TANGENT_HANDLER)
140 | dispatcher.add_handler(AREA_HANDLER)
141 | dispatcher.add_handler(COS_HANDLER)
142 | dispatcher.add_handler(SIN_HANDLER)
143 | dispatcher.add_handler(TAN_HANDLER)
144 | dispatcher.add_handler(ARCCOS_HANDLER)
145 | dispatcher.add_handler(ARCSIN_HANDLER)
146 | dispatcher.add_handler(ARCTAN_HANDLER)
147 | dispatcher.add_handler(ABS_HANDLER)
148 | dispatcher.add_handler(LOG_HANDLER)
149 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/musicplayer.py:
--------------------------------------------------------------------------------
1 | __mod_name__ = "Music Player"
2 |
3 | __help__ = """
4 | =>> *Song Playing* 🎧
5 | ❍ /play - play song you requested
6 | ❍ /dplay - play song you requested via deezer
7 | ❍ /splay - play song you requested via jio saavn
8 | ❍ /playlist - Show now playing list
9 | ❍ /current - Show now playing
10 | ❍ /song - download songs you want quickly
11 | ❍ /search - search videos on youtube with details
12 | ❍ /deezer - download songs you want quickly via deezer
13 | ❍ /saavn - download songs you want quickly via saavn
14 | ❍ /video - download videos you want quickly
15 | =>> *Admins only*
16 | ❍ /player - open music player settings panel
17 | ❍ /pause - pause song play
18 | ❍ /resume - resume song play
19 | ❍ /skip - play next song
20 | ❍ /end - stop music play
21 | ❍ /userbotjoin - invite assistant to your chat
22 | ❍ /admincache - Refresh admin list
23 | =>> *Use*
24 | 1) Add @LaylaRobot in your group to admin with all permission
25 | 2) Add Assistant I'd to your group @LaylaAssistant
26 | """
27 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/paste.py:
--------------------------------------------------------------------------------
1 | import requests
2 | from LaylaRobot import dispatcher
3 | from LaylaRobot.modules.disable import DisableAbleCommandHandler
4 | from telegram import ParseMode, Update
5 | from telegram.ext import CallbackContext, run_async
6 |
7 |
8 | @run_async
9 | def paste(update: Update, context: CallbackContext):
10 | args = context.args
11 | message = update.effective_message
12 |
13 | if message.reply_to_message:
14 | data = message.reply_to_message.text
15 |
16 | elif len(args) >= 1:
17 | data = message.text.split(None, 1)[1]
18 |
19 | else:
20 | message.reply_text("What am I supposed to do with this?")
21 | return
22 |
23 | key = (
24 | requests.post("https://nekobin.com/api/documents", json={"content": data})
25 | .json()
26 | .get("result")
27 | .get("key")
28 | )
29 |
30 | url = f"https://nekobin.com/{key}"
31 |
32 | reply_text = f"Nekofied to *Nekobin* : {url}"
33 |
34 | message.reply_text(
35 | reply_text, parse_mode=ParseMode.MARKDOWN, disable_web_page_preview=True
36 | )
37 |
38 |
39 | PASTE_HANDLER = DisableAbleCommandHandler("paste", paste)
40 | dispatcher.add_handler(PASTE_HANDLER)
41 |
42 | __command_list__ = ["paste"]
43 | __handlers__ = [PASTE_HANDLER]
44 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/ping.py:
--------------------------------------------------------------------------------
1 | import time
2 | from typing import List
3 |
4 | import requests
5 | from telegram import ParseMode, Update
6 | from telegram.ext import CallbackContext, run_async
7 |
8 | from LaylaRobot import StartTime, dispatcher
9 | from LaylaRobot.modules.helper_funcs.chat_status import sudo_plus
10 | from LaylaRobot.modules.disable import DisableAbleCommandHandler
11 |
12 | sites_list = {
13 | "Telegram": "https://api.telegram.org",
14 | "Kaizoku": "https://animekaizoku.com",
15 | "Kayo": "https://animekayo.com",
16 | "Jikan": "https://api.jikan.moe/v3",
17 | }
18 |
19 |
20 | def get_readable_time(seconds: int) -> str:
21 | count = 0
22 | ping_time = ""
23 | time_list = []
24 | time_suffix_list = ["s", "m", "h", "days"]
25 |
26 | while count < 4:
27 | count += 1
28 | if count < 3:
29 | remainder, result = divmod(seconds, 60)
30 | else:
31 | remainder, result = divmod(seconds, 24)
32 | if seconds == 0 and remainder == 0:
33 | break
34 | time_list.append(int(result))
35 | seconds = int(remainder)
36 |
37 | for x in range(len(time_list)):
38 | time_list[x] = str(time_list[x]) + time_suffix_list[x]
39 | if len(time_list) == 4:
40 | ping_time += time_list.pop() + ", "
41 |
42 | time_list.reverse()
43 | ping_time += ":".join(time_list)
44 |
45 | return ping_time
46 |
47 |
48 | def ping_func(to_ping: List[str]) -> List[str]:
49 | ping_result = []
50 |
51 | for each_ping in to_ping:
52 |
53 | start_time = time.time()
54 | site_to_ping = sites_list[each_ping]
55 | r = requests.get(site_to_ping)
56 | end_time = time.time()
57 | ping_time = str(round((end_time - start_time), 2)) + "s"
58 |
59 | pinged_site = f"{each_ping}"
60 |
61 | if each_ping == "Kaizoku" or each_ping == "Kayo":
62 | pinged_site = f'{each_ping}'
63 | ping_time = f"{ping_time} (Status: {r.status_code})
"
64 |
65 | ping_text = f"{pinged_site}: {ping_time}
"
66 | ping_result.append(ping_text)
67 |
68 | return ping_result
69 |
70 |
71 | @run_async
72 | @sudo_plus
73 | def ping(update: Update, context: CallbackContext):
74 | msg = update.effective_message
75 |
76 | start_time = time.time()
77 | message = msg.reply_text("Pinging...")
78 | end_time = time.time()
79 | telegram_ping = str(round((end_time - start_time) * 1000, 3)) + " ms"
80 | uptime = get_readable_time((time.time() - StartTime))
81 |
82 | message.edit_text(
83 | "PONG!!\n"
84 | "Time Taken: {}
\n"
85 | "Service uptime: {}
".format(telegram_ping, uptime),
86 | parse_mode=ParseMode.HTML,
87 | )
88 |
89 |
90 | @run_async
91 | @sudo_plus
92 | def pingall(update: Update, context: CallbackContext):
93 | to_ping = ["Kaizoku", "Kayo", "Telegram", "Jikan"]
94 | pinged_list = ping_func(to_ping)
95 | pinged_list.insert(2, "")
96 | uptime = get_readable_time((time.time() - StartTime))
97 |
98 | reply_msg = "⏱Ping results are:\n"
99 | reply_msg += "\n".join(pinged_list)
100 | reply_msg += "\nService uptime: {}
".format(uptime)
101 |
102 | update.effective_message.reply_text(
103 | reply_msg, parse_mode=ParseMode.HTML, disable_web_page_preview=True
104 | )
105 |
106 |
107 | PING_HANDLER = DisableAbleCommandHandler("ping", ping)
108 | PINGALL_HANDLER = DisableAbleCommandHandler("pingall", pingall)
109 |
110 | dispatcher.add_handler(PING_HANDLER)
111 | dispatcher.add_handler(PINGALL_HANDLER)
112 |
113 | __command_list__ = ["ping", "pingall"]
114 | __handlers__ = [PING_HANDLER, PINGALL_HANDLER]
115 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/purge.py:
--------------------------------------------------------------------------------
1 | import time
2 | from telethon import events
3 |
4 | from LaylaRobot import telethn
5 | from LaylaRobot.modules.helper_funcs.telethn.chatstatus import (
6 | can_delete_messages,
7 | user_is_admin,
8 | )
9 |
10 |
11 | async def purge_messages(event):
12 | start = time.perf_counter()
13 | if event.from_id is None:
14 | return
15 |
16 | if not await user_is_admin(
17 | user_id=event.sender_id, message=event
18 | ) and event.from_id not in [1087968824]:
19 | await event.reply("Only Admins are allowed to use this command")
20 | return
21 |
22 | if not await can_delete_messages(message=event):
23 | await event.reply("Can't seem to purge the message")
24 | return
25 |
26 | reply_msg = await event.get_reply_message()
27 | if not reply_msg:
28 | await event.reply("Reply to a message to select where to start purging from.")
29 | return
30 | messages = []
31 | message_id = reply_msg.id
32 | delete_to = event.message.id
33 |
34 | messages.append(event.reply_to_msg_id)
35 | for msg_id in range(message_id, delete_to + 1):
36 | messages.append(msg_id)
37 | if len(messages) == 100:
38 | await event.client.delete_messages(event.chat_id, messages)
39 | messages = []
40 |
41 | try:
42 | await event.client.delete_messages(event.chat_id, messages)
43 | except:
44 | pass
45 | time_ = time.perf_counter() - start
46 | text = f"Purged Successfully in {time_:0.2f} Second(s)"
47 | await event.respond(text, parse_mode="markdown")
48 |
49 |
50 | async def delete_messages(event):
51 | if event.from_id is None:
52 | return
53 |
54 | if not await user_is_admin(
55 | user_id=event.sender_id, message=event
56 | ) and event.from_id not in [1087968824]:
57 | await event.reply("Only Admins are allowed to use this command")
58 | return
59 |
60 | if not await can_delete_messages(message=event):
61 | await event.reply("Can't seem to delete this?")
62 | return
63 |
64 | message = await event.get_reply_message()
65 | if not message:
66 | await event.reply("Whadya want to delete?")
67 | return
68 | chat = await event.get_input_chat()
69 | del_message = [message, event.message]
70 | await event.client.delete_messages(chat, del_message)
71 |
72 |
73 |
74 | PURGE_HANDLER = purge_messages, events.NewMessage(pattern="^[!/]purge$")
75 | DEL_HANDLER = delete_messages, events.NewMessage(pattern="^[!/]del$")
76 |
77 | telethn.add_event_handler(*PURGE_HANDLER)
78 | telethn.add_event_handler(*DEL_HANDLER)
79 |
80 | __mod_name__ = "DETELE"
81 | __command_list__ = ["del", "purge"]
82 | __handlers__ = [PURGE_HANDLER, DEL_HANDLER]
83 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/reactions.py:
--------------------------------------------------------------------------------
1 | import random
2 |
3 | from LaylaRobot import dispatcher
4 | from LaylaRobot.modules.disable import DisableAbleCommandHandler
5 | from telegram import Update
6 | from telegram.ext import CallbackContext, run_async
7 |
8 | reactions = [
9 | "( ͡° ͜ʖ ͡°)",
10 | "( . •́ _ʖ •̀ .)",
11 | "( ಠ ͜ʖ ಠ)",
12 | "( ͡ ͜ʖ ͡ )",
13 | "(ʘ ͜ʖ ʘ)",
14 | "ヾ(´〇`)ノ♪♪♪",
15 | "ヽ(o´∀`)ノ♪♬",
16 | "♪♬((d⌒ω⌒b))♬♪",
17 | "└(^^)┐",
18 | "( ̄▽ ̄)/♫•*¨*•.¸¸♪",
19 | "ヾ(⌐■_■)ノ♪",
20 | "乁( • ω •乁)",
21 | "♬♫♪◖(● o ●)◗♪♫♬",
22 | "(っ˘ڡ˘ς)",
23 | "( ˘▽˘)っ♨",
24 | "( ・ω・)⊃-[二二]",
25 | "(*´ー`)旦 旦( ̄ω ̄*)",
26 | "(  ̄▽ ̄)[] [](≧▽≦ )",
27 | "(* ̄▽ ̄)旦 且(´∀`*)",
28 | "(ノ ˘_˘)ノ ζ|||ζ ζ|||ζ ζ|||ζ",
29 | "(ノ°∀°)ノ⌒・*:.。. .。.:*・゜゚・*☆",
30 | "(⊃。•́‿•̀。)⊃━✿✿✿✿✿✿",
31 | "(∩` ロ ´)⊃━炎炎炎炎炎",
32 | "( ・∀・)・・・--------☆",
33 | "( -ω-)/占~~~~~",
34 | "○∞∞∞∞ヽ(^ー^ )",
35 | "(*^^)/~~~~~~~~~~◎",
36 | "(((  ̄□)_/",
37 | "(メ ̄▽ ̄)︻┳═一",
38 | "ヽ( ・∀・)ノ_θ彡☆Σ(ノ `Д´)ノ",
39 | "(*`0´)θ☆(メ°皿°)ノ",
40 | "(; -_-)――――――C<―_-)",
41 | "ヽ(>_<ヽ) ―⊂|=0ヘ(^‿^ )",
42 | "(҂` ロ ´)︻デ═一 \(º □ º l|l)/",
43 | "/( .□.)\ ︵╰(°益°)╯︵ /(.□. /)",
44 | "(`⌒*)O-(`⌒´Q)",
45 | "(っ•﹏•)っ ✴==≡눈٩(`皿´҂)ง",
46 | "ヾ(・ω・)メ(・ω・)ノ",
47 | "(*^ω^)八(⌒▽⌒)八(-‿‿- )ヽ",
48 | "ヽ( ⌒ω⌒)人(=^‥^= )ノ",
49 | "。*:☆(・ω・人・ω・)。:゜☆。",
50 | "(°(°ω(°ω°(☆ω☆)°ω°)ω°)°)",
51 | "(っ˘▽˘)(˘▽˘)˘▽˘ς)",
52 | "(*^ω^)人(^ω^*)",
53 | "\(▽ ̄ \ ( ̄▽ ̄) /  ̄▽)/",
54 | "( ̄Θ ̄)",
55 | "\( ˋ Θ ´ )/",
56 | "( ´(00)ˋ )",
57 | "\( ̄(oo) ̄)/",
58 | "/(≧ x ≦)\",
59 | "/(=・ x ・=)\",
60 | "(=^・ω・^=)",
61 | "(= ; ェ ; =)",
62 | "(=⌒‿‿⌒=)",
63 | "(^• ω •^)",
64 | "ଲ(ⓛ ω ⓛ)ଲ",
65 | "ଲ(ⓛ ω ⓛ)ଲ",
66 | "(^◔ᴥ◔^)",
67 | "[(--)]..zzZ",
68 | "( ̄o ̄) zzZZzzZZ",
69 | "(_ _*) Z z z",
70 | "☆ミ(o*・ω・)ノ",
71 | "ε=ε=ε=ε=┌(; ̄▽ ̄)┘",
72 | "ε===(っ≧ω≦)っ",
73 | "__φ(..)",
74 | "ヾ( `ー´)シφ__",
75 | "( ^▽^)ψ__",
76 | "|・ω・)",
77 | "|д・)",
78 | "┬┴┬┴┤・ω・)ノ",
79 | "|・д・)ノ",
80 | "(* ̄ii ̄)",
81 | "(^〃^)",
82 | "m(_ _)m",
83 | "人(_ _*)",
84 | "(シ. .)シ",
85 | "(^_~)",
86 | "(>ω^)",
87 | "(^_<)〜☆",
88 | "(^_<)",
89 | "(づ ̄ ³ ̄)づ",
90 | "(⊃。•́‿•̀。)⊃",
91 | "⊂(´• ω •`⊂)",
92 | "(*・ω・)ノ",
93 | "(^-^*)/",
94 | "ヾ(*'▽'*)",
95 | "(^0^)ノ",
96 | "(*°ー°)ノ",
97 | "( ̄ω ̄)/",
98 | "(≧▽≦)/",
99 | "w(°o°)w",
100 | "(⊙_⊙)",
101 | "(°ロ°) !",
102 | "∑(O_O;)",
103 | "(¬_¬)",
104 | "(¬_¬ )",
105 | "(↼_↼)",
106 | "( ̄ω ̄;)",
107 | "┐('~`;)┌",
108 | "(・_・;)",
109 | "(@_@)",
110 | "(•ิ_•ิ)?",
111 | "ヽ(ー_ー )ノ",
112 | "┐( ̄ヘ ̄)┌",
113 | "┐( ̄~ ̄)┌",
114 | "┐( ´ д ` )┌",
115 | "╮(︶▽︶)╭",
116 | "ᕕ( ᐛ )ᕗ",
117 | "(ノωヽ)",
118 | "(″ロ゛)",
119 | "(/ω\)",
120 | "(((><)))",
121 | "~(>_<~)",
122 | "(×_×)",
123 | "(×﹏×)",
124 | "(ノ_<。)",
125 | "(μ_μ)",
126 | "o(TヘTo)",
127 | "( ゚,_ゝ`)",
128 | "( ╥ω╥ )",
129 | "(/ˍ・、)",
130 | "(つω`。)",
131 | "(T_T)",
132 | "o(〒﹏〒)o",
133 | "(#`Д´)",
134 | "(・`ω´・)",
135 | "( `ε´ )",
136 | "(メ` ロ ´)",
137 | "Σ(▼□▼メ)",
138 | "(҂ `з´ )",
139 | "٩(╬ʘ益ʘ╬)۶",
140 | "↑_(ΦwΦ)Ψ",
141 | "(ノಥ益ಥ)ノ",
142 | "(#><)",
143 | "(; ̄Д ̄)",
144 | "(¬_¬;)",
145 | "(^^#)",
146 | "( ̄︿ ̄)",
147 | "ヾ(  ̄O ̄)ツ",
148 | "(ᗒᗣᗕ)՞",
149 | "(ノ_<。)ヾ(´ ▽ ` )",
150 | "ヽ( ̄ω ̄(。。 )ゝ",
151 | "(ノ_;)ヾ(´ ∀ ` )",
152 | "(´-ω-`( _ _ )",
153 | "(⌒_⌒;)",
154 | "(*/_\)",
155 | "( ◡‿◡ *)",
156 | "(//ω//)",
157 | "( ̄▽ ̄*)ゞ",
158 | "(„ಡωಡ„)",
159 | "(ノ´ з `)ノ",
160 | "(♡-_-♡)",
161 | "(─‿‿─)♡",
162 | "(´ ω `♡)",
163 | "(ღ˘⌣˘ღ)",
164 | "(´• ω •`) ♡",
165 | "╰(*´︶`*)╯♡",
166 | "(≧◡≦) ♡",
167 | "♡ (˘▽˘>ԅ( ˘⌣˘)",
168 | "σ(≧ε≦σ) ♡",
169 | "(˘∀˘)/(μ‿μ) ❤",
170 | "Σ>―(〃°ω°〃)♡→",
171 | "(* ^ ω ^)",
172 | "(o^▽^o)",
173 | "ヽ(・∀・)ノ",
174 | "(o・ω・o)",
175 | "(^人^)",
176 | "( ´ ω ` )",
177 | "(´• ω •`)",
178 | "╰(▔∀▔)╯",
179 | "(✯◡✯)",
180 | "(⌒‿⌒)",
181 | "(*°▽°*)",
182 | "(´。• ᵕ •。`)",
183 | "ヽ(>∀<☆)ノ",
184 | "\( ̄▽ ̄)/",
185 | "(o˘◡˘o)",
186 | "(╯✧▽✧)╯",
187 | "( ‾́ ◡ ‾́ )",
188 | "(๑˘︶˘๑)",
189 | "(´・ᴗ・ ` )",
190 | "( ͡° ʖ̯ ͡°)",
191 | "( ఠ ͟ʖ ఠ)",
192 | "( ಥ ʖ̯ ಥ)",
193 | "(≖ ͜ʖ≖)",
194 | "ヘ( ̄ω ̄ヘ)",
195 | "(ノ≧∀≦)ノ",
196 | "└( ̄- ̄└))",
197 | "┌(^^)┘",
198 | "(^_^♪)",
199 | "(〜 ̄△ ̄)〜",
200 | "(「• ω •)「",
201 | "( ˘ ɜ˘) ♬♪♫",
202 | "( o˘◡˘o) ┌iii┐",
203 | "♨o(>_<)o♨",
204 | "( ・・)つ―{}@{}@{}-",
205 | "(*´з`)口゚。゚口(・∀・ )",
206 | "( *^^)o∀*∀o(^^* )",
207 | "-●●●-c(・・ )",
208 | "(ノ≧∀≦)ノ ‥…━━━★",
209 | "╰( ͡° ͜ʖ ͡° )つ──☆*:・゚",
210 | "(∩ᄑ_ᄑ)⊃━☆゚*・。*・:≡( ε:)",
211 | ]
212 |
213 |
214 | @run_async
215 | def react(update: Update, context: CallbackContext):
216 | message = update.effective_message
217 | react = random.choice(reactions)
218 | if message.reply_to_message:
219 | message.reply_to_message.reply_text(react)
220 | else:
221 | message.reply_text(react)
222 |
223 |
224 | REACT_HANDLER = DisableAbleCommandHandler("react", react)
225 |
226 | dispatcher.add_handler(REACT_HANDLER)
227 |
228 | __command_list__ = ["react"]
229 | __handlers__ = [REACT_HANDLER]
230 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/rules.py:
--------------------------------------------------------------------------------
1 | from typing import Optional
2 |
3 | import LaylaRobot.modules.sql.rules_sql as sql
4 | from LaylaRobot import dispatcher
5 | from LaylaRobot.modules.helper_funcs.chat_status import user_admin
6 | from LaylaRobot.modules.helper_funcs.string_handling import markdown_parser
7 | from telegram import (
8 | InlineKeyboardButton,
9 | InlineKeyboardMarkup,
10 | Message,
11 | ParseMode,
12 | Update,
13 | User,
14 | )
15 | from telegram.error import BadRequest
16 | from telegram.ext import CallbackContext, CommandHandler, Filters, run_async
17 | from telegram.utils.helpers import escape_markdown
18 |
19 |
20 | @run_async
21 | def get_rules(update: Update, context: CallbackContext):
22 | chat_id = update.effective_chat.id
23 | send_rules(update, chat_id)
24 |
25 |
26 | # Do not async - not from a handler
27 | def send_rules(update, chat_id, from_pm=False):
28 | bot = dispatcher.bot
29 | user = update.effective_user # type: Optional[User]
30 | try:
31 | chat = bot.get_chat(chat_id)
32 | except BadRequest as excp:
33 | if excp.message == "Chat not found" and from_pm:
34 | bot.send_message(
35 | user.id,
36 | "The rules shortcut for this chat hasn't been set properly! Ask admins to "
37 | "fix this.\nMaybe they forgot the hyphen in ID",
38 | )
39 | return
40 | else:
41 | raise
42 |
43 | rules = sql.get_rules(chat_id)
44 | text = f"The rules for *{escape_markdown(chat.title)}* are:\n\n{rules}"
45 |
46 | if from_pm and rules:
47 | bot.send_message(
48 | user.id, text, parse_mode=ParseMode.MARKDOWN, disable_web_page_preview=True
49 | )
50 | elif from_pm:
51 | bot.send_message(
52 | user.id,
53 | "The group admins haven't set any rules for this chat yet. "
54 | "This probably doesn't mean it's lawless though...!",
55 | )
56 | elif rules:
57 | update.effective_message.reply_text(
58 | "Please click the button below to see the rules.",
59 | reply_markup=InlineKeyboardMarkup(
60 | [
61 | [
62 | InlineKeyboardButton(
63 | text="Rules", url=f"t.me/{bot.username}?start={chat_id}"
64 | )
65 | ]
66 | ]
67 | ),
68 | )
69 | else:
70 | update.effective_message.reply_text(
71 | "The group admins haven't set any rules for this chat yet. "
72 | "This probably doesn't mean it's lawless though...!"
73 | )
74 |
75 |
76 | @run_async
77 | @user_admin
78 | def set_rules(update: Update, context: CallbackContext):
79 | chat_id = update.effective_chat.id
80 | msg = update.effective_message # type: Optional[Message]
81 | raw_text = msg.text
82 | args = raw_text.split(None, 1) # use python's maxsplit to separate cmd and args
83 | if len(args) == 2:
84 | txt = args[1]
85 | offset = len(txt) - len(raw_text) # set correct offset relative to command
86 | markdown_rules = markdown_parser(
87 | txt, entities=msg.parse_entities(), offset=offset
88 | )
89 |
90 | sql.set_rules(chat_id, markdown_rules)
91 | update.effective_message.reply_text("Successfully set rules for this group.")
92 |
93 |
94 | @run_async
95 | @user_admin
96 | def clear_rules(update: Update, context: CallbackContext):
97 | chat_id = update.effective_chat.id
98 | sql.set_rules(chat_id, "")
99 | update.effective_message.reply_text("Successfully cleared rules!")
100 |
101 |
102 | def __stats__():
103 | return f"• {sql.num_chats()} chats have rules set."
104 |
105 |
106 | def __import_data__(chat_id, data):
107 | # set chat rules
108 | rules = data.get("info", {}).get("rules", "")
109 | sql.set_rules(chat_id, rules)
110 |
111 |
112 | def __migrate__(old_chat_id, new_chat_id):
113 | sql.migrate_chat(old_chat_id, new_chat_id)
114 |
115 |
116 | def __chat_settings__(chat_id, user_id):
117 | return f"This chat has had it's rules set: `{bool(sql.get_rules(chat_id))}`"
118 |
119 |
120 | __help__ = """
121 | ❍ /rules*:* get the rules for this chat.
122 |
123 | *Admins only:*
124 | ❍ /setrules *:* set the rules for this chat.
125 | ❍ /clearrules*:* clear the rules for this chat.
126 | """
127 |
128 | __mod_name__ = "Rules"
129 |
130 | GET_RULES_HANDLER = CommandHandler("rules", get_rules, filters=Filters.group)
131 | SET_RULES_HANDLER = CommandHandler("setrules", set_rules, filters=Filters.group)
132 | RESET_RULES_HANDLER = CommandHandler("clearrules", clear_rules, filters=Filters.group)
133 |
134 | dispatcher.add_handler(GET_RULES_HANDLER)
135 | dispatcher.add_handler(SET_RULES_HANDLER)
136 | dispatcher.add_handler(RESET_RULES_HANDLER)
137 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/shell.py:
--------------------------------------------------------------------------------
1 | import subprocess
2 |
3 | from LaylaRobot import LOGGER, dispatcher
4 | from LaylaRobot.modules.helper_funcs.chat_status import dev_plus
5 | from telegram import ParseMode, Update
6 | from telegram.ext import CallbackContext, CommandHandler
7 | from telegram.ext.dispatcher import run_async
8 |
9 |
10 | @dev_plus
11 | @run_async
12 | def shell(update: Update, context: CallbackContext):
13 | message = update.effective_message
14 | cmd = message.text.split(" ", 1)
15 | if len(cmd) == 1:
16 | message.reply_text("No command to execute was given.")
17 | return
18 | cmd = cmd[1]
19 | process = subprocess.Popen(
20 | cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True
21 | )
22 | stdout, stderr = process.communicate()
23 | reply = ""
24 | stderr = stderr.decode()
25 | stdout = stdout.decode()
26 | if stdout:
27 | reply += f"*Stdout*\n`{stdout}`\n"
28 | LOGGER.info(f"Shell - {cmd} - {stdout}")
29 | if stderr:
30 | reply += f"*Stderr*\n`{stderr}`\n"
31 | LOGGER.error(f"Shell - {cmd} - {stderr}")
32 | if len(reply) > 3000:
33 | with open("shell_output.txt", "w") as file:
34 | file.write(reply)
35 | with open("shell_output.txt", "rb") as doc:
36 | context.bot.send_document(
37 | document=doc,
38 | filename=doc.name,
39 | reply_to_message_id=message.message_id,
40 | chat_id=message.chat_id,
41 | )
42 | else:
43 | message.reply_text(reply, parse_mode=ParseMode.MARKDOWN)
44 |
45 |
46 | SHELL_HANDLER = CommandHandler(["sh"], shell)
47 | dispatcher.add_handler(SHELL_HANDLER)
48 | __mod_name__ = "Shell"
49 | __command_list__ = ["sh"]
50 | __handlers__ = [SHELL_HANDLER]
51 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/speed_test.py:
--------------------------------------------------------------------------------
1 | import speedtest
2 | from LaylaRobot import DEV_USERS, dispatcher
3 | from LaylaRobot.modules.disable import DisableAbleCommandHandler
4 | from LaylaRobot.modules.helper_funcs.chat_status import dev_plus
5 | from telegram import InlineKeyboardButton, InlineKeyboardMarkup, ParseMode, Update
6 | from telegram.ext import CallbackContext, CallbackQueryHandler, run_async
7 |
8 |
9 | def convert(speed):
10 | return round(int(speed) / 1048576, 2)
11 |
12 |
13 | @dev_plus
14 | @run_async
15 | def speedtestxyz(update: Update, context: CallbackContext):
16 | buttons = [
17 | [
18 | InlineKeyboardButton("Image", callback_data="speedtest_image"),
19 | InlineKeyboardButton("Text", callback_data="speedtest_text"),
20 | ]
21 | ]
22 | update.effective_message.reply_text(
23 | "Select SpeedTest Mode", reply_markup=InlineKeyboardMarkup(buttons)
24 | )
25 |
26 |
27 | @run_async
28 | def speedtestxyz_callback(update: Update, context: CallbackContext):
29 | query = update.callback_query
30 |
31 | if query.from_user.id in DEV_USERS:
32 | msg = update.effective_message.edit_text("Running a speedtest....")
33 | speed = speedtest.Speedtest()
34 | speed.get_best_server()
35 | speed.download()
36 | speed.upload()
37 | replymsg = "SpeedTest Results:"
38 |
39 | if query.data == "speedtest_image":
40 | speedtest_image = speed.results.share()
41 | update.effective_message.reply_photo(
42 | photo=speedtest_image, caption=replymsg
43 | )
44 | msg.delete()
45 |
46 | elif query.data == "speedtest_text":
47 | result = speed.results.dict()
48 | replymsg += f"\nDownload: `{convert(result['download'])}Mb/s`\nUpload: `{convert(result['upload'])}Mb/s`\nPing: `{result['ping']}`"
49 | update.effective_message.edit_text(replymsg, parse_mode=ParseMode.MARKDOWN)
50 | else:
51 | query.answer("You are required to join Heroes Association to use this command.")
52 |
53 |
54 | SPEED_TEST_HANDLER = DisableAbleCommandHandler("speedtest", speedtestxyz)
55 | SPEED_TEST_CALLBACKHANDLER = CallbackQueryHandler(
56 | speedtestxyz_callback, pattern="speedtest_.*"
57 | )
58 |
59 | dispatcher.add_handler(SPEED_TEST_HANDLER)
60 | dispatcher.add_handler(SPEED_TEST_CALLBACKHANDLER)
61 |
62 | __mod_name__ = "SpeedTest"
63 | __command_list__ = ["speedtest"]
64 | __handlers__ = [SPEED_TEST_HANDLER, SPEED_TEST_CALLBACKHANDLER]
65 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/sql/__init__.py:
--------------------------------------------------------------------------------
1 | from LaylaRobot import DB_URI
2 | from sqlalchemy import create_engine
3 | from sqlalchemy.ext.declarative import declarative_base
4 | from sqlalchemy.orm import scoped_session, sessionmaker
5 |
6 |
7 | def start() -> scoped_session:
8 | engine = create_engine(DB_URI, client_encoding="utf8")
9 | BASE.metadata.bind = engine
10 | BASE.metadata.create_all(engine)
11 | return scoped_session(sessionmaker(bind=engine, autoflush=False))
12 |
13 |
14 | BASE = declarative_base()
15 | SESSION = start()
16 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/sql/afk_sql.py:
--------------------------------------------------------------------------------
1 | import threading
2 |
3 | from LaylaRobot.modules.sql import BASE, SESSION
4 | from sqlalchemy import Boolean, Column, Integer, UnicodeText
5 |
6 |
7 | class AFK(BASE):
8 | __tablename__ = "afk_users"
9 |
10 | user_id = Column(Integer, primary_key=True)
11 | is_afk = Column(Boolean)
12 | reason = Column(UnicodeText)
13 |
14 | def __init__(self, user_id, reason="", is_afk=True):
15 | self.user_id = user_id
16 | self.reason = reason
17 | self.is_afk = is_afk
18 |
19 | def __repr__(self):
20 | return "afk_status for {}".format(self.user_id)
21 |
22 |
23 | AFK.__table__.create(checkfirst=True)
24 | INSERTION_LOCK = threading.RLock()
25 |
26 | AFK_USERS = {}
27 |
28 |
29 | def is_afk(user_id):
30 | return user_id in AFK_USERS
31 |
32 |
33 | def check_afk_status(user_id):
34 | try:
35 | return SESSION.query(AFK).get(user_id)
36 | finally:
37 | SESSION.close()
38 |
39 |
40 | def set_afk(user_id, reason=""):
41 | with INSERTION_LOCK:
42 | curr = SESSION.query(AFK).get(user_id)
43 | if not curr:
44 | curr = AFK(user_id, reason, True)
45 | else:
46 | curr.is_afk = True
47 |
48 | AFK_USERS[user_id] = reason
49 |
50 | SESSION.add(curr)
51 | SESSION.commit()
52 |
53 |
54 | def rm_afk(user_id):
55 | with INSERTION_LOCK:
56 | curr = SESSION.query(AFK).get(user_id)
57 | if curr:
58 | if user_id in AFK_USERS: # sanity check
59 | del AFK_USERS[user_id]
60 |
61 | SESSION.delete(curr)
62 | SESSION.commit()
63 | return True
64 |
65 | SESSION.close()
66 | return False
67 |
68 |
69 | def toggle_afk(user_id, reason=""):
70 | with INSERTION_LOCK:
71 | curr = SESSION.query(AFK).get(user_id)
72 | if not curr:
73 | curr = AFK(user_id, reason, True)
74 | elif curr.is_afk:
75 | curr.is_afk = False
76 | elif not curr.is_afk:
77 | curr.is_afk = True
78 | SESSION.add(curr)
79 | SESSION.commit()
80 |
81 |
82 | def __load_afk_users():
83 | global AFK_USERS
84 | try:
85 | all_afk = SESSION.query(AFK).all()
86 | AFK_USERS = {user.user_id: user.reason for user in all_afk if user.is_afk}
87 | finally:
88 | SESSION.close()
89 |
90 |
91 | __load_afk_users()
92 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/sql/aihelp_sql.py:
--------------------------------------------------------------------------------
1 | import threading
2 |
3 | from LaylaRobot.modules.sql import BASE, SESSION
4 | from sqlalchemy import Column, String
5 |
6 |
7 | class aiChats(BASE):
8 | __tablename__ = "ai_chats"
9 | chat_id = Column(String(14), primary_key=True)
10 | ses_id = Column(String(70))
11 | expires = Column(String(15))
12 |
13 | def __init__(self, chat_id, ses_id, expires):
14 | self.chat_id = chat_id
15 | self.ses_id = ses_id
16 | self.expires = expires
17 |
18 |
19 | aiChats.__table__.create(checkfirst=True)
20 |
21 | INSERTION_LOCK = threading.RLock()
22 |
23 |
24 | def is_chat(chat_id):
25 | try:
26 | chat = SESSION.query(aiChats).get(str(chat_id))
27 | if chat:
28 | return True
29 | return False
30 | finally:
31 | SESSION.close()
32 |
33 |
34 | def set_ses(chat_id, ses_id, expires):
35 | with INSERTION_LOCK:
36 | autochat = SESSION.query(aiChats).get(str(chat_id))
37 | if not autochat:
38 | autochat = aiChats(str(chat_id), str(ses_id), str(expires))
39 | else:
40 | autochat.ses_id = str(ses_id)
41 | autochat.expires = str(expires)
42 |
43 | SESSION.add(autochat)
44 | SESSION.commit()
45 |
46 |
47 | def get_ses(chat_id):
48 | autochat = SESSION.query(aiChats).get(str(chat_id))
49 | sesh = ""
50 | exp = ""
51 | if autochat:
52 | sesh = str(autochat.ses_id)
53 | exp = str(autochat.expires)
54 |
55 | SESSION.close()
56 | return sesh, exp
57 |
58 |
59 | def rem_chat(chat_id):
60 | with INSERTION_LOCK:
61 | autochat = SESSION.query(aiChats).get(str(chat_id))
62 | if autochat:
63 | SESSION.delete(autochat)
64 |
65 | SESSION.commit()
66 |
67 |
68 | def get_all_chats():
69 | try:
70 | return SESSION.query(aiChats.chat_id).all()
71 | finally:
72 | SESSION.close()
--------------------------------------------------------------------------------
/LaylaRobot/modules/sql/antiflood_sql.py:
--------------------------------------------------------------------------------
1 | import threading
2 |
3 | from sqlalchemy import String, Column, Integer, UnicodeText
4 |
5 | from LaylaRobot.modules.sql import SESSION, BASE
6 |
7 | DEF_COUNT = 1
8 | DEF_LIMIT = 0
9 | DEF_OBJ = (None, DEF_COUNT, DEF_LIMIT)
10 |
11 |
12 | class FloodControl(BASE):
13 | __tablename__ = "antiflood"
14 | chat_id = Column(String(14), primary_key=True)
15 | user_id = Column(Integer)
16 | count = Column(Integer, default=DEF_COUNT)
17 | limit = Column(Integer, default=DEF_LIMIT)
18 |
19 | def __init__(self, chat_id):
20 | self.chat_id = str(chat_id) # ensure string
21 |
22 | def __repr__(self):
23 | return "" % self.chat_id
24 |
25 |
26 | class FloodSettings(BASE):
27 | __tablename__ = "antiflood_settings"
28 | chat_id = Column(String(14), primary_key=True)
29 | flood_type = Column(Integer, default=1)
30 | value = Column(UnicodeText, default="0")
31 |
32 | def __init__(self, chat_id, flood_type=1, value="0"):
33 | self.chat_id = str(chat_id)
34 | self.flood_type = flood_type
35 | self.value = value
36 |
37 | def __repr__(self):
38 | return "<{} will executing {} for flood.>".format(self.chat_id, self.flood_type)
39 |
40 |
41 | FloodControl.__table__.create(checkfirst=True)
42 | FloodSettings.__table__.create(checkfirst=True)
43 |
44 | INSERTION_FLOOD_LOCK = threading.RLock()
45 | INSERTION_FLOOD_SETTINGS_LOCK = threading.RLock()
46 |
47 | CHAT_FLOOD = {}
48 |
49 |
50 | def set_flood(chat_id, amount):
51 | with INSERTION_FLOOD_LOCK:
52 | flood = SESSION.query(FloodControl).get(str(chat_id))
53 | if not flood:
54 | flood = FloodControl(str(chat_id))
55 |
56 | flood.user_id = None
57 | flood.limit = amount
58 |
59 | CHAT_FLOOD[str(chat_id)] = (None, DEF_COUNT, amount)
60 |
61 | SESSION.add(flood)
62 | SESSION.commit()
63 |
64 |
65 | def update_flood(chat_id: str, user_id) -> bool:
66 | if str(chat_id) in CHAT_FLOOD:
67 | curr_user_id, count, limit = CHAT_FLOOD.get(str(chat_id), DEF_OBJ)
68 |
69 | if limit == 0: # no antiflood
70 | return False
71 |
72 | if user_id != curr_user_id or user_id is None: # other user
73 | CHAT_FLOOD[str(chat_id)] = (user_id, DEF_COUNT, limit)
74 | return False
75 |
76 | count += 1
77 | if count > limit: # too many msgs, kick
78 | CHAT_FLOOD[str(chat_id)] = (None, DEF_COUNT, limit)
79 | return True
80 |
81 | # default -> update
82 | CHAT_FLOOD[str(chat_id)] = (user_id, count, limit)
83 | return False
84 |
85 |
86 | def get_flood_limit(chat_id):
87 | return CHAT_FLOOD.get(str(chat_id), DEF_OBJ)[2]
88 |
89 |
90 | def set_flood_strength(chat_id, flood_type, value):
91 | # for flood_type
92 | # 1 = ban
93 | # 2 = kick
94 | # 3 = mute
95 | # 4 = tban
96 | # 5 = tmute
97 | with INSERTION_FLOOD_SETTINGS_LOCK:
98 | curr_setting = SESSION.query(FloodSettings).get(str(chat_id))
99 | if not curr_setting:
100 | curr_setting = FloodSettings(
101 | chat_id, flood_type=int(flood_type), value=value
102 | )
103 |
104 | curr_setting.flood_type = int(flood_type)
105 | curr_setting.value = str(value)
106 |
107 | SESSION.add(curr_setting)
108 | SESSION.commit()
109 |
110 |
111 | def get_flood_setting(chat_id):
112 | try:
113 | setting = SESSION.query(FloodSettings).get(str(chat_id))
114 | if setting:
115 | return setting.flood_type, setting.value
116 | else:
117 | return 1, "0"
118 |
119 | finally:
120 | SESSION.close()
121 |
122 |
123 | def migrate_chat(old_chat_id, new_chat_id):
124 | with INSERTION_FLOOD_LOCK:
125 | flood = SESSION.query(FloodControl).get(str(old_chat_id))
126 | if flood:
127 | CHAT_FLOOD[str(new_chat_id)] = CHAT_FLOOD.get(str(old_chat_id), DEF_OBJ)
128 | flood.chat_id = str(new_chat_id)
129 | SESSION.commit()
130 |
131 | SESSION.close()
132 |
133 |
134 | def __load_flood_settings():
135 | global CHAT_FLOOD
136 | try:
137 | all_chats = SESSION.query(FloodControl).all()
138 | CHAT_FLOOD = {chat.chat_id: (None, DEF_COUNT, chat.limit) for chat in all_chats}
139 | finally:
140 | SESSION.close()
141 |
142 |
143 | __load_flood_settings()
144 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/sql/approve_sql.py:
--------------------------------------------------------------------------------
1 | import threading
2 |
3 | from sqlalchemy import Column, String, UnicodeText, Integer, func, distinct
4 |
5 | from LaylaRobot.modules.sql import BASE, SESSION
6 |
7 |
8 | class Approvals(BASE):
9 | __tablename__ = "approval"
10 | chat_id = Column(String(14), primary_key=True)
11 | user_id = Column(Integer, primary_key=True)
12 |
13 | def __init__(self, chat_id, user_id):
14 | self.chat_id = str(chat_id) # ensure string
15 | self.user_id = user_id
16 |
17 | def __repr__(self):
18 | return "" % self.user_id
19 |
20 |
21 | Approvals.__table__.create(checkfirst=True)
22 |
23 | APPROVE_INSERTION_LOCK = threading.RLock()
24 |
25 |
26 | def approve(chat_id, user_id):
27 | with APPROVE_INSERTION_LOCK:
28 | approve_user = Approvals(str(chat_id), user_id)
29 | SESSION.add(approve_user)
30 | SESSION.commit()
31 |
32 |
33 | def is_approved(chat_id, user_id):
34 | try:
35 | return SESSION.query(Approvals).get((str(chat_id), user_id))
36 | finally:
37 | SESSION.close()
38 |
39 |
40 | def disapprove(chat_id, user_id):
41 | with APPROVE_INSERTION_LOCK:
42 | disapprove_user = SESSION.query(Approvals).get((str(chat_id), user_id))
43 | if disapprove_user:
44 | SESSION.delete(disapprove_user)
45 | SESSION.commit()
46 | return True
47 | else:
48 | SESSION.close()
49 | return False
50 |
51 |
52 | def list_approved(chat_id):
53 | try:
54 | return (
55 | SESSION.query(Approvals)
56 | .filter(Approvals.chat_id == str(chat_id))
57 | .order_by(Approvals.user_id.asc())
58 | .all()
59 | )
60 | finally:
61 | SESSION.close()
62 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/sql/blacklistusers_sql.py:
--------------------------------------------------------------------------------
1 | import threading
2 |
3 | from LaylaRobot.modules.sql import BASE, SESSION
4 | from sqlalchemy import Column, String, UnicodeText
5 |
6 |
7 | class BlacklistUsers(BASE):
8 | __tablename__ = "blacklistusers"
9 | user_id = Column(String(14), primary_key=True)
10 | reason = Column(UnicodeText)
11 |
12 | def __init__(self, user_id, reason=None):
13 | self.user_id = user_id
14 | self.reason = reason
15 |
16 |
17 | BlacklistUsers.__table__.create(checkfirst=True)
18 |
19 | BLACKLIST_LOCK = threading.RLock()
20 | BLACKLIST_USERS = set()
21 |
22 |
23 | def blacklist_user(user_id, reason=None):
24 | with BLACKLIST_LOCK:
25 | user = SESSION.query(BlacklistUsers).get(str(user_id))
26 | if not user:
27 | user = BlacklistUsers(str(user_id), reason)
28 | else:
29 | user.reason = reason
30 |
31 | SESSION.add(user)
32 | SESSION.commit()
33 | __load_blacklist_userid_list()
34 |
35 |
36 | def unblacklist_user(user_id):
37 | with BLACKLIST_LOCK:
38 | user = SESSION.query(BlacklistUsers).get(str(user_id))
39 | if user:
40 | SESSION.delete(user)
41 |
42 | SESSION.commit()
43 | __load_blacklist_userid_list()
44 |
45 |
46 | def get_reason(user_id):
47 | user = SESSION.query(BlacklistUsers).get(str(user_id))
48 | rep = ""
49 | if user:
50 | rep = user.reason
51 |
52 | SESSION.close()
53 | return rep
54 |
55 |
56 | def is_user_blacklisted(user_id):
57 | return user_id in BLACKLIST_USERS
58 |
59 |
60 | def __load_blacklist_userid_list():
61 | global BLACKLIST_USERS
62 | try:
63 | BLACKLIST_USERS = {int(x.user_id) for x in SESSION.query(BlacklistUsers).all()}
64 | finally:
65 | SESSION.close()
66 |
67 |
68 | __load_blacklist_userid_list()
69 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/sql/chatbot_sql.py:
--------------------------------------------------------------------------------
1 | import threading
2 |
3 | from LaylaRobot.modules.sql import BASE, SESSION
4 | from sqlalchemy import Column, String
5 |
6 |
7 | class ChatbotChats(BASE):
8 | __tablename__ = "chatbot_chats"
9 | chat_id = Column(String(14), primary_key=True)
10 | ses_id = Column(String(70))
11 | expires = Column(String(15))
12 |
13 | def __init__(self, chat_id, ses_id, expires):
14 | self.chat_id = chat_id
15 | self.ses_id = ses_id
16 | self.expires = expires
17 |
18 |
19 | ChatbotChats.__table__.create(checkfirst=True)
20 |
21 | INSERTION_LOCK = threading.RLock()
22 |
23 |
24 | def is_chat(chat_id):
25 | try:
26 | chat = SESSION.query(ChatbotChats).get(str(chat_id))
27 | if chat:
28 | return True
29 | else:
30 | return False
31 | finally:
32 | SESSION.close()
33 |
34 |
35 | def set_ses(chat_id, ses_id, expires):
36 | with INSERTION_LOCK:
37 | autochat = SESSION.query(ChatbotChats).get(str(chat_id))
38 | if not autochat:
39 | autochat = ChatbotChats(str(chat_id), str(ses_id), str(expires))
40 | else:
41 | autochat.ses_id = str(ses_id)
42 | autochat.expires = str(expires)
43 |
44 | SESSION.add(autochat)
45 | SESSION.commit()
46 |
47 |
48 | def get_ses(chat_id):
49 | autochat = SESSION.query(ChatbotChats).get(str(chat_id))
50 | sesh = ""
51 | exp = ""
52 | if autochat:
53 | sesh = str(autochat.ses_id)
54 | exp = str(autochat.expires)
55 |
56 | SESSION.close()
57 | return sesh, exp
58 |
59 |
60 | def rem_chat(chat_id):
61 | with INSERTION_LOCK:
62 | autochat = SESSION.query(ChatbotChats).get(str(chat_id))
63 | if autochat:
64 | SESSION.delete(autochat)
65 |
66 | SESSION.commit()
67 |
68 |
69 | def get_all_chats():
70 | try:
71 | return SESSION.query(ChatbotChats.chat_id).all()
72 | finally:
73 | SESSION.close()
74 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/sql/disable_sql.py:
--------------------------------------------------------------------------------
1 | import threading
2 |
3 | from LaylaRobot.modules.sql import BASE, SESSION
4 | from sqlalchemy import Column, String, UnicodeText, distinct, func
5 |
6 |
7 | class Disable(BASE):
8 | __tablename__ = "disabled_commands"
9 | chat_id = Column(String(14), primary_key=True)
10 | command = Column(UnicodeText, primary_key=True)
11 |
12 | def __init__(self, chat_id, command):
13 | self.chat_id = chat_id
14 | self.command = command
15 |
16 | def __repr__(self):
17 | return "Disabled cmd {} in {}".format(self.command, self.chat_id)
18 |
19 |
20 | Disable.__table__.create(checkfirst=True)
21 | DISABLE_INSERTION_LOCK = threading.RLock()
22 |
23 | DISABLED = {}
24 |
25 |
26 | def disable_command(chat_id, disable):
27 | with DISABLE_INSERTION_LOCK:
28 | disabled = SESSION.query(Disable).get((str(chat_id), disable))
29 |
30 | if not disabled:
31 | DISABLED.setdefault(str(chat_id), set()).add(disable)
32 |
33 | disabled = Disable(str(chat_id), disable)
34 | SESSION.add(disabled)
35 | SESSION.commit()
36 | return True
37 |
38 | SESSION.close()
39 | return False
40 |
41 |
42 | def enable_command(chat_id, enable):
43 | with DISABLE_INSERTION_LOCK:
44 | disabled = SESSION.query(Disable).get((str(chat_id), enable))
45 |
46 | if disabled:
47 | if enable in DISABLED.get(str(chat_id)): # sanity check
48 | DISABLED.setdefault(str(chat_id), set()).remove(enable)
49 |
50 | SESSION.delete(disabled)
51 | SESSION.commit()
52 | return True
53 |
54 | SESSION.close()
55 | return False
56 |
57 |
58 | def is_command_disabled(chat_id, cmd):
59 | return str(cmd).lower() in DISABLED.get(str(chat_id), set())
60 |
61 |
62 | def get_all_disabled(chat_id):
63 | return DISABLED.get(str(chat_id), set())
64 |
65 |
66 | def num_chats():
67 | try:
68 | return SESSION.query(func.count(distinct(Disable.chat_id))).scalar()
69 | finally:
70 | SESSION.close()
71 |
72 |
73 | def num_disabled():
74 | try:
75 | return SESSION.query(Disable).count()
76 | finally:
77 | SESSION.close()
78 |
79 |
80 | def migrate_chat(old_chat_id, new_chat_id):
81 | with DISABLE_INSERTION_LOCK:
82 | chats = SESSION.query(Disable).filter(Disable.chat_id == str(old_chat_id)).all()
83 | for chat in chats:
84 | chat.chat_id = str(new_chat_id)
85 | SESSION.add(chat)
86 |
87 | if str(old_chat_id) in DISABLED:
88 | DISABLED[str(new_chat_id)] = DISABLED.get(str(old_chat_id), set())
89 |
90 | SESSION.commit()
91 |
92 |
93 | def __load_disabled_commands():
94 | global DISABLED
95 | try:
96 | all_chats = SESSION.query(Disable).all()
97 | for chat in all_chats:
98 | DISABLED.setdefault(chat.chat_id, set()).add(chat.command)
99 |
100 | finally:
101 | SESSION.close()
102 |
103 |
104 | __load_disabled_commands()
105 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/sql/global_bans_sql.py:
--------------------------------------------------------------------------------
1 | import threading
2 |
3 | from LaylaRobot.modules.sql import BASE, SESSION
4 | from sqlalchemy import Boolean, Column, Integer, String, UnicodeText
5 |
6 |
7 | class GloballyBannedUsers(BASE):
8 | __tablename__ = "gbans"
9 | user_id = Column(Integer, primary_key=True)
10 | name = Column(UnicodeText, nullable=False)
11 | reason = Column(UnicodeText)
12 |
13 | def __init__(self, user_id, name, reason=None):
14 | self.user_id = user_id
15 | self.name = name
16 | self.reason = reason
17 |
18 | def __repr__(self):
19 | return "".format(self.name, self.user_id)
20 |
21 | def to_dict(self):
22 | return {"user_id": self.user_id, "name": self.name, "reason": self.reason}
23 |
24 |
25 | class GbanSettings(BASE):
26 | __tablename__ = "gban_settings"
27 | chat_id = Column(String(14), primary_key=True)
28 | setting = Column(Boolean, default=True, nullable=False)
29 |
30 | def __init__(self, chat_id, enabled):
31 | self.chat_id = str(chat_id)
32 | self.setting = enabled
33 |
34 | def __repr__(self):
35 | return "".format(self.chat_id, self.setting)
36 |
37 |
38 | GloballyBannedUsers.__table__.create(checkfirst=True)
39 | GbanSettings.__table__.create(checkfirst=True)
40 |
41 | GBANNED_USERS_LOCK = threading.RLock()
42 | GBAN_SETTING_LOCK = threading.RLock()
43 | GBANNED_LIST = set()
44 | GBANSTAT_LIST = set()
45 |
46 |
47 | def gban_user(user_id, name, reason=None):
48 | with GBANNED_USERS_LOCK:
49 | user = SESSION.query(GloballyBannedUsers).get(user_id)
50 | if not user:
51 | user = GloballyBannedUsers(user_id, name, reason)
52 | else:
53 | user.name = name
54 | user.reason = reason
55 |
56 | SESSION.merge(user)
57 | SESSION.commit()
58 | __load_gbanned_userid_list()
59 |
60 |
61 | def update_gban_reason(user_id, name, reason=None):
62 | with GBANNED_USERS_LOCK:
63 | user = SESSION.query(GloballyBannedUsers).get(user_id)
64 | if not user:
65 | return None
66 | old_reason = user.reason
67 | user.name = name
68 | user.reason = reason
69 |
70 | SESSION.merge(user)
71 | SESSION.commit()
72 | return old_reason
73 |
74 |
75 | def ungban_user(user_id):
76 | with GBANNED_USERS_LOCK:
77 | user = SESSION.query(GloballyBannedUsers).get(user_id)
78 | if user:
79 | SESSION.delete(user)
80 |
81 | SESSION.commit()
82 | __load_gbanned_userid_list()
83 |
84 |
85 | def is_user_gbanned(user_id):
86 | return user_id in GBANNED_LIST
87 |
88 |
89 | def get_gbanned_user(user_id):
90 | try:
91 | return SESSION.query(GloballyBannedUsers).get(user_id)
92 | finally:
93 | SESSION.close()
94 |
95 |
96 | def get_gban_list():
97 | try:
98 | return [x.to_dict() for x in SESSION.query(GloballyBannedUsers).all()]
99 | finally:
100 | SESSION.close()
101 |
102 |
103 | def enable_gbans(chat_id):
104 | with GBAN_SETTING_LOCK:
105 | chat = SESSION.query(GbanSettings).get(str(chat_id))
106 | if not chat:
107 | chat = GbanSettings(chat_id, True)
108 |
109 | chat.setting = True
110 | SESSION.add(chat)
111 | SESSION.commit()
112 | if str(chat_id) in GBANSTAT_LIST:
113 | GBANSTAT_LIST.remove(str(chat_id))
114 |
115 |
116 | def disable_gbans(chat_id):
117 | with GBAN_SETTING_LOCK:
118 | chat = SESSION.query(GbanSettings).get(str(chat_id))
119 | if not chat:
120 | chat = GbanSettings(chat_id, False)
121 |
122 | chat.setting = False
123 | SESSION.add(chat)
124 | SESSION.commit()
125 | GBANSTAT_LIST.add(str(chat_id))
126 |
127 |
128 | def does_chat_gban(chat_id):
129 | return str(chat_id) not in GBANSTAT_LIST
130 |
131 |
132 | def num_gbanned_users():
133 | return len(GBANNED_LIST)
134 |
135 |
136 | def __load_gbanned_userid_list():
137 | global GBANNED_LIST
138 | try:
139 | GBANNED_LIST = {x.user_id for x in SESSION.query(GloballyBannedUsers).all()}
140 | finally:
141 | SESSION.close()
142 |
143 |
144 | def __load_gban_stat_list():
145 | global GBANSTAT_LIST
146 | try:
147 | GBANSTAT_LIST = {
148 | x.chat_id for x in SESSION.query(GbanSettings).all() if not x.setting
149 | }
150 | finally:
151 | SESSION.close()
152 |
153 |
154 | def migrate_chat(old_chat_id, new_chat_id):
155 | with GBAN_SETTING_LOCK:
156 | chat = SESSION.query(GbanSettings).get(str(old_chat_id))
157 | if chat:
158 | chat.chat_id = new_chat_id
159 | SESSION.add(chat)
160 |
161 | SESSION.commit()
162 |
163 |
164 | # Create in memory userid to avoid disk access
165 | __load_gbanned_userid_list()
166 | __load_gban_stat_list()
167 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/sql/log_channel_sql.py:
--------------------------------------------------------------------------------
1 | import threading
2 |
3 | from LaylaRobot.modules.sql import BASE, SESSION
4 | from sqlalchemy import Column, String, distinct, func
5 |
6 |
7 | class GroupLogs(BASE):
8 | __tablename__ = "log_channels"
9 | chat_id = Column(String(14), primary_key=True)
10 | log_channel = Column(String(14), nullable=False)
11 |
12 | def __init__(self, chat_id, log_channel):
13 | self.chat_id = str(chat_id)
14 | self.log_channel = str(log_channel)
15 |
16 |
17 | GroupLogs.__table__.create(checkfirst=True)
18 |
19 | LOGS_INSERTION_LOCK = threading.RLock()
20 |
21 | CHANNELS = {}
22 |
23 |
24 | def set_chat_log_channel(chat_id, log_channel):
25 | with LOGS_INSERTION_LOCK:
26 | res = SESSION.query(GroupLogs).get(str(chat_id))
27 | if res:
28 | res.log_channel = log_channel
29 | else:
30 | res = GroupLogs(chat_id, log_channel)
31 | SESSION.add(res)
32 |
33 | CHANNELS[str(chat_id)] = log_channel
34 | SESSION.commit()
35 |
36 |
37 | def get_chat_log_channel(chat_id):
38 | return CHANNELS.get(str(chat_id))
39 |
40 |
41 | def stop_chat_logging(chat_id):
42 | with LOGS_INSERTION_LOCK:
43 | res = SESSION.query(GroupLogs).get(str(chat_id))
44 | if res:
45 | if str(chat_id) in CHANNELS:
46 | del CHANNELS[str(chat_id)]
47 |
48 | log_channel = res.log_channel
49 | SESSION.delete(res)
50 | SESSION.commit()
51 | return log_channel
52 |
53 |
54 | def num_logchannels():
55 | try:
56 | return SESSION.query(func.count(distinct(GroupLogs.chat_id))).scalar()
57 | finally:
58 | SESSION.close()
59 |
60 |
61 | def migrate_chat(old_chat_id, new_chat_id):
62 | with LOGS_INSERTION_LOCK:
63 | chat = SESSION.query(GroupLogs).get(str(old_chat_id))
64 | if chat:
65 | chat.chat_id = str(new_chat_id)
66 | SESSION.add(chat)
67 | if str(old_chat_id) in CHANNELS:
68 | CHANNELS[str(new_chat_id)] = CHANNELS.get(str(old_chat_id))
69 |
70 | SESSION.commit()
71 |
72 |
73 | def __load_log_channels():
74 | global CHANNELS
75 | try:
76 | all_chats = SESSION.query(GroupLogs).all()
77 | CHANNELS = {chat.chat_id: chat.log_channel for chat in all_chats}
78 | finally:
79 | SESSION.close()
80 |
81 |
82 | __load_log_channels()
83 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/sql/nsfw_sql.py:
--------------------------------------------------------------------------------
1 | import threading
2 | from sqlalchemy import Column, String
3 | from LaylaRobot.modules.sql import BASE, SESSION
4 | # |----------------------------------|
5 | # | Test Module by @EverythingSuckz |
6 | # | Kang with Credits |
7 | # |----------------------------------|
8 | class NSFWChats(BASE):
9 | __tablename__ = "nsfw_chats"
10 | chat_id = Column(String(14), primary_key=True)
11 |
12 | def __init__(self, chat_id):
13 | self.chat_id = chat_id
14 |
15 | NSFWChats.__table__.create(checkfirst=True)
16 | INSERTION_LOCK = threading.RLock()
17 |
18 |
19 | def is_nsfw(chat_id):
20 | try:
21 | chat = SESSION.query(NSFWChats).get(str(chat_id))
22 | if chat:
23 | return True
24 | else:
25 | return False
26 | finally:
27 | SESSION.close()
28 |
29 | def set_nsfw(chat_id):
30 | with INSERTION_LOCK:
31 | nsfwchat = SESSION.query(NSFWChats).get(str(chat_id))
32 | if not nsfwchat:
33 | nsfwchat = NSFWChats(str(chat_id))
34 | SESSION.add(nsfwchat)
35 | SESSION.commit()
36 |
37 | def rem_nsfw(chat_id):
38 | with INSERTION_LOCK:
39 | nsfwchat = SESSION.query(NSFWChats).get(str(chat_id))
40 | if nsfwchat:
41 | SESSION.delete(nsfwchat)
42 | SESSION.commit()
43 |
44 |
45 | def get_all_nsfw_chats():
46 | try:
47 | return SESSION.query(NSFWChats.chat_id).all()
48 | finally:
49 | SESSION.close()
50 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/sql/reporting_sql.py:
--------------------------------------------------------------------------------
1 | import threading
2 | from typing import Union
3 |
4 | from LaylaRobot.modules.sql import BASE, SESSION
5 | from sqlalchemy import Boolean, Column, Integer, String
6 |
7 |
8 | class ReportingUserSettings(BASE):
9 | __tablename__ = "user_report_settings"
10 | user_id = Column(Integer, primary_key=True)
11 | should_report = Column(Boolean, default=True)
12 |
13 | def __init__(self, user_id):
14 | self.user_id = user_id
15 |
16 | def __repr__(self):
17 | return "".format(self.user_id)
18 |
19 |
20 | class ReportingChatSettings(BASE):
21 | __tablename__ = "chat_report_settings"
22 | chat_id = Column(String(14), primary_key=True)
23 | should_report = Column(Boolean, default=True)
24 |
25 | def __init__(self, chat_id):
26 | self.chat_id = str(chat_id)
27 |
28 | def __repr__(self):
29 | return "".format(self.chat_id)
30 |
31 |
32 | ReportingUserSettings.__table__.create(checkfirst=True)
33 | ReportingChatSettings.__table__.create(checkfirst=True)
34 |
35 | CHAT_LOCK = threading.RLock()
36 | USER_LOCK = threading.RLock()
37 |
38 |
39 | def chat_should_report(chat_id: Union[str, int]) -> bool:
40 | try:
41 | chat_setting = SESSION.query(ReportingChatSettings).get(str(chat_id))
42 | if chat_setting:
43 | return chat_setting.should_report
44 | return False
45 | finally:
46 | SESSION.close()
47 |
48 |
49 | def user_should_report(user_id: int) -> bool:
50 | try:
51 | user_setting = SESSION.query(ReportingUserSettings).get(user_id)
52 | if user_setting:
53 | return user_setting.should_report
54 | return True
55 | finally:
56 | SESSION.close()
57 |
58 |
59 | def set_chat_setting(chat_id: Union[int, str], setting: bool):
60 | with CHAT_LOCK:
61 | chat_setting = SESSION.query(ReportingChatSettings).get(str(chat_id))
62 | if not chat_setting:
63 | chat_setting = ReportingChatSettings(chat_id)
64 |
65 | chat_setting.should_report = setting
66 | SESSION.add(chat_setting)
67 | SESSION.commit()
68 |
69 |
70 | def set_user_setting(user_id: int, setting: bool):
71 | with USER_LOCK:
72 | user_setting = SESSION.query(ReportingUserSettings).get(user_id)
73 | if not user_setting:
74 | user_setting = ReportingUserSettings(user_id)
75 |
76 | user_setting.should_report = setting
77 | SESSION.add(user_setting)
78 | SESSION.commit()
79 |
80 |
81 | def migrate_chat(old_chat_id, new_chat_id):
82 | with CHAT_LOCK:
83 | chat_notes = (
84 | SESSION.query(ReportingChatSettings)
85 | .filter(ReportingChatSettings.chat_id == str(old_chat_id))
86 | .all()
87 | )
88 | for note in chat_notes:
89 | note.chat_id = str(new_chat_id)
90 | SESSION.commit()
91 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/sql/rss_sql.py:
--------------------------------------------------------------------------------
1 | import threading
2 |
3 | from LaylaRobot.modules.sql import BASE, SESSION
4 | from sqlalchemy import Column, Integer, UnicodeText
5 |
6 |
7 | class RSS(BASE):
8 | __tablename__ = "rss_feed"
9 | id = Column(Integer, primary_key=True)
10 | chat_id = Column(UnicodeText, nullable=False)
11 | feed_link = Column(UnicodeText)
12 | old_entry_link = Column(UnicodeText)
13 |
14 | def __init__(self, chat_id, feed_link, old_entry_link):
15 | self.chat_id = chat_id
16 | self.feed_link = feed_link
17 | self.old_entry_link = old_entry_link
18 |
19 | def __repr__(self):
20 | return "".format(
21 | self.chat_id, self.feed_link, self.old_entry_link
22 | )
23 |
24 |
25 | RSS.__table__.create(checkfirst=True)
26 | INSERTION_LOCK = threading.RLock()
27 |
28 |
29 | def check_url_availability(tg_chat_id, tg_feed_link):
30 | try:
31 | return (
32 | SESSION.query(RSS)
33 | .filter(RSS.feed_link == tg_feed_link, RSS.chat_id == tg_chat_id)
34 | .all()
35 | )
36 | finally:
37 | SESSION.close()
38 |
39 |
40 | def add_url(tg_chat_id, tg_feed_link, tg_old_entry_link):
41 | with INSERTION_LOCK:
42 | action = RSS(tg_chat_id, tg_feed_link, tg_old_entry_link)
43 |
44 | SESSION.add(action)
45 | SESSION.commit()
46 |
47 |
48 | def remove_url(tg_chat_id, tg_feed_link):
49 | with INSERTION_LOCK:
50 | # this loops to delete any possible duplicates for the same TG User ID, TG Chat ID and link
51 | for row in check_url_availability(tg_chat_id, tg_feed_link):
52 | # add the action to the DB query
53 | SESSION.delete(row)
54 |
55 | SESSION.commit()
56 |
57 |
58 | def get_urls(tg_chat_id):
59 | try:
60 | return SESSION.query(RSS).filter(RSS.chat_id == tg_chat_id).all()
61 | finally:
62 | SESSION.close()
63 |
64 |
65 | def get_all():
66 | try:
67 | return SESSION.query(RSS).all()
68 | finally:
69 | SESSION.close()
70 |
71 |
72 | def update_url(row_id, new_entry_links):
73 | with INSERTION_LOCK:
74 | row = SESSION.query(RSS).get(row_id)
75 |
76 | # set the new old_entry_link with the latest update from the RSS Feed
77 | row.old_entry_link = new_entry_links[0]
78 |
79 | # commit the changes to the DB
80 | SESSION.commit()
81 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/sql/rules_sql.py:
--------------------------------------------------------------------------------
1 | import threading
2 |
3 | from LaylaRobot.modules.sql import BASE, SESSION
4 | from sqlalchemy import Column, String, UnicodeText, distinct, func
5 |
6 |
7 | class Rules(BASE):
8 | __tablename__ = "rules"
9 | chat_id = Column(String(14), primary_key=True)
10 | rules = Column(UnicodeText, default="")
11 |
12 | def __init__(self, chat_id):
13 | self.chat_id = chat_id
14 |
15 | def __repr__(self):
16 | return "".format(self.chat_id, self.rules)
17 |
18 |
19 | Rules.__table__.create(checkfirst=True)
20 |
21 | INSERTION_LOCK = threading.RLock()
22 |
23 |
24 | def set_rules(chat_id, rules_text):
25 | with INSERTION_LOCK:
26 | rules = SESSION.query(Rules).get(str(chat_id))
27 | if not rules:
28 | rules = Rules(str(chat_id))
29 | rules.rules = rules_text
30 |
31 | SESSION.add(rules)
32 | SESSION.commit()
33 |
34 |
35 | def get_rules(chat_id):
36 | rules = SESSION.query(Rules).get(str(chat_id))
37 | ret = ""
38 | if rules:
39 | ret = rules.rules
40 |
41 | SESSION.close()
42 | return ret
43 |
44 |
45 | def num_chats():
46 | try:
47 | return SESSION.query(func.count(distinct(Rules.chat_id))).scalar()
48 | finally:
49 | SESSION.close()
50 |
51 |
52 | def migrate_chat(old_chat_id, new_chat_id):
53 | with INSERTION_LOCK:
54 | chat = SESSION.query(Rules).get(str(old_chat_id))
55 | if chat:
56 | chat.chat_id = str(new_chat_id)
57 | SESSION.commit()
58 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/sql/userinfo_sql.py:
--------------------------------------------------------------------------------
1 | import threading
2 |
3 | from LaylaRobot.modules.sql import BASE, SESSION
4 | from sqlalchemy import Column, Integer, UnicodeText
5 |
6 |
7 | class UserInfo(BASE):
8 | __tablename__ = "userinfo"
9 | user_id = Column(Integer, primary_key=True)
10 | info = Column(UnicodeText)
11 |
12 | def __init__(self, user_id, info):
13 | self.user_id = user_id
14 | self.info = info
15 |
16 | def __repr__(self):
17 | return "" % self.user_id
18 |
19 |
20 | class UserBio(BASE):
21 | __tablename__ = "userbio"
22 | user_id = Column(Integer, primary_key=True)
23 | bio = Column(UnicodeText)
24 |
25 | def __init__(self, user_id, bio):
26 | self.user_id = user_id
27 | self.bio = bio
28 |
29 | def __repr__(self):
30 | return "" % self.user_id
31 |
32 |
33 | UserInfo.__table__.create(checkfirst=True)
34 | UserBio.__table__.create(checkfirst=True)
35 |
36 | INSERTION_LOCK = threading.RLock()
37 |
38 |
39 | def get_user_me_info(user_id):
40 | userinfo = SESSION.query(UserInfo).get(user_id)
41 | SESSION.close()
42 | if userinfo:
43 | return userinfo.info
44 | return None
45 |
46 |
47 | def set_user_me_info(user_id, info):
48 | with INSERTION_LOCK:
49 | userinfo = SESSION.query(UserInfo).get(user_id)
50 | if userinfo:
51 | userinfo.info = info
52 | else:
53 | userinfo = UserInfo(user_id, info)
54 | SESSION.add(userinfo)
55 | SESSION.commit()
56 |
57 |
58 | def get_user_bio(user_id):
59 | userbio = SESSION.query(UserBio).get(user_id)
60 | SESSION.close()
61 | if userbio:
62 | return userbio.bio
63 | return None
64 |
65 |
66 | def set_user_bio(user_id, bio):
67 | with INSERTION_LOCK:
68 | userbio = SESSION.query(UserBio).get(user_id)
69 | if userbio:
70 | userbio.bio = bio
71 | else:
72 | userbio = UserBio(user_id, bio)
73 |
74 | SESSION.add(userbio)
75 | SESSION.commit()
76 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/sql_extended/forceSubscribe_sql.py:
--------------------------------------------------------------------------------
1 | from sqlalchemy import Column, String, Numeric, Boolean
2 | from LaylaRobot.modules.sql import BASE, SESSION
3 |
4 |
5 | class forceSubscribe(BASE):
6 | __tablename__ = "forceSubscribe"
7 | chat_id = Column(Numeric, primary_key=True)
8 | channel = Column(String)
9 |
10 | def __init__(self, chat_id, channel):
11 | self.chat_id = chat_id
12 | self.channel = channel
13 |
14 |
15 | forceSubscribe.__table__.create(checkfirst=True)
16 |
17 |
18 | def fs_settings(chat_id):
19 | try:
20 | return SESSION.query(forceSubscribe).filter(forceSubscribe.chat_id == chat_id).one()
21 | except:
22 | return None
23 | finally:
24 | SESSION.close()
25 |
26 |
27 | def add_channel(chat_id, channel):
28 | adder = SESSION.query(forceSubscribe).get(chat_id)
29 | if adder:
30 | adder.channel = channel
31 | else:
32 | adder = forceSubscribe(
33 | chat_id,
34 | channel
35 | )
36 | SESSION.add(adder)
37 | SESSION.commit()
38 |
39 | def disapprove(chat_id):
40 | rem = SESSION.query(forceSubscribe).get(chat_id)
41 | if rem:
42 | SESSION.delete(rem)
43 | SESSION.commit()
--------------------------------------------------------------------------------
/LaylaRobot/modules/sql_extended/night_mode_sql.py:
--------------------------------------------------------------------------------
1 | from sqlalchemy import Boolean, Column, Integer, String, UnicodeText
2 | from LaylaRobot.modules.sql import BASE, SESSION
3 |
4 |
5 | class Nightmode(BASE):
6 | __tablename__ = "nightmode"
7 | chat_id = Column(String(14), primary_key=True)
8 |
9 | def __init__(self, chat_id):
10 | self.chat_id = chat_id
11 |
12 |
13 | Nightmode.__table__.create(checkfirst=True)
14 |
15 |
16 | def add_nightmode(chat_id: str):
17 | nightmoddy = Nightmode(str(chat_id))
18 | SESSION.add(nightmoddy)
19 | SESSION.commit()
20 |
21 |
22 | def rmnightmode(chat_id: str):
23 | rmnightmoddy = SESSION.query(Nightmode).get(str(chat_id))
24 | if rmnightmoddy:
25 | SESSION.delete(rmnightmoddy)
26 | SESSION.commit()
27 |
28 |
29 | def get_all_chat_id():
30 | stark = SESSION.query(Nightmode).all()
31 | SESSION.close()
32 | return stark
33 |
34 |
35 | def is_nightmode_indb(chat_id: str):
36 | try:
37 | s__ = SESSION.query(Nightmode).get(str(chat_id))
38 | if s__:
39 | return str(s__.chat_id)
40 | finally:
41 | SESSION.close()
42 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/sql_extended/nsfw_watch_sql.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) Midhun KM 2020-2021
2 | # This program is free software: you can redistribute it and/or modify
3 | # it under the terms of the GNU Affero General Public License as published by
4 | # the Free Software Foundation, either version 3 of the License, or
5 | #
6 | # This program is distributed in the hope that it will be useful,
7 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 | # GNU Affero General Public License for more details.
10 | #
11 | # You should have received a copy of the GNU Affero General Public License
12 | # along with this program. If not, see .
13 |
14 | from sqlalchemy import Column, String
15 |
16 | from LaylaRobot.modules.sql import BASE, SESSION
17 |
18 |
19 | class Nsfwatch(BASE):
20 | __tablename__ = "nsfwatch"
21 | chat_id = Column(String(14), primary_key=True)
22 |
23 | def __init__(self, chat_id):
24 | self.chat_id = chat_id
25 |
26 |
27 | Nsfwatch.__table__.create(checkfirst=True)
28 |
29 |
30 | def add_nsfwatch(chat_id: str):
31 | nsfws = Nsfwatch(str(chat_id))
32 | SESSION.add(nsfws)
33 | SESSION.commit()
34 |
35 |
36 | def rmnsfwatch(chat_id: str):
37 | nsfwm = SESSION.query(Nsfwatch).get(str(chat_id))
38 | if nsfwm:
39 | SESSION.delete(nsfwm)
40 | SESSION.commit()
41 |
42 |
43 | def get_all_nsfw_enabled_chat():
44 | stark = SESSION.query(Nsfwatch).all()
45 | SESSION.close()
46 | return stark
47 |
48 |
49 | def is_nsfwatch_indb(chat_id: str):
50 | try:
51 | s__ = SESSION.query(Nsfwatch).get(str(chat_id))
52 | if s__:
53 | return str(s__.chat_id)
54 | finally:
55 | SESSION.close()
--------------------------------------------------------------------------------
/LaylaRobot/modules/tagall.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2020-2021 by DevsExpo@Github, < https://github.com/DevsExpo >.
2 | #
3 | # This file is part of < https://github.com/DevsExpo/FridayUserBot > project,
4 | # and is released under the "GNU v3.0 License Agreement".
5 | # Please see < https://github.com/DevsExpo/blob/master/LICENSE >
6 | #
7 | # All rights reserved.
8 |
9 |
10 | from pyrogram import filters
11 |
12 | from LaylaRobot.pyrogramee.pluginshelper import admins_only, get_text
13 | from LaylaRobot import pbot
14 |
15 |
16 | @pbot.on_message(filters.command("tagall") & ~filters.edited & ~filters.bot)
17 | @admins_only
18 | async def tagall(client, message):
19 | await message.reply("`Processing.....`")
20 | sh = get_text(message)
21 | if not sh:
22 | sh = "Hi!"
23 | mentions = ""
24 | async for member in client.iter_chat_members(message.chat.id):
25 | mentions += member.user.mention + " "
26 | n = 4096
27 | kk = [mentions[i : i + n] for i in range(0, len(mentions), n)]
28 | for i in kk:
29 | j = f"{sh} \n{i}"
30 | await client.send_message(message.chat.id, j, parse_mode="html")
31 |
32 |
33 | __mod_name__ = "Tagall"
34 | __help__ = """
35 | - /tagall : Tag everyone in a chat
36 | """
--------------------------------------------------------------------------------
/LaylaRobot/modules/truth_and_dare.py:
--------------------------------------------------------------------------------
1 | import html
2 | import random
3 | import LaylaRobot.modules.truth_and_dare_string as truth_and_dare_string
4 | from LaylaRobot import dispatcher
5 | from telegram import ParseMode, Update, Bot
6 | from LaylaRobot.modules.disable import DisableAbleCommandHandler
7 | from telegram.ext import CallbackContext, run_async
8 |
9 | @run_async
10 | def truth(update: Update, context: CallbackContext):
11 | args = context.args
12 | update.effective_message.reply_text(random.choice(truth_and_dare_string.TRUTH))
13 |
14 | @run_async
15 | def dare(update: Update, context: CallbackContext):
16 | args = context.args
17 | update.effective_message.reply_text(random.choice(truth_and_dare_string.DARE))
18 |
19 |
20 | TRUTH_HANDLER = DisableAbleCommandHandler("truth", truth)
21 | DARE_HANDLER = DisableAbleCommandHandler("dare", dare)
22 |
23 |
24 | dispatcher.add_handler(TRUTH_HANDLER)
25 | dispatcher.add_handler(DARE_HANDLER)
26 |
27 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/truth_and_dare_string.py:
--------------------------------------------------------------------------------
1 | TRUTH = (
2 | "Have you ghosted someone?"
3 | "Have you ever walked in on your parents doing 'it'?",
4 | "Who was the last person you liked the most? Why?",
5 | "Have you ever been suspended from school?",
6 | "If you had to choose between going naked or having your thoughts appear in thought bubbles above your head for everyone to read, which would you choose?",
7 | "What’s the one thing you’re afraid to lose?",
8 | "Do you like someone as of the moment?",
9 | "One thing about your best friend you are jealous of?",
10 | "Would you cheat on your boyfriend for a rich guy?",
11 | "What is your biggest turn on?",
12 | "When’s the last time you lied to your parents and why?",
13 | "Describe your ideal partner.",
14 | "What’s the scariest thing you’ve ever done?",
15 | "Have you ever picked your nose and eaten it?",
16 | "When’s the last time you lied to your parents and why?",
17 | "Have you ever lied about your age to participate in a contest?",
18 | "Have you ever been caught checking someone out?",
19 |
20 | )
21 |
22 | DARE = (
23 | "Show the most embarrassing photo on your phone"
24 | "Show the last five people you texted and what the messages said",
25 | "Let the rest of the group DM someone from your Instagram account",
26 | "Eat a raw piece of garlic",
27 | "Do 100 squats",
28 | "Keep three ice cubes in your mouth until they melt",
29 | "Say something dirty to the person on your leftYou've got company!",
30 | "Give a foot massage to the person on your right",
31 | "Put 10 different available liquids into a cup and drink it",
32 | "*Yell out the first word that comes to your mind",
33 | "Give a lap dance to someone of your choice",
34 | "Remove four items of clothing",
35 | "Like the first 15 posts on your Facebook newsfeed",
36 | "Eat a spoonful of mustard",
37 | "Keep your eyes closed until it's your go again",
38 | "Send a sext to the last person in your phonebook",
39 | "Show off your orgasm face",
40 | "Seductively eat a banana",
41 | "Empty out your wallet/purse and show everyone what's inside",
42 | "Do your best sexy crawl",
43 | "Pretend to be the person to your right for 10 minutes",
44 | "Eat a snack without using your hands",
45 | "Say two honest things about everyone else in the group",
46 | "Twerk for a minute",
47 | "Try and make the group laugh as quickly as possible",
48 | "Try to put your whole fist in your mouth",
49 | "Tell everyone an embarrassing story about yourself",
50 | "Try to lick your elbow",
51 | "Post the oldest selfie on your phone on Instagram Stories",
52 | "Tell the saddest story you know",
53 | "Howl like a wolf for two minutes",
54 | "Dance without music for two minutes",
55 | "Pole dance with an imaginary pole",
56 | "Let someone else tickle you and try not to laugh",
57 | "Put as many snacks into your mouth at once as you can",
58 | "Send your most recent selfie.",
59 | "Send your ugliest selfie.",
60 | "Send a screenshot of your facebook search history",
61 | "Send a screenshot of your gallery.",
62 | "Send a screenshot of your messenger inbox",
63 | "Tell something very intimate.",
64 | "Send a screenshot of your twitter inbox",
65 | "Send a screenshot of your homescreen.",
66 | "Send a cover of your favorite song. 🎤",
67 | "Do a lyric prank on someone and send proof.",
68 | "Confess to your current crush. ❤️",
69 | "Declare who is your true love.",
70 | "Send a screenshot of your gallery.",
71 | "Set your crush’s picture as your dp.",
72 | "Suggest me more dares.",
73 | )
74 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/ud.py:
--------------------------------------------------------------------------------
1 | import requests
2 | from LaylaRobot import dispatcher
3 | from LaylaRobot.modules.disable import DisableAbleCommandHandler
4 | from telegram import ParseMode, Update
5 | from telegram.ext import CallbackContext, run_async
6 |
7 |
8 | @run_async
9 | def ud(update: Update, context: CallbackContext):
10 | message = update.effective_message
11 | text = message.text[len("/ud ") :]
12 | results = requests.get(
13 | f"https://api.urbandictionary.com/v0/define?term={text}"
14 | ).json()
15 | try:
16 | reply_text = f'*{text}*\n\n{results["list"][0]["definition"]}\n\n_{results["list"][0]["example"]}_'
17 | except:
18 | reply_text = "No results found."
19 | message.reply_text(reply_text, parse_mode=ParseMode.MARKDOWN)
20 |
21 |
22 | UD_HANDLER = DisableAbleCommandHandler(["ud"], ud)
23 |
24 | dispatcher.add_handler(UD_HANDLER)
25 |
26 | __command_list__ = ["ud"]
27 | __handlers__ = [UD_HANDLER]
28 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/wallpaper.py:
--------------------------------------------------------------------------------
1 | from random import randint
2 |
3 | import requests as r
4 | from LaylaRobot import SUPPORT_CHAT, WALL_API, dispatcher
5 | from LaylaRobot.modules.disable import DisableAbleCommandHandler
6 | from telegram import Update
7 | from telegram.ext import CallbackContext, run_async
8 |
9 | # Wallpapers module by @TheRealPhoenix using wall.alphacoders.com
10 |
11 |
12 | @run_async
13 | def wall(update: Update, context: CallbackContext):
14 | chat_id = update.effective_chat.id
15 | msg = update.effective_message
16 | args = context.args
17 | msg_id = update.effective_message.message_id
18 | bot = context.bot
19 | query = " ".join(args)
20 | if not query:
21 | msg.reply_text("Please enter a query!")
22 | return
23 | else:
24 | caption = query
25 | term = query.replace(" ", "%20")
26 | json_rep = r.get(
27 | f"https://wall.alphacoders.com/api2.0/get.php?auth={WALL_API}&method=search&term={term}"
28 | ).json()
29 | if not json_rep.get("success"):
30 | msg.reply_text(f"An error occurred! Report this @{SUPPORT_CHAT}")
31 | else:
32 | wallpapers = json_rep.get("wallpapers")
33 | if not wallpapers:
34 | msg.reply_text("No results found! Refine your search.")
35 | return
36 | else:
37 | index = randint(0, len(wallpapers) - 1) # Choose random index
38 | wallpaper = wallpapers[index]
39 | wallpaper = wallpaper.get("url_image")
40 | wallpaper = wallpaper.replace("\\", "")
41 | bot.send_photo(
42 | chat_id,
43 | photo=wallpaper,
44 | caption="Preview",
45 | reply_to_message_id=msg_id,
46 | timeout=60,
47 | )
48 | bot.send_document(
49 | chat_id,
50 | document=wallpaper,
51 | filename="wallpaper",
52 | caption=caption,
53 | reply_to_message_id=msg_id,
54 | timeout=60,
55 | )
56 |
57 |
58 | WALLPAPER_HANDLER = DisableAbleCommandHandler("wall", wall)
59 | dispatcher.add_handler(WALLPAPER_HANDLER)
60 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/wiki.py:
--------------------------------------------------------------------------------
1 | import wikipedia
2 | from LaylaRobot import dispatcher
3 | from LaylaRobot.modules.disable import DisableAbleCommandHandler
4 | from telegram import ParseMode, Update
5 | from telegram.ext import CallbackContext, run_async
6 | from wikipedia.exceptions import DisambiguationError, PageError
7 |
8 |
9 | @run_async
10 | def wiki(update: Update, context: CallbackContext):
11 | msg = (
12 | update.effective_message.reply_to_message
13 | if update.effective_message.reply_to_message
14 | else update.effective_message
15 | )
16 | res = ""
17 | if msg == update.effective_message:
18 | search = msg.text.split(" ", maxsplit=1)[1]
19 | else:
20 | search = msg.text
21 | try:
22 | res = wikipedia.summary(search)
23 | except DisambiguationError as e:
24 | update.message.reply_text(
25 | "Disambiguated pages found! Adjust your query accordingly.\n{}".format(
26 | e
27 | ),
28 | parse_mode=ParseMode.HTML,
29 | )
30 | except PageError as e:
31 | update.message.reply_text(
32 | "{}
".format(e), parse_mode=ParseMode.HTML
33 | )
34 | if res:
35 | result = f"{search}\n\n"
36 | result += f"{res}\n"
37 | result += f"""Read more..."""
38 | if len(result) > 4000:
39 | with open("result.txt", "w") as f:
40 | f.write(f"{result}\n\nUwU OwO OmO UmU")
41 | with open("result.txt", "rb") as f:
42 | context.bot.send_document(
43 | document=f,
44 | filename=f.name,
45 | reply_to_message_id=update.message.message_id,
46 | chat_id=update.effective_chat.id,
47 | parse_mode=ParseMode.HTML,
48 | )
49 | else:
50 | update.message.reply_text(
51 | result, parse_mode=ParseMode.HTML, disable_web_page_preview=True
52 | )
53 |
54 |
55 | WIKI_HANDLER = DisableAbleCommandHandler("wiki", wiki)
56 | dispatcher.add_handler(WIKI_HANDLER)
57 |
--------------------------------------------------------------------------------
/LaylaRobot/modules/zombies.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | from asyncio import sleep
3 |
4 | from telethon import events
5 | from telethon.errors import ChatAdminRequiredError, UserAdminInvalidError
6 | from telethon.tl.functions.channels import EditBannedRequest
7 | from telethon.tl.types import ChatBannedRights, ChannelParticipantsAdmins
8 |
9 | from LaylaRobot import telethn, OWNER_ID, DEV_USERS, DRAGONS, DEMONS
10 |
11 | # =================== CONSTANT ===================
12 |
13 | BANNED_RIGHTS = ChatBannedRights(
14 | until_date=None,
15 | view_messages=True,
16 | send_messages=True,
17 | send_media=True,
18 | send_stickers=True,
19 | send_gifs=True,
20 | send_games=True,
21 | send_inline=True,
22 | embed_links=True,
23 | )
24 |
25 |
26 | UNBAN_RIGHTS = ChatBannedRights(
27 | until_date=None,
28 | send_messages=None,
29 | send_media=None,
30 | send_stickers=None,
31 | send_gifs=None,
32 | send_games=None,
33 | send_inline=None,
34 | embed_links=None,
35 | )
36 |
37 | OFFICERS = [OWNER_ID] + DEV_USERS + DRAGONS + DEMONS
38 |
39 | # Check if user has admin rights
40 | async def is_administrator(user_id: int, message):
41 | admin = False
42 | async for user in telethn.iter_participants(
43 | message.chat_id, filter=ChannelParticipantsAdmins
44 | ):
45 | if user_id == user.id or user_id in OFFICERS:
46 | admin = True
47 | break
48 | return admin
49 |
50 |
51 |
52 | @telethn.on(events.NewMessage(pattern=f"^[!/]zombies ?(.*)"))
53 | async def zombies(event):
54 | """ For .zombies command, list all the zombies in a chat. """
55 |
56 | con = event.pattern_match.group(1).lower()
57 | del_u = 0
58 | del_status = "No Deleted Accounts Found, Group Is Clean."
59 |
60 | if con != "clean":
61 | find_zombies = await event.respond("Searching For Zombies...")
62 | async for user in event.client.iter_participants(event.chat_id):
63 |
64 | if user.deleted:
65 | del_u += 1
66 | await sleep(1)
67 | if del_u > 0:
68 | del_status = f"Found **{del_u}** Zombies In This Group.\
69 | \nClean Them By Using - `/zombies clean`"
70 | await find_zombies.edit(del_status)
71 | return
72 |
73 | # Here laying the sanity check
74 | chat = await event.get_chat()
75 | admin = chat.admin_rights
76 | creator = chat.creator
77 |
78 | # Well
79 | if not await is_administrator(user_id=event.from_id, message=event):
80 | await event.respond("You're Not An Admin!")
81 | return
82 |
83 | if not admin and not creator:
84 | await event.respond("I Am Not An Admin Here!")
85 | return
86 |
87 | cleaning_zombies = await event.respond("Cleaning Zombies...")
88 | del_u = 0
89 | del_a = 0
90 |
91 | async for user in event.client.iter_participants(event.chat_id):
92 | if user.deleted:
93 | try:
94 | await event.client(
95 | EditBannedRequest(event.chat_id, user.id, BANNED_RIGHTS)
96 | )
97 | except ChatAdminRequiredError:
98 | await cleaning_zombies.edit("I Don't Have Ban Rights In This Group.")
99 | return
100 | except UserAdminInvalidError:
101 | del_u -= 1
102 | del_a += 1
103 | await event.client(EditBannedRequest(event.chat_id, user.id, UNBAN_RIGHTS))
104 | del_u += 1
105 |
106 | if del_u > 0:
107 | del_status = f"Cleaned `{del_u}` Zombies"
108 |
109 | if del_a > 0:
110 | del_status = f"Cleaned `{del_u}` Zombies \
111 | \n`{del_a}` Zombie Admin Accounts Are Not Removed!"
112 |
113 | await cleaning_zombies.edit(del_status)
114 |
115 |
116 | from telethon.tl.types import UserStatusLastMonth, UserStatusLastWeek, ChatBannedRights
117 | from LaylaRobot.events import register
118 | from telethon import *
119 | from telethon.tl.functions.channels import (EditBannedRequest)
120 |
121 |
122 | @register(pattern="^/kickthefools")
123 | async def _(event):
124 | if event.fwd_from:
125 | return
126 | chat = await event.get_chat()
127 | admin = chat.admin_rights
128 | creator = chat.creator
129 | if not event.chat.admin_rights.ban_users:
130 | return
131 | if not admin and not creator:
132 | await event.reply("I am not admin here !")
133 | return
134 | c = 0
135 | KICK_RIGHTS = ChatBannedRights(until_date=None, view_messages=True)
136 | await event.reply("Searching Participant Lists...")
137 | async for i in event.client.iter_participants(event.chat_id):
138 |
139 | if isinstance(i.status, UserStatusLastMonth):
140 | status = await event.client(EditBannedRequest(event.chat_id, i, KICK_RIGHTS))
141 | if not status:
142 | return
143 | else:
144 | c = c + 1
145 |
146 | if isinstance(i.status, UserStatusLastMonth):
147 | status = await event.client(EditBannedRequest(event.chat_id, i, KICK_RIGHTS))
148 | if not status:
149 | return
150 | else:
151 | c = c + 1
152 |
153 | required_string = "Successfully Kicked **{}** users"
154 | await event.reply(required_string.format(c))
155 |
156 |
--------------------------------------------------------------------------------
/LaylaRobot/mongo.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | import sys
3 |
4 | from motor import motor_asyncio
5 | from LaylaRobot import MONGO_DB_URI
6 | from pymongo import MongoClient
7 | from pymongo.errors import ServerSelectionTimeoutError
8 | from LaylaRobot.conf import get_int_key, get_str_key
9 |
10 |
11 | MONGO_PORT = get_int_key("27017")
12 | MONGO_DB_URI = get_str_key("MONGO_DB_URI")
13 | MONGO_DB = "DaisyX"
14 |
15 |
16 | client = MongoClient()
17 | client = MongoClient(MONGO_DB_URI, MONGO_PORT)[MONGO_DB]
18 | motor = motor_asyncio.AsyncIOMotorClient(MONGO_DB_URI, MONGO_PORT)
19 | db = motor[MONGO_DB]
20 | db = client["LaylaRobot"]
21 | try:
22 | asyncio.get_event_loop().run_until_complete(motor.server_info())
23 | except ServerSelectionTimeoutError:
24 | sys.exit(log.critical("Can't connect to mongodb! Exiting..."))
--------------------------------------------------------------------------------
/LaylaRobot/pyrogramee/dark.py:
--------------------------------------------------------------------------------
1 | def get_arg(message):
2 | msg = message.text
3 | msg = msg.replace(" ", "", 1) if msg[1] == " " else msg
4 | split = msg[1:].replace("\n", " \n").split(" ")
5 | if " ".join(split[1:]).strip() == "":
6 | return ""
7 | return " ".join(split[1:])
8 |
--------------------------------------------------------------------------------
/LaylaRobot/pyrogramee/errors.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import traceback
3 | from functools import wraps
4 | from LaylaRobot import pbot, SUPPORT_CHAT
5 |
6 | def split_limits(text):
7 | if len(text) < 2048:
8 | return [text]
9 |
10 | lines = text.splitlines(True)
11 | small_msg = ''
12 | result = []
13 | for line in lines:
14 | if len(small_msg) + len(line) < 2048:
15 | small_msg += line
16 | else:
17 | result.append(small_msg)
18 | small_msg = line
19 | else:
20 | result.append(small_msg)
21 |
22 | return result
23 |
24 | def capture_err(func):
25 | @wraps(func)
26 | async def capture(client, message, *args, **kwargs):
27 | try:
28 | return await func(client, message, *args, **kwargs)
29 | except Exception as err:
30 | exc_type, exc_obj, exc_tb = sys.exc_info()
31 | errors = traceback.format_exception(
32 | etype=exc_type, value=exc_obj, tb=exc_tb,
33 | )
34 | error_feedback = split_limits(
35 | '**ERROR** | `{}` | `{}`\n\n```{}```\n\n```{}```\n'.format(
36 | 0 if not message.from_user else message.from_user.id,
37 | 0 if not message.chat else message.chat.id,
38 | message.text or message.caption,
39 | ''.join(errors),
40 | ),
41 | )
42 | for x in error_feedback:
43 | await pbot.send_message(
44 | SUPPORT_CHAT,
45 | x
46 | )
47 | raise err
48 | return capture
49 |
--------------------------------------------------------------------------------
/LaylaRobot/resources/Chopsic.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shiv-x/LaylaRobot/a899ec54e1fa4048a1a71fdaedba14f9e679d8fb/LaylaRobot/resources/Chopsic.otf
--------------------------------------------------------------------------------
/LaylaRobot/resources/Maghrib.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shiv-x/LaylaRobot/a899ec54e1fa4048a1a71fdaedba14f9e679d8fb/LaylaRobot/resources/Maghrib.ttf
--------------------------------------------------------------------------------
/LaylaRobot/resources/blackbg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shiv-x/LaylaRobot/a899ec54e1fa4048a1a71fdaedba14f9e679d8fb/LaylaRobot/resources/blackbg.jpg
--------------------------------------------------------------------------------
/LaylaRobot/resources/hero.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shiv-x/LaylaRobot/a899ec54e1fa4048a1a71fdaedba14f9e679d8fb/LaylaRobot/resources/hero.png
--------------------------------------------------------------------------------
/LaylaRobot/resources/images.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shiv-x/LaylaRobot/a899ec54e1fa4048a1a71fdaedba14f9e679d8fb/LaylaRobot/resources/images.jpeg
--------------------------------------------------------------------------------
/LaylaRobot/sample_config.py:
--------------------------------------------------------------------------------
1 | # Create a new config.py or rename this to config.py file in same dir and import, then extend this class.
2 | import json
3 | import os
4 |
5 |
6 | def get_user_list(config, key):
7 | with open("{}/LaylaRobot/{}".format(os.getcwd(), config), "r") as json_file:
8 | return json.load(json_file)[key]
9 |
10 |
11 | # Create a new config.py or rename this to config.py file in same dir and import, then extend this class.
12 | class Config(object):
13 | LOGGER = True
14 | # REQUIRED
15 | # Login to https://my.telegram.org and fill in these slots with the details given by it
16 |
17 | API_ID = 123456 # integer value, dont use ""
18 | API_HASH = "awoo"
19 | TOKEN = "BOT_TOKEN" # This var used to be API_KEY but it is now TOKEN, adjust accordingly.
20 | OWNER_ID = 797768146 # If you dont know, run the bot and do /id in your private chat with it, also an integer
21 | OWNER_USERNAME = "HEROGAMERS1"
22 | SUPPORT_CHAT = "AwesomeSupport" # Your own group for support, do not add the @
23 | JOIN_LOGGER = (
24 | -1001392103597
25 | ) # Prints any new group the bot is added to, prints just the name and ID.
26 | EVENT_LOGS = (
27 | -1001392103597
28 | ) # Prints information like gbans, sudo promotes, AI enabled disable states that may help in debugging and shit
29 |
30 | # RECOMMENDED
31 | SQLALCHEMY_DATABASE_URI = "something://somewhat:user@hosturl:port/databasename" # needed for any database modules
32 | LOAD = []
33 | NO_LOAD = ["rss", "cleaner", "connection", "math"]
34 | WEBHOOK = False
35 | INFOPIC = True
36 | URL = None
37 | SPAMWATCH_API = "" # go to support.spamwat.ch to get key
38 | SPAMWATCH_SUPPORT_CHAT = "SpamWatchSupport"
39 |
40 | # OPTIONAL
41 | ##List of id's - (not usernames) for users which have sudo access to the bot.
42 | DRAGONS = get_user_list("elevated_users.json", "sudos")
43 | ##List of id's - (not usernames) for developers who will have the same perms as the owner
44 | DEV_USERS = get_user_list("elevated_users.json", "devs")
45 | ##List of id's (not usernames) for users which are allowed to gban, but can also be banned.
46 | DEMONS = get_user_list("elevated_users.json", "supports")
47 | # List of id's (not usernames) for users which WONT be banned/kicked by the bot.
48 | TIGERS = get_user_list("elevated_users.json", "tigers")
49 | WOLVES = get_user_list("elevated_users.json", "whitelists")
50 | DONATION_LINK = None # EG, paypal
51 | CERT_PATH = None
52 | PORT = 5000
53 | DEL_CMDS = True # Delete commands that users dont have access to, like delete /ban if a non admin uses it.
54 | STRICT_GBAN = True
55 | WORKERS = (
56 | 8 # Number of subthreads to use. Set as number of threads your processor uses
57 | )
58 | BAN_STICKER = "" # banhammer marie sticker id, the bot will send this sticker before banning or kicking a user in chat.
59 | ALLOW_EXCL = True # Allow ! commands as well as / (Leave this to true so that blacklist can work)
60 | CASH_API_KEY = (
61 | "awoo" # Get your API key from https://www.alphavantage.co/support/#api-key
62 | )
63 | TIME_API_KEY = "awoo" # Get your API key from https://timezonedb.com/api
64 | WALL_API = (
65 | "awoo" # For wallpapers, get one from https://wall.alphacoders.com/api.php
66 | )
67 | AI_API_KEY = "awoo" # For chatbot, get one from https://coffeehouse.intellivoid.net/dashboard
68 | BL_CHATS = [] # List of groups that you want blacklisted.
69 | SPAMMERS = None
70 |
71 | class Production(Config):
72 | LOGGER = True
73 |
74 |
75 | class Development(Config):
76 | LOGGER = True
77 |
--------------------------------------------------------------------------------
/LaylaRobot/utils/X:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/LaylaRobot/utils/__init__.py:
--------------------------------------------------------------------------------
1 | from .progress import progress
2 | from .tools import human_to_bytes, humanbytes, md5, time_formatter
3 |
--------------------------------------------------------------------------------
/LaylaRobot/utils/dbfunc.py:
--------------------------------------------------------------------------------
1 | from LaylaRobot.mongo import db
2 | from typing import Dict, List, Union
3 |
4 |
5 | coupledb = db.couple
6 |
7 |
8 | # Couple Chooser
9 |
10 | async def _get_lovers(chat_id: int):
11 | lovers = coupledb.find_one({"chat_id": chat_id})
12 | if lovers:
13 | lovers = lovers["couple"]
14 | else:
15 | lovers = {}
16 | return lovers
17 |
18 |
19 | async def get_couple(chat_id: int, date: str):
20 | lovers = await _get_lovers(chat_id)
21 | if date in lovers:
22 | return lovers[date]
23 | else:
24 | return False
25 |
26 |
27 | async def save_couple(chat_id: int, date: str, couple: dict):
28 | lovers = await _get_lovers(chat_id)
29 | lovers[date] = couple
30 | await coupledb.update_one(
31 | {"chat_id": chat_id},
32 | {
33 | "$set": {
34 | "couple": lovers
35 | }
36 | },
37 | upsert=True
38 | )
39 |
--------------------------------------------------------------------------------
/LaylaRobot/utils/errors.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import traceback
3 | from functools import wraps
4 | from LaylaRobot import pbot as app
5 | from pyrogram.errors.exceptions.forbidden_403 import ChatWriteForbidden
6 |
7 | LOG_GROUP_ID = int(-1001196083551)
8 |
9 | def split_limits(text):
10 | if len(text) < 2048:
11 | return [text]
12 |
13 | lines = text.splitlines(True)
14 | small_msg = ''
15 | result = []
16 | for line in lines:
17 | if len(small_msg) + len(line) < 2048:
18 | small_msg += line
19 | else:
20 | result.append(small_msg)
21 | small_msg = line
22 | else:
23 | result.append(small_msg)
24 |
25 | return result
26 |
27 |
28 | def capture_err(func):
29 | @wraps(func)
30 | async def capture(client, message, *args, **kwargs):
31 | try:
32 | return await func(client, message, *args, **kwargs)
33 | except ChatWriteForbidden:
34 | await app.leave_chat(message.chat.id)
35 | return
36 | except Exception as err:
37 | exc_type, exc_obj, exc_tb = sys.exc_info()
38 | errors = traceback.format_exception(
39 | etype=exc_type, value=exc_obj, tb=exc_tb,
40 | )
41 | error_feedback = split_limits(
42 | '**ERROR** | `{}` | `{}`\n\n```{}```\n\n```{}```\n'.format(
43 | 0 if not message.from_user else message.from_user.id,
44 | 0 if not message.chat else message.chat.id,
45 | message.text or message.caption,
46 | ''.join(errors),
47 | ),
48 | )
49 | for x in error_feedback:
50 | await app.send_message(
51 | LOG_GROUP_ID,
52 | x
53 | )
54 | raise err
55 | return capture
56 |
--------------------------------------------------------------------------------
/LaylaRobot/utils/exceptions.py:
--------------------------------------------------------------------------------
1 | class CancelProcess(Exception):
2 | """
3 | Cancel Process
4 | """
5 |
--------------------------------------------------------------------------------
/LaylaRobot/utils/my.py:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/LaylaRobot/utils/progress.py:
--------------------------------------------------------------------------------
1 | import math
2 | import time
3 |
4 | from .exceptions import CancelProcess
5 | from .tools import humanbytes, time_formatter
6 |
7 |
8 | async def progress(
9 | current, total, gdrive, start, prog_type, file_name=None, is_cancelled=False
10 | ):
11 | now = time.time()
12 | diff = now - start
13 | if is_cancelled is True:
14 | raise CancelProcess
15 |
16 | if round(diff % 10.00) == 0 or current == total:
17 | percentage = current * 100 / total
18 | speed = current / diff
19 | elapsed_time = round(diff)
20 | eta = round((total - current) / speed)
21 | if "upload" in prog_type.lower():
22 | status = "Uploading"
23 | elif "download" in prog_type.lower():
24 | status = "Downloading"
25 | else:
26 | status = "Unknown"
27 | progress_str = "`{0}` | [{1}{2}] `{3}%`".format(
28 | status,
29 | "".join("●" for i in range(math.floor(percentage / 10))),
30 | "".join("○" for i in range(10 - math.floor(percentage / 10))),
31 | round(percentage, 2),
32 | )
33 | tmp = (
34 | f"{progress_str}\n"
35 | f"`{humanbytes(current)} of {humanbytes(total)}"
36 | f" @ {humanbytes(speed)}`\n"
37 | f"`ETA` -> {time_formatter(eta)}\n"
38 | f"`Duration` -> {time_formatter(elapsed_time)}"
39 | )
40 | await gdrive.edit(f"`{prog_type}`\n\n" f"`Status`\n{tmp}")
41 |
--------------------------------------------------------------------------------
/LaylaRobot/utils/tools.py:
--------------------------------------------------------------------------------
1 | import hashlib
2 | import re
3 |
4 |
5 | async def md5(fname: str) -> str:
6 | hash_md5 = hashlib.md5()
7 | with open(fname, "rb") as f:
8 | for chunk in iter(lambda: f.read(4096), b""):
9 | hash_md5.update(chunk)
10 | return hash_md5.hexdigest()
11 |
12 |
13 | def humanbytes(size: int) -> str:
14 | if size is None or isinstance(size, str):
15 | return ""
16 |
17 | power = 2 ** 10
18 | raised_to_pow = 0
19 | dict_power_n = {0: "", 1: "Ki", 2: "Mi", 3: "Gi", 4: "Ti"}
20 | while size > power:
21 | size /= power
22 | raised_to_pow += 1
23 | return str(round(size, 2)) + " " + dict_power_n[raised_to_pow] + "B"
24 |
25 |
26 | def time_formatter(seconds: int) -> str:
27 | minutes, seconds = divmod(seconds, 60)
28 | hours, minutes = divmod(minutes, 60)
29 | days, hours = divmod(hours, 24)
30 | tmp = (
31 | ((str(days) + " day(s), ") if days else "")
32 | + ((str(hours) + " hour(s), ") if hours else "")
33 | + ((str(minutes) + " minute(s), ") if minutes else "")
34 | + ((str(seconds) + " second(s), ") if seconds else "")
35 | )
36 | return tmp[:-2]
37 |
38 |
39 | def human_to_bytes(size: str) -> int:
40 | units = {
41 | "M": 2 ** 20,
42 | "MB": 2 ** 20,
43 | "G": 2 ** 30,
44 | "GB": 2 ** 30,
45 | "T": 2 ** 40,
46 | "TB": 2 ** 40,
47 | }
48 |
49 | size = size.upper()
50 | if not re.match(r" ", size):
51 | size = re.sub(r"([KMGT])", r" \1", size)
52 | number, unit = [string.strip() for string in size.split()]
53 | return int(float(number) * units[unit])
54 |
--------------------------------------------------------------------------------
/Procfile:
--------------------------------------------------------------------------------
1 | worker: python3 -m LaylaRobot
2 | ps:scale worker=1
3 |
--------------------------------------------------------------------------------
/Setup venv.bat:
--------------------------------------------------------------------------------
1 | TITLE Setting up virtual env
2 | :: Running it once is fine, this just sets up virtual env >> install all modules there
3 | py -m venv env && env\scripts\activate.bat && pip install -r requirements.txt
4 |
5 | :: Note to rerun the requirements.txt in case you ever add a mdoule.
6 | :: Running this multiple time will not make a mess of your setup, dont worry about that bit.
7 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-architect
--------------------------------------------------------------------------------
/exp.sh:
--------------------------------------------------------------------------------
1 | sudo bash -c 'echo "{ \"cgroup-parent\": \"/actions_job\",\"experimental\":true}" > /etc/docker/daemon.json'
2 | sudo systemctl restart docker.service
--------------------------------------------------------------------------------
/heroku.yml:
--------------------------------------------------------------------------------
1 | build:
2 | docker:
3 | worker: Dockerfile
4 | run:
5 | worker: python3 -m LaylaRobot
6 |
--------------------------------------------------------------------------------
/profanity_wordlist.txt:
--------------------------------------------------------------------------------
1 | 2g1c
2 | 2 girls 1 cup
3 | 4r5e
4 | anal
5 | anus
6 | arse
7 | ass
8 | asses
9 | assfucker
10 | assfukka
11 | asshole
12 | arsehole
13 | asswhole
14 | assmunch
15 | auto erotic
16 | autoerotic
17 | ballsack
18 | bastard
19 | beastial
20 | bestial
21 | bellend
22 | bdsm
23 | beastiality
24 | bestiality
25 | bitch
26 | bitches
27 | bitchin
28 | bitching
29 | bimbo
30 | bimbos
31 | blow job
32 | blowjob
33 | blowjobs
34 | blue waffle
35 | boob
36 | boobs
37 | booobs
38 | boooobs
39 | booooobs
40 | booooooobs
41 | breasts
42 | booty call
43 | brown shower
44 | brown showers
45 | boner
46 | bondage
47 | buceta
48 | bukake
49 | bukkake
50 | bullshit
51 | bull shit
52 | busty
53 | butthole
54 | carpet muncher
55 | cawk
56 | chink
57 | cipa
58 | clit
59 | clits
60 | clitoris
61 | cnut
62 | cock
63 | cocks
64 | cockface
65 | cockhead
66 | cockmunch
67 | cockmuncher
68 | cocksuck
69 | cocksucked
70 | cocksucking
71 | cocksucks
72 | cocksucker
73 | cokmuncher
74 | coon
75 | cow girl
76 | cow girls
77 | cowgirl
78 | cowgirls
79 | crap
80 | crotch
81 | cum
82 | cummer
83 | cumming
84 | cuming
85 | cums
86 | cumshot
87 | cunilingus
88 | cunillingus
89 | cunnilingus
90 | cunt
91 | cuntlicker
92 | cuntlicking
93 | cunts
94 | damn
95 | dick
96 | dickhead
97 | dildo
98 | dildos
99 | dink
100 | dinks
101 | deepthroat
102 | deep throat
103 | dog style
104 | doggie style
105 | doggiestyle
106 | doggy style
107 | doggystyle
108 | donkeyribber
109 | doosh
110 | douche
111 | duche
112 | dyke
113 | ejaculate
114 | ejaculated
115 | ejaculates
116 | ejaculating
117 | ejaculatings
118 | ejaculation
119 | ejakulate
120 | erotic
121 | erotism
122 | fag
123 | faggot
124 | fagging
125 | faggit
126 | faggitt
127 | faggs
128 | fagot
129 | fagots
130 | fags
131 | fatass
132 | femdom
133 | fingering
134 | footjob
135 | foot job
136 | fuck
137 | fucks
138 | fucker
139 | fuckers
140 | fucked
141 | fuckhead
142 | fuckheads
143 | fuckin
144 | fucking
145 | fcuk
146 | fcuker
147 | fcuking
148 | felching
149 | fellate
150 | fellatio
151 | fingerfuck
152 | fingerfucked
153 | fingerfucker
154 | fingerfuckers
155 | fingerfucking
156 | fingerfucks
157 | fistfuck
158 | fistfucked
159 | fistfucker
160 | fistfuckers
161 | fistfucking
162 | fistfuckings
163 | fistfucks
164 | flange
165 | fook
166 | fooker
167 | fucka
168 | fuk
169 | fuks
170 | fuker
171 | fukker
172 | fukkin
173 | fukking
174 | futanari
175 | futanary
176 | gangbang
177 | gangbanged
178 | gang bang
179 | gokkun
180 | golden shower
181 | goldenshower
182 | gaysex
183 | goatse
184 | handjob
185 | hand job
186 | hentai
187 | hooker
188 | hoer
189 | homo
190 | horny
191 | incest
192 | jackoff
193 | jack off
194 | jerkoff
195 | jerk off
196 | jizz
197 | knob
198 | kinbaku
199 | labia
200 | masturbate
201 | masochist
202 | mofo
203 | mothafuck
204 | motherfuck
205 | motherfucker
206 | mothafucka
207 | mothafuckas
208 | mothafuckaz
209 | mothafucked
210 | mothafucker
211 | mothafuckers
212 | mothafuckin
213 | mothafucking
214 | mothafuckings
215 | mothafucks
216 | mother fucker
217 | motherfucked
218 | motherfucker
219 | motherfuckers
220 | motherfuckin
221 | motherfucking
222 | motherfuckings
223 | motherfuckka
224 | motherfucks
225 | milf
226 | muff
227 | nigga
228 | nigger
229 | nigg
230 | nipple
231 | nipples
232 | nob
233 | nob jokey
234 | nobhead
235 | nobjocky
236 | nobjokey
237 | numbnuts
238 | nutsack
239 | nude
240 | nudes
241 | orgy
242 | orgasm
243 | orgasms
244 | panty
245 | panties
246 | penis
247 | playboy
248 | porn
249 | porno
250 | pornography
251 | pron
252 | pussy
253 | pussies
254 | rape
255 | raping
256 | rapist
257 | rectum
258 | retard
259 | rimming
260 | sadist
261 | sadism
262 | schlong
263 | scrotum
264 | sex
265 | semen
266 | shemale
267 | she male
268 | shibari
269 | shibary
270 | shit
271 | shitdick
272 | shitfuck
273 | shitfull
274 | shithead
275 | shiting
276 | shitings
277 | shits
278 | shitted
279 | shitters
280 | shitting
281 | shittings
282 | shitty
283 | shota
284 | skank
285 | slut
286 | sluts
287 | smut
288 | smegma
289 | spunk
290 | strip club
291 | stripclub
292 | tit
293 | tits
294 | titties
295 | titty
296 | titfuck
297 | tittiefucker
298 | titties
299 | tittyfuck
300 | tittywank
301 | titwank
302 | threesome
303 | three some
304 | throating
305 | twat
306 | twathead
307 | twatty
308 | twunt
309 | viagra
310 | vagina
311 | vulva
312 | wank
313 | wanker
314 | wanky
315 | whore
316 | whoar
317 | xxx
318 | xx
319 | yaoi
320 | yury
321 | sexy
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | future
2 | emoji
3 | lxml
4 | wget
5 | gtts
6 | faker
7 | beautifulsoup4
8 | requests==2.20.0
9 | python-telegram-bot==12.8
10 | sqlalchemy==1.3.20
11 | psycopg2-binary
12 | feedparser
13 | hachoir
14 | pynewtonmath
15 | spongemock
16 | zalgo-text
17 | geopy
18 | nltk
19 | psutil
20 | aiohttp>=2.2.5
21 | Pillow>=4.2.0
22 | CurrencyConverter
23 | #googletrans
24 | google_trans_new
25 | jikanpy
26 | speedtest-cli
27 | coffeehouse==2.2.4
28 | regex
29 | bleach
30 | git+https://github.com/starry69/python-markdown2.git
31 | wikipedia
32 | telethon==1.16.4
33 | telegraph
34 | heroku3
35 | spamwatch
36 | alphabet_detector
37 | pybase64
38 | pySmartDL
39 | validators
40 | nekos.py
41 | aiofiles
42 | pyrate-limiter
43 | cachetools
44 | ujson
45 | pretty_errors
46 | TgCrypto
47 | Pyrogram
48 | youtube-dl
49 | youtube_search_python
50 | youtube_search
51 | asyncio
52 | dateparser==1.0.0
53 | pymongo==3.11.0
54 | dnspython
55 | secureme
56 | apscheduler
57 | emoji-country-flag
58 | countryinfo
59 | html2text
60 | bs4
61 | fontTools
62 | bing_image_downloader
63 | search_engine_parser
64 | pytz
65 | lyricsgenius
66 | tswift
67 | envparse
68 | better_profanity
69 | nudepy
70 | motor
71 | cloudscraper
72 |
--------------------------------------------------------------------------------
/restart.bat:
--------------------------------------------------------------------------------
1 | :: starts a cmd to silently start the bat file, just another dirty way of getting things done for my env on windows
2 | start cmd.exe /c start_service.bat
--------------------------------------------------------------------------------
/runtime.txt:
--------------------------------------------------------------------------------
1 | python-3.8.6
2 |
--------------------------------------------------------------------------------
/start.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | TITLE Layla Robot
3 | :: Enables virtual env mode and then starts Rika
4 | env\scripts\activate.bat && py -m LaylaRobot
5 |
--------------------------------------------------------------------------------
/start_service.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | :: This runs the batch file as an admin - required UAC to be off
3 | :: This is just an asty hack in to get job done cause we host it on windows dedi.
4 | :: BatchGotAdmin
5 | :-------------------------------------
6 | REM --> Check for permissions
7 | >nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"
8 |
9 | REM --> If error flag set, we do not have admin.
10 | if '%errorlevel%' NEQ '0' (
11 | echo Requesting administrative privileges...
12 | goto UACPrompt
13 | ) else ( goto gotAdmin )
14 |
15 | :UACPrompt
16 | echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
17 | set params = %*:"=""
18 | echo UAC.ShellExecute "cmd.exe", "/c %~s0 %params%", "", "runas", 1 >> "%temp%\getadmin.vbs"
19 |
20 | "%temp%\getadmin.vbs"
21 | del "%temp%\getadmin.vbs"
22 | exit /B
23 |
24 | :gotAdmin
25 | pushd "%CD%"
26 | CD /D "%~dp0"
27 | :--------------------------------------
28 | :: your commands begin from this point.
29 | :: stops the service and then starts it
30 | net stop LaylaRobot
31 | net start LaylaRobot
32 |
--------------------------------------------------------------------------------