Merge pull request #24 from the-superpirate/master

- repo(nexus): Refactoring legacy
This commit is contained in:
the-superpirate 2021-04-11 17:45:16 +03:00 committed by GitHub
commit 58d4f50465
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 192 additions and 358 deletions

23
.gitignore vendored
View File

@ -1,8 +1,23 @@
# Ignore all bazel-* symlinks. There is no full list since this can change
# based on the name of the directory bazel is cloned into.
/bazel-*
node_modules/
# Python
venv
test.db
__pycache__/
cover
.coverage
dump.rdb
/build/
tasq
devenv/
# NodeJS
node_modules/
.nuxt
# Development
/bazel-*
.idea/
*.log
.DS_Store
# Telethon session files
*.session

View File

@ -77,36 +77,6 @@ http_archive(
],
)
_configure_python_based_on_os = """
if [[ "$OSTYPE" == "darwin"* ]]; then
./configure --prefix=$(pwd)/bazel_install --with-openssl=$(brew --prefix openssl)
else
./configure --prefix=$(pwd)/bazel_install
fi
"""
http_archive(
name = "python_interpreter",
build_file_content = """
exports_files(["python_bin"])
filegroup(
name = "files",
srcs = glob(["bazel_install/**"], exclude = ["**/* *"]),
visibility = ["//visibility:public"],
)
""",
patch_cmds = [
"mkdir $(pwd)/bazel_install",
_configure_python_based_on_os,
"make",
"make install",
"ln -s bazel_install/bin/python3 python_bin",
],
sha256 = "4b0e6644a76f8df864ae24ac500a51bbf68bd098f6a173e27d3b61cdca9aa134",
strip_prefix = "Python-3.9.4",
urls = ["https://www.python.org/ftp/python/3.9.4/Python-3.9.4.tar.xz"],
)
http_archive(
name = "rules_python",
sha256 = "b228318a786d99b665bc83bd6cdb81512cae5f8eb15e8cd19f9956604b8939f5",
@ -118,6 +88,7 @@ http_archive(
http_archive(
name = "subpar",
sha256 = "481233d60c547e0902d381cd4fb85b63168130379600f330821475ad234d9336",
strip_prefix = "subpar-9fae6b63cfeace2e0fb93c9c1ebdc28d3991b16f",
urls = [
"https://github.com/google/subpar/archive/9fae6b63cfeace2e0fb93c9c1ebdc28d3991b16f.tar.gz",
@ -134,6 +105,22 @@ http_archive(
],
)
# Images Install
load("//images:install.bzl", "images_install")
images_install()
# Python
register_toolchains("//rules/python:py_toolchain")
load("@rules_python//python:pip.bzl", "pip_install")
pip_install(
name = "pip_modules",
requirements = "//rules/python:requirements.txt",
)
# Java
load("//rules/java:artifacts.bzl", "maven_fetch_remote_artifacts")
@ -230,17 +217,6 @@ py3_image_repos()
rust_image_repos()
# Python
register_toolchains("//rules/python:py_3_toolchain")
load("@rules_python//python:pip.bzl", "pip_install")
pip_install(
name = "pip_modules",
python_interpreter_target = "@python_interpreter//:python_bin",
requirements = "//rules/python:requirements.txt",
)
# K8s
load("@io_bazel_rules_k8s//k8s:k8s.bzl", "k8s_repositories")
@ -261,12 +237,6 @@ load("//rules/misc:install.bzl", "rules_misc_install_internal")
rules_misc_install_internal()
# Images Install
load("//images:install.bzl", "images_install")
images_install()
# Proto / gRPC
load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_proto_toolchains")

View File

@ -105,7 +105,6 @@ class IdmApi2GrpcClient(AioThing):
ban_until=None,
ban_message=None,
is_admin=None,
last_location=None,
):
response = await self.chats_stub.update_chat(
UpdateChatRequest(
@ -116,7 +115,6 @@ class IdmApi2GrpcClient(AioThing):
ban_until=ban_until,
ban_message=ban_message,
is_admin=is_admin,
last_location=last_location,
),
metadata=(
('request-id', request_id),

View File

@ -12,7 +12,6 @@ message ChatData {
int32 ban_until = 6;
string ban_message = 7;
bool is_admin = 8;
string tzinfo = 9;
bool is_subscribed = 10;
int64 created_at = 11;
}
@ -57,9 +56,6 @@ message UpdateChatRequest {
oneof is_admin_oneof {
bool is_admin = 7;
}
oneof last_location_oneof {
idm.api2.proto.Location last_location = 8;
}
}
service Chats {

View File

@ -21,7 +21,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
syntax='proto3',
serialized_options=None,
create_key=_descriptor._internal_create_key,
serialized_pb=b'\n\"idm/api2/proto/chats_service.proto\x12\x0eidm.api2.proto\x1a\x1didm/api2/proto/location.proto\"\xf2\x01\n\x08\x43hatData\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x10\n\x08username\x18\x02 \x01(\t\x12\x10\n\x08language\x18\x03 \x01(\t\x12#\n\x1bis_system_messaging_enabled\x18\x04 \x01(\x08\x12\x1c\n\x14is_discovery_enabled\x18\x05 \x01(\x08\x12\x11\n\tban_until\x18\x06 \x01(\x05\x12\x13\n\x0b\x62\x61n_message\x18\x07 \x01(\t\x12\x10\n\x08is_admin\x18\x08 \x01(\x08\x12\x0e\n\x06tzinfo\x18\t \x01(\t\x12\x15\n\ris_subscribed\x18\n \x01(\x08\x12\x12\n\ncreated_at\x18\x0b \x01(\x03\"4\n\tChatsData\x12\'\n\x05\x63hats\x18\x01 \x03(\x0b\x32\x18.idm.api2.proto.ChatData\"H\n\x11\x43reateChatRequest\x12\x0f\n\x07\x63hat_id\x18\x01 \x01(\x03\x12\x10\n\x08username\x18\x02 \x01(\t\x12\x10\n\x08language\x18\x03 \x01(\t\"!\n\x0eGetChatRequest\x12\x0f\n\x07\x63hat_id\x18\x01 \x01(\x03\"H\n\x10ListChatsRequest\x12\x1a\n\x10\x62\x61nned_at_moment\x18\x01 \x01(\x05H\x00\x42\x18\n\x16\x62\x61nned_at_moment_oneof\"\x98\x03\n\x11UpdateChatRequest\x12\x0f\n\x07\x63hat_id\x18\x01 \x01(\x03\x12\x12\n\x08language\x18\x02 \x01(\tH\x00\x12%\n\x1bis_system_messaging_enabled\x18\x03 \x01(\x08H\x01\x12\x1e\n\x14is_discovery_enabled\x18\x04 \x01(\x08H\x02\x12\x13\n\tban_until\x18\x05 \x01(\x05H\x03\x12\x15\n\x0b\x62\x61n_message\x18\x06 \x01(\tH\x04\x12\x12\n\x08is_admin\x18\x07 \x01(\x08H\x05\x12\x31\n\rlast_location\x18\x08 \x01(\x0b\x32\x18.idm.api2.proto.LocationH\x06\x42\x10\n\x0elanguage_oneofB#\n!is_system_messaging_enabled_oneofB\x1c\n\x1ais_discovery_enabled_oneofB\x11\n\x0f\x62\x61n_until_oneofB\x13\n\x11\x62\x61n_message_oneofB\x10\n\x0eis_admin_oneofB\x15\n\x13last_location_oneof2\xb8\x02\n\x05\x43hats\x12L\n\x0b\x63reate_chat\x12!.idm.api2.proto.CreateChatRequest\x1a\x18.idm.api2.proto.ChatData\"\x00\x12\x46\n\x08get_chat\x12\x1e.idm.api2.proto.GetChatRequest\x1a\x18.idm.api2.proto.ChatData\"\x00\x12K\n\nlist_chats\x12 .idm.api2.proto.ListChatsRequest\x1a\x19.idm.api2.proto.ChatsData\"\x00\x12L\n\x0bupdate_chat\x12!.idm.api2.proto.UpdateChatRequest\x1a\x18.idm.api2.proto.ChatData\"\x00\x62\x06proto3'
serialized_pb=b'\n\"idm/api2/proto/chats_service.proto\x12\x0eidm.api2.proto\x1a\x1didm/api2/proto/location.proto\"\xe2\x01\n\x08\x43hatData\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x10\n\x08username\x18\x02 \x01(\t\x12\x10\n\x08language\x18\x03 \x01(\t\x12#\n\x1bis_system_messaging_enabled\x18\x04 \x01(\x08\x12\x1c\n\x14is_discovery_enabled\x18\x05 \x01(\x08\x12\x11\n\tban_until\x18\x06 \x01(\x05\x12\x13\n\x0b\x62\x61n_message\x18\x07 \x01(\t\x12\x10\n\x08is_admin\x18\x08 \x01(\x08\x12\x15\n\ris_subscribed\x18\n \x01(\x08\x12\x12\n\ncreated_at\x18\x0b \x01(\x03\"4\n\tChatsData\x12\'\n\x05\x63hats\x18\x01 \x03(\x0b\x32\x18.idm.api2.proto.ChatData\"H\n\x11\x43reateChatRequest\x12\x0f\n\x07\x63hat_id\x18\x01 \x01(\x03\x12\x10\n\x08username\x18\x02 \x01(\t\x12\x10\n\x08language\x18\x03 \x01(\t\"!\n\x0eGetChatRequest\x12\x0f\n\x07\x63hat_id\x18\x01 \x01(\x03\"H\n\x10ListChatsRequest\x12\x1a\n\x10\x62\x61nned_at_moment\x18\x01 \x01(\x05H\x00\x42\x18\n\x16\x62\x61nned_at_moment_oneof\"\xce\x02\n\x11UpdateChatRequest\x12\x0f\n\x07\x63hat_id\x18\x01 \x01(\x03\x12\x12\n\x08language\x18\x02 \x01(\tH\x00\x12%\n\x1bis_system_messaging_enabled\x18\x03 \x01(\x08H\x01\x12\x1e\n\x14is_discovery_enabled\x18\x04 \x01(\x08H\x02\x12\x13\n\tban_until\x18\x05 \x01(\x05H\x03\x12\x15\n\x0b\x62\x61n_message\x18\x06 \x01(\tH\x04\x12\x12\n\x08is_admin\x18\x07 \x01(\x08H\x05\x42\x10\n\x0elanguage_oneofB#\n!is_system_messaging_enabled_oneofB\x1c\n\x1ais_discovery_enabled_oneofB\x11\n\x0f\x62\x61n_until_oneofB\x13\n\x11\x62\x61n_message_oneofB\x10\n\x0eis_admin_oneof2\xb8\x02\n\x05\x43hats\x12L\n\x0b\x63reate_chat\x12!.idm.api2.proto.CreateChatRequest\x1a\x18.idm.api2.proto.ChatData\"\x00\x12\x46\n\x08get_chat\x12\x1e.idm.api2.proto.GetChatRequest\x1a\x18.idm.api2.proto.ChatData\"\x00\x12K\n\nlist_chats\x12 .idm.api2.proto.ListChatsRequest\x1a\x19.idm.api2.proto.ChatsData\"\x00\x12L\n\x0bupdate_chat\x12!.idm.api2.proto.UpdateChatRequest\x1a\x18.idm.api2.proto.ChatData\"\x00\x62\x06proto3'
,
dependencies=[idm_dot_api2_dot_proto_dot_location__pb2.DESCRIPTOR,])
@ -93,21 +93,14 @@ _CHATDATA = _descriptor.Descriptor(
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='tzinfo', full_name='idm.api2.proto.ChatData.tzinfo', index=8,
number=9, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='is_subscribed', full_name='idm.api2.proto.ChatData.is_subscribed', index=9,
name='is_subscribed', full_name='idm.api2.proto.ChatData.is_subscribed', index=8,
number=10, type=8, cpp_type=7, label=1,
has_default_value=False, default_value=False,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='created_at', full_name='idm.api2.proto.ChatData.created_at', index=10,
name='created_at', full_name='idm.api2.proto.ChatData.created_at', index=9,
number=11, type=3, cpp_type=2, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
@ -126,7 +119,7 @@ _CHATDATA = _descriptor.Descriptor(
oneofs=[
],
serialized_start=86,
serialized_end=328,
serialized_end=312,
)
@ -157,8 +150,8 @@ _CHATSDATA = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
serialized_start=330,
serialized_end=382,
serialized_start=314,
serialized_end=366,
)
@ -203,8 +196,8 @@ _CREATECHATREQUEST = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
serialized_start=384,
serialized_end=456,
serialized_start=368,
serialized_end=440,
)
@ -235,8 +228,8 @@ _GETCHATREQUEST = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
serialized_start=458,
serialized_end=491,
serialized_start=442,
serialized_end=475,
)
@ -272,8 +265,8 @@ _LISTCHATSREQUEST = _descriptor.Descriptor(
create_key=_descriptor._internal_create_key,
fields=[]),
],
serialized_start=493,
serialized_end=565,
serialized_start=477,
serialized_end=549,
)
@ -334,13 +327,6 @@ _UPDATECHATREQUEST = _descriptor.Descriptor(
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='last_location', full_name='idm.api2.proto.UpdateChatRequest.last_location', index=7,
number=8, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
],
extensions=[
],
@ -382,21 +368,15 @@ _UPDATECHATREQUEST = _descriptor.Descriptor(
index=5, containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[]),
_descriptor.OneofDescriptor(
name='last_location_oneof', full_name='idm.api2.proto.UpdateChatRequest.last_location_oneof',
index=6, containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[]),
],
serialized_start=568,
serialized_end=976,
serialized_start=552,
serialized_end=886,
)
_CHATSDATA.fields_by_name['chats'].message_type = _CHATDATA
_LISTCHATSREQUEST.oneofs_by_name['banned_at_moment_oneof'].fields.append(
_LISTCHATSREQUEST.fields_by_name['banned_at_moment'])
_LISTCHATSREQUEST.fields_by_name['banned_at_moment'].containing_oneof = _LISTCHATSREQUEST.oneofs_by_name['banned_at_moment_oneof']
_UPDATECHATREQUEST.fields_by_name['last_location'].message_type = idm_dot_api2_dot_proto_dot_location__pb2._LOCATION
_UPDATECHATREQUEST.oneofs_by_name['language_oneof'].fields.append(
_UPDATECHATREQUEST.fields_by_name['language'])
_UPDATECHATREQUEST.fields_by_name['language'].containing_oneof = _UPDATECHATREQUEST.oneofs_by_name['language_oneof']
@ -415,9 +395,6 @@ _UPDATECHATREQUEST.fields_by_name['ban_message'].containing_oneof = _UPDATECHATR
_UPDATECHATREQUEST.oneofs_by_name['is_admin_oneof'].fields.append(
_UPDATECHATREQUEST.fields_by_name['is_admin'])
_UPDATECHATREQUEST.fields_by_name['is_admin'].containing_oneof = _UPDATECHATREQUEST.oneofs_by_name['is_admin_oneof']
_UPDATECHATREQUEST.oneofs_by_name['last_location_oneof'].fields.append(
_UPDATECHATREQUEST.fields_by_name['last_location'])
_UPDATECHATREQUEST.fields_by_name['last_location'].containing_oneof = _UPDATECHATREQUEST.oneofs_by_name['last_location_oneof']
DESCRIPTOR.message_types_by_name['ChatData'] = _CHATDATA
DESCRIPTOR.message_types_by_name['ChatsData'] = _CHATSDATA
DESCRIPTOR.message_types_by_name['CreateChatRequest'] = _CREATECHATREQUEST
@ -477,8 +454,8 @@ _CHATS = _descriptor.ServiceDescriptor(
index=0,
serialized_options=None,
create_key=_descriptor._internal_create_key,
serialized_start=979,
serialized_end=1291,
serialized_start=889,
serialized_end=1201,
methods=[
_descriptor.MethodDescriptor(
name='create_chat',

View File

@ -11,8 +11,14 @@ def images_install():
container_pull(
name = "ubuntu",
digest = "sha256:45ff0162921e61c004010a67db1bee7d039a677bed0cb294e61f2b47346d42b3",
digest = "sha256:5403064f94b617f7975a19ba4d1a1299fd584397f6ee4393d0e16744ed11aab1",
registry = "index.docker.io",
repository = "library/ubuntu",
tag = "20.10",
tag = "20.04",
)
container_pull(
name = "jupyter",
registry = "index.docker.io",
repository = "jupyter/tensorflow-notebook",
tag = "latest",
)

View File

@ -13,7 +13,7 @@ download_pkgs(
"libev4",
"libgomp1",
"libgoogle-perftools-dev",
"libprotobuf23",
"libprotobuf17",
"libssl1.1",
],
)

View File

@ -15,13 +15,8 @@ py3_image(
base = "//images/production:base-python-image",
data = [
"configs/base.yaml",
"configs/custom.yaml",
"configs/development.yaml",
"configs/logging.yaml",
"configs/metrics.yaml",
"configs/production.yaml",
"configs/promotions.yaml",
"configs/testing.yaml",
],
main = "main.py",
srcs_version = "PY3ONLY",

View File

@ -1,8 +1,6 @@
# Nexus Search: Telegram Bot
`Bot` is a daemon processing user input from Telegram. This version has cut `configs`
subdirectory due to hard reliance of configs on the network infrastructure you are using.
You have to write your own configs taking example below into account.
`Bot` is a daemon processing user input from Telegram.
The bot requires three other essential parts:
- IDM API (auth)
@ -10,109 +8,3 @@ The bot requires three other essential parts:
- Nexus Meta API (rescoring API for Summa Search server)
or their substitutions
## Sample `configs/base.yaml`
```yaml
---
application:
# Amazon Recipient Email in /donate message
amazon_gift_card_recipient: pirate@ship.space
# Amazon URL for buying card in /donate message
amazon_gift_card_url: https://www.amazon.com/dp/B07TMNGSN4
bot_version: 1.6.0
# Bitcoin Donation address in /donate message
btc_donate_address: 3QbF3zRQVjn3qMJBSbmLC1gb6VUc555xkw
# List of chat IDs that is allowed to bypass maintenance mode
bypass_maintenance: []
# Debugging mode
debug: true
# All users (except `bypass_maintenance` ones) will get UPGRADE_MAINTENANCE message in response
is_maintenance_mode: false
# Disable /settings, uploading new articles (can be used while vacuuming backend Postgres)
# and preventing creation of new users
is_read_only_mode: false
# Require subscription to `related_channel` before allowing to use the bot
is_subscription_required: false
# Libera Pay URL in /donate message
libera_pay_url:
maintenance_picture_url:
nexus_version: InterCom
# Default page size for SERP
page_size: 5
# Length of generated Request-ID used for tracking requests across all backends
request_id_length: 12
# Enabled schemas (passed to Nexus Meta API)
schemas:
- scimag
- scitech
# Length of generated Session-ID used in commands to clue user sessions
session_id_length: 8
too_difficult_picture_url:
upgrade_maintenance_picture_url:
# Configuring behaviour of the bot in some cases
views:
settings:
has_discovery_button: true
has_language_buttons: true
has_location_button: false
has_router: false
has_system_messaging_button: true
hub:
url:
idm:
url:
log_path: '/var/log/nexus-bot/{{ ENV_TYPE }}'
meta_api:
url:
telegram:
# Telegram App Hash from https://my.telegram.org/
app_hash: '{{ APP_HASH }}'
# Telegram App ID from https://my.telegram.org/
app_id: 00000
# External bot name shown in messages to users
bot_external_name: libgen_scihub_bot
# Internal bot name used in logging
bot_name: nexus-bot
bot_token: '{{ BOT_TOKEN }}'
# WARNING! Potentially buggy telethon option. Sometimes it goes mad and overload users with tons of messages
# Collect missed messages at startup time and answer to them
catch_up: false
# Telegram account for forwarding copyright infringements from /copyright command
copyright_infringement_account:
# Telethon database for keeping cache
database:
session_id: '/usr/lib/nexus-bot/{{ ENV_TYPE }}/session.db'
# Enabled handlers
handlers:
- nexus.bot.handlers.admin.AdminHandler
- nexus.bot.handlers.ban.BanHandler
- nexus.bot.handlers.ban.BanlistHandler
- nexus.bot.handlers.ban.UnbanHandler
- nexus.bot.handlers.contact.ContactHandler
- nexus.bot.handlers.copyright.CopyrightHandler
- nexus.bot.handlers.close.CloseHandler
- nexus.bot.handlers.donate.DonateHandler
- nexus.bot.handlers.download.DownloadHandler
- nexus.bot.handlers.emoji.EmojiHandler
- nexus.bot.handlers.help.HelpHandler
- nexus.bot.handlers.referencing_to.ReferencingToHandler
- nexus.bot.handlers.referencing_to.ReferencingToPagingHandler
- nexus.bot.handlers.roll.RollHandler
- nexus.bot.handlers.settings.SettingsButtonsHandler
- nexus.bot.handlers.settings.SettingsRouterHandler
- nexus.bot.handlers.settings.SettingsManualHandler
- nexus.bot.handlers.shortlink.ShortlinkHandler
- nexus.bot.handlers.submit.SubmitHandler
- nexus.bot.handlers.start.StartHandler
- nexus.bot.handlers.stop.StopHandler
- nexus.bot.handlers.view.ViewHandler
- nexus.bot.handlers.vote.VoteHandler
- nexus.bot.handlers.noop.NoopHandler
- nexus.bot.handlers.search.SearchHandler
- nexus.bot.handlers.search.SearchEditHandler
- nexus.bot.handlers.search.SearchPagingHandler
# Channel that will be shown in /help, /donate, /contact and in promotions
related_channel: '@nexus_search'
```

View File

@ -0,0 +1,98 @@
---
application:
# Amazon Recipient Email in /donate message
amazon_gift_card_recipient: pirate@ship.space
# Amazon URL for buying card in /donate message
amazon_gift_card_url: https://www.amazon.com/dp/B07TMNGSN4
bot_version: 1.6.0
# Bitcoin Donation address in /donate message
btc_donate_address: 3QbF3zRQVjn3qMJBSbmLC1gb6VUc555xkw
# List of chat IDs that is allowed to bypass maintenance mode
bypass_maintenance: []
# Debugging mode
debug: true
# All users (except `bypass_maintenance` ones) will get UPGRADE_MAINTENANCE message in response
is_maintenance_mode: false
# Disable /settings, uploading new articles (can be used while vacuuming backend Postgres)
# and preventing creation of new users
is_read_only_mode: false
# Require subscription to `related_channel` before allowing to use the bot
is_subscription_required: false
# Libera Pay URL in /donate message
libera_pay_url:
maintenance_picture_url:
nexus_version: InterCom
# Default page size for SERP
page_size: 5
# Length of generated Request-ID used for tracking requests across all backends
request_id_length: 12
# Enabled schemas (passed to Nexus Meta API)
schemas:
- scimag
- scitech
# Length of generated Session-ID used in commands to clue user sessions
session_id_length: 8
too_difficult_picture_url:
upgrade_maintenance_picture_url:
# Configuring behaviour of the bot in some cases
views:
settings:
has_discovery_button: true
has_language_buttons: true
has_system_messaging_button: true
hub:
url:
idm:
url:
log_path: '/var/log/nexus-bot/{{ ENV_TYPE }}'
meta_api:
url:
telegram:
# Telegram App Hash from https://my.telegram.org/
app_hash: '{{ APP_HASH }}'
# Telegram App ID from https://my.telegram.org/
app_id: 00000
# External bot name shown in messages to users
bot_external_name: libgen_scihub_bot
# Internal bot name used in logging
bot_name: nexus-bot
bot_token: '{{ BOT_TOKEN }}'
# WARNING! Potentially buggy telethon option. Sometimes it goes mad and overload users with tons of messages
# Collect missed messages at startup time and answer to them
catch_up: false
# Telegram account for forwarding copyright infringements from /copyright command
copyright_infringement_account:
# Telethon database for keeping cache
database:
session_id: '/usr/lib/nexus-bot/{{ ENV_TYPE }}/session.db'
# Enabled handlers
handlers:
- nexus.bot.handlers.admin.AdminHandler
- nexus.bot.handlers.ban.BanHandler
- nexus.bot.handlers.ban.BanlistHandler
- nexus.bot.handlers.ban.UnbanHandler
- nexus.bot.handlers.contact.ContactHandler
- nexus.bot.handlers.copyright.CopyrightHandler
- nexus.bot.handlers.close.CloseHandler
- nexus.bot.handlers.donate.DonateHandler
- nexus.bot.handlers.download.DownloadHandler
- nexus.bot.handlers.emoji.EmojiHandler
- nexus.bot.handlers.help.HelpHandler
- nexus.bot.handlers.referencing_to.ReferencingToHandler
- nexus.bot.handlers.referencing_to.ReferencingToPagingHandler
- nexus.bot.handlers.roll.RollHandler
- nexus.bot.handlers.settings.SettingsButtonsHandler
- nexus.bot.handlers.settings.SettingsHandler
- nexus.bot.handlers.shortlink.ShortlinkHandler
- nexus.bot.handlers.submit.SubmitHandler
- nexus.bot.handlers.start.StartHandler
- nexus.bot.handlers.stop.StopHandler
- nexus.bot.handlers.view.ViewHandler
- nexus.bot.handlers.vote.VoteHandler
- nexus.bot.handlers.noop.NoopHandler
- nexus.bot.handlers.search.SearchHandler
- nexus.bot.handlers.search.SearchEditHandler
- nexus.bot.handlers.search.SearchPagingHandler
# Channel that will be shown in /help, /donate, /contact and in promotions
related_channel: '@nexus_search'

View File

@ -1,15 +1,6 @@
from izihawa_utils.podolsky_encoding import encode
from library.telegram.base import RequestContext
from nexus.bot.widgets.settings_widget import (
SettingsManualWidget,
SettingsRouterWidget,
)
from nexus.translations import t
from telethon import (
Button,
events,
functions,
)
from nexus.bot.widgets.settings_widget import SettingsWidget
from telethon import events
from .base import (
BaseCallbackQueryHandler,
@ -17,7 +8,7 @@ from .base import (
)
class SettingsRouterHandler(BaseHandler):
class SettingsHandler(BaseHandler):
filter = events.NewMessage(incoming=True, pattern='^/settings(@[A-Za-z0-9_]+)?$')
is_group_handler = True
writing_handler = True
@ -25,43 +16,7 @@ class SettingsRouterHandler(BaseHandler):
async def handler(self, event: events.ChatAction, request_context: RequestContext):
request_context.add_default_fields(mode='settings_router')
request_context.statbox(action='show')
if self.application.config['application']['views']['settings']['has_router']:
settings_router_widget = SettingsRouterWidget(
application=self.application,
chat=request_context.chat,
request_id=request_context.request_id,
)
text, buttons = await settings_router_widget.render()
else:
settings_widget = SettingsManualWidget(
application=self.application,
chat=request_context.chat,
is_group_mode=event.is_group or event.is_channel,
request_id=request_context.request_id,
)
text, buttons = await settings_widget.render()
await event.reply(text, buttons=buttons)
class SettingsAutomaticHandler(BaseHandler):
filter = events.NewMessage(incoming=True, pattern=f'^🌎{encode("1")}')
async def handler(self, event, request_context: RequestContext):
request_context.add_default_fields(mode='settings_automatic')
request_context.statbox(action='show')
await event.reply(
f'{t("SEND_YOUR_LOCATION", language=request_context.chat.language)}{encode("sg")}',
buttons=Button.clear()
)
class SettingsManualHandler(BaseHandler):
filter = events.NewMessage(incoming=True, pattern=f'^👇{encode("1")}')
async def handler(self, event, request_context: RequestContext):
request_context.add_default_fields(mode='settings_manual')
request_context.statbox(action='show')
settings_widget = SettingsManualWidget(
settings_widget = SettingsWidget(
application=self.application,
chat=request_context.chat,
is_group_mode=event.is_group or event.is_channel,
@ -82,48 +37,17 @@ class SettingsButtonsHandler(BaseCallbackQueryHandler):
request_context.statbox(action='change', query=f'action_id: {action_id} data: {data}')
settings_manual_widget = SettingsManualWidget(
settings_widget = SettingsWidget(
application=self.application,
chat=request_context.chat,
is_group_mode=event.is_group or event.is_channel,
request_id=request_context.request_id,
)
is_changed = await settings_manual_widget.process_action(action_id=action_id, data=data)
text, buttons = await settings_manual_widget.render()
is_changed = await settings_widget.process_action(action_id=action_id, data=data)
text, buttons = await settings_widget.render()
if not is_changed and not (event.is_group or event.is_channel):
await event.answer()
return
if event.is_group or event.is_channel:
buttons = None
await event.edit(text, buttons=buttons)
class GeoHandler(BaseHandler):
filter = events.NewMessage(incoming=True)
stop_propagation = False
async def handler(self, event, request_context: RequestContext):
request_context.add_default_fields(mode='geo')
if not event.geo:
return
request_context.statbox(action='geo', query=f'lon:{event.geo.long} lat:{event.geo.lat}')
result = await self.application.telegram_client(functions.messages.GetMessagesRequest(id=[event.id - 1]))
if not result.messages:
return
previous_message = result.messages[0]
if previous_message.message.endswith(encode("sg")):
request_context.statbox(action='catched_settings')
settings_manual_widget = SettingsManualWidget(
application=self.application,
chat=request_context.chat,
has_language_buttons=False,
is_group_mode=event.is_group or event.is_channel,
request_id=request_context.request_id,
)
await settings_manual_widget.set_last_location(lon=event.geo.long, lat=event.geo.lat)
text, buttons = await settings_manual_widget.render()
await event.reply(text, buttons=buttons or Button.clear())
raise events.StopPropagation()

View File

@ -1,8 +1,6 @@
from typing import Optional
from idm.api2.proto.chats_service_pb2 import ChatData as Chat
from idm.api2.proto.location_pb2 import Location
from izihawa_utils.podolsky_encoding import encode
from nexus.bot.application import TelegramApplication
from nexus.translations import t
from telethon import Button
@ -32,23 +30,7 @@ boolean_emoji = {
}
class SettingsRouterWidget:
def __init__(self, application: TelegramApplication, chat: Chat, request_id: str = None):
self.application = application
self.chat = chat
self.request_id = request_id
async def render(self):
sa = f'🌎{encode("1")}{t("SETUP_AUTOMATICALLY", language=self.chat.language)}'
sm = f'👇{encode("1")}{t("SETUP_MANUALLY", language=self.chat.language)}'
return t("SETTINGS_ROUTER_HELP", language=self.chat.language), [[
Button.text(sa, resize=True, single_use=True),
Button.text(sm, resize=True, single_use=True),
Button.force_reply(),
]]
class SettingsManualWidget:
class SettingsWidget:
def __init__(
self,
application: TelegramApplication,
@ -71,11 +53,12 @@ class SettingsManualWidget:
}
async def _switch_language(self, target_language: str):
return await self.application.idm_client.update_chat(
self.chat = await self.application.idm_client.update_chat(
chat_id=self.chat.id,
language=target_language,
request_id=self.request_id,
)
return self.chat
async def _switch_system_messaging(self, is_system_messaging_enabled: str):
self.chat = await self.application.idm_client.update_chat(
@ -93,14 +76,6 @@ class SettingsManualWidget:
)
return self.chat
async def set_last_location(self, lon: float, lat: float):
self.chat = await self.application.idm_client.update_chat(
chat_id=self.chat.id,
last_location=Location(lon=lon, lat=lat),
request_id=self.request_id,
)
return
async def process_action(self, action_id: str, data: str):
old_chat = self.chat
await self._actions[action_id](data)
@ -111,7 +86,6 @@ class SettingsManualWidget:
bot_version=self.application.config['application']['bot_version'],
nexus_version=self.application.config['application']['nexus_version'],
language=top_languages.get(self.chat.language, self.chat.language),
tzinfo=self.chat.tzinfo or 'UTC',
)
if not self.is_group_mode and self.application.config['application']['views']['settings']['has_discovery_button']:
text = f"{text}\n\n{t('NEXUS_DISCOVERY_DESCRIPTION', language=self.chat.language)}"
@ -151,8 +125,4 @@ class SettingsManualWidget:
data=f'/settings_sd_{1 - int(self.chat.is_discovery_enabled)}'
)
])
if self.application.config['application']['views']['settings']['has_location_button']:
buttons.append([
Button.request_location('Setup preferences automatically', resize=True)
])
return text, buttons

View File

@ -15,7 +15,6 @@ py3_image(
"configs/base.yaml",
"configs/logging.yaml",
],
legacy_create_init = False,
main = "main.py",
srcs_version = "PY3ONLY",
visibility = ["//visibility:public"],

View File

@ -137,14 +137,10 @@ en:
REPORT_OK_FILE: ✅ What Is Needed
SEARCHING: '`searching...`'
SEND_YOUR_LOCATION: Send your location (through the left attach button)
SETTINGS_ROUTER_HELP: >
Settings could be set up automatically or manually.
Automatic mode will requests location to set timezone, language and georanking.
SETTINGS_TEMPLATE: |
**Bot Version:** {bot_version}
**Nexus Version:** {nexus_version}
**Language:** {language}
**Timezone:** {tzinfo}
SETUP_AUTOMATICALLY: Setup automatically
SETUP_MANUALLY: Setup manually
SOURCES_UNAVAILABLE: '`{document}` is unavailable right now. Please, try later.'
@ -300,14 +296,10 @@ es:
REPLY_MESSAGE_HAS_BEEN_DELETED: El mensaje de búsqueda ha sido (re)movido. Vuelve a buscar.
SEARCHING: '`buscando...`'
SEND_YOUR_LOCATION: Envía tu ubicación (a través del botón de adjuntar de la izquierda)
SETTINGS_ROUTER_HELP: >
Los ajustes se pueden configurar de forma automática o manual.
El modo automático solicitará la ubicación para establecer la zona horaria, el idioma y la clasificación geográfica.
SETTINGS_TEMPLATE: |
**Versión del bot:** {bot_version}
**Versión de Nexus:** {nexus_version}
**Idioma:** {language}
**Zona horaria:** {tzinfo}
SETUP_AUTOMATICALLY: Configurar automáticamente
SETUP_MANUALLY: Configurar manualmente
SOURCES_UNAVAILABLE: '`{document}` no está disponible en este momento. Por favor intenta más tarde.'
@ -440,14 +432,10 @@ it:
REPLY_MESSAGE_HAS_BEEN_DELETED: Il messaggio di ricerca è stato (ri-)mosso. Ripeti la ricerca.
SEARCHING: '`ricerca in corso...`'
SEND_YOUR_LOCATION: Invia la tua posizione (tramite il pulsante allegato a sinistra)
SETTINGS_ROUTER_HELP: >
Le impostazioni possono essere configurate automaticamente o manualmente.
La modalità automatica richiederà la tua posizione per impostare il fuso orario, la lingua e il ranking geografico.
SETTINGS_TEMPLATE: |
**Versione del Bot:** {bot_version}
**Versione del Nexus:** {nexus_version}
**Lingua:** {language}
**Fuso orario:** {tzinfo}
SETUP_AUTOMATICALLY: Configura automaticamente
SETUP_MANUALLY: Configura manualmente
SOURCES_UNAVAILABLE: '`{document}` non è disponibile adesso. Per favore, prova più tardi.'
@ -599,14 +587,10 @@ pb:
REPLY_MESSAGE_HAS_BEEN_DELETED: A mensagem de pesquisa foi (re)movida. Pesquise novamente.
SEARCHING: '`procurando...`'
SEND_YOUR_LOCATION: Envie sua localização (através do botão esquerdo anexar)
SETTINGS_ROUTER_HELP: >
As configurações podem ser configuradas automática ou manualmente.
O modo automático solicitará um local para definir o fuso horário, o idioma e a classificação geográfica.
SETTINGS_TEMPLATE: |
**Versão do bot:** {bot_version}
**Versão do Nexus:** {nexus_version}
**Idioma:** {language}
**Fuso horário:** {tzinfo}
SETUP_AUTOMATICALLY: Configurar automaticamente
SETUP_MANUALLY: Configurar manualmente
SOURCES_UNAVAILABLE: '`{document}` está indisponível nesse momento. Por favor, tente mais tarde.'
@ -744,14 +728,10 @@ ru:
REPLY_MESSAGE_HAS_BEEN_DELETED: Сообщение с запросом было удалено/перемещено, выполните поиск заново.
SEARCHING: '`ищем...`'
SEND_YOUR_LOCATION: Отправьте вашу геопозицию (кнопка прикрепления файла слева)
SETTINGS_ROUTER_HELP: >
Настройки можно установить автоматически или в ручном режиме.
Автоматический режим запросит ваше местнонахождение для установки часового пояса, языка и георанжирования.
SETTINGS_TEMPLATE: |
**Версия бота:** {bot_version}
**Версия индекса Nexus:** {nexus_version}
**Язык:** {language}
**Часовой пояс:** {tzinfo}
SETUP_AUTOMATICALLY: Установить автоматически
SETUP_MANUALLY: Установить вручную
SOURCES_UNAVAILABLE: 'Прямо сейчас `{document}` недоступен. Попробуйте скачать его позже.'

View File

@ -2,22 +2,36 @@ load("@bazel_tools//tools/python:toolchain.bzl", "py_runtime_pair")
load("@rules_python//python:defs.bzl", "py_runtime")
py_runtime(
name = "python3_runtime",
files = ["@python_interpreter//:files"],
interpreter = "@python_interpreter//:python_bin",
name = "python2.7",
files = [],
interpreter_path = select({
"//:osx": "/usr/local/bin/python2.7",
"//:linux": "/usr/bin/python2.7",
}),
python_version = "PY2",
visibility = ["//visibility:public"],
)
py_runtime(
name = "python3",
files = [],
interpreter_path = select({
"//:osx": "/usr/local/bin/python3.9",
"//:linux": "/usr/bin/python3.9",
}),
python_version = "PY3",
visibility = ["//visibility:public"],
)
py_runtime_pair(
name = "py_runtime_pair",
py2_runtime = None,
py3_runtime = ":python3_runtime",
name = "hyperboria_py_runtime_pair",
py2_runtime = ":python2.7",
py3_runtime = ":python3",
)
toolchain(
name = "py_3_toolchain",
toolchain = ":py_runtime_pair",
name = "py_toolchain",
toolchain = ":hyperboria_py_runtime_pair",
toolchain_type = "@bazel_tools//tools/python:toolchain_type",
)