├── .dockerignore
├── .env.example
├── .gitattributes
├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Dockerfile
├── LICENSE
├── README.md
├── VERSION
├── config.py
├── core
├── __init__.py
├── commands
│ ├── __init__.py
│ ├── admin
│ │ ├── __init__.py
│ │ ├── badword.py
│ │ ├── ban.py
│ │ ├── check_permission.py
│ │ ├── dashboard.py
│ │ ├── delete_message.py
│ │ ├── filters.py
│ │ ├── greport.py
│ │ ├── info_group.py
│ │ ├── mute.py
│ │ ├── pin.py
│ │ ├── promote.py
│ │ ├── say.py
│ │ ├── set_custom_handler.py
│ │ ├── set_lang.py
│ │ ├── set_rules.py
│ │ ├── set_welcome.py
│ │ ├── settings.py
│ │ ├── shield.py
│ │ ├── top.py
│ │ ├── unban.py
│ │ ├── user_info.py
│ │ └── warn.py
│ ├── index.py
│ ├── owner
│ │ ├── __init__.py
│ │ ├── add_antispam.py
│ │ ├── add_community.py
│ │ ├── add_owner.py
│ │ ├── broadcast.py
│ │ ├── exit.py
│ │ ├── export_invite_link.py
│ │ ├── list_community.py
│ │ ├── server_info.py
│ │ ├── superban.py
│ │ ├── test.py
│ │ └── whitelist.py
│ └── public
│ │ ├── __init__.py
│ │ ├── eggs.py
│ │ ├── help.py
│ │ ├── io.py
│ │ ├── kickme.py
│ │ ├── report.py
│ │ ├── rules.py
│ │ ├── source.py
│ │ ├── staff.py
│ │ ├── start.py
│ │ └── user_search.py
├── database
│ ├── __init__.py
│ ├── db_connect.py
│ ├── migrations.py
│ ├── redis_connect.py
│ └── repository
│ │ ├── __init__.py
│ │ ├── community.py
│ │ ├── dashboard.py
│ │ ├── group.py
│ │ ├── group_language.py
│ │ ├── superban.py
│ │ └── user.py
├── decorators
│ ├── __init__.py
│ ├── admin.py
│ ├── bot.py
│ ├── delete.py
│ ├── owner.py
│ ├── private.py
│ └── public.py
├── handlers
│ ├── __init__.py
│ ├── check_status_chat.py
│ ├── check_status_user.py
│ ├── custom_handler.py
│ ├── errors.py
│ ├── filters_chat.py
│ ├── flood_wait.py
│ ├── handler_errors.py
│ ├── handlers_index.py
│ ├── logs.py
│ └── welcome.py
├── jobs
│ ├── __init__.py
│ ├── night_mode.py
│ ├── query_repeat.py
│ ├── send_db_backup.py
│ └── send_debug.py
└── utilities
│ ├── __init__.py
│ ├── constants.py
│ ├── functions.py
│ ├── menu.py
│ ├── message.py
│ ├── monads.py
│ ├── regex.py
│ └── strings.py
├── docker-compose.yml
├── languages
├── EN.py
├── IT.py
├── __init__.py
└── getLang.py
├── main.py
├── plugins
├── __init__.py
├── distrowatch.py
├── inspire.py
├── plugin_index.py
├── search.py
├── weather.py
└── wikipedia.py
├── poetry.lock
├── pyproject.toml
├── requirements.txt
└── runtime.txt
/.dockerignore:
--------------------------------------------------------------------------------
1 | .git*
2 | .dockerignore
3 | .circleci
4 | .vscode
5 | Dockerfile
6 | env
7 | venv
8 | docker/
9 | docker-compose.yml
10 |
--------------------------------------------------------------------------------
/.env.example:
--------------------------------------------------------------------------------
1 | # BOT SETTINGS
2 | TOKEN = 'YOUR_TOKEN'
3 | # DATABASE SETTINGS
4 | MYSQL_HOST = 'localhost'
5 | MYSQL_PORT = 3306
6 | MYSQL_USER = 'root'
7 | MYSQL_PASSWORD = ''
8 | MYSQL_DBNAME = 'nebula'
9 | #REDIS SETTINGS
10 | REDIS_HOST = 'localhost'
11 | REDIS_PORT = 6379
12 | REDIS_PASSWORD = ''
13 | REDIS_DB = 0
14 | # TELEGRAM SETTINGS
15 | TG_DEFAULT_WELCOME = 'Welcome {} to the {} group'
16 | TG_DEFAULT_RULES = 'https://github.com/Squirrel-Network/GroupRules'
17 | TG_DEFAULT_LOG_CHANNEL = -100123456789
18 | TG_DEFAULT_STAFF_GROUP = -100123456789
19 | # PROJECT SETTINGS
20 | DEV_CHAT_ID = -100123456789
21 | OPENWEATHER_TOKEN = 'YOUR_TOKEN'
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.* linguist-language=python
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | pip-wheel-metadata/
24 | share/python-wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .nox/
44 | .coverage
45 | .coverage.*
46 | .cache
47 | nosetests.xml
48 | coverage.xml
49 | *.cover
50 | .hypothesis/
51 | .pytest_cache/
52 | .idea/
53 |
54 | # Translations
55 | *.mo
56 | *.pot
57 |
58 | # Django stuff:
59 | *.log
60 | local_settings.py
61 | db.sqlite3
62 | db.sqlite3-journal
63 |
64 | # Flask stuff:
65 | instance/
66 | .webassets-cache
67 |
68 | # Scrapy stuff:
69 | .scrapy
70 |
71 | # Sphinx documentation
72 | docs/_build/
73 |
74 | # PyBuilder
75 | target/
76 |
77 | # Jupyter Notebook
78 | .ipynb_checkpoints
79 |
80 | # IPython
81 | profile_default/
82 | ipython_config.py
83 |
84 | # pyenv
85 | .python-version
86 |
87 | # pipenv
88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
91 | # install all needed dependencies.
92 | #Pipfile.lock
93 |
94 | # celery beat schedule file
95 | celerybeat-schedule
96 |
97 | # SageMath parsed files
98 | *.sage.py
99 |
100 | # Environments
101 | .env
102 | .venv
103 | env/
104 | venv/
105 | ENV/
106 | env.bak/
107 | venv.bak/
108 |
109 | # Spyder project settings
110 | .spyderproject
111 | .spyproject
112 |
113 | # Rope project settings
114 | .ropeproject
115 |
116 | # mkdocs documentation
117 | /site
118 |
119 | # mypy
120 | .mypy_cache/
121 | .dmypy.json
122 | dmypy.json
123 |
124 | # Pyre type checker
125 | .pyre/
126 |
127 | # app
128 | .vsls.json
129 | .vscode
130 | .vs
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at officialsquirrelnetwork@gmail.com. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | When contributing to this repository, please first discuss the change you wish to make via issue,
4 | email, or any other method with the owners of this repository before making a change.
5 |
6 | Please note we have a code of conduct, please follow it in all your interactions with the project.
7 |
8 | ## Pull Request Process
9 |
10 | 1. Ensure any install or build dependencies are removed before the end of the layer when doing a
11 | build.
12 | 2. Update the README.md with details of changes to the interface, this includes new environment
13 | variables, exposed ports, useful file locations and container parameters.
14 | 3. Increase the version numbers in any examples files and the README.md to the new version that this
15 | Pull Request would represent. The versioning scheme we use is [SemVer](http://semver.org/).
16 | 4. You may merge the Pull Request in once you have the sign-off of two other developers, or if you
17 | do not have permission to do that, you may request the second reviewer to merge it for you.
18 |
19 | ## Code of Conduct
20 |
21 | ### Our Pledge
22 |
23 | In the interest of fostering an open and welcoming environment, we as
24 | contributors and maintainers pledge to making participation in our project and
25 | our community a harassment-free experience for everyone, regardless of age, body
26 | size, disability, ethnicity, gender identity and expression, level of experience,
27 | nationality, personal appearance, race, religion, or sexual identity and
28 | orientation.
29 |
30 | ### Our Standards
31 |
32 | Examples of behavior that contributes to creating a positive environment
33 | include:
34 |
35 | * Using welcoming and inclusive language
36 | * Being respectful of differing viewpoints and experiences
37 | * Gracefully accepting constructive criticism
38 | * Focusing on what is best for the community
39 | * Showing empathy towards other community members
40 |
41 | Examples of unacceptable behavior by participants include:
42 |
43 | * The use of sexualized language or imagery and unwelcome sexual attention or
44 | advances
45 | * Trolling, insulting/derogatory comments, and personal or political attacks
46 | * Public or private harassment
47 | * Publishing others' private information, such as a physical or electronic
48 | address, without explicit permission
49 | * Other conduct which could reasonably be considered inappropriate in a
50 | professional setting
51 |
52 | ### Our Responsibilities
53 |
54 | Project maintainers are responsible for clarifying the standards of acceptable
55 | behavior and are expected to take appropriate and fair corrective action in
56 | response to any instances of unacceptable behavior.
57 |
58 | Project maintainers have the right and responsibility to remove, edit, or
59 | reject comments, commits, code, wiki edits, issues, and other contributions
60 | that are not aligned to this Code of Conduct, or to ban temporarily or
61 | permanently any contributor for other behaviors that they deem inappropriate,
62 | threatening, offensive, or harmful.
63 |
64 | ### Scope
65 |
66 | This Code of Conduct applies both within project spaces and in public spaces
67 | when an individual is representing the project or its community. Examples of
68 | representing a project or community include using an official project e-mail
69 | address, posting via an official social media account, or acting as an appointed
70 | representative at an online or offline event. Representation of a project may be
71 | further defined and clarified by project maintainers.
72 |
73 | ### Enforcement
74 |
75 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
76 | reported by contacting the project team at [INSERT EMAIL ADDRESS]. All
77 | complaints will be reviewed and investigated and will result in a response that
78 | is deemed necessary and appropriate to the circumstances. The project team is
79 | obligated to maintain confidentiality with regard to the reporter of an incident.
80 | Further details of specific enforcement policies may be posted separately.
81 |
82 | Project maintainers who do not follow or enforce the Code of Conduct in good
83 | faith may face temporary or permanent repercussions as determined by other
84 | members of the project's leadership.
85 |
86 | ### Attribution
87 |
88 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
89 | available at [http://contributor-covenant.org/version/1/4][version]
90 |
91 | [homepage]: http://contributor-covenant.org
92 | [version]: http://contributor-covenant.org/version/1/4/
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | # first stage
2 | FROM python:3.9 AS builder
3 | COPY requirements.txt .
4 |
5 | # install dependencies to the local user directory (eg. /root/.local)
6 | RUN pip install --user -r requirements.txt
7 |
8 | # second unnamed stage
9 | FROM python:3.9-slim
10 | WORKDIR /app
11 |
12 | # copy only the dependencies installation from the 1st stage image
13 | COPY --from=builder /root/.local /root/.local
14 | COPY . /app
15 |
16 | # update PATH environment variable
17 | ENV PATH=/root/.local:$PATH
18 |
19 | CMD [ "python", "./main.py" ]
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://www.python.org/) [](https://en.wikipedia.org/wiki/Open_source)
2 |
3 | [](https://www.codacy.com/gh/Squirrel-Network/nebula8/dashboard?utm_source=github.com&utm_medium=referral&utm_content=Squirrel-Network/nebula8&utm_campaign=Badge_Grade) [](https://app.circleci.com/pipelines/github/Squirrel-Network/nebula8) [](https://t.me/squirrelnetwork)
4 | # NEBULA BOT
5 |
6 | ❗❗️️❗️ The new Version compatible with the python-telegram-bot 20.X library is under development❗️❗️❗️
7 |
--------------------------------------------------------------------------------
/VERSION:
--------------------------------------------------------------------------------
1 | 8.6.2
--------------------------------------------------------------------------------
/config.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | import os
6 | from dotenv import load_dotenv
7 |
8 | load_dotenv()
9 |
10 | class Config(object):
11 | ###########################
12 | ## DATABASE SETTINGS ##
13 | ##########################
14 | HOST = os.environ.get('MYSQL_HOST', 'localhost')
15 | PORT = int(os.environ.get('MYSQL_PORT', '3306'))
16 | USER = os.environ.get('MYSQL_USER', 'root')
17 | PASSWORD = os.environ.get('MYSQL_PASSWORD')
18 | DBNAME = os.environ.get('MYSQL_DBNAME')
19 | ##########################
20 | ## REDIS SETTINGS ##
21 | ##########################
22 | RD_HOST = os.environ.get('REDIS_HOST', 'localhost')
23 | RD_PORT = os.environ.get('REDIS_PORT', '6379')
24 | RD_PASSWORD = os.environ.get('REDIS_PASSWORD')
25 | RD_DB = os.environ.get('REDIS_DB', 0)
26 | ###########################
27 | ## TELEGRAM SETTINGS ##
28 | ##########################
29 | BOT_TOKEN = os.environ.get('TOKEN')
30 | DEFAULT_WELCOME = os.environ.get('TG_DEFAULT_WELCOME', 'Welcome {} to the {} group')
31 | DEFAULT_RULES = os.environ.get('TG_DEFAULT_RULES', 'https://github.com/Squirrel-Network/GroupRules')
32 | DEFAULT_LOG_CHANNEL = os.environ.get('TG_DEFAULT_LOG_CHANNEL')
33 | DEFAULT_STAFF_GROUP = os.environ.get('TG_DEFAULT_STAFF_GROUP')
34 | ##########################
35 | ## PROJECT SETTINGS ##
36 | ##########################
37 | OPENWEATHER_API = os.environ.get('OPENWEATHER_TOKEN')
38 | ENABLE_PLUGINS = True
39 | DEFAULT_LANGUAGE = "EN"
40 | VERSION = '8.6.2'
41 | VERSION_NAME = 'Hatterene'
42 | REPO = 'https://github.com/Squirrel-Network/nebula8'
43 | DEVELOPER_CHAT_ID = os.environ.get('DEV_CHAT_ID')
44 | DEBUG = False
45 | if BOT_TOKEN is None:
46 | print("The environment variable TOKEN was not set correctly!")
47 | quit(1)
48 | if RD_PASSWORD is None:
49 | print("The environment variable REDIS_PASSWORD was not set correctly!")
50 | quit(1)
51 | if DEFAULT_LOG_CHANNEL is None:
52 | print("The environment variable TG_DEFAULT_LOG_CHANNEL was not set correctly!")
53 | quit(1)
54 | if DEFAULT_STAFF_GROUP is None:
55 | print("The environment variable TG_DEFAULT_STAFF_GROUP was not set correctly!")
56 | quit(1)
57 | if OPENWEATHER_API is None:
58 | print("The environment variable OPENWEATHER_TOKEN was not set correctly! this will not allow the weather plugin to work")
59 |
--------------------------------------------------------------------------------
/core/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | """Import Files"""
7 | __all__ = ["commands",
8 | "decorators",
9 | "handlers",
10 | "utilities"
11 | ]
12 |
13 | from core import *
--------------------------------------------------------------------------------
/core/commands/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | """Import Files"""
7 | __all__ = ["admin",
8 | "owner",
9 | "public",
10 | "index"
11 | ]
12 |
13 | from core.commands import *
--------------------------------------------------------------------------------
/core/commands/admin/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | """Import Files"""
7 | __all__ = ["badword","ban","check_permission","dashboard","delete_message","filters","greport","info_group","mute","pin","promote","say","set_custom_handler","set_lang","set_rules","set_welcome","settings","shield","top","unban","user_info","warn"]
8 |
9 | from core.commands.admin import *
--------------------------------------------------------------------------------
/core/commands/admin/badword.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | from core import decorators
7 | from languages.getLang import languages
8 | from core.utilities.message import message
9 | from core.utilities.functions import chat_object
10 | from core.database.repository.group import GroupRepository
11 |
12 | @decorators.admin.user_admin
13 | @decorators.delete.init
14 | def init(update,context):
15 | chat = chat_object(update)
16 | msg = update.message.text[8:].strip()
17 | if msg != "":
18 | data = [(msg,chat.id)]
19 | GroupRepository().insert_badword(data)
20 | message(update,context,languages.badlist_add.format(msg))
21 | else:
22 | message(update, context,languages.badlist_add_empty)
23 |
24 | @decorators.admin.user_admin
25 | @decorators.delete.init
26 | def badlist(update,context):
27 | chat = chat_object(update)
28 | languages(update,context)
29 | rows = GroupRepository().get_badwords_group(chat.id)
30 | if rows:
31 | string = ""
32 | for row in rows:
33 | string += "▪️ {}\n".format(row['word'])
34 | message(update,context,languages.badlist_text.format(chat.title,string))
35 | else:
36 | message(update,context,languages.badlist_empty)
37 |
--------------------------------------------------------------------------------
/core/commands/admin/ban.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | from core import decorators
7 | from core.handlers.logs import sys_loggers, telegram_loggers
8 | from core.utilities.functions import (
9 | ban_user_reply,
10 | ban_user_by_username,
11 | ban_user_by_id,
12 | bot_object,
13 | delete_message_reply,
14 | reply_member_status_object,
15 | chat_object)
16 | from core.utilities.message import message
17 | from core.utilities.strings import Strings
18 | from core.utilities.monads import Try
19 | from telegram.utils.helpers import mention_html
20 | from core.database.repository.group import GroupRepository
21 | from languages.getLang import languages
22 |
23 | def ban_error(update, context, username = None, id = None):
24 | message(
25 | update,
26 | context,
27 | "Si è verificato un problema per il ban dell'utente %s" % (username if username is not None else id))
28 |
29 | def ban_success(update, context, username = None, id = None):
30 | message(update,context,"Ho bannato %s" % (username if username is not None else id))
31 |
32 | @decorators.admin.user_admin
33 | @decorators.delete.init
34 | def init(update, context):
35 | languages(update,context)
36 | chat = chat_object(update)
37 | row = GroupRepository().getById(chat.id)
38 |
39 | bot = bot_object(update,context)
40 | chat = update.effective_chat
41 | reply = update.message.reply_to_message
42 | if row['set_gh'] == 0:
43 | if reply is not None:
44 | user_status = reply_member_status_object(update,context)
45 | user = reply.from_user
46 | row = GroupRepository().getById(chat.id)
47 | if user.id == bot.id:
48 | text = languages.ban_self_ban
49 |
50 | message(update,context,text)
51 | elif user_status.status == 'administrator' or user_status.status == 'creator':
52 | message(update,context,languages.ban_error_ac)
53 | else:
54 | if row['ban_message']:
55 | parsed_message = row['ban_message'].replace('{first_name}',
56 | user.first_name).replace('{chat}',
57 | update.message.chat.title).replace('{username}',
58 | "@"+user.username if user.username else user.first_name).replace('{mention}',mention_html(user.id, user.first_name)).replace('{userid}',str(user.id))
59 | ban_text = "{}".format(parsed_message)
60 | else:
61 | ban_text = languages.ban_message.format(
62 | user = reply.from_user.username or reply.from_user.first_name,
63 | userid = reply.from_user.id,
64 | chat = chat.title
65 | )
66 | #Log Ban
67 | logs_text = Strings.BAN_LOG.format(
68 | username = reply.from_user.username or reply.from_user.first_name,
69 | id = reply.from_user.id,
70 | chat = chat.title
71 | )
72 |
73 | delete_message_reply(update,context)
74 | ban_user_reply(update,context)
75 | message(update,context,ban_text)
76 | telegram_loggers(update,context,logs_text)
77 |
78 | formatter = "Ban eseguito da: {} nella chat {}".format(
79 | update.message.from_user.id,
80 | chat.title)
81 |
82 | sys_loggers("[BAN_LOGS]",formatter,False,True)
83 | else:
84 | ban_argument = update.message.text[5:]
85 |
86 | is_user_id = Try.of(lambda: int(ban_argument)).valueOf() is not None
87 |
88 | if ban_argument[0] == '@':
89 | username = ban_argument
90 |
91 | Try.of(lambda: ban_user_by_username(update, context, username)) \
92 | .catch(lambda err: ban_error(update, context, username = username)) \
93 | .map(lambda x : ban_success(update, context, username = username))
94 | elif is_user_id:
95 | userid = ban_argument
96 |
97 | Try.of(lambda: ban_user_by_id(update, context, userid)) \
98 | .catch(lambda err: ban_error(update, context, id = userid)) \
99 | .map(lambda x : ban_success(update, context, id = userid))
100 | else:
101 | message(
102 | update,
103 | context,
104 | languages.ban_syntax_error.format(ban_argument)
105 | )
106 | return
107 | else:
108 | return
109 |
110 | @decorators.admin.user_admin
111 | @decorators.delete.init
112 | def set_ban_message(update, context):
113 | languages(update,context)
114 | record = GroupRepository.BAN_MESSAGE
115 | chat = update.effective_chat.id
116 | msg = update.message.text[7:]
117 | reply = update.message.reply_to_message
118 | if reply:
119 | ban_text = str(reply.text).lower()
120 | data = [(ban_text, chat)]
121 | GroupRepository().update_group_settings(record, data)
122 | message(update,context, languages.set_ban_message)
123 | else:
124 | if msg != "":
125 | data = [(msg, chat)]
126 | GroupRepository().update_group_settings(record, data)
127 | message(update, context, languages.set_ban_message)
128 | else:
129 | message(update, context, languages.ban_error_empty)
--------------------------------------------------------------------------------
/core/commands/admin/check_permission.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | from core import decorators
6 | from core.utilities.functions import bot_object
7 | from core.utilities.message import message
8 | from languages.getLang import languages
9 |
10 | @decorators.admin.user_admin
11 | @decorators.public.init
12 | def init(update, context):
13 | bot = bot_object(update, context)
14 | chat_id = update.message.chat_id
15 | get_bot = bot.getChatMember(chat_id,bot.id)
16 | languages(update,context)
17 |
18 | perm_delete = get_bot.can_delete_messages
19 | perm_ban = get_bot.can_restrict_members
20 | perm_pin = get_bot.can_pin_messages
21 | perm_edit_msg = get_bot.can_be_edited
22 | perm_media = get_bot.can_send_media_messages
23 | perm_send_message = get_bot.can_send_messages
24 | if None in [perm_delete, perm_ban, perm_pin, perm_edit_msg, perm_media, perm_send_message]:
25 | message(update,context, languages.perm_error)
26 | else:
27 | message(update, context, languages.perm_ok)
--------------------------------------------------------------------------------
/core/commands/admin/dashboard.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | import datetime
7 | from core.utilities.functions import member_status_object, chat_status_object
8 | from core.database.repository.dashboard import DashboardRepository
9 | from core.utilities.message import message
10 |
11 | def init(update,context):
12 | reply = update.message.reply_to_message
13 | if reply:
14 | message(update,context,"Questo comando al momento non può essere utilizzato in risposta ad un messaggio!")
15 | else:
16 | user_status = member_status_object(update,context)
17 | chat_status = chat_status_object(update, context)
18 | if user_status.status == 'creator' or user_status.status == 'administrator':
19 | user = user_status.user
20 | username = "@"+user.username
21 | save_date = datetime.datetime.utcnow().isoformat()
22 | row = DashboardRepository().getById(user.id)
23 | if row:
24 | if row['enable'] == 0:
25 | message(update,context,"Mi dispiace sei stato disabilitato a questa funzionalità, Contatta un amministratore su: https://t.me/nebulabot_support")
26 | else:
27 | get_group_dashboard = DashboardRepository().getUserAndGroup((chat_status.id,user.id))
28 | if get_group_dashboard:
29 | data = [(username, user_status.status, save_date, user.id, chat_status.id)]
30 | DashboardRepository().update(data)
31 | message(update,context,"Ho aggiornato i tuoi dati sul database!")
32 | else:
33 | data_add = [(user.id,username,chat_status.id,1,user_status.status,save_date,save_date)]
34 | DashboardRepository().add(data_add)
35 | message(update,context,"Ho aggiornato i tuoi dati sul database! e ho inserito {} nella Dashboard\n\nEsegui il login su: https://nebula.squirrel-network.online".format(chat_status.title))
36 | else:
37 | data = [(user.id,username,chat_status.id,1,user_status.status,save_date,save_date)]
38 | DashboardRepository().add(data)
39 | message(update,context,"{} hai eseguito la prima abilitazione alla dashboard di Nebula \n\nEsegui il login su: https://nebula.squirrel-network.online".format(username))
40 | else:
41 | msg = "Non sei amministratore o proprietario del gruppo non puoi usare questo comando!"
42 | message(update,context,msg)
--------------------------------------------------------------------------------
/core/commands/admin/delete_message.py:
--------------------------------------------------------------------------------
1 | from core import decorators
2 | from languages.getLang import languages
3 | from core.utilities.functions import delete_message_reply
4 | from core.utilities.message import message
5 |
6 | @decorators.admin.user_admin
7 | @decorators.bot.check_is_admin
8 | @decorators.bot.check_can_delete
9 | @decorators.delete.init
10 | def init(update,context):
11 | languages(update,context)
12 | reply = update.message.reply_to_message
13 | if reply is not None:
14 | delete_message_reply(update,context)
15 | else:
16 | message(update, context, languages.delete_error_msg)
--------------------------------------------------------------------------------
/core/commands/admin/filters.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | from core import decorators
6 | from core.utilities.menu import build_menu
7 | from core.utilities.functions import update_db_settings
8 | from telegram import InlineKeyboardButton, InlineKeyboardMarkup
9 | from core.database.repository.group import GroupRepository
10 |
11 | def keyboard_filters(update,context,editkeyboard = False):
12 | bot = context.bot
13 | chat = update.message.chat_id
14 | chat_title = update.message.chat.title
15 | group = GroupRepository().getById(chat)
16 | list_buttons = []
17 | list_buttons.append(InlineKeyboardButton('❇️ Activate All', callback_data='ffseall'))
18 | list_buttons.append(InlineKeyboardButton('⛔️ Deactivate All', callback_data='ffdeall'))
19 | list_buttons.append(InlineKeyboardButton('Exe Filters %s' % ('✅' if group['exe_filter'] == 1 else '❌'), callback_data='ffexe_filters'))
20 | list_buttons.append(InlineKeyboardButton('GIF Filters %s' % ('✅' if group['gif_filter'] == 1 else '❌'), callback_data='ffgif_filters'))
21 | list_buttons.append(InlineKeyboardButton('Zip Filters %s' % ('✅' if group['zip_filter'] == 1 else '❌'), callback_data='ffzip_filters'))
22 | list_buttons.append(InlineKeyboardButton('TarGZ Filters %s' % ('✅' if group['targz_filter'] == 1 else '❌'), callback_data='fftargz_filters'))
23 | list_buttons.append(InlineKeyboardButton('JPG Filters %s' % ('✅' if group['jpg_filter'] == 1 else '❌'), callback_data='ffjpg_filters'))
24 | list_buttons.append(InlineKeyboardButton('Doc/x Filters %s' % ('✅' if group['docx_filter'] == 1 else '❌'), callback_data='ffdocx_filters'))
25 | list_buttons.append(InlineKeyboardButton('Apk Filters %s' % ('✅' if group['apk_filter'] == 1 else '❌'), callback_data='ffapk_filters'))
26 | list_buttons.append(InlineKeyboardButton("Close", callback_data='closeMenu'))
27 | menu = build_menu(list_buttons,2)
28 | if editkeyboard == False:
29 | keyboard_menu = bot.send_message(chat,"⚙️ Group Filters Settings\n\n📜 Group Name: {}\n🏷 ChatId: {}
".format(chat_title,chat),reply_markup=InlineKeyboardMarkup(menu),parse_mode='HTML')
30 | if editkeyboard == True:
31 | keyboard_menu = bot.edit_message_reply_markup(chat,update.message.message_id,reply_markup=InlineKeyboardMarkup(menu))
32 | return keyboard_menu
33 |
34 | @decorators.public.init
35 | @decorators.admin.user_admin
36 | @decorators.bot.check_is_admin
37 | @decorators.delete.init
38 | def init(update,context):
39 | keyboard_filters(update,context)
40 |
41 | @decorators.admin.user_admin
42 | def update_filters(update,context):
43 | query = update.callback_query
44 | chat = update.effective_message.chat_id
45 | group = GroupRepository().getById(chat)
46 | ###################################
47 | #### SET CHAT FILTERS ####
48 | ###################################
49 | if query.data.startswith("ff"):
50 | txt = query.data[2:]
51 | if txt == 'exe_filters':
52 | record = GroupRepository.EXE_FILTER
53 | row = group['exe_filter']
54 | if row == 0:
55 | update_db_settings(update, record, False)
56 | return keyboard_filters(query,context,True)
57 | else:
58 | update_db_settings(update, record, True)
59 | return keyboard_filters(query,context,True)
60 | if txt == 'zip_filters':
61 | record = GroupRepository.ZIP_FILTER
62 | row = group["zip_filter"]
63 | if row == 0:
64 | update_db_settings(update, record, False)
65 | return keyboard_filters(query,context,True)
66 | else:
67 | update_db_settings(update, record, True)
68 | return keyboard_filters(query,context,True)
69 |
70 | if txt== 'targz_filters':
71 | record = GroupRepository.TARGZ_FILTER
72 | row = group["targz_filter"]
73 | if row == 0:
74 | update_db_settings(update, record, False)
75 | return keyboard_filters(query,context,True)
76 | else:
77 | update_db_settings(update, record, True)
78 | return keyboard_filters(query,context,True)
79 |
80 | if txt == 'gif_filters':
81 | record = GroupRepository.GIF_FILTER
82 | row = group['gif_filter']
83 | if row == 0:
84 | update_db_settings(update, record, False)
85 | return keyboard_filters(query,context,True)
86 | else:
87 | update_db_settings(update, record, True)
88 | return keyboard_filters(query,context,True)
89 |
90 | if txt == 'jpg_filters':
91 | record = GroupRepository.JPG_FILTER
92 | row = group['jpg_filter']
93 | if row == 0:
94 | update_db_settings(update, record, False)
95 | return keyboard_filters(query,context,True)
96 | else:
97 | update_db_settings(update, record, True)
98 | return keyboard_filters(query,context,True)
99 |
100 | if txt == 'docx_filters':
101 | record = GroupRepository.DOCX_FILTER
102 | row = group['docx_filter']
103 | if row == 0:
104 | update_db_settings(update, record, False)
105 | return keyboard_filters(query,context,True)
106 | else:
107 | update_db_settings(update, record, True)
108 | return keyboard_filters(query,context,True)
109 |
110 | if txt == 'apk_filters':
111 | record = GroupRepository.APK_FILTER
112 | row = group['apk_filter']
113 | if row == 0:
114 | update_db_settings(update, record, False)
115 | return keyboard_filters(query,context,True)
116 | else:
117 | update_db_settings(update, record, True)
118 | return keyboard_filters(query,context,True)
119 |
120 | if txt == 'seall':
121 | record_TARGZ = GroupRepository.TARGZ_FILTER
122 | record_ZIP = GroupRepository.ZIP_FILTER
123 | record_EXE = GroupRepository.EXE_FILTER
124 | record_JPG = GroupRepository.JPG_FILTER
125 | record_APK = GroupRepository.APK_FILTER
126 | record_GIF = GroupRepository.GIF_FILTER
127 | record_DOCX = GroupRepository.DOCX_FILTER
128 |
129 | update_db_settings(update, record_TARGZ, False)
130 | update_db_settings(update, record_ZIP, False)
131 | update_db_settings(update, record_EXE, False)
132 | update_db_settings(update, record_JPG, False)
133 | update_db_settings(update, record_APK, False)
134 | update_db_settings(update, record_GIF, False)
135 | update_db_settings(update, record_DOCX, False)
136 | return keyboard_filters(query,context,True)
137 |
138 | if txt == 'deall':
139 | record_TARGZ = GroupRepository.TARGZ_FILTER
140 | record_ZIP = GroupRepository.ZIP_FILTER
141 | record_EXE = GroupRepository.EXE_FILTER
142 | record_JPG = GroupRepository.JPG_FILTER
143 | record_APK = GroupRepository.APK_FILTER
144 | record_GIF = GroupRepository.GIF_FILTER
145 | record_DOCX = GroupRepository.DOCX_FILTER
146 |
147 | update_db_settings(update, record_TARGZ, True)
148 | update_db_settings(update, record_ZIP, True)
149 | update_db_settings(update, record_EXE, True)
150 | update_db_settings(update, record_JPG, True)
151 | update_db_settings(update, record_APK, True)
152 | update_db_settings(update, record_GIF, True)
153 | update_db_settings(update, record_DOCX, True)
154 | return keyboard_filters(query,context,True)
155 |
--------------------------------------------------------------------------------
/core/commands/admin/greport.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | from core import decorators
6 | from languages.getLang import languages
7 | from core.utilities.message import message
8 | from core.utilities.functions import chat_object
9 | from core.handlers.logs import staff_loggers
10 |
11 | @decorators.public.init
12 | @decorators.admin.user_admin
13 | @decorators.delete.init
14 | def init(update, context):
15 | bot = context.bot
16 | chat = chat_object(update)
17 | languages(update,context)
18 | if update.effective_message.reply_to_message:
19 | message(update, context, languages.delete_error_msg)
20 | else:
21 | link = bot.export_chat_invite_link(chat.id)
22 | msg = "#GlobalReport\nChatId: {}\nChat: {}\nLink: {}".format(chat.id, chat.title, link)
23 | msg_report = languages.global_report_msg
24 | staff_loggers(update, context, msg)
25 | message(update, context, msg_report)
--------------------------------------------------------------------------------
/core/commands/admin/info_group.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | import time
6 | import calendar
7 | from core.database.repository.group import GroupRepository
8 | from languages.getLang import languages
9 | from core.utilities.message import message
10 | from core.utilities.functions import save_group
11 | from core import decorators
12 |
13 | @decorators.admin.user_admin
14 | @decorators.bot.check_is_admin
15 | @decorators.public.init
16 | @decorators.bot.check_can_delete
17 | @decorators.delete.init
18 | def init(update, context):
19 | languages(update,context)
20 | chat = update.effective_message.chat_id
21 | chat_title = update.effective_chat.title
22 | record = GroupRepository.SET_GROUP_NAME
23 | row = GroupRepository().getById([chat])
24 | if row:
25 | current_GMT = time.gmtime()
26 | ts = calendar.timegm(current_GMT)
27 | data = [(chat_title, chat)]
28 | GroupRepository().update_group_settings(record, data)
29 | counter = GroupRepository().getUpdatesByChatMonth(chat)
30 | img = "{}?v={}".format(row['group_photo'],ts)
31 | caption = languages.group_info.format(
32 | row['group_name'],
33 | row['id_group'],
34 | row['languages'],
35 | row['max_warn'],
36 | row['total_users'],
37 | counter['counter'])
38 | message(update, context, caption, 'HTML', 'photo', None, img)
39 | else:
40 | save_group(update)
41 |
42 | @decorators.admin.user_admin
43 | @decorators.delete.init
44 | def id_chat(update,context):
45 | chat = update.effective_message.chat_id
46 | message(update,context,"⚙️ Chat Id:\n🏷 [{}
]\n\nFor more information on the group type /status".format(chat))
--------------------------------------------------------------------------------
/core/commands/admin/mute.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | import re
7 | from core import decorators
8 | from core.utilities.regex import Regex
9 | from languages.getLang import languages
10 | from core.utilities.message import message
11 | from core.utilities.menu import build_menu
12 | from telegram.utils.helpers import mention_html
13 | from core.database.repository.group import GroupRepository
14 | from telegram import InlineKeyboardButton, InlineKeyboardMarkup
15 | from core.utilities.functions import mute_user_reply, mute_user_by_id, mute_user_by_id_time, mute_user_by_username_time, chat_object
16 |
17 | def convert_time(update,context,time_args):
18 | if time_args == "1d":
19 | time_args = int(86400)
20 | elif time_args == "3d":
21 | time_args = int(259200)
22 | elif time_args == "7d":
23 | time_args = int(604800)
24 | elif time_args == "1h":
25 | time_args = int(3600)
26 | elif time_args == "30s":
27 | time_args = int(30)
28 | else:
29 | error_msg = "You must enter a valid time value for the bot among the following: 1d, 3d, 7d, 1h, 30s
"
30 | message(update,context,error_msg)
31 | return int(time_args)
32 |
33 | def mute_message(user,time):
34 | message = '🔇 You muted the user {}\n[{}
]\n\nfor {}
Time'.format(mention_html(user.id, user.first_name),user.id,time)
35 | return message
36 |
37 | @decorators.admin.user_admin
38 | @decorators.delete.init
39 | def init(update,context):
40 | languages(update,context)
41 | chat = chat_object(update)
42 | row = GroupRepository().getById(chat.id)
43 | if row['set_gh'] == 0:
44 | if update.message.reply_to_message:
45 | user = update.message.reply_to_message.from_user
46 | buttons = []
47 | buttons.append(InlineKeyboardButton(languages.mute_button, callback_data='CMunmute'))
48 | buttons.append(InlineKeyboardButton('30Sec', callback_data='CM30'))
49 | buttons.append(InlineKeyboardButton('1 Hour', callback_data='CM3600'))
50 | buttons.append(InlineKeyboardButton('1 Day', callback_data='CM86400'))
51 | buttons.append(InlineKeyboardButton('3 Days', callback_data='CM259200'))
52 | buttons.append(InlineKeyboardButton('7 Days', callback_data='CM604800'))
53 | buttons.append(InlineKeyboardButton('Forever', callback_data='CMforever'))
54 | menu = build_menu(buttons,2)
55 | msg = languages.mute_msg.format(user.id,user.first_name,user.id)
56 | update.message.reply_to_message.reply_text(msg, reply_markup=InlineKeyboardMarkup(menu),parse_mode='HTML')
57 | mute_user_reply(update,context,True)
58 | else:
59 | text = update.message.text
60 | input_user_id = text[5:].strip().split(" ", 1)
61 | user_id = input_user_id[0]
62 | time_args = input_user_id[1]
63 | if user_id != "" and time_args != "":
64 | #Mute via Username es: /mute @username 1d
65 | if user_id.startswith('@'):
66 | time_args = input_user_id[1]
67 | arg_time = convert_time(update,context,time_args)
68 | mute_user_by_username_time(update,context,user_id,True,arg_time)
69 | msg = '🔇 You muted the user {} for {}
time'.format(user_id,time_args)
70 | message(update,context,msg)
71 | else:
72 | #Mute via Id es: /mute 1234568 1d
73 | time_args = input_user_id[1]
74 | number = re.search(Regex.HAS_NUMBER, user_id)
75 | if number is None:
76 | message(update,context,"Type a correct telegram id or type in the username!")
77 | else:
78 | mute_user_by_id_time(update,context,user_id,True,int(time_args))
79 | msg = '🔇 You muted the user {} [{}]
for {}
time'.format(user_id,user_id,user_id,time_args)
80 | message(update,context,msg)
81 | else:
82 | message(update,context,"Attention you have not entered the user id and mute time correctly")
83 | else:
84 | return
85 |
86 | @decorators.admin.user_admin
87 | def update_mute(update,context):
88 | query = update.callback_query
89 | user = query.message.reply_to_message.from_user
90 | if query.data.startswith("CM"):
91 | txt = query.data[2:]
92 | if txt == "30":
93 | mute_user_by_id_time(update,context,user.id,True,int(txt))
94 | query.edit_message_text(mute_message(user,txt), parse_mode='HTML')
95 | if txt == "3600":
96 | mute_user_by_id_time(update,context,user.id,True,int(txt))
97 | query.edit_message_text(mute_message(user,'1 Hour'), parse_mode='HTML')
98 | if txt == "86400":
99 | mute_user_by_id_time(update,context,user.id,True,int(txt))
100 | query.edit_message_text(mute_message(user,'1 Day'), parse_mode='HTML')
101 | if txt == "259200":
102 | mute_user_by_id_time(update,context,user.id,True,int(txt))
103 | query.edit_message_text(mute_message(user,'3 Days'), parse_mode='HTML')
104 | if txt == "604800":
105 | mute_user_by_id_time(update,context,user.id,True,int(txt))
106 | query.edit_message_text(mute_message(user,'7 Days'), parse_mode='HTML')
107 | if txt == "forever":
108 | mute_user_by_id(update,context,user.id,True)
109 | query.edit_message_text(mute_message(user,'Forever'), parse_mode='HTML')
110 | if txt == 'unmute':
111 | languages(update,context)
112 | mute_user_by_id(update,context,user.id,False)
113 | msg = languages.mute_msg_r.format(user.id,user.first_name,user.id)
114 | query.edit_message_text(msg, parse_mode='HTML')
--------------------------------------------------------------------------------
/core/commands/admin/pin.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | from core import decorators
7 | from core.utilities.message import message
8 |
9 | @decorators.admin.user_admin
10 | @decorators.delete.init
11 | def pin(update,context):
12 | bot = context.bot
13 | reply = update.message.reply_to_message
14 | if reply:
15 | msg = str(reply.text).strip()
16 | if reply.photo:
17 | caption = update.message.reply_to_message.caption
18 | update.message.reply_to_message.reply_photo(photo=reply.photo[-1].file_id, caption=caption)
19 | bot.pin_chat_message(update.message.chat_id, update.message.message_id+1,disable_notification=True)
20 | else:
21 | message(update,context,msg)
22 | bot.pin_chat_message(update.message.chat_id, update.message.message_id+1,disable_notification=True)
23 | else:
24 | msg = update.message.text[4:].strip()
25 | message(update,context,msg)
26 | bot.pin_chat_message(update.message.chat_id, update.message.message_id+1,disable_notification=True)
27 |
28 | @decorators.admin.user_admin
29 | @decorators.delete.init
30 | def unpin_all(update, context):
31 | bot = context.bot
32 | bot.unpin_all_chat_messages(chat_id=update.effective_chat.id)
33 | message(update,context,"All messages have been Unpinned!")
--------------------------------------------------------------------------------
/core/commands/admin/promote.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | from telegram.error import BadRequest
7 | from core import decorators
8 | from core.utilities.message import message
9 | from core.utilities.functions import bot_object, chat_object, user_reply_object
10 | from languages.getLang import languages
11 |
12 | @decorators.admin.user_admin
13 | def init(update,context):
14 | try:
15 | languages(update,context)
16 | if update.message.reply_to_message:
17 | bot = bot_object(update,context)
18 | chat = chat_object(update)
19 | user = user_reply_object(update)
20 | bot.promoteChatMember(chat.id,user.id,
21 | can_change_info=True,
22 | can_delete_messages=True,
23 | can_invite_users=True,
24 | can_restrict_members=True,
25 | can_pin_messages=True,
26 | can_promote_members=True
27 | )
28 | else:
29 | message(update,context,languages.delete_error_msg)
30 | except BadRequest:
31 | message(update,context,text="Non ho il permesso per promuovere questo utente come admin!\nPuoi darmi questo permesso spuntando il flag:\n Aggiungere Amministratori")
--------------------------------------------------------------------------------
/core/commands/admin/say.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | from core import decorators
6 | from languages.getLang import languages
7 | from core.utilities.message import message
8 |
9 | @decorators.admin.user_admin
10 | @decorators.bot.check_can_delete
11 | @decorators.delete.init
12 | def init(update,context):
13 | languages(update,context)
14 | msg = update.message.text[4:].strip()
15 | if msg != "":
16 | message(update, context, msg, 'HTML', 'message', None, None)
17 | else:
18 | message(update, context, languages.say_error, 'HTML', 'message', None, None)
--------------------------------------------------------------------------------
/core/commands/admin/set_custom_handler.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | from core import decorators
7 | from core.utilities.message import message
8 | from core.utilities.functions import chat_object
9 | from core.database.repository.group import GroupRepository
10 |
11 | @decorators.admin.user_admin
12 | @decorators.delete.init
13 | def init(update, context):
14 | chat = chat_object(update)
15 | msg = update.message.text[7:]
16 | reply = update.message.reply_to_message
17 | if reply:
18 | custom_question = str(reply.text)
19 | if custom_question == '/test':
20 | message(update, context, 'This command is reserved for the bot!')
21 | else:
22 | custom_answer = str(msg).lower()
23 | data = [(chat.id,custom_question,custom_answer)]
24 | GroupRepository().insert_custom_handler(data)
25 | message(update,context,"Custom handler setted!\n\nQuestion: {}
\nAnswer: {}
".format(custom_question,custom_answer))
26 | else:
27 | message(update,context,"You must reply to a message to use this command!")
--------------------------------------------------------------------------------
/core/commands/admin/set_lang.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | from core import decorators
6 | from core.database.repository.group import GroupRepository
7 | from telegram import InlineKeyboardButton, InlineKeyboardMarkup
8 | from core.utilities.message import message
9 | from core.utilities.functions import flag
10 |
11 | LANGUAGE_KEYBOARD = [[
12 | InlineKeyboardButton(flag('gb'), callback_data='language_en'),
13 | InlineKeyboardButton(flag('it'), callback_data='language_it')
14 | ]]
15 |
16 | record = GroupRepository.SET_LANGUAGE
17 |
18 | @decorators.admin.user_admin
19 | def init(update,context):
20 | reply_markup = InlineKeyboardMarkup(LANGUAGE_KEYBOARD)
21 | msg = "Please select your preferred language\n\nPerfavore seleziona la tua lingua di preferenza"
22 | message(update,context,msg,reply_markup=reply_markup)
23 |
24 | @decorators.admin.user_admin
25 | def language_en(update, context):
26 | chat = update.effective_message.chat_id
27 | msg = "You have selected the English language for your group"
28 | query = update.callback_query
29 | query.answer()
30 | lang = "EN"
31 | data = [(lang,chat)]
32 | GroupRepository().update_group_settings(record, data)
33 | query.edit_message_text(msg,parse_mode='HTML')
34 |
35 | @decorators.admin.user_admin
36 | def language_it(update, context):
37 | chat = update.effective_message.chat_id
38 | msg = "Hai selezionato la lingua italiana per il tuo gruppo"
39 | query = update.callback_query
40 | query.answer()
41 | lang = "IT"
42 | data = [(lang,chat)]
43 | GroupRepository().update_group_settings(record, data)
44 | query.edit_message_text(msg,parse_mode='HTML')
--------------------------------------------------------------------------------
/core/commands/admin/set_rules.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | from core import decorators
7 | from core.utilities.message import message
8 | from languages.getLang import languages
9 | from core.database.repository.group import GroupRepository
10 |
11 | @decorators.admin.user_admin
12 | @decorators.delete.init
13 | def init(update, context):
14 | record = GroupRepository.SET_RULES_TEXT
15 | chat = update.effective_chat.id
16 | msg = update.message.text[9:].strip()
17 | languages(update,context)
18 | if msg != "":
19 | data = [(msg, chat)]
20 | GroupRepository().update_group_settings(record, data)
21 | message(update, context, languages.rules_msg)
22 | else:
23 | message(update, context, languages.rules_error_msg)
--------------------------------------------------------------------------------
/core/commands/admin/set_welcome.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | from core import decorators
7 | from core.utilities.message import message
8 | from languages.getLang import languages
9 | from core.database.repository.group import GroupRepository
10 | from telegram import InlineKeyboardButton, InlineKeyboardMarkup
11 | from core.utilities.menu import build_menu
12 | import json
13 |
14 | def _remove_button(group_id, btn_id):
15 | """
16 | group_id, int indicating the id of the group
17 | btn_id, json button id to remove
18 | """
19 | # select
20 | group_record = GroupRepository().getById(group_id)
21 | welcome_btns = group_record['welcome_buttons']
22 | welcome_btns = json.loads(welcome_btns)['buttons']
23 |
24 | new_welcome_btns = [btn for btn in welcome_btns if btn['id'] != int(btn_id)]
25 |
26 | # insert
27 | welcome_btns_text = json.dumps({"buttons": new_welcome_btns})
28 | GroupRepository().updateWelcomeButtonsByGroupId(group_id, welcome_btns_text)
29 |
30 | def _add_button(group_id, btn):
31 | """
32 | group_id, int indicating the id of the group
33 | btn, dict representing a json button
34 | """
35 | # select
36 | group_record = GroupRepository().getById(group_id)
37 | welcome_btns = group_record['welcome_buttons']
38 | welcome_btns = (json.loads(welcome_btns))['buttons']
39 |
40 | # add
41 | if len(welcome_btns) == 0:
42 | btn['id'] = 0
43 | else:
44 | btn['id'] = welcome_btns[-1]['id'] + 1
45 |
46 | welcome_btns.append(btn)
47 |
48 | # insert
49 | welcome_btns_text = json.dumps({"buttons": welcome_btns})
50 | GroupRepository().updateWelcomeButtonsByGroupId(group_id, welcome_btns_text)
51 |
52 | @decorators.admin.user_admin
53 | @decorators.delete.init
54 | def set_welcome_buttons(update, context):
55 | try:
56 | cmd_args = update.message.text[16:].strip().split()
57 | action = cmd_args[0]
58 | group_id = update.effective_chat.id
59 |
60 | # Add Welcome Buttons /welcomebuttons add "title" "url"
61 | if action == 'add':
62 | title = cmd_args[1][1:-1]
63 | url = cmd_args[2][1:-1]
64 | button = {'title': title, 'url': url}
65 |
66 | _add_button(group_id, button)
67 | message(update, context, "You have added a button to the welcome!")
68 | # Remove Welcome Buttons /welcomebuttons remove "buttonid"
69 | elif action == 'remove':
70 | button_id = cmd_args[1][1:-1]
71 | _remove_button(group_id, button_id)
72 | message(update, context, "You have removed the button with id: {}
".format(button_id))
73 | # If no action has been taken, this error is returned
74 | else:
75 | message(update, context, "The action you requested is incorrect type add
or remove
")
76 | except IndexError:
77 | # List Welcome Buttons /welcomebuttons with no args
78 | chat = update.effective_message.chat_id
79 | buttons = GroupRepository().getById(chat)
80 | welcome_buttons = buttons['welcome_buttons']
81 | format_json = json.loads(welcome_buttons)
82 | x = format_json['buttons']
83 | options = ""
84 | for a in x:
85 | if 'id' in a:
86 | button_id = a['id']
87 | else:
88 | button_id = -1
89 | title = a['title']
90 | url = a['url']
91 | options += "Button Id: {}
\n".format(button_id)
92 | options += "Button Text: {}\n".format(title)
93 | options += "Button Url: {}
\n\n\n".format(url)
94 | message(update, context, options)
95 |
96 | @decorators.admin.user_admin
97 | @decorators.delete.init
98 | def init(update, context):
99 | languages(update,context)
100 | record = GroupRepository.SET_WELCOME_TEXT
101 | chat = update.effective_chat.id
102 | msg = update.message.text[8:].strip()
103 | reply = update.message.reply_to_message
104 | if reply:
105 | welcome_text = str(reply.text).lower()
106 | data = [(welcome_text, chat)]
107 | GroupRepository().update_group_settings(record, data)
108 | message(update,context, text="Welcome impostato!")
109 | else:
110 | if msg != "":
111 | data = [(msg, chat)]
112 | GroupRepository().update_group_settings(record, data)
113 | message(update, context, languages.set_welcome_help)
114 | else:
115 | message(update, context, languages.set_welcome_main)
116 |
117 |
118 | @decorators.admin.user_admin
119 | @decorators.delete.init
120 | def set_type_no_username(update, context):
121 | bot = context.bot
122 | chat = update.effective_message.chat_id
123 | buttons = []
124 | buttons.append(InlineKeyboardButton('Kick Only', callback_data='tpnu1'))
125 | buttons.append(InlineKeyboardButton('Message Only', callback_data='tpnu2'))
126 | buttons.append(InlineKeyboardButton('Mute Only', callback_data='tpnu3'))
127 | buttons.append(InlineKeyboardButton('Ban Only', callback_data='tpnu4'))
128 | buttons.append(InlineKeyboardButton('Silent Kick', callback_data='tpnu5'))
129 | buttons.append(InlineKeyboardButton('No action', callback_data='tpnu6'))
130 | buttons.append(InlineKeyboardButton('Close', callback_data='closeMenu'))
131 | menu = build_menu(buttons,3)
132 | bot.send_message(chat,"No Username Filter Settings\nThe message is always present except for the Silent Kick and No Action", reply_markup=InlineKeyboardMarkup(menu),parse_mode='HTML')
133 |
134 |
135 | @decorators.admin.user_admin
136 | def update_set_tpnu(update, context):
137 | query = update.callback_query
138 | if query.data.startswith("tpnu"):
139 | chat_id = query.message.chat_id
140 | tpnu_set = query.data[4:]
141 | record = GroupRepository.SET_TPNU
142 | data = [(tpnu_set,chat_id)]
143 | GroupRepository().update_group_settings(record, data)
144 | text = "You have set the filter to {}
\nLegend:\n1 == Kick\n2 == Message\n3 == Mute\n4 == Ban\n5 == Silent Kick\n6 == No Action
".format(tpnu_set)
145 | query.edit_message_text(text, parse_mode='HTML')
146 |
--------------------------------------------------------------------------------
/core/commands/admin/settings.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | from core import decorators
6 | from languages.getLang import languages
7 | from core.commands.admin import set_lang
8 | from core.utilities.menu import build_menu
9 | from core.utilities.functions import update_db_settings, save_group
10 | from core.utilities.constants import PERM_TRUE, PERM_FALSE
11 | from core.utilities.message import message
12 | from telegram import InlineKeyboardButton, InlineKeyboardMarkup
13 | from core.database.repository.group import GroupRepository
14 |
15 | def keyboard_settings(update,context,editkeyboard = False):
16 | bot = context.bot
17 | chat = update.message.chat_id
18 | chat_title = update.message.chat.title
19 | group = GroupRepository().getById(chat)
20 | if group:
21 | list_buttons = []
22 | list_buttons.append(InlineKeyboardButton('%s Welcome 👋🏻' % ('✅' if group['set_welcome'] == 1 else '❌'), callback_data='setWelcome'))
23 | list_buttons.append(InlineKeyboardButton('%s Silence 🤫' % ('✅' if group['set_silence'] == 1 else '❌'), callback_data='setSilence'))
24 | list_buttons.append(InlineKeyboardButton('%s Deny All Entry 🚷' % ('✅' if group['block_new_member'] == 1 else '❌'), callback_data='setBlockEntry'))
25 | list_buttons.append(InlineKeyboardButton('%s AntiFlood 🚫' % ('✅' if group['set_antiflood'] == 1 else '❌'), callback_data='setAntiflood'))
26 | list_buttons.append(InlineKeyboardButton('%s No User Photo Entry ⛔️' % ('✅' if group['set_user_profile_picture'] == 1 else '❌'), callback_data='userPhoto'))
27 | list_buttons.append(InlineKeyboardButton('%s No Arabic Entry ⛔️' % ('✅' if group['set_arabic_filter'] == 1 else '❌'), callback_data='arabic'))
28 | list_buttons.append(InlineKeyboardButton('%s No Russian Entry ⛔️' % ('✅' if group['set_cirillic_filter'] == 1 else '❌'), callback_data='cirillic'))
29 | list_buttons.append(InlineKeyboardButton('%s No Chinese Entry ⛔️' % ('✅' if group['set_chinese_filter'] == 1 else '❌'), callback_data='chinese'))
30 | list_buttons.append(InlineKeyboardButton('%s No ZooPhile Entry ⛔️' % ('✅' if group['zoophile_filter'] == 1 else '❌'), callback_data='zoophile'))
31 | list_buttons.append(InlineKeyboardButton('%s Block Vocal ⛔️' % ('✅' if group['set_no_vocal'] == 1 else '❌'), callback_data='novocal'))
32 | list_buttons.append(InlineKeyboardButton('%s Block Channel 📢' % ('✅' if group['sender_chat_block'] == 1 else '❌'), callback_data='channelblock'))
33 | list_buttons.append(InlineKeyboardButton('%s Block Spoiler 🚫' % ('✅' if group['spoiler_block'] == 1 else '❌'), callback_data='spoilerblock'))
34 | list_buttons.append(InlineKeyboardButton('%s Live with GH 🤖' % ('✅' if group['set_gh'] == 1 else '❌'),callback_data='setgrouphelp'))
35 | list_buttons.append(InlineKeyboardButton('Languages 🌍', callback_data='lang'))
36 | list_buttons.append(InlineKeyboardButton('Commands', url='https://github.com/Squirrel-Network/nebula8/wiki/Command-List'))
37 | list_buttons.append(InlineKeyboardButton('Dashboard', url='https://nebula.squirrel-network.online'))
38 | list_buttons.append(InlineKeyboardButton("Close 🗑", callback_data='close'))
39 | menu = build_menu(list_buttons,2)
40 | if editkeyboard == False:
41 | keyboard_menu = message(update,context,"⚙️ Bot settings\n\n📜 Group Name: {}\n🏷 ChatId: {}
".format(chat_title,chat),reply_markup=InlineKeyboardMarkup(menu))
42 | if editkeyboard == True:
43 | keyboard_menu = bot.edit_message_reply_markup(chat,update.message.message_id,reply_markup=InlineKeyboardMarkup(menu))
44 | return keyboard_menu
45 | else:
46 | save_group(update)
47 |
48 | @decorators.public.init
49 | @decorators.admin.user_admin
50 | @decorators.bot.check_is_admin
51 | @decorators.delete.init
52 | def init(update,context):
53 | keyboard_settings(update,context)
54 |
55 | @decorators.admin.user_admin
56 | def update_settings(update,context):
57 | bot = context.bot
58 | languages(update,context)
59 | query = update.callback_query
60 | chat = update.effective_message.chat_id
61 | group = GroupRepository().getById(chat)
62 | # Set Welcome
63 | if query.data == 'setWelcome':
64 | record = GroupRepository.SET_WELCOME
65 | row = group['set_welcome']
66 | if row == 1:
67 | update_db_settings(update, record, True)
68 | return keyboard_settings(query,context,True)
69 | else:
70 | data_block = [(1,0,chat)]
71 | update_db_settings(update, record, False)
72 | GroupRepository().set_block_entry(data_block)
73 | return keyboard_settings(query,context,True)
74 | # Set Global Silence
75 | if query.data == 'setSilence':
76 | record = GroupRepository.SET_SILENCE
77 | row = group['set_silence']
78 | if row == 0:
79 | update_db_settings(update, record, False)
80 | bot.set_chat_permissions(update.effective_chat.id, PERM_FALSE)
81 | return keyboard_settings(query,context,True)
82 | else:
83 | update_db_settings(update, record, True)
84 | bot.set_chat_permissions(update.effective_chat.id, PERM_TRUE)
85 | return keyboard_settings(query,context,True)
86 | # Set Block Entry
87 | if query.data == 'setBlockEntry':
88 | row = group['block_new_member']
89 | if row == 0:
90 | data = [(0,1,chat)]
91 | GroupRepository().set_block_entry(data)
92 | return keyboard_settings(query,context,True)
93 | else:
94 | data = [(1,0,chat)]
95 | GroupRepository().set_block_entry(data)
96 | return keyboard_settings(query,context,True)
97 | if query.data == 'channelblock':
98 | record = GroupRepository.SENDER_CHAT_BLOCK
99 | row = group['sender_chat_block']
100 | if row == 1:
101 | update_db_settings(update, record, True)
102 | return keyboard_settings(query,context,True)
103 | else:
104 | update_db_settings(update, record, False)
105 | return keyboard_settings(query,context,True)
106 | if query.data == 'spoilerblock':
107 | record = GroupRepository.SPOILER_BLOCK
108 | row = group['spoiler_block']
109 | if row == 1:
110 | update_db_settings(update, record, True)
111 | return keyboard_settings(query,context,True)
112 | else:
113 | update_db_settings(update, record, False)
114 | return keyboard_settings(query,context,True)
115 |
116 | if query.data == 'novocal':
117 | record = GroupRepository.SET_NO_VOCAL
118 | row = group['set_no_vocal']
119 | if row == 1:
120 | update_db_settings(update, record, True)
121 | return keyboard_settings(query,context,True)
122 | else:
123 | update_db_settings(update, record, False)
124 | return keyboard_settings(query,context,True)
125 |
126 | if query.data == 'setAntiflood':
127 | record = GroupRepository.SET_ANTIFLOOD
128 | row = group['set_antiflood']
129 | if row == 1:
130 | update_db_settings(update, record, True)
131 | return keyboard_settings(query,context,True)
132 | else:
133 | update_db_settings(update, record, False)
134 | return keyboard_settings(query,context,True)
135 |
136 | if query.data == 'setgrouphelp':
137 | record = GroupRepository.SET_GH
138 | row = group['set_gh']
139 | if row == 1:
140 | update_db_settings(update, record, True)
141 | return keyboard_settings(query,context,True)
142 | else:
143 |
144 | update_db_settings(update, record, False)
145 | return keyboard_settings(query,context,True)
146 |
147 | ###################################
148 | #### SET WELCOME FILTERS ####
149 | ###################################
150 | # Set Block Arabic Entry
151 | if query.data == 'arabic':
152 | record = GroupRepository.SET_ARABIC
153 | row = group['set_arabic_filter']
154 | if row == 1:
155 | update_db_settings(update, record, True)
156 | return keyboard_settings(query,context,True)
157 | else:
158 | update_db_settings(update, record, False)
159 | return keyboard_settings(query,context,True)
160 | # Set Block Cirillic Entry
161 | if query.data == 'cirillic':
162 | record = GroupRepository.SET_CIRILLIC
163 | row = group['set_cirillic_filter']
164 | if row == 1:
165 | update_db_settings(update, record, True)
166 | return keyboard_settings(query,context,True)
167 | else:
168 | update_db_settings(update, record, False)
169 | return keyboard_settings(query,context,True)
170 | if query.data == 'chinese':
171 | record = GroupRepository.SET_CHINESE
172 | row = group['set_chinese_filter']
173 | if row == 1:
174 | update_db_settings(update, record, True)
175 | return keyboard_settings(query,context,True)
176 | else:
177 | update_db_settings(update, record, False)
178 | return keyboard_settings(query,context,True)
179 | if query.data == 'userPhoto':
180 | record = GroupRepository.SET_USER_PROFILE_PICT
181 | row = group['set_user_profile_picture']
182 | if row == 1:
183 | update_db_settings(update, record, True)
184 | return keyboard_settings(query,context,True)
185 | else:
186 | update_db_settings(update, record, False)
187 | return keyboard_settings(query,context,True)
188 | if query.data == 'zoophile':
189 | record = GroupRepository.ZOOPHILE_FILTER
190 | row = group['zoophile_filter']
191 | if row == 1:
192 | update_db_settings(update, record, True)
193 | return keyboard_settings(query,context,True)
194 | else:
195 | update_db_settings(update, record, False)
196 | return keyboard_settings(query,context,True)
197 | ###################################
198 | #### SET CHAT LANGUAGE ####
199 | ###################################
200 | if query.data == 'lang':
201 | set_lang.init(update, context)
202 | query.edit_message_text("You have closed the settings menu and open languages menu",parse_mode='HTML')
203 |
204 | # Close Menu
205 | if query.data == 'close':
206 | query.message.delete()
--------------------------------------------------------------------------------
/core/commands/admin/shield.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | from core import decorators
7 | from languages.getLang import languages
8 | from core.utilities.functions import chat_object,update_db_settings
9 | from core.database.repository.group import GroupRepository
10 | from core.utilities.constants import PERM_FALSE, PERM_TRUE
11 | from core.utilities.menu import build_menu
12 | from telegram import InlineKeyboardButton, InlineKeyboardMarkup
13 | from core.handlers.logs import telegram_loggers
14 |
15 | @decorators.admin.user_admin
16 | @decorators.delete.init
17 | def init(update, context):
18 | bot = context.bot
19 | chat = chat_object(update)
20 | languages(update,context)
21 | record_arabic = GroupRepository.SET_ARABIC
22 | record_chinese = GroupRepository.SET_CHINESE
23 | record_cirillic = GroupRepository.SET_CIRILLIC
24 | record_no_user_photo = GroupRepository.SET_USER_PROFILE_PICT
25 | record_silence = GroupRepository.SET_SILENCE
26 | record_block_channel = GroupRepository.SENDER_CHAT_BLOCK
27 | record_zoophile = GroupRepository.ZOOPHILE_FILTER
28 |
29 |
30 | data = [(0,1,chat.id)]
31 | GroupRepository().set_block_entry(data)
32 | update_db_settings(update, record_arabic, False)
33 | update_db_settings(update, record_chinese, False)
34 | update_db_settings(update, record_cirillic, False)
35 | update_db_settings(update, record_no_user_photo, False)
36 | update_db_settings(update, record_silence, False)
37 | update_db_settings(update, record_block_channel, False)
38 | update_db_settings(update, record_zoophile, False)
39 | buttons = []
40 | buttons.append(InlineKeyboardButton('❌ Remove Shield', callback_data='removeShield'))
41 | menu = build_menu(buttons,1)
42 |
43 | bot.set_chat_permissions(update.effective_chat.id, PERM_FALSE)
44 | bot.send_message(chat.id,languages.shield_on,reply_markup=InlineKeyboardMarkup(menu),parse_mode='HTML')
45 | logs_text = '🛡Shield Activated in {} [{}]
'.format(chat.title,chat.id)
46 | telegram_loggers(update,context,logs_text)
47 |
48 | @decorators.admin.user_admin
49 | def update_shield(update,context):
50 | bot = context.bot
51 | query = update.callback_query
52 | if query.data == 'removeShield':
53 | chat = update.effective_message.chat_id
54 | chat_title = update.effective_message.chat.title
55 | record_arabic = GroupRepository.SET_ARABIC
56 | record_chinese = GroupRepository.SET_CHINESE
57 | record_cirillic = GroupRepository.SET_CIRILLIC
58 | record_no_user_photo = GroupRepository.SET_USER_PROFILE_PICT
59 | record_silence = GroupRepository.SET_SILENCE
60 | record_block_channel = GroupRepository.SENDER_CHAT_BLOCK
61 | record_zoophile = GroupRepository.ZOOPHILE_FILTER
62 |
63 |
64 | data = [(1,0,chat)]
65 | GroupRepository().set_block_entry(data)
66 | update_db_settings(update, record_arabic, True)
67 | update_db_settings(update, record_chinese, True)
68 | update_db_settings(update, record_cirillic, True)
69 | update_db_settings(update, record_no_user_photo, True)
70 | update_db_settings(update, record_silence, True)
71 | update_db_settings(update, record_block_channel, True)
72 | update_db_settings(update, record_zoophile, True)
73 | bot.set_chat_permissions(update.effective_chat.id, PERM_TRUE)
74 | msg = '✅ Shield removed!'
75 | query.edit_message_text(msg, parse_mode='HTML')
76 | logs_text = '🛡Shield Deactivated in {} [{}]
'.format(chat_title,chat)
77 | telegram_loggers(update,context,logs_text)
--------------------------------------------------------------------------------
/core/commands/admin/top.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | import time
7 | import calendar
8 | from core import decorators
9 | from core.utilities.message import message
10 | from core.utilities.menu import build_menu
11 | from core.database.repository.group import GroupRepository
12 | from telegram import InlineKeyboardButton, InlineKeyboardMarkup
13 | from core.utilities.functions import upd_charts_DESC, upd_charts_ASC
14 |
15 |
16 | @decorators.admin.user_admin
17 | @decorators.bot.check_is_admin
18 | @decorators.public.init
19 | @decorators.bot.check_can_delete
20 | @decorators.delete.init
21 | def init(update, context):
22 | list_buttons = []
23 | list_buttons.append(InlineKeyboardButton('📈 Active', callback_data='useractive'))
24 | list_buttons.append(InlineKeyboardButton('📉 Inactive', callback_data='userinactive'))
25 | list_buttons.append(InlineKeyboardButton("🗑 Close", callback_data='close'))
26 | menu = build_menu(list_buttons,1)
27 | message(update,context,'Please select an option',reply_markup=InlineKeyboardMarkup(menu))
28 |
29 | @decorators.admin.user_admin
30 | def update_top(update,context):
31 | query = update.callback_query
32 | current_GMT = time.gmtime()
33 | ts = calendar.timegm(current_GMT)
34 | if query.data == 'useractive':
35 | chat = update.effective_message.chat_id
36 | topUsers = GroupRepository().getTopActiveUsers(chat)
37 | string = ""
38 | for row in topUsers:
39 | username = row['tg_username']
40 | user = username.replace('@', '')
41 | string += '▪️{} [{}
messages]\n'.format(user,user,row['counter'])
42 | upd_charts_DESC(update,context)
43 | img = "https://naos.hersel.it/charts/{}desc.jpg?v={}".format(chat,ts)
44 | caption = 'Top 10 Active Users Until 30 Days\n\n{}'.format(string)
45 | time.sleep(1)
46 | query.message.delete()
47 | message(update, context, caption, 'HTML', 'photo', None, img)
48 | if query.data == 'userinactive':
49 | chat = update.effective_message.chat_id
50 | topUsers = GroupRepository().getTopInactiveUsers(chat)
51 | string = ""
52 | for row in topUsers:
53 | username = row['tg_username']
54 | user = username.replace('@', '')
55 | string += '▪️{} [{}
messages]\n'.format(user,user,row['counter'])
56 | upd_charts_ASC(update,context)
57 | img = "https://naos.hersel.it/charts/{}asc.jpg?v={}".format(chat,ts)
58 | caption = 'Top 10 Inactive Users Until 30 Days\n\n{}'.format(string)
59 | time.sleep(1)
60 | query.message.delete()
61 | message(update, context, caption, 'HTML', 'photo', None, img)
--------------------------------------------------------------------------------
/core/commands/admin/unban.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | from core import decorators
7 | from core.utilities.message import message
8 | from telegram.utils.helpers import mention_html
9 | from core.utilities.functions import chat_object, user_reply_object
10 | from core.utilities.functions import reply_member_status_object
11 |
12 | @decorators.admin.user_admin
13 | def init(update,context):
14 | bot = context.bot
15 | reply = update.message.reply_to_message
16 | if reply is not None:
17 | user_status = reply_member_status_object(update,context)
18 | if user_status.status == 'kicked':
19 | chat = chat_object(update)
20 | user = user_reply_object(update)
21 | message(update,context,"the ban for the user {} [{}]
has been removed".format(mention_html(user.id, user.first_name),user.id))
22 | bot.unban_chat_member(chat.id, user.id)
23 | else:
24 | user = user_reply_object(update)
25 | message(update,context,"the user {} [{}]
is not banned".format(mention_html(user.id, user.first_name),user.id))
26 | else:
27 | message(update,context,"This command should be used in response to a user!")
--------------------------------------------------------------------------------
/core/commands/admin/user_info.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | import datetime
6 | from core import decorators
7 | from core.utilities.message import message
8 | from core.utilities.functions import user_reply_object, chat_object
9 | from core.database.repository.user import UserRepository
10 | from core.utilities.strings import Strings
11 |
12 | @decorators.admin.user_admin
13 | @decorators.delete.init
14 | def init(update, context):
15 | user = user_reply_object(update)
16 | chat = chat_object(update)
17 | user_db = UserRepository().getById(user.id)
18 | get_warn = UserRepository().getUserByGroup([user.id,chat.id])
19 | current_time = datetime.datetime.utcnow().isoformat()
20 | default_warn = 0
21 | default_score = 0
22 | if user_db:
23 | username = "@"+user.username
24 | data = [(username,current_time,user.id)]
25 | UserRepository().update(data)
26 | warn_count = get_warn['warn_count']
27 | data_mtm = [(user.id, chat.id, default_warn, default_score)]
28 | UserRepository().add_into_mtm(data_mtm)
29 | msg = Strings.USER_INFO.format(id=user.id,username=user.username,chat=chat.title,warn=warn_count)
30 | message(update, context, msg, 'HTML', 'private')
31 | else:
32 | username = "@"+user.username
33 | data = [(user.id,username,current_time,current_time, default_score)]
34 | UserRepository().add(data)
35 | data_mtm = [(user.id, chat.id, default_warn)]
36 | UserRepository().add_into_mtm(data_mtm)
37 | msg = Strings.USER_INFO.format(id=user.id,username=user.username,chat=chat.title,warn=default_warn)
38 | message(update, context, msg, 'HTML', 'private')
--------------------------------------------------------------------------------
/core/commands/admin/warn.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | import datetime
6 | from core import decorators
7 | from languages.getLang import languages
8 | from core.utilities.message import message
9 | from core.utilities.menu import build_menu
10 | from telegram.utils.helpers import mention_html
11 | from core.handlers.logs import telegram_loggers
12 | from core.database.repository.user import UserRepository
13 | from core.database.repository.group import GroupRepository
14 | from telegram import InlineKeyboardButton, InlineKeyboardMarkup
15 | from core.utilities.functions import user_reply_object, chat_object, ban_user_reply, ban_user_by_id
16 |
17 | @decorators.admin.user_admin
18 | @decorators.delete.init
19 | def init(update,context):
20 | chat = chat_object(update)
21 | get_group = GroupRepository().getById(chat.id)
22 | max_warn = get_group['max_warn']
23 | current_time = datetime.datetime.utcnow().isoformat()
24 | default_warn = 1
25 | languages(update,context)
26 | if get_group['set_gh'] == 0:
27 | if update.message.reply_to_message:
28 | reason = update.message.text[5:]
29 | user = user_reply_object(update)
30 | get_user = UserRepository().getUserByGroup([user.id,chat.id])
31 | warn_count = get_user['warn_count'] if get_user is not None else 0
32 | if warn_count != max_warn:
33 | buttons = []
34 | buttons.append(InlineKeyboardButton('➖ 1', callback_data='downWarn'))
35 | buttons.append(InlineKeyboardButton('➕ 1', callback_data='upWarn'))
36 | buttons.append(InlineKeyboardButton(languages.button_remove, callback_data='removeWarn'))
37 | menu = build_menu(buttons,3)
38 | if get_user:
39 | default_warn_count = 0
40 | default_user_score = 0
41 | username = "@"+user.username
42 | data = [(username,current_time,user.id)]
43 | UserRepository().update(data)
44 | data_mtm = [(user.id, chat.id, default_warn_count,default_user_score)]
45 | UserRepository().add_into_mtm(data_mtm)
46 | data_warn = [(user.id,chat.id)]
47 | UserRepository().updateWarn(data_warn)
48 | if reason:
49 | msg = languages.warn_with_reason.format(mention_html(user.id, user.first_name),get_user['warn_count']+1,max_warn,chat.title,chat.id,reason)
50 | update.message.reply_to_message.reply_text(msg, reply_markup=InlineKeyboardMarkup(menu),parse_mode='HTML')
51 | else:
52 | msg = languages.warn_user.format(mention_html(user.id, user.first_name),get_user['warn_count']+1,max_warn,chat.title,chat.id)
53 | update.message.reply_to_message.reply_text(msg, reply_markup=InlineKeyboardMarkup(menu),parse_mode='HTML')
54 | log_txt = "‼️ #Log {} was warned\nin the group: {} [{}
]\nWarns: {}\{}
".format(mention_html(user.id, user.first_name),chat.title,chat.id,get_user['warn_count']+1,max_warn)
55 | if reason:
56 | log_txt = "‼️ #Log {} was warned\nin the group: {} [{}
]\nReason: {}\nWarns: {}\{}
".format(mention_html(user.id, user.first_name),chat.title,chat.id,reason,get_user['warn_count']+1,max_warn)
57 | telegram_loggers(update,context,log_txt)
58 | else:
59 | username = "@"+user.username
60 | data = [(user.id,username,current_time,current_time)]
61 | UserRepository().add(data)
62 | data_mtm = [(user.id, chat.id, default_warn)]
63 | UserRepository().add_into_mtm(data_mtm)
64 | if reason:
65 | message(update,context,languages.warn_with_reason.format(username,chat.title,chat.id,reason))
66 | else:
67 | message(update,context,languages.warn_user.format(username,chat.title,chat.id))
68 | log_txt = "‼️ #Log {} was warned\nin the group: {} [{}]
".format(mention_html(user.id, user.first_name),chat.title,chat.id)
69 | if reason:
70 | log_txt = "‼️ #Log {} was warned\nin the group: {} [{}]
\nReason: {}".format(mention_html(user.id, user.first_name),chat.title,chat.id,reason)
71 | telegram_loggers(update,context,log_txt)
72 | else:
73 | ban_user_reply(update,context)
74 | buttons = []
75 | buttons.append(InlineKeyboardButton('Remove', callback_data='removeWarn'))
76 | menu = build_menu(buttons,2)
77 | msg = languages.warn_user_max.format(user.username,chat.title)
78 | update.message.reply_to_message.reply_text(msg, reply_markup=InlineKeyboardMarkup(menu),parse_mode='HTML')
79 | else:
80 | message(update,context,languages.error_response_user_msg)
81 | else:
82 | return
83 |
84 |
85 |
86 | @decorators.admin.user_admin
87 | @decorators.delete.init
88 | def set_warn(update, context):
89 | bot = context.bot
90 | chat = update.effective_message.chat_id
91 | buttons = []
92 | buttons.append(InlineKeyboardButton('2️⃣', callback_data='w2'))
93 | buttons.append(InlineKeyboardButton('3️⃣', callback_data='w3'))
94 | buttons.append(InlineKeyboardButton('4️⃣', callback_data='w4'))
95 | buttons.append(InlineKeyboardButton('5️⃣', callback_data='w5'))
96 | buttons.append(InlineKeyboardButton('6️⃣', callback_data='w6'))
97 | buttons.append(InlineKeyboardButton('7️⃣', callback_data='w7'))
98 | buttons.append(InlineKeyboardButton('8️⃣', callback_data='w8'))
99 | buttons.append(InlineKeyboardButton('9️⃣', callback_data='w9'))
100 | buttons.append(InlineKeyboardButton('🔟', callback_data='w10'))
101 | menu = build_menu(buttons,3)
102 | bot.send_message(chat,"⚙ Warn Settings", reply_markup=InlineKeyboardMarkup(menu),parse_mode='HTML' )
103 |
104 | @decorators.admin.user_admin
105 | def update_set_warn(update, context):
106 | query = update.callback_query
107 | if query.data.startswith("w"):
108 | chat_id = query.message.chat_id
109 | warn_limit = query.data[1:]
110 | record = GroupRepository.SET_MAX_WARN
111 | data = [(warn_limit,chat_id)]
112 | GroupRepository().update_group_settings(record, data)
113 | text = "You have changed the maximum number\nof warns in this group to {}
".format(warn_limit)
114 | query.edit_message_text(text, parse_mode='HTML')
115 |
116 | @decorators.admin.user_admin
117 | def update_warn(update,context):
118 | query = update.callback_query
119 | user_id = query.message.reply_to_message.from_user.id
120 | chat_id = query.message.reply_to_message.chat_id
121 | get_user = UserRepository().getUserByGroup([user_id,chat_id])
122 | get_group = GroupRepository().getById(chat_id)
123 | max_warn = get_group['max_warn']
124 | warn_count = get_user['warn_count'] if get_user is not None else 0
125 | if query.data == 'upWarn':
126 | if warn_count != max_warn:
127 | data_warn = [(user_id,chat_id)]
128 | UserRepository().updateWarn(data_warn)
129 | msg = 'You Upwarned: {}\nWarns: {}/{}'.format(user_id,user_id,get_user['warn_count']+1,max_warn)
130 | query.edit_message_text(msg, parse_mode='HTML')
131 | else:
132 | ban_user_by_id(update,context,user_id)
133 | msg = "The user has been banned because it has reached the maximum number of warns"
134 | query.edit_message_text(msg, parse_mode='HTML')
135 | if query.data == 'downWarn':
136 | if warn_count != 0:
137 | data_warn = [(user_id,chat_id)]
138 | UserRepository().downWarn(data_warn)
139 | msg = 'You Downwarned: {}\nWarns: {}/{}'.format(user_id,user_id,get_user['warn_count']-1,max_warn)
140 | query.edit_message_text(msg, parse_mode='HTML')
141 | else:
142 | msg = "The user cannot be downwarned anymore!"
143 | query.edit_message_text(msg, parse_mode='HTML')
144 | if query.data == 'removeWarn':
145 | data_warn = [(user_id,chat_id)]
146 | UserRepository().removeWarn(data_warn)
147 | msg = 'You have removed the Warns from user: {}'.format(user_id,user_id)
148 | query.edit_message_text(msg, parse_mode='HTML')
--------------------------------------------------------------------------------
/core/commands/index.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | from core.commands import public ,admin, owner
6 | from telegram.ext import (CommandHandler as CMH,CallbackQueryHandler as CQH)
7 | from core.utilities.functions import close_menu
8 |
9 | """
10 | Here are inserted all the commands with user permissions
11 | """
12 | def user_command(dsp):
13 | function = dsp.add_handler
14 | ######################
15 | ### CommandHandler ###
16 | ######################
17 | function(CMH('start', public.start.init))
18 | function(CMH('help', public.help.init))
19 | function(CMH('rules', public.rules.init))
20 | function(CMH('io', public.io.init))
21 | function(CMH('source', public.source.init))
22 | function(CMH('lost', public.eggs.egg_lost))
23 | function(CMH('kickme', public.kickme.init))
24 | function(CMH('staff', public.staff.init))
25 | function(CMH('usearch', public.user_search.init))
26 |
27 | """
28 | Here are inserted all the commands with admin permissions
29 | """
30 | def admin_command(dsp):
31 | function = dsp.add_handler
32 | ######################
33 | ### CommandHandler ###
34 | ######################
35 | function(CMH('ban', admin.ban.init))
36 | function(CMH('unban', admin.unban.init))
37 | function(CMH('setban', admin.ban.set_ban_message))
38 | function(CMH('status', admin.info_group.init))
39 | function(CMH('lang', admin.set_lang.init))
40 | function(CMH('mute', admin.mute.init))
41 | #function(CMH('check', admin.check_permission.init)) Need to Fix
42 | function(CMH('warn', admin.warn.init))
43 | function(CMH('info', admin.user_info.init))
44 | function(CMH('say', admin.say.init))
45 | function(CMH('welcome', admin.set_welcome.init))
46 | function(CMH('settings', admin.settings.init))
47 | function(CMH('filters', admin.filters.init))
48 | function(CMH('setwarn', admin.warn.set_warn))
49 | function(CMH('setrules', admin.set_rules.init))
50 | function(CMH('setnousername', admin.set_welcome.set_type_no_username))
51 | function(CMH('del', admin.delete_message.init))
52 | function(CMH('welcomebuttons', admin.set_welcome.set_welcome_buttons))
53 | function(CMH('shield', admin.shield.init))
54 | function(CMH('badword', admin.badword.init))
55 | function(CMH('badlist', admin.badword.badlist))
56 | function(CMH('promote', admin.promote.init))
57 | function(CMH('dashboard', admin.dashboard.init))
58 | function(CMH('chatid', admin.info_group.id_chat))
59 | function(CMH('custom', admin.set_custom_handler.init))
60 | function(CMH('top', admin.top.init))
61 | function(CMH('unpinall', admin.pin.unpin_all))
62 | function(CMH('pin', admin.pin.pin))
63 | function(CMH('greport', admin.greport.init))
64 | #############################
65 | ### CallbackQuery Handler ###
66 | #############################
67 | function(CQH(owner.superban.update_superban, pattern='m'))
68 | function(CQH(close_menu, pattern='closeMenu'))
69 | function(CQH(owner.superban.update_superban, pattern='removeSuperban'))
70 | function(CQH(owner.whitelist.remove_blacklist, pattern='removeBL'))
71 | function(CQH(owner.whitelist.remove_blacklist, pattern='closed'))
72 | function(CQH(admin.warn.update_set_warn, pattern='w'))
73 | function(CQH(admin.warn.update_warn, pattern='upWarn'))
74 | function(CQH(admin.warn.update_warn, pattern='downWarn'))
75 | function(CQH(admin.warn.update_warn, pattern='removeWarn'))
76 | function(CQH(admin.set_welcome.update_set_tpnu, pattern='tpnu'))
77 | function(CQH(owner.add_community.callback_community, pattern='comm'))
78 | function(CQH(admin.mute.update_mute, pattern='CM'))
79 | function(CQH(admin.set_lang.language_en, pattern='language_en'))
80 | function(CQH(admin.set_lang.language_it, pattern='language_it'))
81 | function(CQH(admin.filters.update_filters, pattern='ff'))
82 | function(CQH(public.rules.update_rules, pattern='openRules'))
83 | function(CQH(public.report.update_resolve, pattern='resolved'))
84 | function(CQH(admin.shield.update_shield, pattern='removeShield'))
85 | function(CQH(admin.top.update_top, pattern='useractive'))
86 | function(CQH(admin.top.update_top, pattern='userinactive'))
87 | function(CQH(owner.add_owner.update_owner, pattern='OwnerRemove'))
88 | function(CQH(admin.settings.update_settings))
89 | """
90 | Here are inserted all the commands with owner permissions
91 | """
92 | def owner_command(dsp):
93 | function = dsp.add_handler
94 | ######################
95 | ### CommandHandler ###
96 | ######################
97 | function(CMH('b', owner.broadcast.init, run_async=True))
98 | function(CMH('gb', owner.broadcast.global_broadcast, run_async=True))
99 | function(CMH('s', owner.superban.init, run_async=True))
100 | function(CMH('ms', owner.superban.multi_superban, run_async=True))
101 | function(CMH('us', owner.superban.remove_superban_via_id, run_async=True))
102 | function(CMH('w', owner.whitelist.init))
103 | function(CMH('server', owner.server_info.init))
104 | function(CMH('community', owner.add_community.init))
105 | function(CMH('test', owner.test.init))
106 | function(CMH('owner', owner.add_owner.init))
107 | function(CMH('exit', owner.exit.init))
108 | function(CMH('exportlink', owner.export_invite_link.init))
109 | function(CMH('maxport', owner.export_invite_link.manual_export))
110 | function(CMH('spam', owner.add_antispam.init))
111 | function(CMH('channels', owner.list_community.channels))
112 | function(CMH('groups', owner.list_community.groups))
113 | function(CMH('rexit', owner.exit.remote_exit))
--------------------------------------------------------------------------------
/core/commands/owner/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | """Import Files"""
7 | __all__ = ["add_antispam","add_community","add_owner","broadcast","exit","export_invite_link","list_community","server_info","superban","test","whitelist"]
8 |
9 | from core.commands.owner import *
--------------------------------------------------------------------------------
/core/commands/owner/add_antispam.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | from core import decorators
7 | from core.utilities.message import message
8 | from core.database.repository.group import GroupRepository
9 |
10 | @decorators.owner.init
11 | @decorators.delete.init
12 | def init(update,context):
13 | msg = update.message.text[5:].strip()
14 | if msg != "":
15 | GroupRepository().insert_spam(msg)
16 | message(update,context,"You have entered a new ANTISPAM logic in the database, the logic you have entered is the following: {}".format(msg))
17 | else:
18 | message(update, context,"Empty Logic")
--------------------------------------------------------------------------------
/core/commands/owner/add_community.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | from core import decorators
6 | from core.utilities.message import message
7 | from core.utilities.functions import chat_object
8 | from core.database.repository.community import CommunityRepository
9 | from core.database.repository.group import GroupRepository
10 | from core.utilities.menu import build_menu
11 | from telegram import InlineKeyboardButton, InlineKeyboardMarkup
12 |
13 | @decorators.owner.init
14 | def init(update,context):
15 | bot = context.bot
16 | chat = chat_object(update)
17 | if chat.type == 'supergroup':
18 | row = CommunityRepository().getById(chat.id)
19 | if row:
20 | record = GroupRepository.SET_COMMUNITY
21 | default_community = 1
22 | data = [(chat.title,chat.id)]
23 | data_group = [(default_community, chat.id)]
24 | CommunityRepository().update(data)
25 | GroupRepository().update_group_settings(record,data_group)
26 | message(update,context,"I updated the community on the database")
27 | else:
28 | buttons = []
29 | buttons.append(InlineKeyboardButton('IT', callback_data='commIT'))
30 | buttons.append(InlineKeyboardButton('EN', callback_data='commEN'))
31 | buttons.append(InlineKeyboardButton('Close', callback_data='closeMenu'))
32 | menu = build_menu(buttons,2)
33 | bot.send_message(chat_id=update.effective_chat.id,text="Please select the language of the community",reply_markup=InlineKeyboardMarkup(menu))
34 | else:
35 | message(update,context,"Attention! this command can only be used in public supergroups!")
36 |
37 | @decorators.owner.init
38 | def callback_community(update,context):
39 | query = update.callback_query
40 | if query.data.startswith("comm"):
41 | lang_set = query.data[4:]
42 | type_community = query.message.chat.type
43 | chat_id = query.message.chat_id
44 | chat_title = query.message.chat.title
45 | chat_username = query.message.chat.username
46 | link = "https://t.me/{}".format(chat_username)
47 | record = GroupRepository.SET_COMMUNITY
48 | default_community = 1
49 | data = [(chat_title,chat_id,link,lang_set,type_community)]
50 | data_group = [(default_community, chat_id)]
51 | CommunityRepository().add(data)
52 | GroupRepository().update_group_settings(record,data_group)
53 | query.edit_message_text("I have added the community [{}] to the database".format(chat_title), parse_mode='HTML')
--------------------------------------------------------------------------------
/core/commands/owner/add_owner.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | from core import decorators
7 | from core.utilities.menu import build_menu
8 | from core.utilities.message import message
9 | from core.utilities.functions import user_reply_object
10 | from core.database.repository.user import UserRepository
11 | from telegram import InlineKeyboardButton, InlineKeyboardMarkup
12 |
13 | @decorators.owner.init
14 | @decorators.delete.init
15 | def init(update,context):
16 | if update.message.reply_to_message:
17 | user = user_reply_object(update)
18 | user_id = user.id
19 | username = "@"+user.username
20 | row = UserRepository().getOwnerById(user.id)
21 | list_buttons = []
22 | if row:
23 | list_buttons.append(InlineKeyboardButton('❌ Remove', callback_data='OwnerRemove'))
24 | list_buttons.append(InlineKeyboardButton("🗑 Close", callback_data='close'))
25 | menu = build_menu(list_buttons, 1)
26 | update.message.reply_to_message.reply_text('{} This owner already exists in the database'.format(username),reply_markup=InlineKeyboardMarkup(menu),parse_mode='HTML')
27 | else:
28 | data = [(user_id, username)]
29 | UserRepository().add_owner(data)
30 | message(update,context, "You have entered {} [{}
] a new owner in the database!\nRestart the Bot!".format(username,user_id))
31 | else:
32 | message(update,context, "Error! This command should be used in response to the user!")
33 |
34 | @decorators.owner.init
35 | def update_owner(update,context):
36 | query = update.callback_query
37 | user = query.message.reply_to_message.from_user
38 | if query.data == 'OwnerRemove':
39 | data = [(user.id)]
40 | UserRepository().remove_owner(data)
41 | query.edit_message_text("You have removed owner {} [{}
] from the database".format(user.first_name,user.id), parse_mode='HTML')
--------------------------------------------------------------------------------
/core/commands/owner/broadcast.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | import asyncio
6 | from core import decorators
7 | from core.utilities.message import message,messageWithAsyncById
8 | from core.utilities.strings import Strings
9 | from core.database.repository.community import CommunityRepository
10 | from core.database.repository.group import GroupRepository
11 | from telegram.error import BadRequest, Unauthorized
12 |
13 | loop = asyncio.get_event_loop()
14 |
15 | @decorators.owner.init
16 | def init(update, context):
17 | msg = update.message.text[2:].strip()
18 | rows = CommunityRepository().getAll()
19 | for a in rows:
20 | id_groups = a['tg_group_id']
21 | try:
22 | if msg != "":
23 | loop.run_until_complete(messageWithAsyncById(update,context,id_groups,2,msg))
24 | else:
25 | message(update,context,"You cannot send an empty message!")
26 | except (BadRequest,Unauthorized):
27 | category = a['type']
28 | message(update,context,Strings.ERROR_HANDLING.format(id_groups,category))
29 |
30 | @decorators.owner.init
31 | def global_broadcast(update, context):
32 | msg = update.message.text[3:].strip()
33 | rows = GroupRepository().getAll()
34 | for a in rows:
35 | id_groups = a['id_group']
36 | try:
37 | if msg != "":
38 | loop.run_until_complete(messageWithAsyncById(update,context,id_groups,2,msg))
39 | else:
40 | message(update,context,"You cannot send an empty message!")
41 | except (BadRequest,Unauthorized):
42 | message(update,context,Strings.ERROR_HANDLING.format(id_groups))
--------------------------------------------------------------------------------
/core/commands/owner/exit.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 | import time
4 |
5 | # Copyright SquirrelNetwork
6 | from config import Config
7 | from core import decorators
8 | from core.utilities.message import message
9 | from core.handlers.logs import sys_loggers
10 | from core.utilities.functions import chat_object
11 | from core.utilities.message import ApiGroupRemove
12 | #from core.database.repository.group import GroupRepository
13 |
14 | #TODO NEED FIX DELETE GROUP IN DATABASE
15 |
16 | @decorators.owner.init
17 | def init(update, context):
18 | bot = context.bot
19 | chat = chat_object(update)
20 | #GroupRepository.remove(chat.id)
21 | bot.leaveChat(update.message.chat_id)
22 | message(update, context, "#Log the bot has left the chat {}
\nby operator {}
".format(chat.id,update.message.from_user.id), 'HTML', 'messageid', Config.DEFAULT_LOG_CHANNEL, None)
23 | formatter = "Il bot è uscito dalla chat {} e il comando è stato eseguito da: {}".format(chat.id,update.message.from_user.id)
24 | sys_loggers("[BOT_EXIT_LOGS]",formatter,False,False,True)
25 |
26 | @decorators.owner.init
27 | def remote_exit(update,context):
28 | try:
29 | text = update.message.text
30 | input_user_id = text[6:].strip().split(" ", 1)
31 | chatid = input_user_id[0]
32 | message(update,context,"The bot remotely exited the following group: {}
".format(chatid))
33 | time.sleep(1)
34 | ApiGroupRemove(chatid)
35 | except Exception as e:
36 | print(e)
--------------------------------------------------------------------------------
/core/commands/owner/export_invite_link.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | from core import decorators
6 | from core.utilities.functions import chat_object
7 | from core.utilities.message import message
8 |
9 | @decorators.owner.init
10 | @decorators.delete.init
11 | def init(update, context):
12 | bot = context.bot
13 | chat = chat_object(update)
14 | link = bot.export_chat_invite_link(chat.id)
15 | message(update, context, "An invitation link was generated for the chat {}\nThe invitation was sent in private".format(chat.title))
16 | message(update, context, "Chat: {}\nInvite Link: {}".format(chat.title,link), 'HTML', 'private')
17 |
18 | @decorators.owner.init
19 | @decorators.delete.init
20 | def manual_export(update,context):
21 | bot = context.bot
22 | chat = update.message.text[8:].strip()
23 | print(chat)
24 | link = bot.export_chat_invite_link(chat)
25 | message(update, context, "Invite Link: {}".format(link), 'HTML', 'private')
--------------------------------------------------------------------------------
/core/commands/owner/list_community.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | from core import decorators
6 | from core.database.repository.community import CommunityRepository
7 | from telegram import InlineKeyboardButton, InlineKeyboardMarkup
8 | from core.utilities.menu import build_menu
9 |
10 | @decorators.owner.init
11 | def groups(update,context):
12 | bot = context.bot
13 | chat = update.effective_chat.id
14 | list_buttons = []
15 | rows = CommunityRepository().getCommunityGroups()
16 | for link in rows:
17 | list_buttons.append(InlineKeyboardButton(text=link['tg_group_name'], url=link['tg_group_link']))
18 | menu = build_menu(list_buttons,2)
19 | main_text = "=== 🐿[SN] Squirrel Network Official 🐿===\nTo participate in the Network contact:\n@TheLonelyAdventurer\n@SteelManITA\n@BluLupo"
20 | bot.send_message(chat,text=main_text,reply_markup=InlineKeyboardMarkup(menu), parse_mode="HTML")
21 |
22 | @decorators.owner.init
23 | def channels(update,context):
24 | bot = context.bot
25 | chat = update.effective_chat.id
26 | list_buttons = []
27 | rows = CommunityRepository().getCommunityChannels()
28 | for link in rows:
29 | list_buttons.append(InlineKeyboardButton(text=link['tg_group_name'], url=link['tg_group_link']))
30 | menu = build_menu(list_buttons,2)
31 | main_text = "=== 🐿[SN] Squirrel Network Official 🐿===\nTo participate in the Network contact:\n@TheLonelyAdventurer\n@SteelManITA\n@BluLupo"
32 | bot.send_message(chat,text=main_text,reply_markup=InlineKeyboardMarkup(menu), parse_mode="HTML")
--------------------------------------------------------------------------------
/core/commands/owner/server_info.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | import psutil, datetime, platform
6 | from core import decorators
7 | from core.utilities.message import message
8 | from core.handlers.logs import sys_loggers
9 |
10 | NAME_SERVER = "NAOS"
11 |
12 | @decorators.owner.init
13 | @decorators.delete.init
14 | def init(update,context):
15 | msg = system_status()
16 | message(update,context,msg)
17 | formatter = "Eseguito da: {}".format(update.message.from_user.id)
18 | sys_loggers("[SERVER_INFO_LOGS]",formatter,False,False,True)
19 |
20 | def get_size(bytes, suffix="B"):
21 | """
22 | Scale bytes to its proper format
23 | e.g:
24 | 1253656 => '1.20MB'
25 | 1253656678 => '1.17GB'
26 | """
27 | factor = 1024
28 | for unit in ["", "K", "M", "G", "T", "P"]:
29 | if bytes < factor:
30 | return f"{bytes:.2f}{unit}{suffix}"
31 | bytes /= factor
32 |
33 | def system_status():
34 | cpu_percent = psutil.cpu_percent()
35 | memory_percent = psutil.virtual_memory()[2]
36 | svmem = psutil.virtual_memory()
37 | boot_time = datetime.datetime.fromtimestamp(psutil.boot_time())
38 | partitions = psutil.disk_partitions()
39 | uname = platform.uname()
40 | cpufreq = psutil.cpu_freq()
41 | net_io = psutil.net_io_counters()
42 | running_since = boot_time.strftime("%A %d. %B %Y")
43 | response = "{} Server Status:\n\n".format(NAME_SERVER)
44 | response += "⚙️ ==== SYSTEM INFO ==== ⚙️\n"
45 | response += "System: {}
\n".format(uname.system)
46 | response +="Node Name: {}
\n".format(uname.node)
47 | response +="Release: {}
\n".format(uname.release)
48 | response +="Version: {}
\n".format(uname.version)
49 | response +="Machine: {}
\n\n".format(uname.machine)
50 | response += "⚙️ ==== CPU INFO ==== ⚙️\n"
51 | response += "Current CPU utilization is: {}%
\n".format(cpu_percent)
52 | response += "Current Frequency: {}Mhz
\n".format(cpufreq.current)
53 | response += "Physical cores: {}
\n".format(psutil.cpu_count(logical=False))
54 | response += "Total cores: {}
\n\n".format(psutil.cpu_count(logical=True))
55 | response += "⚙️ ==== DISK INFO ==== ⚙️\n"
56 | for partition in partitions:
57 | try:
58 | partition_usage = psutil.disk_usage(partition.mountpoint)
59 | except PermissionError:
60 | continue
61 | response += "Total Size: {}
\n".format(get_size(partition_usage.total))
62 | response += "Used: {}
\n".format(get_size(partition_usage.used))
63 | response += "Free: {}
\n".format(get_size(partition_usage.free))
64 | response += "Current Disk_percent is: {}%
\n\n".format(partition_usage.percent)
65 | response += "⚙️ ==== MEMORY INFO ==== ⚙️ \n"
66 | response += "Current memory utilization: {}%
\n".format(memory_percent)
67 | response += "Total: {}
\n\n".format(get_size(svmem.total))
68 | response += "⚙️ ==== NETWORK INFO ==== ⚙️ \n"
69 | response += "Total Bytes Sent: {}
\n".format(get_size(net_io.bytes_sent))
70 | response += "Total Bytes Received: {}
\n".format(get_size(net_io.bytes_recv))
71 | response += "It's running since {}".format(running_since)
72 | return response
--------------------------------------------------------------------------------
/core/commands/owner/test.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | from core import decorators
7 |
8 | @decorators.owner.init
9 | def init(update,context):
10 | bot = context.bot
11 | chat = update.effective_chat.id
12 | thread_id = update.effective_message.message_thread_id
13 | text = "Test"
14 | bot.send_message(chat, text, parse_mode='HTML',message_thread_id=thread_id)
--------------------------------------------------------------------------------
/core/commands/owner/whitelist.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | from core import decorators
6 | from core.utilities.message import message
7 | from core.database.repository.superban import SuperbanRepository
8 | from core.utilities.functions import user_reply_object
9 | from core.utilities.menu import build_menu
10 | from telegram import InlineKeyboardButton, InlineKeyboardMarkup
11 |
12 | @decorators.owner.init
13 | @decorators.delete.init
14 | def init(update,context):
15 | if update.message.reply_to_message:
16 | user = user_reply_object(update)
17 | row = SuperbanRepository().getWhitelistById(user.id)
18 | get_superban = SuperbanRepository().getById(user.id)
19 | if get_superban:
20 | buttons = []
21 | buttons.append(InlineKeyboardButton('Remove Superban', callback_data='removeBL'))
22 | buttons.append(InlineKeyboardButton('Close', callback_data='closed'))
23 | menu = build_menu(buttons,2)
24 | msg = "Attention the user is blacklisted! do you want to remove it?"
25 | update.message.reply_to_message.reply_text(msg, reply_markup=InlineKeyboardMarkup(menu),parse_mode='HTML')
26 | else:
27 | if row:
28 | message(update, context, "You have already whitelisted this user")
29 | else:
30 | user_username = "@"+user.username
31 | data = [(user.id, user_username)]
32 | SuperbanRepository().addWhitelist(data)
33 | message(update, context, "You have entered the user {} in the Whitelist".format(user_username))
34 | else:
35 | message(update, context, "This message can only be used in response to a user")
36 |
37 |
38 | @decorators.owner.init
39 | def remove_blacklist(update,context):
40 | query = update.callback_query
41 | if query.data == 'removeBL':
42 | user_id = query.message.reply_to_message.from_user.id
43 | row = SuperbanRepository().getById(user_id)
44 | if row:
45 | data = [(user_id)]
46 | SuperbanRepository().remove(data)
47 | msg = "I removed the superban to user {}
".format(user_id)
48 | query.edit_message_text(msg,parse_mode='HTML')
49 | else:
50 | query.edit_message_text("Attention this user not super banned!!!",parse_mode='HTML')
51 | if query.data == 'closed':
52 | query.edit_message_text("You have closed the Menu", parse_mode='HTML')
--------------------------------------------------------------------------------
/core/commands/public/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | """Import Files"""
7 | __all__ = ["eggs","help","io","kickme","report","rules","source","staff","start","user_search"]
8 |
9 | from core.commands.public import *
--------------------------------------------------------------------------------
/core/commands/public/eggs.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | """
7 | List of Easter Eggs
8 | """
9 | from core import decorators
10 | from core.utilities.message import message
11 |
12 | @decorators.public.init
13 | @decorators.delete.init
14 | def egg_lost(update,context):
15 | message(update, context, "4 8 15 16 23 42
")
16 |
17 | @decorators.public.init
18 | def egg_gh(update,context):
19 | if str(update.effective_message.text).lower().startswith(".fiko"):
20 | msg = "I'm not GroupHelp! If you want to know who they are type /source"
21 | animation = "https://i.imgur.com/LP23P90.gif"
22 | message(update,context,msg,type='animation',img=animation)
23 |
24 | @decorators.public.init
25 | def nanachi(update,context):
26 | if str(update.effective_message.text).lower().startswith("nanachi"):
27 | msg = "Naaaa~~ 🐾"
28 | animation = "https://i.imgur.com/P9HXqM8.mp4"
29 | message(update,context,msg,type='animation',img=animation)
--------------------------------------------------------------------------------
/core/commands/public/help.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | from core.utilities.menu import build_menu
6 | from languages.getLang import languages
7 | from telegram import InlineKeyboardButton, InlineKeyboardMarkup
8 |
9 | def init(update,context):
10 | bot = context.bot
11 | chat = update.effective_message.chat_id
12 | languages(update,context)
13 | msg = languages.helps.format("@"+bot.username)
14 | buttons = []
15 | buttons.append(InlineKeyboardButton("Commands List", url='https://github.com/Squirrel-Network/nebula8/wiki/Command-List'))
16 | buttons.append(InlineKeyboardButton("Source", url='https://github.com/Squirrel-Network/nebula8'))
17 | buttons.append(InlineKeyboardButton("Logs Channel", url='https://t.me/nebulalogs'))
18 | buttons.append(InlineKeyboardButton("News Channel", url='https://t.me/nebulanewsbot'))
19 | buttons.append(InlineKeyboardButton("BlackList Search", url='https://squirrel-network.online/knowhere'))
20 | buttons.append(InlineKeyboardButton("Official API Docs", url='https://api.nebula.squirrel-network.online/apidocs'))
21 | buttons.append(InlineKeyboardButton("Network SN", url='https://t.me/squirrelnetwork'))
22 | menu = build_menu(buttons,3)
23 | bot.send_message(chat,msg,reply_markup=InlineKeyboardMarkup(menu))
--------------------------------------------------------------------------------
/core/commands/public/io.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | from core import decorators
6 | from core.utilities.message import message
7 | from core.utilities.functions import user_object
8 | from core.database.repository.superban import SuperbanRepository
9 |
10 | @decorators.private.init
11 | @decorators.delete.init
12 | def init(update,context):
13 | user = user_object(update)
14 | nickname = "@"+ user.username
15 | superban = SuperbanRepository().getById(user.id)
16 | if superban:
17 | msg = "User id: {}
\nNickname: {}\nBlacklist: ✅".format(user.id, nickname or user.first_name)
18 | else:
19 | msg = "User id: {}
\nNickname: {}\nBlacklist: ❌".format(user.id, nickname or user.first_name)
20 | message(update,context,msg)
--------------------------------------------------------------------------------
/core/commands/public/kickme.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | from core import decorators
7 | from core.utilities.message import message
8 | from core.utilities.functions import kick_user_by_id, user_object
9 |
10 | @decorators.delete.init
11 | def init(update,context):
12 | user = user_object(update)
13 | img = 'https://i.imgur.com/CKU9Y75.png'
14 | kick_user_by_id(update, context, user.id)
15 | message(update, context, 'You kicked yourself [{}]
\nWe only used 15 lines of code to make a free feature, not paid\nPut a stars to our repository => /source'.format(user.id), 'HTML', 'photo', None, img)
--------------------------------------------------------------------------------
/core/commands/public/report.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | from core import decorators
6 | from languages.getLang import languages
7 | from core.utilities.strings import Strings
8 | from core.utilities.message import message
9 | from core.handlers.logs import telegram_loggers
10 | from telegram import InlineKeyboardButton, InlineKeyboardMarkup
11 | from core.utilities.menu import build_menu
12 |
13 |
14 | @decorators.public.init
15 | def init(update,context):
16 | bot = context.bot
17 | staff_group_id = -1001267698171
18 | buttons = []
19 | buttons.append(InlineKeyboardButton('Risolto✅', callback_data='resolved'))
20 | menu = build_menu(buttons,2)
21 | if update.effective_message.forward_date is not None:
22 | return
23 |
24 | chat = update.effective_chat
25 | languages(update,context)
26 | if str(update.effective_message.text).lower().startswith("@admin") or str(update.effective_message.text).lower().startswith("/report"):
27 | if update.effective_message.reply_to_message:
28 | msg = update.effective_message.reply_to_message
29 | format_link = "https://t.me/c/{}/{}".format(str(chat.id)[3:],msg.message_id)
30 | format_message = Strings.REPORT_MSG.format(chat.id,chat.title,msg.text,format_link)
31 | message(update, context, languages.report_msg, 'HTML', 'reply', None, None)
32 | telegram_loggers(update,context,format_message)
33 | bot.send_message(staff_group_id,format_message, reply_markup=InlineKeyboardMarkup(menu),parse_mode='HTML')
34 | else:
35 | msg_id = update.effective_message.message_id
36 | user_id = update.message.from_user.id
37 | user_first = update.message.from_user.first_name
38 | format_link = "https://t.me/c/{}/{}".format(str(chat.id)[3:],msg_id)
39 | format_message = '#Report\nUser: {}\nGroup Id: [{}
]\nGroup Title: {}\nLink: {}'.format(user_id,user_first,str(chat.id)[3:],chat.title,format_link)
40 | message(update, context, languages.report_msg, 'HTML', 'reply', None, None)
41 | telegram_loggers(update,context,format_message)
42 | bot.send_message(staff_group_id,format_message, reply_markup=InlineKeyboardMarkup(menu),parse_mode='HTML')
43 |
44 | @decorators.admin.user_admin
45 | def update_resolve(update,context):
46 | query = update.callback_query
47 | var_message = query.message.text
48 | query.edit_message_text(text="{}\nRisolto da: @{username}"
49 | .format(var_message,username=str(update.effective_user.username)),parse_mode='HTML')
--------------------------------------------------------------------------------
/core/commands/public/rules.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | from core import decorators
6 | from core.utilities.menu import build_menu
7 | from languages.getLang import languages
8 | from core.database.repository.group import GroupRepository
9 | from telegram import InlineKeyboardButton, InlineKeyboardMarkup
10 |
11 | @decorators.public.init
12 | @decorators.delete.init
13 | def init(update, context):
14 | bot = context.bot
15 | languages(update,context)
16 | chat = update.effective_message.chat_id
17 | chat_title = update.message.chat.title
18 | list_buttons = []
19 | list_buttons.append(InlineKeyboardButton(languages.rules_button, callback_data='openRules'))
20 | menu = build_menu(list_buttons,1)
21 | bot.send_message(chat,languages.rules_main.format(chat_title,chat),reply_markup=InlineKeyboardMarkup(menu),parse_mode='HTML')
22 |
23 |
24 | def update_rules(update,context):
25 | query = update.callback_query
26 | if query.data == 'openRules':
27 | languages(update,context)
28 | chat = update.effective_message.chat_id
29 | row = GroupRepository().getById([chat])
30 | query.edit_message_text(languages.rules.format(row['rules_text']),parse_mode='HTML')
--------------------------------------------------------------------------------
/core/commands/public/source.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | from config import Config
6 | from core import decorators
7 | from core.utilities.message import message
8 | from core.utilities.functions import bot_object
9 | from core.utilities.strings import Strings
10 |
11 | @decorators.delete.init
12 | def init(update,context):
13 | bot = bot_object(update,context)
14 | version = Config.VERSION
15 | version_name = Config.VERSION_NAME
16 | repo = Config.REPO
17 | format_message = Strings.SOURCE.format("@"+bot.username,version,version_name,repo)
18 | message(update,context,format_message)
--------------------------------------------------------------------------------
/core/commands/public/staff.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | from core import decorators
7 | from telegram.utils.helpers import mention_markdown
8 |
9 | @decorators.public.init
10 | @decorators.delete.init
11 | def init(update,context):
12 | bot = context.bot
13 | administrators = update.effective_chat.get_administrators()
14 | chat = update.effective_chat.id
15 | string = "Group Staff:\n"
16 | for admin in administrators:
17 | user = admin.user
18 | user_first = user.first_name
19 | string += "👮 {}\n".format(mention_markdown(user.id, user_first, version=2))
20 | bot.send_message(chat,string,parse_mode='MarkdownV2')
--------------------------------------------------------------------------------
/core/commands/public/start.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | from core import decorators
6 | from languages.getLang import languages
7 | from core.utilities.message import message
8 | from core.utilities.functions import bot_object, user_object, chat_object
9 | from telegram import InlineKeyboardButton, InlineKeyboardMarkup
10 | from core.utilities.menu import build_menu
11 |
12 | @decorators.private.init
13 | @decorators.delete.init
14 | def init(update, context):
15 | bot = context.bot
16 | languages(update,context)
17 | chat = update.effective_message.chat_id
18 | get_bot = bot_object(update,context)
19 | user = user_object(update)
20 | get_user_lang = user.language_code
21 | if get_user_lang == 'it':
22 | list_buttons = []
23 | list_buttons.append(InlineKeyboardButton('Commands', url='https://github.com/Squirrel-Network/nebula8/wiki/Command-List'))
24 | list_buttons.append(InlineKeyboardButton('Dashboard', url='https://nebula.squirrel-network.online'))
25 | list_buttons.append(InlineKeyboardButton('Api', url='https://api.nebula.squirrel-network.online'))
26 | list_buttons.append(InlineKeyboardButton('Knowhere', url='https://squirrel-network.online/knowhere'))
27 | list_buttons.append(InlineKeyboardButton('News', url='https://t.me/nebulanewsbot'))
28 | list_buttons.append(InlineKeyboardButton('Logs', url='https://t.me/nebulalogs'))
29 | list_buttons.append(InlineKeyboardButton('SquirrelNetwork', url='https://t.me/squirrelnetwork'))
30 | list_buttons.append(InlineKeyboardButton('👥 Add me to a Group', url='https://t.me/thenebulabot?startgroup=start'))
31 | menu = build_menu(list_buttons, 3)
32 | text = "🤖 Ciao io mi chiamo {}\n\nSono un bot ricco di funzionalità per la gestione dei gruppi\n"\
33 | "Possiedo una Blacklist enorme ho un antispam, un antiflood e molto altro ancora!!\n\n"\
34 | "ℹ Se hai bisogno di aiuto: [/help]\n\n\n🔵 Sapevi che sono OpenSource e cerco sempre aiuto? [/source]".format("@"+get_bot.username)
35 | bot.send_message(chat, text, reply_markup=InlineKeyboardMarkup(menu),parse_mode='HTML')
36 | else:
37 | message(update,context,languages.start.format("@"+get_bot.username))
--------------------------------------------------------------------------------
/core/commands/public/user_search.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | from core import decorators
6 | from core.utilities.functions import user_reply_object
7 | from core.utilities.message import message
8 | from core.database.repository.user import UserRepository
9 |
10 | @decorators.admin.user_admin
11 | @decorators.delete.init
12 | def init(update,context):
13 | text = update.message.text
14 | if update.message.reply_to_message:
15 | user = user_reply_object(update)
16 | row = UserRepository().getById(user.id)
17 | if row:
18 | message(update, context, text="The user search returned the following results:\nTelegram Id: {}
\nUsername: {}\nLast Update: {} [UTC]"
19 | .format(
20 | row['tg_id'],
21 | row['tg_username'],
22 | row['updated_at'].isoformat()
23 | ))
24 | else:
25 | message(update,context, text="The user is not present in the database")
26 | else:
27 | input_user_id = text[8:].strip().split(" ", 1)
28 | user_id = input_user_id[0]
29 | if user_id != "":
30 | row = UserRepository().getByUsername(user_id)
31 | if row:
32 | message(update, context, text="The user search returned the following results:\nTelegram Id: {}
\nUsername: {}\nLast Update: {} [UTC]"
33 | .format(
34 | row['tg_id'],
35 | row['tg_username'],
36 | row['updated_at'].isoformat()
37 | ))
38 | else:
39 | message(update,context, text="The user is not present in the database")
40 | else:
41 | message(update,context,"Attention the user id you entered does not exist!")
--------------------------------------------------------------------------------
/core/database/__init__.py:
--------------------------------------------------------------------------------
1 | __all__ = ["repository","db_connect","migrations","redis_connect"]
2 |
3 | from core.database import *
--------------------------------------------------------------------------------
/core/database/db_connect.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | import pymysql
6 | from pymysql import OperationalError
7 | from config import Config
8 | from loguru import logger
9 | from sqlalchemy import create_engine
10 | from core.database.migrations import Migrations
11 |
12 | """
13 | This class handles database connection and inbound queries
14 | """
15 | class Connection:
16 | def __init__(self):
17 | try:
18 | self.con = pymysql.connect(
19 | host = Config.HOST,
20 | port = Config.PORT,
21 | user = Config.USER,
22 | password = Config.PASSWORD,
23 | db = Config.DBNAME,
24 | autocommit=True,
25 | charset = 'utf8mb4',
26 | cursorclass = pymysql.cursors.DictCursor
27 | )
28 | self.cur = self.con.cursor()
29 | except OperationalError as e:
30 | logger.error(e)
31 | args = e.args
32 | self.con = pymysql.connect(
33 | host = Config.HOST,
34 | port = Config.PORT,
35 | user = Config.USER,
36 | password = Config.PASSWORD,
37 | autocommit=True,
38 | charset = 'utf8mb4',
39 | cursorclass = pymysql.cursors.DictCursor
40 | )
41 | #Pseudo Migrations
42 | if args[0] == 1049:
43 | def _execute(self,sql):
44 | self.cur = self.con.cursor()
45 | query = self.cur
46 | q = query.execute(sql)
47 | return q
48 | _execute(self,'CREATE DATABASE IF NOT EXISTS nebula')
49 | _execute(self,Migrations.OWNERS)
50 | _execute(self,Migrations.USERS)
51 | _execute(self,Migrations.GROUPS)
52 | _execute(self,Migrations.COMMUNITY)
53 | _execute(self,Migrations.GROUPS_BADWORDS)
54 | _execute(self,Migrations.GROUP_USERS)
55 | _execute(self,Migrations.NEBULA_UPDATES)
56 | logger.info('I created the nebula database and Tables')
57 | quit(1)
58 |
59 | def _select(self,sql,args=None):
60 | self.cur.execute(sql,args)
61 | self.sel = self.cur.fetchone()
62 | self.cur.close()
63 | self.con.close()
64 | return self.sel
65 |
66 | def _selectAll(self,sql,args=None):
67 | self.cur.execute(sql,args)
68 | self.sel = self.cur.fetchall()
69 | self.cur.close()
70 | self.con.close()
71 | return self.sel
72 |
73 | def _insert(self,sql,args=None):
74 | self.ins = self.cur.executemany(sql,args)
75 | return self.ins
76 |
77 | def _single_insert(self,sql,args=None):
78 | self.sins = self.cur.execute(sql,args)
79 | return self.sins
80 |
81 | def _dict_insert(self, sql, dictionary):
82 | self.dins = self.cur.execute(sql, list(dictionary.values()))
83 | return self.dins
84 |
85 | def _update(self,sql, args=None):
86 | self.upd = self.cur.executemany(sql,args)
87 | return self.upd
88 |
89 | def _delete(self, sql, args=None):
90 | self.delete = self.cur.executemany(sql,args)
91 | return self.delete
92 |
93 |
94 | class SqlAlchemyConnection:
95 | def __init__(self):
96 | self.server = '{}:{}'.format(Config.HOST,Config.PORT)
97 | self.db = Config.DBNAME
98 | self.login = Config.USER
99 | self.passwd = Config.PASSWORD
100 | self.engine_str = 'mysql+pymysql://{}:{}@{}/{}'.format(self.login, self.passwd, self.server, self.db)
101 | self.engine = create_engine(self.engine_str)
--------------------------------------------------------------------------------
/core/database/migrations.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | class Migrations(object):
7 | USERS = 'CREATE TABLE IF NOT EXISTS nebula.users (id int(11) NOT NULL,tg_id varchar(50) NOT NULL,tg_username varchar(50) NOT NULL,created_at datetime NOT NULL,updated_at datetime NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4'
8 | OWNERS = 'CREATE TABLE IF NOT EXISTS nebula.owner_list (id int(11) NOT NULL,tg_id varchar(255) NOT NULL,tg_username varchar(255) NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4'
9 | GROUPS = "CREATE TABLE IF NOT EXISTS nebula.groups (" \
10 | "id int(11) NOT NULL AUTO_INCREMENT," \
11 | "id_group varchar(50) NOT NULL," \
12 | "group_name varchar(255) NOT NULL," \
13 | "welcome_text text NOT NULL," \
14 | "welcome_buttons longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT '{}'," \
15 | "rules_text text NOT NULL," \
16 | "community tinyint(1) NOT NULL DEFAULT 0," \
17 | "languages varchar(20) DEFAULT 'EN'," \
18 | "set_welcome tinyint(2) NOT NULL DEFAULT 1," \
19 | "max_warn int(11) NOT NULL DEFAULT 3," \
20 | "set_silence tinyint(2) NOT NULL DEFAULT 0," \
21 | "exe_filter tinyint(1) NOT NULL DEFAULT 0," \
22 | "block_new_member tinyint(1) NOT NULL DEFAULT 0," \
23 | "set_arabic_filter tinyint(1) NOT NULL DEFAULT 1," \
24 | "set_cirillic_filter tinyint(1) NOT NULL DEFAULT 1," \
25 | "set_chinese_filter tinyint(1) NOT NULL DEFAULT 1," \
26 | "set_user_profile_picture tinyint(1) NOT NULL DEFAULT 0," \
27 | "gif_filter tinyint(1) NOT NULL DEFAULT 0," \
28 | "set_cas_ban tinyint(1) NOT NULL DEFAULT 1," \
29 | "type_no_username int(1) NOT NULL DEFAULT 1," \
30 | "log_channel varchar(50) NOT NULL DEFAULT '-1001359708474'," \
31 | "group_photo varchar(255) NOT NULL DEFAULT 'https://naos.hersel.it/group_photo/default.jpg'," \
32 | "total_users int(50) NOT NULL DEFAULT 0," \
33 | "zip_filter tinyint(1) NOT NULL DEFAULT 0," \
34 | "targz_filter tinyint(1) NOT NULL DEFAULT 0," \
35 | "jpg_filter tinyint(1) NOT NULL DEFAULT 0," \
36 | "docx_filter tinyint(1) NOT NULL DEFAULT 0," \
37 | "apk_filter tinyint(1) NOT NULL DEFAULT 0," \
38 | "zoophile_filter tinyint(1) NOT NULL DEFAULT 1," \
39 | "sender_chat_block tinyint(1) NOT NULL DEFAULT 1," \
40 | "spoiler_block tinyint(1) NOT NULL DEFAULT 0," \
41 | "set_no_vocal tinyint(1) NOT NULL DEFAULT 0," \
42 | "set_antiflood tinyint(1) NOT NULL DEFAULT 1," \
43 | "ban_message text NOT NULL DEFAULT '{mention} has been banned from: {chat}'",\
44 | "PRIMARY KEY (id)," \
45 | "UNIQUE KEY group_id (id_group)" \
46 | ") ENGINE=InnoDB AUTO_INCREMENT=141 DEFAULT CHARSET=utf8mb4".format('{ "buttons": [{"id": 0,"title": "Bot Logs","url": "https://t.me/nebulalogs"}]}')
47 | COMMUNITY = "CREATE TABLE IF NOT EXISTS nebula.community (id int(11) NOT NULL,tg_group_name varchar(50) DEFAULT NULL,tg_group_id varchar(50) DEFAULT NULL,tg_group_link varchar(50) DEFAULT NULL,language varchar(50) NOT NULL DEFAULT 'IT',type varchar(50) NOT NULL DEFAULT 'supergroup') ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"
48 | GROUPS_BADWORDS = "CREATE TABLE IF NOT EXISTS nebula.groups_badwords (id int(11) NOT NULL,word varchar(255) NOT NULL,tg_group_id varchar(255) NOT NULL,user_score bigint(20) NOT NULL DEFAULT 0) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"
49 | GROUP_USERS = "CREATE TABLE IF NOT EXISTS nebula.group_users (id int(11) NOT NULL,tg_id varchar(50) DEFAULT NULL,tg_group_id varchar(50) DEFAULT NULL,warn_count int(11) NOT NULL DEFAULT 0) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"
50 | NEBULA_UPDATES = "CREATE TABLE IF NOT EXISTS nebula.nebula_updates (id int(11) NOT NULL AUTO_INCREMENT,update_id varchar(255) NOT NULL,tg_group_id varchar(255) NOT NULL,tg_user_id varchar(255) NOT NULL,date datetime(6) NOT NULL,PRIMARY KEY (id),UNIQUE KEY update_index (update_id)) ENGINE=InnoDB AUTO_INCREMENT=184434 DEFAULT CHARSET=utf8mb4"
--------------------------------------------------------------------------------
/core/database/redis_connect.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | import redis
7 | from config import Config
8 | from loguru import logger
9 |
10 | class RedisConnect():
11 | def __init__(self):
12 | try:
13 | self.con = redis.Redis(
14 | host=Config.RD_HOST,
15 | port=Config.RD_PORT,
16 | password=Config.RD_PASSWORD,
17 | db=Config.RD_DB
18 | )
19 | except Exception as e:
20 | logger.error(e)
21 |
22 | def hdel(self,key,field):
23 | self.con.hdel(key,field)
24 |
25 | def hexists(self,key,field):
26 | return self.con.hexists(key,field)
27 |
28 | def hget(self,key,field):
29 | return self.con.hget(key,field)
30 |
31 | def hset(self,key,field,value):
32 | self.con.hset(key,field,value)
--------------------------------------------------------------------------------
/core/database/repository/__init__.py:
--------------------------------------------------------------------------------
1 | __all__ = [
2 | "community",
3 | "dashboard",
4 | "group",
5 | "user",
6 | "group_language",
7 | "superban"
8 | ]
9 |
10 | from core.database.repository import *
--------------------------------------------------------------------------------
/core/database/repository/community.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | from core.database.db_connect import Connection
6 | from pypika import Query, Table
7 |
8 | community = Table("community")
9 |
10 | class CommunityRepository(Connection):
11 | def getAll(self):
12 | query = Query.from_(community).select("*")
13 | q = query.get_sql(quote_char=None)
14 | return self._selectAll(q)
15 |
16 | def getById(self, args=None):
17 | query = Query.from_(community).select("*").where(community.tg_group_id == '%s')
18 | q = query.get_sql(quote_char=None)
19 |
20 | return self._select(q, args)
21 |
22 | def update(self, args=None):
23 | q = "UPDATE community SET tg_group_name = %s WHERE tg_group_id = %s"
24 | return self._update(q, args)
25 |
26 | def add(self, args=None):
27 | q = "INSERT INTO community(tg_group_name, tg_group_id, tg_group_link, language, type) VALUES (%s,%s,%s,%s,%s)"
28 | return self._insert(q, args)
29 |
30 | def getCommunityGroups(self):
31 |
32 | q = "SELECT * FROM community WHERE type = 'supergroup'"
33 |
34 | return self._selectAll(q)
35 |
36 | def getCommunityChannels(self):
37 |
38 | q = "SELECT * FROM community WHERE type = 'channel'"
39 |
40 | return self._selectAll(q)
--------------------------------------------------------------------------------
/core/database/repository/dashboard.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | from core.database.db_connect import Connection
6 | from pypika import Query, Table
7 |
8 |
9 | dashboard = Table("nebula_dashboard")
10 |
11 | class DashboardRepository(Connection):
12 |
13 | def getById(self, args=None):
14 | query = Query.from_(dashboard).select("*").where(dashboard.tg_id == "%s")
15 | q = query.get_sql(quote_char=None)
16 |
17 | return self._select(q, args)
18 |
19 | def getByGroupId(self, args=None):
20 | query = Query.from_(dashboard).select("*").where(dashboard.tg_group_id == "%s")
21 | q = query.get_sql(quote_char=None)
22 |
23 | return self._select(q, args)
24 |
25 | def getByUsername(self, args=None):
26 | q = "SELECT * FROM nebula_dashboard WHERE tg_username = %s"
27 |
28 | return self._select(q, args)
29 |
30 | def getUserAndGroup(self, args=None):
31 | q = "SELECT * FROM nebula_dashboard WHERE tg_group_id = %s AND tg_id = %s"
32 |
33 | return self._select(q, args)
34 |
35 | def add(self, args=None):
36 | q = "INSERT INTO nebula_dashboard (tg_id, tg_username, tg_group_id, enable, role, created_at, updated_at) VALUES (%s,%s,%s,%s,%s,%s,%s)"
37 | return self._insert(q, args)
38 |
39 | def update(self, args=None):
40 | q = "UPDATE nebula_dashboard SET tg_username = %s, role = %s, updated_at = %s WHERE tg_id = %s AND tg_group_id = %s"
41 | return self._update(q, args)
--------------------------------------------------------------------------------
/core/database/repository/group.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | from core.database.db_connect import Connection
6 | from pypika import Query, Table
7 |
8 | groups = Table("groups")
9 | whitelist_channels = Table("whitelist_channel")
10 |
11 | class GroupRepository(Connection):
12 | ###### Column constants of the table ######
13 | SET_ID_GROUP = "id_group"
14 | SET_GROUP_NAME = "group_name"
15 | SET_WELCOME_TEXT = "welcome_text"
16 | SET_WELCOME_BUTTONS = "welcome_buttons"
17 | SET_RULES_TEXT = "rules_text"
18 | SET_COMMUNITY = "community"
19 | SET_LANGUAGE = "languages"
20 | SET_WELCOME = "set_welcome"
21 | SET_MAX_WARN = "max_warn"
22 | SET_SILENCE = "set_silence"
23 | EXE_FILTER = "exe_filter"
24 | SET_BLOCK_N_M = "block_new_member"
25 | SET_ARABIC = "set_arabic_filter"
26 | SET_CIRILLIC = "set_cirillic_filter"
27 | SET_CHINESE = "set_chinese_filter"
28 | SET_USER_PROFILE_PICT = "set_user_profile_picture"
29 | GIF_FILTER = "gif_filter"
30 | SET_CAS_BAN = "set_cas_ban"
31 | SET_TPNU = "type_no_username"
32 | SET_LOG_CHANNEL = "log_channel"
33 | SET_GROUP_PHOTO = "group_photo"
34 | SET_GROUP_MEMBERS_COUNT = "total_users"
35 | ZIP_FILTER = "zip_filter"
36 | TARGZ_FILTER = "targz_filter"
37 | JPG_FILTER = "jpg_filter"
38 | DOCX_FILTER = "docx_filter"
39 | APK_FILTER = "apk_filter"
40 | ZOOPHILE_FILTER = "zoophile_filter"
41 | SENDER_CHAT_BLOCK = "sender_chat_block"
42 | SPOILER_BLOCK = "spoiler_block"
43 | SET_NO_VOCAL = "set_no_vocal"
44 | SET_ANTIFLOOD = "set_antiflood"
45 | BAN_MESSAGE = "ban_message"
46 | CREATED_AT = "created_at"
47 | UPDATED_AT = "updated_at"
48 | SET_GH = "set_gh"
49 |
50 | def getById(self, args=None):
51 | query = Query.from_(groups).select("*").where(groups.id_group == '%s')
52 | q = query.get_sql(quote_char=None)
53 |
54 | return self._select(q, args)
55 |
56 | def getAllById(self, args=None):
57 | query = Query.from_(groups).select("*").where(groups.id_group == '%s')
58 | q = query.get_sql(quote_char=None)
59 |
60 | return self._selectAll(q, args)
61 |
62 | def getAll(self):
63 | query = Query.from_(groups).select("*")
64 | q = query.get_sql(quote_char=None)
65 |
66 | return self._selectAll(q)
67 |
68 | # Save group by Welcome
69 | def add_with_dict(self,dictionary):
70 | placeholders = ', '.join(['%s'] * len(dictionary))
71 | columns = ', '.join(dictionary.keys())
72 | sql = "INSERT INTO groups ( %s ) VALUES ( %s )" % (columns, placeholders) # pylint: disable-this-line-in-some-way
73 | return self._dict_insert(sql, dictionary)
74 |
75 | #Update welcome buttons
76 | def updateWelcomeButtonsByGroupId(self, group_id, button):
77 | query = Query.update(groups).set(groups.welcome_buttons, '%s').where(groups.id_group == '%s')
78 | query = query.get_sql(quote_char='`')
79 | query = query.replace("'", "")
80 |
81 | self._update(query, [(button, group_id)])
82 |
83 | # I update the group id if the group changes from group to supergroup
84 | def update(self, args=None):
85 | q = "UPDATE groups SET id_group = %s WHERE id_group = %s"
86 | return self._update(q, args)
87 |
88 | # I insert the updates for the message count by group
89 | def insert_updates(self, args=None):
90 | q = "INSERT INTO nebula_updates (update_id, message_id, tg_group_id, tg_user_id, date) VALUES (%s,%s,%s,%s,%s)"
91 | return self._insert(q, args)
92 |
93 | # I collect the updates to know how many messages have been sent
94 | def getUpdatesByChatMonth(self, args=None):
95 | q = 'SELECT COUNT(*) AS counter FROM nebula_updates WHERE date BETWEEN DATE_SUB(NOW(), INTERVAL 31 DAY) AND NOW() AND tg_group_id = %s ORDER BY date DESC'
96 |
97 | return self._select(q, args)
98 |
99 | def getUpdatesByUserMonth(self, args=None):
100 | q = 'SELECT COUNT(*) AS counter FROM nebula_updates WHERE DATE BETWEEN DATE_SUB(NOW(), INTERVAL 30 DAY) AND NOW() AND tg_group_id = %s AND tg_user_id = %s ORDER BY DATE DESC'
101 |
102 | return self._select(q, args)
103 |
104 | def getAllUpdates(self):
105 | q = 'SELECT COUNT(*) AS counter FROM nebula_updates'
106 |
107 | return self._select(q)
108 |
109 | def change_group_photo(self, args=None):
110 | q = "INSERT INTO groups SET group_photo = %s WHERE id_group = %s"
111 |
112 | return self._insert(q, args)
113 |
114 | def get_group_badwords(self, args=None):
115 | q = "SELECT * FROM groups_badwords WHERE INSTR(%s, word) <> 0 AND tg_group_id = %s"
116 |
117 | return self._select(q, args)
118 |
119 | def get_antispam_logic(self, args=None):
120 | q = "SELECT logic FROM nebula_antispam WHERE INSTR(%s, logic) <> 0"
121 |
122 | return self._select(q, args)
123 |
124 | def get_badwords_group(self, args=None):
125 | q = "SELECT * FROM groups_badwords WHERE tg_group_id = %s"
126 |
127 | return self._selectAll(q, args)
128 |
129 | def insert_badword(self, args=None):
130 | q = "INSERT IGNORE INTO groups_badwords (word, tg_group_id) VALUES (%s,%s)"
131 |
132 | return self._insert(q, args)
133 |
134 | def insert_spam(self, args=None):
135 | q = "INSERT IGNORE INTO nebula_antispam (logic) VALUES (%s)"
136 |
137 | return self._single_insert(q, args)
138 |
139 |
140 | def remove(self, args=None):
141 | q = "DELETE FROM groups WHERE id_group = %s"
142 | return self._delete(q, args)
143 |
144 | def get_custom_handler(self, args=None):
145 | q = "SELECT answer FROM custom_handler WHERE question = %s AND chat_id = %s"
146 |
147 | return self._select(q, args)
148 |
149 | def insert_custom_handler(self, args=None):
150 | q = "INSERT INTO custom_handler (chat_id, question, answer) VALUES (%s,%s,%s)"
151 |
152 | return self._insert(q, args)
153 |
154 | def getTopActiveUsers(self, args=None):
155 |
156 | q = "SELECT COUNT(*) AS counter, u.tg_username, u.tg_id FROM nebula_updates nu INNER JOIN users u ON u.tg_id = nu.tg_user_id WHERE DATE BETWEEN DATE_SUB(NOW(), INTERVAL 30 DAY) AND NOW() AND nu.tg_group_id = %s GROUP BY nu.tg_user_id ORDER BY counter DESC LIMIT 10"
157 |
158 | return self._selectAll(q, args)
159 |
160 | def getTopInactiveUsers(self, args=None):
161 |
162 | q = "SELECT COUNT(*) AS counter, u.tg_username, u.tg_id FROM nebula_updates nu INNER JOIN users u ON u.tg_id = nu.tg_user_id WHERE DATE BETWEEN DATE_SUB(NOW(), INTERVAL 30 DAY) AND NOW() AND nu.tg_group_id = %s GROUP BY nu.tg_user_id ORDER BY counter ASC LIMIT 10"
163 |
164 | return self._selectAll(q, args)
165 |
166 | ##########################
167 | ##### GROUP SETTINGS #####
168 | ##########################
169 |
170 | def set_block_entry(self, args=None):
171 | q = "UPDATE groups SET set_welcome = %s, block_new_member = %s WHERE id_group = %s"
172 | return self._update(q, args)
173 |
174 | def update_group_settings(self, record, args=None):
175 | q = "UPDATE groups SET @record = %s WHERE id_group = %s".replace('@record',record)
176 | return self._update(q, args)
177 |
178 | def job_nebula_updates(self, args=None):
179 | q = "DELETE FROM nebula_updates WHERE date < NOW() - INTERVAL 90 DAY"
180 | return self._delete(q, args)
181 |
--------------------------------------------------------------------------------
/core/database/repository/group_language.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | from core.database.db_connect import Connection
6 | from pypika import Query, Table
7 |
8 |
9 | class GroupLanguageRepository(Connection):
10 | def getById(self, args=None):
11 | groups = Table("groups")
12 | query = Query.from_(groups).select(groups.languages).where(groups.id_group == '%s')
13 | q = query.get_sql(quote_char=None)
14 |
15 | return self._select(q, args)
--------------------------------------------------------------------------------
/core/database/repository/superban.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | from core.database.db_connect import Connection
6 | from pypika import Query, Table
7 |
8 | superban = Table("superban_table")
9 | whitelist = Table("whitelist_table")
10 | group_blacklist = Table("groups_blacklist")
11 |
12 | class SuperbanRepository(Connection):
13 | def getById(self, args=None):
14 | query = Query.from_(superban).select("*").where(superban.user_id == '%s')
15 | q = query.get_sql(quote_char=None)
16 |
17 | return self._select(q, args)
18 |
19 | def getWhitelistById(self, args=None):
20 | query = Query.from_(whitelist).select("*").where(whitelist.tg_id == '%s')
21 | q = query.get_sql(quote_char=None)
22 |
23 | return self._select(q, args)
24 |
25 | def getGroupBlacklistById(self, args=None):
26 | query = Query.from_(group_blacklist).select("*").where(group_blacklist.tg_id_group == '%s')
27 | q = query.get_sql(quote_char=None)
28 |
29 | return self._select(q, args)
30 |
31 | def addWhitelist(self, args=None):
32 | q = "INSERT IGNORE INTO whitelist_table(tg_id, tg_username) VALUES (%s,%s)"
33 | return self._insert(q, args)
34 |
35 | def getAll(self, args=None):
36 | query = Query.from_(superban).select("user_id").where(superban.user_id == '%s')
37 | q = query.get_sql(quote_char=None)
38 |
39 | return self._selectAll(q, args)
40 |
41 | def add(self, args=None):
42 | q = "INSERT IGNORE INTO superban_table(user_id, user_first_name, motivation_text, user_date, id_operator, username_operator, first_name_operator) VALUES (%s,%s,%s,%s,%s,%s,%s)"
43 | return self._insert(q, args)
44 |
45 | def remove(self, args=None):
46 | q = "DELETE FROM superban_table WHERE user_id = %s"
47 | return self._delete(q, args)
--------------------------------------------------------------------------------
/core/database/repository/user.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | from core.database.db_connect import Connection
6 | from pypika import Query, Table
7 |
8 | users = Table("users")
9 | owners = Table("owner_list")
10 |
11 | class UserRepository(Connection):
12 | def getById(self, args=None):
13 | query = Query.from_(users).select("*").where(users.tg_id == "%s")
14 | q = query.get_sql(quote_char=None)
15 |
16 | return self._select(q, args)
17 |
18 | def getByUsername(self, args=None):
19 | q = "SELECT * FROM users WHERE tg_username = %s"
20 |
21 | return self._select(q, args)
22 |
23 | def getUserByGroup(self, args=None):
24 | q = "SELECT u.tg_id,u.tg_username,gr.id_group,gu.warn_count, gr.max_warn, gr.group_name FROM users u INNER JOIN group_users gu ON gu.tg_id = u.tg_id INNER JOIN groups gr ON gu.tg_group_id = gr.id_group WHERE u.tg_id = %s AND gr.id_group = %s"
25 | return self._select(q, args)
26 |
27 | def getUserByGroups(self, args=None):
28 | q = "SELECT u.tg_id,u.tg_username,gr.id_group,gu.warn_count, gr.max_warn, gr.group_name FROM users u INNER JOIN group_users gu ON gu.tg_id = u.tg_id INNER JOIN groups gr ON gu.tg_group_id = gr.id_group WHERE u.tg_id = %s"
29 | return self._selectAll(q, args)
30 |
31 | def getAll(self, args=None):
32 | query = Query.from_(users).select("*").where(users.tg_id == "%s")
33 | q = query.get_sql(quote_char=None)
34 |
35 | return self._selectAll(q, args)
36 |
37 | def add(self, args=None):
38 | q = "INSERT IGNORE INTO users (tg_id, tg_username, created_at, updated_at) VALUES (%s,%s,%s,%s)"
39 | return self._insert(q, args)
40 |
41 | def add_owner(self, args=None):
42 | q = "INSERT IGNORE INTO owner_list (tg_id, tg_username) VALUES (%s,%s)"
43 | return self._insert(q, args)
44 |
45 | def remove_owner(self, args=None):
46 | q = "DELETE FROM owner_list WHERE tg_id = %s"
47 | return self._delete(q, args)
48 |
49 | def add_into_mtm(self, args=None):
50 | q = "INSERT IGNORE INTO group_users (tg_id, tg_group_id, warn_count, user_score) VALUES (%s,%s,%s,%s)"
51 | return self._insert(q, args)
52 |
53 | def update(self, args=None):
54 | q = "UPDATE users SET tg_username = %s, updated_at = %s WHERE tg_id = %s"
55 | return self._update(q, args)
56 |
57 | def delete_user(self, args=None):
58 | q = "DELETE FROM users WHERE tg_id = %s"
59 | return self._delete(q, args)
60 |
61 | def updateWarn(self, args=None):
62 | q = "UPDATE group_users SET warn_count = warn_count + 1 WHERE tg_id = %s AND tg_group_id = %s"
63 | return self._update(q, args)
64 |
65 | def downWarn(self, args=None):
66 | q = "UPDATE group_users SET warn_count = warn_count - 1 WHERE tg_id = %s AND tg_group_id = %s"
67 | return self._update(q, args)
68 |
69 | def removeWarn(self, args=None):
70 | q = "UPDATE group_users SET warn_count = 0 WHERE tg_id = %s AND tg_group_id = %s"
71 | return self._update(q, args)
72 |
73 | def getOwners(self):
74 | query = Query.from_(owners).select("*")
75 | q = query.get_sql(quote_char=None)
76 |
77 | return self._selectAll(q)
78 |
79 | def getOwnerById(self, args=None):
80 | query = Query.from_(owners).select("*").where(owners.tg_id == "%s")
81 | q = query.get_sql(quote_char=None)
82 |
83 | return self._select(q, args)
--------------------------------------------------------------------------------
/core/decorators/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | """
7 | Import Files
8 | """
9 | __all__ = ["admin","bot","delete","owner","private","public"]
10 |
11 | from core.decorators import *
--------------------------------------------------------------------------------
/core/decorators/admin.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | from functools import wraps
6 | from core.decorators.owner import OWNER_LIST
7 |
8 | TITLES = ['creator', 'administrator']
9 |
10 | def user_admin(func):
11 | @wraps(func)
12 | def wrapped(update, context):
13 | user_id = update.effective_user
14 | try:
15 | stat = context.bot.get_chat_member(update.message.chat_id, update.effective_user['id'])['status']
16 | except:
17 | stat = context.bot.get_chat_member(update.callback_query.message.chat_id, update.callback_query.from_user['id'])['status']
18 | if (user_id['id'] not in OWNER_LIST) and (stat not in TITLES):
19 | print("Unauthorized access denied for {}.".format(user_id['id']))
20 | return
21 | return func(update, context)
22 | return wrapped
--------------------------------------------------------------------------------
/core/decorators/bot.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | from functools import wraps
6 | from core.utilities.functions import bot_object
7 |
8 | def check_is_admin(func):
9 | @wraps(func)
10 | def wrapped(update, context):
11 | bot = bot_object(update, context)
12 | chat = update.effective_message.chat_id
13 | get_bot = bot.getChatMember(chat,bot.id)
14 | if get_bot.status == 'administrator':
15 | print("is_admin")
16 | else:
17 | update.effective_message.reply_text("I'm not admin!")
18 | return False
19 | return func(update, context)
20 | return wrapped
21 |
22 | def check_can_delete(func):
23 | @wraps(func)
24 | def wrapped(update, context):
25 | bot = bot_object(update, context)
26 | chat = update.effective_message.chat_id
27 | get_bot = bot.getChatMember(chat,bot.id)
28 | perm_delete = get_bot.can_delete_messages
29 | print(perm_delete)
30 | if perm_delete is not False or not None:
31 | print("can_delete")
32 | else:
33 | update.effective_message.reply_text("I can't delete messages here!\nMake sure I'm admin and can delete other user's messages.")
34 | return False
35 | return func(update, context)
36 | return wrapped
--------------------------------------------------------------------------------
/core/decorators/delete.py:
--------------------------------------------------------------------------------
1 | from functools import wraps
2 |
3 | def init(func):
4 | @wraps(func)
5 | def wrapped(update, context):
6 | bot = context.bot
7 | if update.message.text is not None:
8 | if update.message.text.startswith("/"):
9 | bot.delete_message(update.effective_message.chat_id, update.message.message_id)
10 | else:
11 | print("AAA")
12 | return func(update, context)
13 | return wrapped
--------------------------------------------------------------------------------
/core/decorators/owner.py:
--------------------------------------------------------------------------------
1 | from functools import wraps
2 | from core.utilities.functions import get_owner_list
3 |
4 | OWNER_LIST = get_owner_list()
5 |
6 | def init(func):
7 | @wraps(func)
8 | def wrapped(update, context):
9 | if update.effective_user is not None:
10 | user_id = update.effective_user.id
11 | if user_id not in OWNER_LIST:
12 | print("Unauthorized access denied for {}.".format(user_id))
13 | return
14 | else:
15 | return False
16 | return func(update, context)
17 | return wrapped
--------------------------------------------------------------------------------
/core/decorators/private.py:
--------------------------------------------------------------------------------
1 | def init(fn):
2 | def wrapper(*args,**kwargs):
3 | message = args[0].message
4 | if message.chat.type == 'private':
5 | return fn(*args,**kwargs)
6 | else:
7 | return False
8 | return wrapper
--------------------------------------------------------------------------------
/core/decorators/public.py:
--------------------------------------------------------------------------------
1 | def init(fn):
2 | def wrapper(update,context):
3 | chat = update.effective_chat
4 | if chat.type == 'supergroup' or chat.type == 'group':
5 | return fn(update,context)
6 | else:
7 | return False
8 | return wrapper
--------------------------------------------------------------------------------
/core/handlers/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | __all__ = ["check_status_chat","check_status_user","custom_handler","errors","filters_chat","flood_wait","handler_errors","handlers_index","logs","welcome"]
6 |
7 | from core.handlers import *
--------------------------------------------------------------------------------
/core/handlers/check_status_user.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | import datetime
6 | from core import decorators
7 | from core.utilities.constants import *
8 | from core.utilities.message import message
9 | from core.database.repository.user import UserRepository
10 | from core.handlers.flood_wait import Flood_Manager_Python
11 | from core.database.repository.group import GroupRepository
12 | from core.database.repository.superban import SuperbanRepository
13 | from core.database.repository.dashboard import DashboardRepository
14 | from core.utilities.functions import user_object, chat_object, ban_user, kick_user, delete_message, mute_user_by_id, member_status_object, chat_status_object, check_user_permission
15 |
16 | flood_manager = Flood_Manager_Python()
17 |
18 | @decorators.public.init
19 | def check_status(update,context):
20 | # Telegram Variables
21 | bot = context.bot
22 | chat = chat_object(update)
23 | user = user_object(update)
24 | get_superban_user_id = update.effective_user.id
25 | user_photo = user.get_profile_photos(user.id)
26 | user_status = member_status_object(update,context)
27 | chat_status = chat_status_object(update, context)
28 |
29 | #Get Group via Database
30 | get_group = GroupRepository().getById(chat.id)
31 | #Get User via Database
32 | user_db = UserRepository().getById(user.id)
33 | #Get User via Database in Many to Many Association
34 | get_user = UserRepository().getUserByGroup([user.id,chat.id])
35 | #Get User in Superban Table
36 | get_superban = SuperbanRepository().getById(get_superban_user_id)
37 | #get user in Dashboard
38 | get_dashboard = DashboardRepository().getById(user.id)
39 | #Get User Warn
40 | warn_count = get_user['warn_count'] if get_user is not None else DEFAULT_COUNT_WARN
41 | #Get Max Warn in group
42 | max_warn = get_group['max_warn'] if get_group is not None else DEFAULT_MAX_WARN
43 |
44 | if get_group:
45 | user_set_photo = get_group['set_user_profile_picture']
46 | type_no_username = get_group['type_no_username']
47 | else:
48 | user_set_photo = 0
49 | #Check if the user has a username if he does not have a username I perform a temporary kick and check that the user is not a service account
50 | if update.effective_user.id == SERVICE_ACCOUNT:
51 | print("Service Account")
52 | elif user.username is None or user.username == "":
53 | if type_no_username == 1:
54 | kick_user(update, context)
55 | msg = "#Automatic Handler\n{}
set an username! You were kicked for safety!"
56 | message(update,context,msg.format(user.id))
57 | elif type_no_username == 2:
58 | msg = "#Automatic Handler\n{}
set an username!"
59 | message(update,context,msg.format(user.id))
60 | elif type_no_username == 3:
61 | mute_user_by_id(update, context, user.id, True)
62 | msg = "#Automatic Handler\n{}
set an username! You were Muted for safety!"
63 | message(update,context,msg.format(user.id))
64 | elif type_no_username == 4:
65 | ban_user(update,context)
66 | msg = "#Automatic Handler\n{}
was banned because they didn't have an username"
67 | message(update,context,msg.format(user.id))
68 | elif type_no_username == 5:
69 | kick_user(update, context)
70 | else:
71 | print("No action even if you don't have a username")
72 | else:
73 | #Check if the user exists on the database if it exists makes an update of his username and his latest update if not exist insert it
74 | if user_db:
75 | #Get the Current Time
76 | current_time = datetime.datetime.utcnow().isoformat()
77 | username = "@"+user.username
78 | data = [(username,current_time,user.id)]
79 | UserRepository().update(data)
80 | data_mtm = [(user.id, chat.id, DEFAULT_COUNT_WARN,DEFAULT_USER_SCORE)]
81 | UserRepository().add_into_mtm(data_mtm)
82 | else:
83 | #Get the Current Time
84 | current_time = datetime.datetime.utcnow().isoformat()
85 | username = "@"+user.username
86 | data = [(user.id,username,current_time,current_time)]
87 | UserRepository().add(data)
88 | data_mtm = [(user.id, chat.id, DEFAULT_COUNT_WARN,DEFAULT_USER_SCORE)]
89 | UserRepository().add_into_mtm(data_mtm)
90 | #Check if the user has a profile photo
91 | if user_photo.total_count == 0 and user_set_photo == 1:
92 | kick_user(update, context)
93 | msg = "#Automatic Handler\n{}
set a profile picture! You were kicked for safety!"
94 | message(update,context,msg.format(user.id))
95 | #Check if the user has been blacklisted
96 | if get_superban:
97 | superban_reason = get_superban['motivation_text']
98 | msg = '#Automatic Handler\nI got super banned {} [{}]
\nFor the following Reason: {}'.format(user.id,user.first_name,user.id,superban_reason)
99 | message(update,context,msg)
100 | delete_message(update,context)
101 | ban_user(update,context)
102 | #If a user is enabled on the dashboard, I perform an update
103 | if get_dashboard:
104 | username = "@"+user.username
105 | save_date = datetime.datetime.utcnow().isoformat()
106 | dash_data = [(username, user_status.status, save_date, user.id, chat_status.id)]
107 | DashboardRepository().update(dash_data)
108 | #Check if the user has reached the maximum number of warns and ban him
109 | if warn_count == max_warn and check_user_permission(update,context) == False:
110 | ban_user(update,context)
111 | msg = "#Automatic Handler\n{}
has reached the maximum number of warns"
112 | message(update,context,msg.format(user.id))
113 | #I run an antiflood check if a user exceeds the allowed limit the antiflood starts working
114 | if flood_manager.check_flood_wait(update) == 1 and get_group['set_antiflood'] == 1 and check_user_permission(update,context) == False:
115 | bot.delete_message(update.effective_message.chat_id, update.message.message_id)
116 | kick_user(update, context)
117 | msg = "#Automatic Handler\n{}
has been kicked for flood".format(user.id)
118 | message(update,context,msg.format(user.id))
--------------------------------------------------------------------------------
/core/handlers/custom_handler.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | from core.utilities.functions import chat_object, user_object
7 | from core.utilities.message import message
8 | from core.database.repository.group import GroupRepository
9 | from telegram.utils.helpers import mention_html
10 |
11 | def init(update,context):
12 | if str(update.effective_message.text).lower().startswith("nebula") or str(update.effective_message.text).lower().startswith("!") or str(update.effective_message.text).lower().startswith("/"):
13 | chat = chat_object(update)
14 | user = user_object(update)
15 | question = str(update.message.text.lower())
16 | row = GroupRepository().get_custom_handler([question,chat.id])
17 | if row:
18 | parsed_message = row['answer'].replace('{first_name}',
19 | user.first_name).replace('{chat}',
20 | update.message.chat.title).replace('{username}',
21 | "@"+user.username).replace('{mention}',mention_html(user.id, user.first_name)).replace('{userid}',str(user.id))
22 | text = "{}".format(parsed_message)
23 | message(update,context,text)
24 | else:
25 | return
--------------------------------------------------------------------------------
/core/handlers/errors.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | import html
7 | import json
8 | import logging
9 | import traceback
10 | from telegram import Update, ParseMode
11 | from telegram.ext import CallbackContext
12 |
13 | logging.basicConfig(
14 | format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO
15 | )
16 |
17 | logger = logging.getLogger(__name__)
18 |
19 | DEVELOPER_CHAT_ID = 1065189838
20 |
21 | #ERROR HANDLER 3.0
22 | def error_handler(update: Update, context: CallbackContext) -> None:
23 | """Log the error and send a telegram message to notify the developer."""
24 | # Log the error before we do anything else, so we can see it even if something breaks.
25 | logger.error(msg="Exception while handling an update:", exc_info=context.error)
26 |
27 | # traceback.format_exception returns the usual python message about an exception, but as a
28 | # list of strings rather than a single string, so we have to join them together.
29 | tb_list = traceback.format_exception(None, context.error, context.error.__traceback__)
30 | tb_string = ''.join(tb_list)
31 |
32 | # Build the message with some markup and additional information about what happened.
33 | # You might need to add some logic to deal with messages longer than the 4096 character limit.
34 | message = (
35 | 'An exception was raised while handling an update\n'
36 | '
update = {}\n\n' 37 | '
context.chat_data = {}\n\n' 38 | '
context.user_data = {}\n\n' 39 | '
{}' 40 | ).format( 41 | html.escape(json.dumps(update.to_dict(), indent=2, ensure_ascii=False)), 42 | html.escape(str(context.chat_data)), 43 | html.escape(str(context.user_data)), 44 | html.escape(tb_string), 45 | ) 46 | 47 | # Finally, send the message 48 | context.bot.send_message(chat_id=DEVELOPER_CHAT_ID, text=message, parse_mode=ParseMode.HTML) -------------------------------------------------------------------------------- /core/handlers/filters_chat.py: -------------------------------------------------------------------------------- 1 | from core.utilities.functions import delete_message 2 | from core.utilities.message import message 3 | from core.database.repository.group import GroupRepository 4 | """ 5 | This function allows you to terminate the type 6 | of file that contains a message on telegram and filter it 7 | """ 8 | def init(update, context): 9 | # Mime Types 10 | apk = 'application/vnd.android.package-archive' 11 | doc = 'application/msword' 12 | docx = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' 13 | exe = 'application/x-ms-dos-executable' 14 | gif = 'video/mp4' 15 | jpg = 'image/jpeg' 16 | mp3 = 'audio/mpeg' 17 | pdf = 'application/pdf' 18 | py = 'text/x-python' 19 | svg = 'image/svg+xml' 20 | txt = 'text/plain' 21 | targz = 'application/x-compressed-tar' 22 | wav = 'audio/x-wav' 23 | xml = 'application/xml' 24 | filezip = 'application/zip' 25 | 26 | #Variables 27 | msg = update.effective_message 28 | chat = update.effective_message.chat_id 29 | group = GroupRepository().getById(chat) 30 | 31 | #Start Control 32 | if msg.document is not None: 33 | #No APK Allowed 34 | if msg.document.mime_type == apk and group['apk_filter'] == 1: 35 | delete_message(update,context) 36 | message(update, context, "#Automatic Filter Handler: No APK Allowed!") 37 | #No DOC/DOCX Allowed 38 | if msg.document.mime_type == doc or msg.document.mime_type == docx and group['docx_filter'] == 1: 39 | delete_message(update,context) 40 | message(update, context, "#Automatic Filter Handler: No DOC/DOCX Allowed!") 41 | #No EXE Allowed 42 | if msg.document.mime_type == exe and group['exe_filter'] == 1: 43 | delete_message(update,context) 44 | message(update, context, "#Automatic Filter Handler: No EXE Allowed!") 45 | #No GIF Allowed 46 | if msg.document.mime_type == gif and group['gif_filter'] == 1: 47 | delete_message(update,context) 48 | message(update, context, "#Automatic Filter Handler: No GIF Allowed!") 49 | #No JPG Allowed 50 | if msg.document.mime_type == jpg and group['jpg_filter'] == 1: 51 | delete_message(update,context) 52 | message(update, context, "#Automatic Filter Handler: No JPG Allowed!") 53 | #No TARGZ Allowed 54 | if msg.document.mime_type == targz and group['targz_filter'] == 1: 55 | delete_message(update,context) 56 | message(update, context, "#Automatic Filter Handler: No TARGZ Allowed!") 57 | #No ZIP Allowed 58 | if msg.document.mime_type == filezip and group['zip_filter'] == 1: 59 | delete_message(update,context) 60 | message(update, context, "#Automatic Filter Handler: No ZIP Allowed!") 61 | if msg.document.mime_type == wav: 62 | print("NO WAV ALLOWED") 63 | if msg.document.mime_type == xml: 64 | print("NO XML ALLOWED") 65 | if msg.document.mime_type == mp3: 66 | print("NO MP3 ALLOWED") 67 | if msg.document.mime_type == pdf: 68 | print("NO PDF ALLOWED") 69 | if msg.document.mime_type == py: 70 | print("NO PY ALLOWED") 71 | if msg.document.mime_type == svg: 72 | print("NO SVG ALLOWED") 73 | if msg.document.mime_type == txt: 74 | print("NO TXT ALLOWED") -------------------------------------------------------------------------------- /core/handlers/flood_wait.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # Copyright SquirrelNetwork 5 | # Credits LakyDev 6 | 7 | import json 8 | from typing import List 9 | from core.database.redis_connect import RedisConnect 10 | from time import time 11 | 12 | 13 | class Flood_Manager_Python(RedisConnect): 14 | def __init__(self): 15 | super().__init__() 16 | self._knows_gids: List[str] = [] 17 | 18 | def _register_id(self, user_id: int, chat_id: int, group_id: int): 19 | self._knows_gids.append(f'{chat_id}{user_id}{group_id}') 20 | 21 | def _is_known_id(self, user_id: int, chat_id: int, group_id: int) -> bool: 22 | return f'{chat_id}{user_id}{group_id}' in self._knows_gids 23 | 24 | def check_flood_wait(self,update) -> int: 25 | # 0 = No Flood 26 | # 1 = Flood Start 27 | # 2 = Flood Wait 28 | 29 | user_id = update.effective_user.id 30 | chat_id = update.effective_chat.id 31 | media_id = update.effective_message.media_group_id 32 | if media_id is not None: 33 | if self._is_known_id(user_id, chat_id, media_id): 34 | return 0 35 | else: 36 | self._register_id(user_id, chat_id, media_id) 37 | 38 | id_data = f'{chat_id}:{user_id}' 39 | now_time = int(time()) 40 | if not self.hexists('groups',chat_id): 41 | self.update_group_data(chat_id, 5, 5, 30) 42 | print("No Group Data") 43 | else: 44 | chat_data = json.loads(self.hget('groups',chat_id)) 45 | self.hget('groups', chat_id) 46 | get_data = { 47 | 'messages': 1, 48 | 'last_message': now_time, 49 | } 50 | if self.hexists('flood_wait', id_data): 51 | get_data = json.loads(self.hget('flood_wait', id_data)) 52 | if get_data['messages'] >= chat_data['max_message']: 53 | mute_time = (get_data['last_message'] + chat_data['mute_time']) - now_time 54 | if mute_time > 0: 55 | return 2 56 | else: 57 | get_data['last_message'] = now_time 58 | get_data['messages'] = 1 59 | else: 60 | limit_exceeded = now_time - get_data['last_message'] > chat_data['max_time'] 61 | get_data['messages'] = 0 if limit_exceeded else get_data['messages'] + 1 62 | get_data['last_message'] = now_time if limit_exceeded else get_data['last_message'] 63 | self.hset('flood_wait', id_data, json.dumps(get_data)) 64 | return 1 if get_data['messages'] >= chat_data['max_message'] else 0 65 | 66 | def update_group_data(self, chat_id, max_time, max_message, mute_time): 67 | self.hset('groups', chat_id, json.dumps({'max_time': max_time, 'max_message': max_message,'mute_time': mute_time})) 68 | 69 | 70 | #print(check_flood_wait('-1001497049823', 1065189838)) 71 | -------------------------------------------------------------------------------- /core/handlers/handler_errors.py: -------------------------------------------------------------------------------- 1 | import logging 2 | from config import Config 3 | from telegram.error import (TelegramError, Unauthorized, BadRequest, TimedOut, ChatMigrated, NetworkError) 4 | from core.utilities.message import message 5 | 6 | 7 | def init(update, context): 8 | txt = update.message.text 9 | err = '[error]' 10 | try: 11 | raise context.error 12 | except Unauthorized: 13 | err = '🔴 [ERROR]:
Unauthorized
\n'
14 | # remove update.message.chat_id from conversation list
15 | except BadRequest:
16 | err = '🔴 [ERROR]: BadRequest - malformed requests
\n'
17 | # handle malformed requests - read more below!
18 | except TimedOut:
19 | err = '🔴 [ERROR]: TimedOut - slow connection problems
\n'
20 | # handle slow connection problems
21 | except NetworkError:
22 | err = '🔴 [ERROR]: NetworkError - other connection problems
\n'
23 | # handle other connection problems
24 | except ChatMigrated:
25 | err = '🔴 [ERROR]: ChatMigrated - chat_id not found (maybe group/channel migrated?)
\n'
26 | # the chat_id of a group has changed, use e.new_chat_id instead
27 | except TelegramError:
28 | err = '🔴 [ERROR]: TelegramError\nThis is a generic error not handled by other handlers, check the console logs for info
\n'
29 | # handle all other telegram related errors
30 | except AttributeError:
31 | err = '🔴 [ERROR]: AttributeError - bad code
'
32 | except TypeError:
33 | # err = '[ERROR] TypeError - Unknown'
34 | # need to fix this...
35 | err = None
36 |
37 | if err != None:
38 | error_message(update, context, err, txt)
39 |
40 | logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO)
41 | logger = logging.getLogger(__name__)
42 | def error_message(update, context, err, txt):
43 | chat_id = Config.DEVELOPER_CHAT_ID
44 | log = '\n🔵 [LOG_ERROR]: {}
'.format(context.error)
45 | txt = "🤖 Bot Command: {}\n\n{}{}".format(txt, err, log)
46 | message(update, context, txt, 'HTML', 'messageid', chat_id, None)
--------------------------------------------------------------------------------
/core/handlers/handlers_index.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | from core import handlers
6 | from core.commands import public
7 | from telegram.ext import (MessageHandler as MH,Filters)
8 | from core.utilities import constants
9 | from core import jobs
10 |
11 | def core_handlers(dsp):
12 | function = dsp.add_handler
13 | function(MH(Filters.status_update.new_chat_members, handlers.welcome.init, run_async=True))
14 | function(MH(Filters.chat_type, group_handlers, run_async=True))
15 |
16 | def group_handlers(update,context):
17 | handlers.check_status_user.check_status(update, context)
18 | handlers.check_status_chat.check_status(update, context)
19 | handlers.check_status_chat.check_updates(update)
20 | handlers.custom_handler.init(update, context)
21 | public.report.init(update,context)
22 | public.eggs.egg_gh(update,context)
23 | public.eggs.nanachi(update,context)
24 | handlers.filters_chat.init(update, context)
25 | handlers.logs.set_log_channel(update,context)
26 |
27 | # Jobs Handlers Without Update Object
28 | def jobs_handlers(job_updater):
29 | job_updater.run_repeating(jobs.send_debug.send_log,interval=constants.DAILY,first=0.0, name="[DEBUG_LOG_JOB]")
30 | job_updater.run_repeating(jobs.query_repeat.query,interval=constants.FOUR_HOUR,first=0.0, name="[QUERY_REPEAT_JOB]")
31 | #job_updater.run_repeating(jobs.send_db_backup.send_backup, interval=constants.ONE_MINUTE, first=0.0,name="[DATABASE_BACKUP]")
--------------------------------------------------------------------------------
/core/handlers/logs.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | # Credits https://github.com/PaulSonOfLars/tgbot/
6 | import logging
7 | from config import Config
8 | from telegram.error import BadRequest, Unauthorized
9 | from core.utilities.message import message
10 | from core.database.repository.group import GroupRepository
11 |
12 | SET_CHANNEL_DEBUG = True
13 |
14 | def sys_loggers(name="",message="",debugs = False,info = False,warning = False,errors = False, critical = False):
15 | logger = logging.getLogger(name)
16 | logger.setLevel((logging.INFO, logging.DEBUG)[Config.DEBUG])
17 | fh = logging.FileHandler('debug.log')
18 | fh.setLevel(logging.INFO)
19 | logger.addHandler(fh)
20 | formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
21 | fh.setFormatter(formatter)
22 | logger.addHandler(fh)
23 | if debugs == True:
24 | logger.debug(message)
25 | elif info == True:
26 | logger.info(message)
27 | elif warning == True:
28 | logger.warning(message)
29 | elif errors == True:
30 | logger.error(message)
31 | elif critical == True:
32 | logger.critical(message)
33 |
34 | """
35 | This function makes a logger on the telegram channel
36 | set if it is not set it is sent to the default channel
37 | """
38 | def telegram_loggers(update,context,msg = ""):
39 | chat = update.effective_message.chat_id
40 | row = GroupRepository().getById([chat])
41 | id_channel = Config.DEFAULT_LOG_CHANNEL
42 | if row:
43 | get_log_channel = row['log_channel']
44 | send = message(update, context, msg, 'HTML', 'messageid', get_log_channel, None)
45 | else:
46 | send = message(update, context, msg, 'HTML', 'messageid', id_channel, None)
47 | return send
48 |
49 | def staff_loggers(update,context,msg = ""):
50 | id_staff_group = Config.DEFAULT_STAFF_GROUP
51 | send = message(update, context, msg, 'HTML', 'messageid', id_staff_group, None)
52 | return send
53 |
54 | def debug_channel(update,context,msg = ""):
55 | id_debug_channel = -1001540824311
56 | if SET_CHANNEL_DEBUG == True:
57 | send = message(update, context, msg, 'HTML', 'messageid', id_debug_channel, None)
58 | else:
59 | return
60 | return send
61 |
62 | def set_log_channel(update,context):
63 | msg = update.effective_message
64 | chat = update.effective_chat
65 | user = update.effective_user
66 | record = GroupRepository.SET_LOG_CHANNEL
67 | if user is not None:
68 | member = chat.get_member(user.id)
69 | if chat.type == 'channel' and str(update.effective_message.text).lower().startswith("/setlog"):
70 | msg.reply_text("Now, forward the /setlog to the group you want to tie this channel to!")
71 |
72 | elif msg.forward_from_chat and msg.text == '/setlog' and member.status == 'creator':
73 | data = [(msg.forward_from_chat.id, chat.id)]
74 | GroupRepository().update_group_settings(record, data)
75 | try:
76 | msg.delete()
77 | except BadRequest as excp:
78 | if excp.message == "Message to delete not found":
79 | pass
80 | else:
81 | message(update,context,"Error deleting message in log channel. Should work anyway though.")
82 |
83 | try:
84 | msg = "This channel has been set as the log channel for {}.".format(chat.title or chat.first_name)
85 | message(update, context, msg, 'HTML', 'messageid', msg.forward_from_chat.id, None)
86 | except Unauthorized as excp:
87 | if excp.message == "Forbidden: bot is not a member of the channel chat":
88 | message(update,context, "Successfully set log channel!")
89 | else:
90 | message(update,context,"ERROR in setting the log channel.")
91 |
92 | message(update,context, "Successfully set log channel!")
93 |
94 | else:
95 | if str(update.effective_message.text).lower().startswith("/setlog"):
96 | msg.reply_text("The steps to set a log channel are:\n"
97 | " - add bot to the desired channel\n"
98 | " - send /setlog to the channel\n"
99 | " - forward the /setlog to the group\n"
100 | " - You need to be a creator of the group")
--------------------------------------------------------------------------------
/core/jobs/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | """Import Files"""
7 | __all__ = ["night_mode","query_repeat","send_db_backup","send_debug"]
8 |
9 | from core.jobs import *
--------------------------------------------------------------------------------
/core/jobs/night_mode.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | from core.utilities.constants import PERM_FALSE
7 |
8 | def init(update,context):
9 | context.job_queue.run_repeating(callback_night,interval=10.0,first=0.0, name="[NIGHT_SCHEDULE_JOB]",context=update.effective_chat.id)
10 |
11 | def callback_night(context):
12 | chat_id = context.job.context
13 | context.bot.send_message(chat_id=chat_id, text="TEST_NIGHT_SCHEDULE")
14 | context.bot.set_chat_permissions(chat_id, PERM_FALSE)
15 | print(chat_id)
--------------------------------------------------------------------------------
/core/jobs/query_repeat.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | #Send debug.log into Dev_Channel
7 | from core.database.repository.group import GroupRepository
8 |
9 | def query(context):
10 | bot = context.bot
11 | chat = '-1001540824311'
12 | GroupRepository().job_nebula_updates()
13 | bot.send_message(chat,text="[DEBUG LOGGER] I ran the nebula_updates table cleanup query",parse_mode='HTML')
--------------------------------------------------------------------------------
/core/jobs/send_db_backup.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | #Send database backup into Telegram Private Channel
7 | def send_backup(context):
8 | context.bot.send_document(chat_id='-1001316452992', document=open('/home/HgeyPaZppivx/internal_db_backup/nebula.sql', 'rb'))
--------------------------------------------------------------------------------
/core/jobs/send_debug.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | #Send debug.log into Dev_Channel
7 | def send_log(context):
8 | context.bot.send_document(chat_id='-1001540824311', document=open('debug.log', 'rb'))
--------------------------------------------------------------------------------
/core/utilities/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | """Import Files"""
7 | __all__ = ["constants","menu","message","functions","strings","regex","monads"]
8 |
9 | from core.utilities import *
--------------------------------------------------------------------------------
/core/utilities/constants.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | from telegram import ChatPermissions
7 |
8 | #general constants
9 | DEFAULT_COUNT_WARN = 0
10 | DEFAULT_USER_SCORE = 0
11 | DEFAULT_MAX_WARN = 3
12 | SERVICE_ACCOUNT = 777000
13 |
14 | # constants for time management
15 | # DAILY == 24h ; TWELVE_HOUR == 12h ; EIGHT_HOUR == 8h ; FOUR_HOUR == 4h ; ONE_HOUR == 1h
16 | DAILY = 86400.0
17 | TWELVE_HOUR = 43200.0
18 | EIGHT_HOUR = 28800.0
19 | FOUR_HOUR = 14400.0
20 | ONE_HOUR = 3600.0
21 | ONE_MINUTE = 60.0
22 |
23 | #these constants change and disrupt an entire group
24 | PERM_FALSE = ChatPermissions(
25 | can_send_messages=False,
26 | can_send_media_messages=False,
27 | can_send_polls=False,
28 | can_send_other_messages=False,
29 | can_add_web_page_previews=False,
30 | can_change_info=False,
31 | can_invite_users=False,
32 | can_pin_messages=False
33 | )
34 | PERM_TRUE = ChatPermissions(
35 | can_send_messages=True,
36 | can_send_media_messages=True,
37 | can_send_polls=True,
38 | can_send_other_messages=True,
39 | can_add_web_page_previews=True,
40 | can_change_info=False,
41 | can_invite_users=False,
42 | can_pin_messages=False
43 | )
44 |
45 | PERM_MEDIA_TRUE = ChatPermissions(
46 | can_send_messages=True,
47 | can_send_media_messages=True,
48 | can_send_polls=True,
49 | can_send_other_messages=True,
50 | can_add_web_page_previews=True,
51 | can_change_info=False,
52 | can_invite_users=False,
53 | can_pin_messages=False
54 | )
55 |
56 | PERM_MEDIA_FALSE = ChatPermissions(
57 | can_send_messages=True,
58 | can_send_media_messages=False,
59 | can_send_polls=True,
60 | can_send_other_messages=False,
61 | can_add_web_page_previews=True,
62 | can_change_info=False,
63 | can_invite_users=False,
64 | can_pin_messages=False
65 | )
--------------------------------------------------------------------------------
/core/utilities/menu.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | from typing import Union, List
6 | from telegram import InlineKeyboardButton
7 |
8 | # Build Menu 2.0
9 | """
10 | Example to use(https://github.com/python-telegram-bot/python-telegram-bot/wiki/Code-snippets#build-a-menu-with-buttons):
11 | ##########################################################################################################################
12 | You can use the header_buttons and footer_buttons lists to put buttons in the first or last row respectively.
13 | ##########################################################################################################################
14 | button_list = [
15 | InlineKeyboardButton("col1", callback_data=...),
16 | InlineKeyboardButton("col2", callback_data=...),
17 | InlineKeyboardButton("row 2", callback_data=...)
18 | ]
19 | reply_markup = InlineKeyboardMarkup(util.build_menu(button_list, n_cols=2))
20 | bot.send_message(..., "A two-column menu", reply_markup=reply_markup)
21 |
22 |
23 | ##########################################################################################################################
24 | Or, if you need a dynamic version, use list comprehension to generate your button_list dynamically from a list of strings:
25 | ##########################################################################################################################
26 | some_strings = ["col1", "col2", "row2"]
27 | button_list = [[KeyboardButton(s)] for s in some_strings]
28 |
29 | """
30 | def build_menu(
31 | buttons: List[InlineKeyboardButton],
32 | n_cols: int,
33 | header_buttons: Union[InlineKeyboardButton, List[InlineKeyboardButton]]=None,
34 | footer_buttons: Union[InlineKeyboardButton, List[InlineKeyboardButton]]=None
35 | ) -> List[List[InlineKeyboardButton]]:
36 | menu = [buttons[i:i + n_cols] for i in range(0, len(buttons), n_cols)]
37 | if header_buttons:
38 | menu.insert(0, header_buttons if isinstance(header_buttons, list) else [header_buttons])
39 | if footer_buttons:
40 | menu.append(footer_buttons if isinstance(footer_buttons, list) else [footer_buttons])
41 | return menu
42 |
--------------------------------------------------------------------------------
/core/utilities/message.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | import asyncio
6 | import urllib.request
7 | import requests
8 | from config import Config
9 |
10 | MAIN_URL = "https://api.telegram.org/"
11 | TOKEN = Config.BOT_TOKEN
12 |
13 | def TopicMessage(thread_id,chat_id,text = ""):
14 | url = MAIN_URL + "bot{}/sendmessage?message_thread_id={}&chat_id={}&text={}&parse_mode=HTML".format(TOKEN, thread_id,chat_id, text)
15 | send = requests.get(url)
16 | return send
17 | def message(update, context, text = "", parse = 'HTML', type = 'message', chatid=None, img=None, reply_markup = None):
18 | bot = context.bot
19 | chat = update.effective_chat.id
20 | forum = bot.getChat(chat).is_forum
21 | thread_id = update.effective_message.message_thread_id if forum is not None else 0
22 |
23 | if type == 'message':
24 | send = bot.send_message(chat, text, parse_mode=parse,message_thread_id=thread_id,reply_markup=reply_markup)
25 | elif type == 'photo':
26 | send = bot.sendPhoto(chat_id=update.effective_chat.id, photo=img, caption=text, parse_mode=parse,message_thread_id=thread_id)
27 | elif type == 'reply':
28 | send = update.message.reply_text(text, parse_mode=parse,message_thread_id=thread_id,reply_markup=reply_markup)
29 | elif type == 'messageid':
30 | send = bot.send_message(chatid,text,parse_mode=parse)
31 | elif type == 'private':
32 | send = bot.send_message(update.message.from_user.id,text,parse_mode=parse,reply_markup=reply_markup)
33 | elif type == 'animation':
34 | send = bot.sendAnimation(chat, img, caption=text,message_thread_id=thread_id)
35 | return send
36 |
37 | def ApiMessage(text, chat_id):
38 | text = urllib.parse.quote_plus(text)
39 | url = MAIN_URL + "bot{}/sendmessage?chat_id={}&text={}&parse_mode=HTML".format(TOKEN, chat_id, text)
40 | send = requests.get(url)
41 | return send
42 |
43 | def ApiGroupRemove(chat_id):
44 | url = MAIN_URL + "bot{}/leaveChat?chat_id={}".format(TOKEN,chat_id)
45 | send = requests.get(url)
46 | return send
47 |
48 | async def messageWithAsync(update,context,delay,text = ""):
49 | bot = context.bot
50 | chat = update.effective_chat.id
51 | await asyncio.sleep(delay)
52 | msg = bot.send_message(chat,text,parse_mode='HTML')
53 | return msg
54 |
55 | async def messageWithAsyncById(update,context,chat,delay,text = ""):
56 | bot = context.bot
57 | await asyncio.sleep(delay)
58 | msg = bot.send_message(chat,text,parse_mode='HTML')
59 | return msg
60 |
--------------------------------------------------------------------------------
/core/utilities/monads.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | # Schrödinger's cat but in Python
7 | class Optional:
8 | @staticmethod
9 | def of(value = None):
10 | if value == None:
11 | return Nope()
12 | else:
13 | return Just(value)
14 |
15 | def __init__(self, value = None):
16 | self.maybeValue = value
17 |
18 | def valueOf(self):
19 | return self.maybeValue
20 |
21 | class Nope(Optional):
22 | def map(self, f):
23 | return Nope()
24 |
25 | def flatMap(self, f):
26 | return Nope()
27 |
28 | def valueOf(self):
29 | return None
30 |
31 | class Just(Optional):
32 | @staticmethod
33 | def of(value = None):
34 | return Just(value)
35 |
36 | def map(self, f):
37 | return Optional.of(f(self.maybeValue))
38 |
39 | def flatMap(self, f):
40 | flattened = f(self.maybeValue)
41 | assert isinstance(flattened, Optional)
42 | return flattened
43 |
44 | def valueOf(self):
45 | return self.maybeValue
46 |
47 | class Given(Optional):
48 | def of(value = None):
49 | return Given(value)
50 |
51 | def when(self, predicate, then):
52 | if predicate(self.maybeValue):
53 | return GivenJust(then)
54 | else:
55 | return GivenNope(self.maybeValue)
56 |
57 | def otherwise(self, then):
58 | return Just.of(then)
59 |
60 | def valueOf(self):
61 | return self.maybeValue
62 |
63 | class GivenNope(Given):
64 | def __init__(self, searchVal = None):
65 | self.maybeValue = searchVal
66 |
67 | def valueOf(self):
68 | return None
69 |
70 | def otherwise(self, then):
71 | return Just.of(then)
72 |
73 | class GivenJust(Given):
74 | def valueOf(self):
75 | return self.maybeValue
76 |
77 | def when(self, predicate, then):
78 | return self
79 |
80 | def otherwise(self, then):
81 | return Just.of(self.maybeValue)
82 |
83 | class Try(Optional):
84 | @staticmethod
85 | def of(f):
86 | assert callable(f)
87 | return Try(f)
88 |
89 | def __init__(self, f):
90 | self.maybeValue = False
91 | try:
92 | value = f()
93 | self.maybeValue = True
94 |
95 | self.tryResult = value
96 | except Exception as e:
97 | self.error = e
98 |
99 | def catch(self, f):
100 | if not self.maybeValue:
101 | f(self.error)
102 | return self
103 |
104 | def map(self, f):
105 | if self.maybeValue:
106 | return Just(self.tryResult).map(f)
107 | else:
108 | return Nope()
109 |
110 | def flatMap(self, f):
111 | if self.maybeValue:
112 | return Just(self.tryResult).flatMap(f)
113 | else:
114 | return Nope()
115 |
116 | def valueOf(self):
117 | if self.maybeValue:
118 | return self.maybeValue
119 | else:
120 | return None
--------------------------------------------------------------------------------
/core/utilities/regex.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | import re
7 |
8 | class Regex(object):
9 | HAS_ARABIC = "[\u0600-\u06ff]|[\u0750-\u077f]|[\ufb50-\ufbc1]|[\ufbd3-\ufd3f]|[\ufd50-\ufd8f]|[\ufd92-\ufdc7]|[\ufe70-\ufefc]|[\uFDF0-\uFDFD]+"
10 | HAS_CIRILLIC = "[а-яА-Я]+"
11 | HAS_CHINESE = "[\u4e00-\u9fff]+"
12 | HAS_NUMBER = "^[0-9]+$"
13 | HAS_LETTER = "^[a-zA-Z]+$"
14 | HAS_ZOOPHILE = "[ζ]"
15 | HAS_URL = "((http|https)\:\/\/)?[a-zA-Z0-9\.\/\?\:@\-_=#]+\.([a-zA-Z]){2,6}([a-zA-Z0-9\.\&\/\?\:@\-_=#])*"
16 |
17 | def check_string(regex_type,string):
18 | check = re.search(regex_type, string)
19 | if check is None:
20 | return False
21 | else:
22 | return True
--------------------------------------------------------------------------------
/core/utilities/strings.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | class Strings(object):
7 | ERROR_HANDLING = "Attention I detected a problem to send the message in the following group:\n ID: {}
\nTYPE: {}"
8 | BAN_LOG = "⚠️ #Log User Banned!\n👤 User_Id: {id}
\n"\
9 | '👤 Username: {username}\n'\
10 | "👥 Group: {chat}\n"
11 | SUPERBAN_LOG = '🚷 #Log User Superbanned!\n👤 User: {}[{}
]\n📜 Reason: {}\n🕐 Datetime: {}
\n👮♀️ Operator: {}\n{} [{}
]'
12 | REPORT_MSG = "⚠️#Report\nGroup Id: {}
\nGroup Title: {}\nMessage: {}\n📎 Link: {}"
13 | SOURCE = "Hi! my name is: {}\nMy Version is: {} {}
\nMy repository is: {}"
14 | USER_INFO = '⚙️ INFO USER:\n👤 UserId: {id}
\n👤 Username: {username}\n⚠️ Warn: {warn}
\n👥 Group: {chat}'
15 | WELCOME_BOT = "Thanks for adding me to the group ❤️\nPlease select your language => [/lang]\n\n❇️ Remember to make me administrator to work properly❗️\n\n🆘 Need Help? => /help\n\n⚙️ To change the group settings, press the [/settings] command\n\n⚙️ To change the filters in the group, type [/filters]\n\n⚙️ To change the warn limit in the group, type [/setwarn]\n\n⚙️ To change welcome type [/welcome] and follow the instructions\n\nMy Version is: {} {}"
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.7'
2 |
3 | services:
4 | bot:
5 | image: squirrelnet/nebula8
6 | build:
7 | context: docker/bot/
8 | volumes:
9 | - bot_data:/opt/service/data
10 | - bot_requirements:/root
11 | environment:
12 | REPO: $REPO
13 | BRANCH: $BRANCH
14 |
15 | HOST: $HOST
16 | PORT: $PORT
17 | USER: $USER
18 | PASSWORD: $PASSWORD
19 | DBNAME: $DBNAME
20 |
21 | BOT_TOKEN: $BOT_TOKEN
22 | SUPERADMIN: $SUPERADMIN
23 | OWNER: $OWNER
24 | DEFAULT_WELCOME: $DEFAULT_WELCOME
25 | DEFAULT_RULES: $DEFAULT_RULES
26 | DEFAULT_LOG_CHANNEL: $DEFAULT_LOG_CHANNEL
27 | DEFAULT_STAFF_GROUP: $DEFAULT_STAFF_GROUP
28 |
29 | OPENWEATHER_API: $OPENWEATHER_API
30 | ENABLE_PLUGINS: $ENABLE_PLUGINS
31 | DEFAULT_LANGUAGE: $DEFAULT_LANGUAGE
32 | VERSION: $VERSION
33 | VERSION_NAME: $VERSION_NAME
34 |
35 | DEBUG: $DEBUG
36 |
37 | volumes:
38 | bot_data:
39 | bot_requirements:
--------------------------------------------------------------------------------
/languages/EN.py:
--------------------------------------------------------------------------------
1 | English = {
2 | "LANG_DEFAULT": "en",
3 | "START_COMMAND": "Hi, my name is {} and I am a tool for managing groups with many special functions to be discovered and I am Open Source! If you want to see my source type: /source If you need help, type /help",
4 | "HELP_COMMAND": "Hi my name is {}\nDo You need Help?",
5 | "GROUP_INFO": "Group Title: {}
\n\nGroup Id: {}
\n\nGroup's Language: {}
\n\nWarn Limit: {}
\n\nTotal Group Users: {}
\n\nTotal Group Messages: {}
In the last 30 days",
6 | "BOT_WELCOME": "Thank you for adding me to the {} group\nFor working properly i need admins privileges!",
7 | "BAN_MESSAGE": '{user} has been banned from: {chat}',
8 | "RULES": "Here are the group rules: {}",
9 | "BAN_USER": "I got banned %s",
10 | "BAN_BOT": "I can't ban myself!",
11 | "BAN_ERROR": "Incorrect command syntax or unrecognized user: {}",
12 | "BAN_USER_ERROR": "There was a problem with the user ban %s",
13 | "SAY_MESSAGE": "Error the message cannot be empty!",
14 | "DELETE_MESSAGE": "You must use this command in response to a message!",
15 | "CLOSE_SETTINGS": "You have closed the bot settings menu!",
16 | "MAIN_TEXT_SETTINGS": "Bot Settings menu",
17 | "WELCOME_SETTINGS": "Welcome %s",
18 | "SET_MAIN_WELCOME": "Group Welcome Instructions:\nYou have to use the command like this /welcome args
\nwhere args is the text you need to insert\nit is possible to use special tags that are interpreted by the bot:\n{username} = user's username\n{chat} = group name\n{first_name} = user's first name\n{userid} = user id\n{mention} = user mention
\nHTML tags can also be used\nb , i, code
\nand emojis can also be used\n\nEXAMPLE:\nWelcome {username} in {chat}
",
19 | "WELCOME_MAIN_HELP_SET": "I changed the welcome of the group!\nif you want help type /welcome
without any message",
20 | "WEATHER_MSG": "Current weather in {}\nMin: {} C°
\nMax: {} C°
\nHumidity: {}%
\nIl The sky is: {}",
21 | "REPORT_ADMIN_MSG": "Reporting done! an admin will take care of your request!",
22 | "RULES_MSG": "You have correctly changed the rules of the group!",
23 | "RULES_ERROR_MSG": "The message is empty! The correct format is: /setrules args
",
24 | "PERM_MSG_ERROR": "The bot does not have the correct permissions to function properly!❌\nPlease promote the bot as an admin",
25 | "PERM_MSG_OK": "The bot has the correct permissions to function properly ✅",
26 | "CLOSE_MENU": "You have closed the Menu",
27 | "GLOBAL_REPORT_MSG": "You have reported a problem to the bot staff, an available operator will come to assist",
28 | "ERROR_RESPONSE_USER_MSG": "You must use this command in response to a user",
29 | "WARN_USER": "‼️ {} was warned! For the {}°
time (su {}).\nin the {} group [{}
]",
30 | "WARN_USER_MAX": "User @{} has reached the maximum number\n of warns in the {} group and has been banned",
31 | "BUTTON_REMOVE": '🗑 Remove',
32 | "MUTE_MSG": 'You muted the user {} [{}]
',
33 | "MUTE_MSG_R": 'You have removed the mute from user {} [{}]
',
34 | "MUTE_BUTTON": "✅ Unmute",
35 | "RULES_MAIN_TEXT": "📜 Rules of: {} [{}]
",
36 | "RULES_BUTTON": "▶️ Rules ◀️",
37 | "BADWORD_LIST_TEXT": "🗒 Badword list of the group {}:\n{}",
38 | "BADWORD_LIST_EMPTY": "There is no badword for this group.\nYou can add a badword with the command /badword word
",
39 | "BADWORD_ADD_TEXT": "You have entered the forbidden word: [{}] in the database",
40 | "BADWORD_ADD_EMPTY": "You cannot enter an empty forbidden word!\nthe correct format of the command is: /badword banana
",
41 | "SHIELD_ON": "🛡Shield Activated!\nAttention! By activating this command you have completely blocked the group!!!\nto change the settings again you have to type /settings",
42 | "WARN_USER_REASON": "‼️ {} was warned! For the {}°
time (su {}).\nin the {} group [{}
]\nfor the following reason: {}",
43 | "KICKED_USER_MESSAGE_NO_USERNAME": "⛔️ {}, to be welcome in the group, set your own username!\nAction: {}",
44 | "SET_BAN_MESSAGE": "You have set up the custom ban message successfully!",
45 | "BAN_ERROR_SYNTAX": "Incorrect command syntax or unrecognized user: {}",
46 | "BAN_ERROR_AC": "I can't ban an administrator or owner!",
47 | "BAN_EMPTY_ERROR": "The text of the ban cannot be empty!",
48 | "BAN_SELF_BAN": "I can't ban myself, Use this command in the correct way!"
49 | }
--------------------------------------------------------------------------------
/languages/IT.py:
--------------------------------------------------------------------------------
1 | Italian = {
2 | "LANG_DEFAULT": "it",
3 | "START_COMMAND": "Ciao io mi chiamo {} e sono uno strumento per la gestione dei gruppi con tante funzioni speciali tutte da scoprire e sono Open Source! Se vuoi vedere il mio sorgente digita: /source Se hai bisogno di aiuto digita /help",
4 | "HELP_COMMAND": "Ciao mi chiamo {}\nHai bisogno di aiuto?",
5 | "GROUP_INFO": "Titolo Gruppo: {}
\n\nId del gruppo: {}
\n\nLingua del gruppo: {}
\n\nLimite Warn: {}
\n\nTotale Utenti Gruppo: {}
\n\nTotale Messaggi Gruppo: {}
Negli ultimi 30 giorni",
6 | "BOT_WELCOME": "Grazie di avermi aggiunta al gruppo {}\nPer funzionare correttamente ho bisogno dei privilegi di amministratore!",
7 | "BAN_MESSAGE": '{user} è stato bannato da {chat}',
8 | "RULES": "Ecco il regolamento del gruppo: {}",
9 | "BAN_USER": "Ho bannato %s",
10 | "BAN_BOT": "Non posso bannarmi da sola!",
11 | "BAN_ERROR": "Sintassi del comando errata o utente non riconosciuto: {}",
12 | "BAN_USER_ERROR": "Si è verificato un problema per il ban dell'utente %s",
13 | "SAY_MESSAGE": "Errore il messaggio non può essere vuoto!",
14 | "DELETE_MESSAGE": "Devi utilizzare questo comando in risposta ad un messaggio!",
15 | "CLOSE_SETTINGS": "Hai chiuso il menu impostazioni del bot!",
16 | "MAIN_TEXT_SETTINGS": "Menu Impostazioni del bot",
17 | "WELCOME_SETTINGS": "Benvenuto %s",
18 | "SET_MAIN_WELCOME": "Istruzioni per il benvenuto del Gruppo:\nDovete utilizzare il comando in questo modo /welcome args
\ndove args è il testo che dovete inserire\nè possibilie utilizzare dei tag speciali che vengono interpretati dal bot:\n{username} = username utente\n{chat} = nome del gruppo\n{first_name} = nome utente\n{userid} = id utente\n{mention} = menzione utente
\nè possibile utilizzare anche i tag HTML\nb , i, code
\ne possono essere usate anche le Emoji\n\nESEMPIO:\nBenvenuto {username} in {chat}
",
19 | "WELCOME_MAIN_HELP_SET": "Ho modificato il welcome del gruppo!\nse vuoi un aiuto digita /welcome
senza nessun messaggio",
20 | "WEATHER_MSG": "Tempo attuale a {}\nMin: {} C°
\nMax: {} C°
\nUmidità: {}%
\nIl Cielo è: {}",
21 | "REPORT_ADMIN_MSG": "Segnalazione effettuata! un admin prenderà in carico la tua richiesta!",
22 | "RULES_MSG": "Hai cambiato correttamente le regole del gruppo!",
23 | "RULES_ERROR_MSG": "Il messaggio è vuoto! Il formato corretto è: /setrules args
",
24 | "PERM_MSG_ERROR": "Il bot non ha i permessi corretti per funzionare correttamente!❌\nPromuovi il bot come amministratore",
25 | "PERM_MSG_OK": "Il bot ha i permessi corretti per funzionare correttamente ✅",
26 | "CLOSE_MENU": "Hai chiuso il Menu",
27 | "GLOBAL_REPORT_MSG": "Hai segnalato un problema al personale del bot, un operatore disponibile verrà ad aiutarti",
28 | "ERROR_RESPONSE_USER_MSG": "È necessario utilizzare questo comando in risposta a un utente",
29 | "WARN_USER": "‼️ {} è stato warnato! per la {}°
volta (su {}).\nnel gruppo {} [{}
]",
30 | "WARN_USER_MAX": "L'utente @{} ha raggiunto il numero massimo\n di avvertimenti nel gruppo {} ed è stato bannato",
31 | "BUTTON_REMOVE": '🗑 Rimuovi',
32 | "MUTE_MSG": 'Hai mutato {} [{}]
',
33 | "MUTE_MSG_R": 'Hai rimosso il muta di {} [{}]
',
34 | "MUTE_BUTTON": "✅ Smuta",
35 | "RULES_MAIN_TEXT": "📜 Regole di: {} [{}]
",
36 | "RULES_BUTTON": "▶️ Regole ◀️",
37 | "BADWORD_LIST_TEXT": "🗒 Lista Badword del gruppo {}:\n{}",
38 | "BADWORD_LIST_EMPTY": "Non c'è nessuna badword per questo gruppo.\nPuoi aggiungere una badword con il comando /badword word
",
39 | "BADWORD_ADD_TEXT": "Hai inserito la parola proibita: [{}] nel database",
40 | "BADWORD_ADD_EMPTY": "Non puoi inserire una badword vuota!\nIl formato corretto del comando è: /badword banana
",
41 | "SHIELD_ON": "🛡Scudo attivato!\nAttenzione! Attivando questo comando hai completamente bloccato il gruppo!!!\nper modificare nuovamente le impostazioni è necessario digitare /settings",
42 | "WARN_USER_REASON": "‼️ {} è stato warnato! per la {}°
volta (su {}).\nnel gruppo {} [{}
]\nper il seguente motivo: {}",
43 | "KICKED_USER_MESSAGE_NO_USERNAME": '⛔️ {}, per essere ben accetto nel gruppo, imposta un tuo username!\nAzione: {}',
44 | "SET_BAN_MESSAGE": "Hai impostato il messaggio di ban personalizzato con successo!",
45 | "BAN_ERROR_SYNTAX": "Sintassi del comando errata o utente non riconosciuto: {}",
46 | "BAN_ERROR_AC": "Non posso bannare un amministratore o un owner!",
47 | "BAN_EMPTY_ERROR": "Il testo del ban non può essere vuoto!",
48 | "BAN_SELF_BAN": "Non posso bannarmi da sola, usa questo comando nel modo corretto!"
49 | }
--------------------------------------------------------------------------------
/languages/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | """Import Files"""
7 | __all__ = ["EN","getLang","IT"]
8 |
9 | from languages import *
--------------------------------------------------------------------------------
/languages/getLang.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | from config import Config
7 | from core.database.repository.group_language import GroupLanguageRepository
8 | from languages import (EN,IT)
9 |
10 | def get(update, context):
11 | chat = update.effective_message.chat_id
12 | row = GroupLanguageRepository().getById([chat])
13 | if row is None:
14 | return None
15 | else:
16 | return row['languages']
17 |
18 | def languages(update, context):
19 | LANGUAGE = get(update,context)
20 |
21 | if LANGUAGE == "" or LANGUAGE is None:
22 | LANGUAGE = Config.DEFAULT_LANGUAGE
23 |
24 | if LANGUAGE == "IT":
25 | setLang = IT.Italian
26 | elif LANGUAGE == "EN":
27 | setLang = EN.English
28 |
29 | languages.lang_default = setLang["LANG_DEFAULT"]
30 | languages.start = setLang["START_COMMAND"]
31 | languages.helps = setLang["HELP_COMMAND"]
32 | languages.group_info = setLang["GROUP_INFO"]
33 | languages.bot_welcome = setLang["BOT_WELCOME"]
34 | languages.ban_message = setLang["BAN_MESSAGE"]
35 | languages.rules = setLang["RULES"]
36 | languages.user_ban = setLang["BAN_USER"]
37 | languages.bot_ban = setLang["BAN_BOT"]
38 | languages.ban_error = setLang["BAN_ERROR"]
39 | languages.ban_user_error = setLang["BAN_USER_ERROR"]
40 | languages.say_error = setLang["SAY_MESSAGE"]
41 | languages.delete_error_msg = setLang["DELETE_MESSAGE"]
42 | languages.close_menu_msg = setLang["CLOSE_SETTINGS"]
43 | languages.main_menu_msg = setLang["MAIN_TEXT_SETTINGS"]
44 | languages.welcome_set = setLang["WELCOME_SETTINGS"]
45 | languages.set_welcome_main = setLang["SET_MAIN_WELCOME"]
46 | languages.set_welcome_help = setLang["WELCOME_MAIN_HELP_SET"]
47 | languages.weather_message = setLang["WEATHER_MSG"]
48 | languages.report_msg = setLang["REPORT_ADMIN_MSG"]
49 | languages.rules_msg = setLang["RULES_MSG"]
50 | languages.rules_error_msg = setLang["RULES_ERROR_MSG"]
51 | languages.perm_error = setLang["PERM_MSG_ERROR"]
52 | languages.perm_ok = setLang["PERM_MSG_OK"]
53 | languages.close_menu_general = setLang["CLOSE_MENU"]
54 | languages.global_report_msg = setLang["GLOBAL_REPORT_MSG"]
55 | languages.error_response_user_msg = setLang["ERROR_RESPONSE_USER_MSG"]
56 | languages.warn_user = setLang["WARN_USER"]
57 | languages.warn_user_max = setLang["WARN_USER_MAX"]
58 | languages.button_remove = setLang["BUTTON_REMOVE"]
59 | languages.mute_msg = setLang["MUTE_MSG"]
60 | languages.mute_msg_r = setLang["MUTE_MSG_R"]
61 | languages.mute_button = setLang["MUTE_BUTTON"]
62 | languages.rules_main = setLang["RULES_MAIN_TEXT"]
63 | languages.rules_button = setLang["RULES_BUTTON"]
64 | languages.badlist_text = setLang["BADWORD_LIST_TEXT"]
65 | languages.badlist_empty = setLang["BADWORD_LIST_EMPTY"]
66 | languages.badlist_add = setLang["BADWORD_ADD_TEXT"]
67 | languages.badlist_add_empty = setLang["BADWORD_ADD_EMPTY"]
68 | languages.shield_on = setLang["SHIELD_ON"]
69 | languages.warn_with_reason = setLang["WARN_USER_REASON"]
70 | languages.kicked_user_message = setLang["KICKED_USER_MESSAGE_NO_USERNAME"]
71 | languages.set_ban_message = setLang["SET_BAN_MESSAGE"]
72 | languages.ban_syntax_error = setLang["BAN_ERROR_SYNTAX"]
73 | languages.ban_error_ac = setLang["BAN_ERROR_AC"]
74 | languages.ban_error_empty = setLang["BAN_EMPTY_ERROR"]
75 | languages.ban_self_ban = setLang["BAN_SELF_BAN"]
76 | return LANGUAGE
--------------------------------------------------------------------------------
/main.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | import sys
6 | import pytz
7 | import logging
8 | from config import Config
9 | from loguru import logger
10 | from telegram.ext import Updater, Defaults
11 | from telegram import ParseMode
12 | from core.commands import index
13 | from plugins import plugin_index
14 | from core import handlers
15 | from core.handlers import handlers_index
16 | from tabulate import tabulate
17 |
18 | # crea la tabella con i dati desiderati
19 | table_data = [
20 | ["Type", "Description", "Extra"],
21 | ["Version", Config.VERSION, Config.VERSION_NAME],
22 | ["Author", "SquirrelNetwork", Config.REPO],
23 | ["Debug", Config.DEBUG],
24 | ["Plugins", "Enable"]
25 | ]
26 |
27 | # stampa la tabella formattata
28 |
29 |
30 |
31 |
32 | # if version < 3.7, stop bot.
33 | LOGGING = logging.getLogger(__name__)
34 | if sys.version_info[0] < 3 or sys.version_info[1] < 7:
35 | LOGGING.error("You MUST have a python version of at least 3.7! Multiple features depend on this. Bot quitting.")
36 | quit(1)
37 |
38 | # Enable logging (In config.py DEBUG = True enable Debug Logging)
39 | logging.basicConfig(level=(logging.INFO, logging.DEBUG)[Config.DEBUG], format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
40 |
41 | @logger.catch
42 | def main():
43 | """Instantiate a Defaults object"""
44 | defaults = Defaults(parse_mode=ParseMode.HTML, tzinfo=pytz.timezone('Europe/Rome'))
45 | updater = Updater(Config.BOT_TOKEN, defaults=defaults, workers=32)
46 | dsp = updater.dispatcher
47 | job_updater = updater.job_queue
48 |
49 | # I load all admin, user and owner commands
50 | index.user_command(dsp)
51 | index.admin_command(dsp)
52 | index.owner_command(dsp)
53 |
54 | #Plugins Section (if in the config.py ENABLE_PLUGINS is True it loads the plugins if ENABLE_PLUGINS is False it does not load them)
55 | if Config.ENABLE_PLUGINS == True :
56 | plugin_index.function_plugins(dsp)
57 | logger.info('Plugin Enabled')
58 | else:
59 | logger.info('Plugin Disabled')
60 |
61 | # I load all handlers, commands without '/'
62 | handlers_index.core_handlers(dsp)
63 | handlers.logs.sys_loggers()
64 | handlers.handlers_index.jobs_handlers(job_updater)
65 | # I load the error handler, when the bot receives an error it sends a private message to the developer
66 | dsp.add_error_handler(handlers.errors.error_handler)
67 | dsp.add_error_handler(handlers.handler_errors.init)
68 |
69 | # Start the Bot Polling
70 | updater.start_polling(poll_interval=1.0, timeout=5.0)
71 | updater.idle()
72 |
73 | if __name__ == '__main__':
74 | main()
--------------------------------------------------------------------------------
/plugins/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | """Import Files"""
7 | __all__ = ["distrowatch","search","inspire","plugin_index","weather","wikipedia"]
8 |
9 | from plugins import *
--------------------------------------------------------------------------------
/plugins/distrowatch.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | import requests
7 | from core import decorators
8 | from bs4 import BeautifulSoup
9 | from core.utilities.menu import build_menu
10 | from telegram import InlineKeyboardButton, InlineKeyboardMarkup
11 |
12 | @decorators.delete.init
13 | def init(update, context):
14 | bot = context.bot
15 | r = requests.get("https://distrowatch.com/random.php")
16 | parsed_html = BeautifulSoup(r.text, features="html.parser")
17 | distro_long_name = parsed_html.title.string[17:].lower()
18 | distro_name = distro_long_name.split()[0]
19 | distro_url = f'https://distrowatch.com/table.php?distribution={distro_name}'
20 | distro_message = "Here is a random linux distribution: "
21 | button_list = [InlineKeyboardButton("🐧 ▶️ ", url=distro_url)]
22 | reply_markup = InlineKeyboardMarkup(build_menu(button_list, n_cols=1))
23 | bot.send_message(update.message.chat_id,text=distro_message,reply_markup=reply_markup,parse_mode='HTML')
--------------------------------------------------------------------------------
/plugins/inspire.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 | import requests
6 | from core import decorators
7 |
8 | @decorators.delete.init
9 | def init(update,context):
10 | bot = context.bot
11 | url = r"http://inspirobot.me/api?generate=true"
12 | get = requests.get(url)
13 | img = get.text
14 | bot.sendPhoto(chat_id=update.effective_chat.id, photo=img, caption="Want another one? click /inspire")
--------------------------------------------------------------------------------
/plugins/plugin_index.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | import plugins
7 | from telegram.ext import (CommandHandler as CMH)
8 |
9 | def function_plugins(dsp):
10 | function = dsp.add_handler
11 | function(CMH('distro',plugins.distrowatch.init))
12 | function(CMH('google',plugins.search.google))
13 | function(CMH('mdn',plugins.search.mdn))
14 | function(CMH('ddg',plugins.search.duckduckgo))
15 | function(CMH('wiki',plugins.wikipedia.init))
16 | function(CMH('weather',plugins.weather.init))
17 | function(CMH('inspire',plugins.inspire.init))
--------------------------------------------------------------------------------
/plugins/search.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright SquirrelNetwork
5 |
6 | from core.utilities.menu import build_menu
7 | from core.utilities.message import message
8 | from telegram import InlineKeyboardButton, InlineKeyboardMarkup
9 |
10 | """
11 | /mdn {terms}
12 | """
13 | def mdn(update, context):
14 | bot = context.bot
15 | msg=str(update.message.text[4:]).strip()
16 | if msg != "":
17 | main_text = "Here are the results of your MDN search"
18 | gurl = "https://developer.mozilla.org/en-US/search?q={0}".format(msg.replace(' ','+'))
19 | button_list = [InlineKeyboardButton("🔎 Search", url=gurl)]
20 | reply_markup = InlineKeyboardMarkup(build_menu(button_list, n_cols=1))
21 | bot.send_message(update.message.chat_id,text=main_text,reply_markup=reply_markup,parse_mode='HTML')
22 | else:
23 | message(update,context, text="You need to type a search criteria!\nHow to use the command: /mdn text
")
24 | """
25 | /google {terms}
26 | """
27 | def google(update, context):
28 | bot = context.bot
29 | msg=str(update.message.text[7:]).strip()
30 | if msg != "":
31 | main_text = "Here are the results of your Google search"
32 | gurl = "https://www.google.com/search?&q={0}".format(msg.replace(' ','+'))
33 | button_list = [InlineKeyboardButton("🔎 Search", url=gurl)]
34 | reply_markup = InlineKeyboardMarkup(build_menu(button_list, n_cols=1))
35 | bot.send_message(update.message.chat_id,text=main_text,reply_markup=reply_markup,parse_mode='HTML')
36 | else:
37 | message(update,context, text="You need to type a search criteria!\nHow to use the command: /google text
")
38 | """
39 | /ddg {terms}
40 | """
41 | def duckduckgo(update, context):
42 | bot = context.bot
43 | msg=str(update.message.text[4:]).strip()
44 | if msg != "":
45 | main_text = "Here are the results of your DuckDuckGo search"
46 | gurl = "https://duckduckgo.com/?q={0}".format(msg.replace(' ','+'))
47 | button_list = [InlineKeyboardButton("🔎 Search", url=gurl)]
48 | reply_markup = InlineKeyboardMarkup(build_menu(button_list, n_cols=1))
49 | bot.send_message(update.message.chat_id,text=main_text,reply_markup=reply_markup,parse_mode='HTML')
50 | else:
51 | message(update,context, text="You need to type a search criteria!\nHow to use the command: /ddg text
")
--------------------------------------------------------------------------------
/plugins/weather.py:
--------------------------------------------------------------------------------
1 | from pyowm import OWM
2 | from pyowm.commons import exceptions
3 | from config import Config
4 | from core import decorators
5 | from core.utilities.message import message
6 | from languages.getLang import languages
7 |
8 | def sendWeatherMessage(update,context,city,mintemp,maxtemp,humidity,icon):
9 | languages(update,context)
10 | stringMessage = languages.weather_message.format(city,mintemp,maxtemp,humidity,icon)
11 | msg = message(update,context,stringMessage)
12 | return msg
13 |
14 | @decorators.delete.init
15 | def init(update, context):
16 | text = update.message.text[8:].strip().capitalize()
17 | if text != "":
18 | try:
19 | owm = OWM(Config.OPENWEATHER_API)
20 | mgr = owm.weather_manager()
21 | observation = mgr.weather_at_place(text)
22 | w = observation.weather
23 | temp = w.temperature('celsius')
24 | mintemp = temp['temp_min']
25 | maxtemp = temp['temp_max']
26 | humidity = w.humidity
27 | status = w.status
28 | if status == 'Clear':
29 | sendWeatherMessage(update,context,text,mintemp,maxtemp,humidity,'☀️')
30 | elif status == 'Clouds':
31 | sendWeatherMessage(update,context,text,mintemp,maxtemp,humidity,'☁️')
32 | elif status == 'Rain':
33 | sendWeatherMessage(update,context,text,mintemp,maxtemp,humidity,'🌧')
34 | elif status == 'Drizzle':
35 | sendWeatherMessage(update,context,text,mintemp,maxtemp,humidity,'🌧')
36 | elif status == 'Mist':
37 | sendWeatherMessage(update,context,text,mintemp,maxtemp,humidity,'🌫')
38 | else:
39 | sendWeatherMessage(update,context,text,mintemp,maxtemp,humidity,status)
40 | except exceptions.NotFoundError:
41 | message(update,context, text="The city you searched for does not exist!")
42 | else:
43 | message(update,context, text="You need to type a search criteria!\nHow to use the command: /weather text
")
--------------------------------------------------------------------------------
/plugins/wikipedia.py:
--------------------------------------------------------------------------------
1 | import wikipedia as wiki
2 | from core.utilities.message import message
3 | from telegram import InlineKeyboardButton, InlineKeyboardMarkup
4 | from core.utilities.menu import build_menu
5 | from core.database.repository.group import GroupRepository
6 |
7 | def init(update, context):
8 | arg = update.message.text[5:]
9 | chat = update.effective_message.chat_id
10 | group = GroupRepository().getById(chat)
11 | if group is None:
12 | lang = 'EN'
13 | else:
14 | lang = group['languages']
15 | wiki.set_lang(lang.lower())
16 | try:
17 | pg = wiki.page(wiki.search(arg)[0])
18 | title = pg.title
19 | pg_url = pg.url
20 | define = pg.summary
21 | button_list = [InlineKeyboardButton("Go to ==>", url=pg_url)]
22 | reply_markup = InlineKeyboardMarkup(build_menu(button_list, n_cols=1))
23 | text = "*{}:*\n\n{}".format(title, define)
24 | update.message.reply_markdown(text, reply_markup=reply_markup)
25 | except:
26 | message(update, context, "Sorry {} I didn't find what you were looking for".format(update.message.from_user.first_name))
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [tool.poetry]
2 | name = "nebula"
3 | version = "8.6.2"
4 | description = "Open source bot to administer a telegram group with different functionalities and blacklist"
5 | authors = ["SquirrelNetwork"]
6 | license = "Apache 2.0"
7 | readme = "README.md"
8 |
9 | [tool.poetry.dependencies]
10 | python = "3.9.2"
11 | pandas = "^1.4.4"
12 | matplotlib = "^3.5.3"
13 | PyMySQL = "^1.0.2"
14 | python-telegram-bot = "^13.14"
15 | telegram = "^0.0.1"
16 | psutil = "^5.9.2"
17 | loguru = "^0.6.0"
18 | pyowm = "^3.3.0"
19 | PyPika = "^0.48.9"
20 | wikipedia = "^1.4.0"
21 | beautifulsoup4 = "^4.11.1"
22 | pip = "^22.2.2"
23 | SQLAlchemy = "^1.4.40"
24 |
25 |
26 | [build-system]
27 | requires = ["poetry-core"]
28 | build-backend = "poetry.core.masonry.api"
29 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | APScheduler==3.6.3
2 | async-timeout==4.0.2
3 | beautifulsoup4==4.11.1
4 | cachetools==4.2.2
5 | certifi==2022.9.24
6 | charset-normalizer==2.1.1
7 | contourpy==1.0.5
8 | cycler==0.11.0
9 | Deprecated==1.2.13
10 | fonttools==4.38.0
11 | geojson==2.5.0
12 | greenlet==1.1.3.post0
13 | idna==3.4
14 | kiwisolver==1.4.4
15 | loguru==0.6.0
16 | matplotlib==3.6.1
17 | numpy==1.23.4
18 | packaging==21.3
19 | pandas==1.5.1
20 | Pillow==9.2.0
21 | psutil==5.9.3
22 | PyMySQL==1.0.2
23 | pyowm==3.3.0
24 | pyparsing==3.0.9
25 | PyPika==0.48.9
26 | PySocks==1.7.1
27 | python-dateutil==2.8.2
28 | python-dotenv==0.21.0
29 | python-telegram-bot==13.14
30 | pytz==2022.5
31 | pytz-deprecation-shim==0.1.0.post0
32 | redis==4.5.3
33 | requests==2.28.1
34 | six==1.16.0
35 | soupsieve==2.3.2.post1
36 | SQLAlchemy==1.4.42
37 | telegram==0.0.1
38 | tornado==6.1
39 | tzdata==2022.5
40 | tzlocal==4.2
41 | urllib3==1.26.12
42 | wikipedia==1.4.0
43 | wrapt==1.14.1
44 |
--------------------------------------------------------------------------------
/runtime.txt:
--------------------------------------------------------------------------------
1 | python-3.9.6
--------------------------------------------------------------------------------