commit 321fa87461c29777f8c03165b272da4e07eb6e61 Author: bursa-pastoris Date: Thu Dec 2 23:57:42 2021 +0100 New repo diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a2ba233 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*.mo +*.po~ +.venv/ +__pycache__/ +log/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..e83c348 --- /dev/null +++ b/README.md @@ -0,0 +1,161 @@ +# Albatrobot + +Albatrobot is a personal project born as a bot to dice rolling only, but has +since then evolved with the addition of more functions (most of which is +useless). But I like it even if it is substantially bloat. + +## Installation and usage + +### Installation + +To install Albatrobot, follow those steps. +1. Download the source code +2. Move it to the installation path of your choice and run + ``` + python3 -m venv .venv + source .venv/bin/activate + python3 -m pip install -r requirements.txt + ``` +3. Configure the bot as you like (see [Configuration](#configuration) + paragraph). + +## Configuration + +All the required configuration is in `settings.ini` file, that can be edited +either manually or through the configuration script `setup.py`. The first way +is recommended one. + +The settings in `settings.ini` are described below. + +* `Token`: token to connect the software to the bot user on Telegram server. + Seealso and + . +* `AuthUsers`: user IDs of the users allowed to use the bot. The numbers must + be separated by commas. +* `MsgCooldown`: minimum time in seconds between two following uses of commands + `/Easter` or `/Christmas` by the same user. The time is the same, but it is + considered separately for the two commands. +* `CitePath`: path of the document containing the citations for `/Easter` + command. +* `ImgPath`: path containing the images for `/Christmas` command. + +If you choose to use the configuration script, you must run it in the +installation path as + + python3 setup.py + +### Usage + +#### Manual boot + +You can boot Albatrobot with the following command: + + cd && source .venv/bin/activate && ./main.py + +However, running Albatrobot like that is not recommended (except for testing +purposes). If you do that, you can then stop the bot with `Ctrl + C`. + +#### Automatic boot + +Albatrobot can be automatically run at system boot by adding the following +command in `crontab` queue: + + @reboot sleep 10 && cd && ./main.py > /tmp/albatrobot.txt 2>&1 + +To do so, run `crontab -e` and add the above line to the file that will be +opened, then save and close. + +If you run Albatrobot this way - the recommended one - consider the following. + +* `sleep 10` adds a delay of 10 seconds. It is necessary to allow the system + to set the network up and prevents errors due to impossibility to connect to + the Internet and to Telegram APIs. You can change the time to comply with + your necessities. +* If Albatrobot can't be launched, some error information should be saved in + `/tmp/albatrobot.txt`. + +You can stop Albatrobot by killing its process. I will add a better way in the +future. + +## Common problems + +### When I try to start the bot Python exits with an error + +Check: +1. that the configuration file content is in the correct format and contains + the correct information (see paragraph [Configuration](#configuration)); +2. that you have installed the required libraries (see paragraph + [Installation](#installation)); +3. that you have activate the virtual environment (see paragraph + [Installation](#installation)); +4. that the virtual environment has not been changed after the installation. + +In the first three cases, the solution is self-explaining. In the fourth, the +simplest way is to just delete the virtual environment and recreate it. Just +run the following commands in the installation path: + + rm -rf .venv python3 -m venv .venv source .venv/bin/activate python3 -m pip install -r requirements.txt + +This does not cause any data loss. + +### The Albatrobot seems correctly booted but on Telegram it doesn't work or behaves oddly + +Check: +1. that you have used the correct token (see paragraph + [Configuration](#configuration)); +2. that only one instance of the albatrobot is active for the same Telegram bot + user + +If none of the above solution has effect, try the ones of those suggested for +[Python errors](#when-i-try-to-start-the-bot-python-exits-with-an-error). + +### Albatrobot says that there are no avilable citations or images + +Check: +1. that there are available citations and images; +2. that citations and images are in supported formats; +3. that in the configuration the correct paths are set. + +## Some notes + +### About language + +Albatrobot was not originally developed nor used in English and the translation +may contain mistakes. Sorry for that. If you want so, you can help improving +it. + +### About the repository + +This git repository does not contain all the project's development history +because of two causes. +1. At the beginning, the project was not tracked with git. +2. I chose to redistribute the software after much time of development, so the + original archive contained some data that I didn't want nor could publish. + But at that time it was way easier to create a new archive than purging + those data from the original one. And the original archive contained many + completely unuseful files. + +## License + +Albatrobot is proudly [free +software](https://www.gnu.org/philosophy/free-sw.html#four-freedoms) (as both +in "free speech" and "free beer") and always will be, as it is released under +[AGPL-3.0-only](https://www.gnu.org/licenses/agpl-3.0-standalone.html) license. +Its source code is publicly available at +[Disroot](https://git.disroot.org/bursapastoris/albatrobot). + +## Disclaimer + +Albatrobot is free software, but it works interacting with +[Telegram](https://telegram.org)'s servers and API. Most of Telegram's clients +are distributed under a free license, but *all Telegram's servers' code is +proprietary software* and as such it yields unjust power over its users and +cannot be trusted. *Albatrobot's development does not want to promote non-free +software* and is just an instructive hobby. + +Please, *at least* for communication that must be kept private or secret do not +use Telegram. Use only free software and free protocols instead. + +* * * + +![](https://www.gnu.org/graphics/agplv3-with-text-162x68.png "AGPL-3.0 logo") diff --git a/TRANSLATE.md b/TRANSLATE.md new file mode 100644 index 0000000..8301b2c --- /dev/null +++ b/TRANSLATE.md @@ -0,0 +1,106 @@ +# Translate + +This document explains how to translate the Albatrobot. + +## Prerequisites + +To translate the Albatrobot, you will need to have the [`gettext` +package](https://www.gnu.org/software/gettext/) from the GNU project installed +in your system. In Debian, you can install with `sudo apt install gettext`. + +## Translate to a new language + +To translate to a new language, create a path named +`locales//LC_MESSAGES` (where `` is the two-letters code of the +language you are translasting to), then run `xgettext main.py albatrobot.py -o +locales//LC_MESSAGES/template.to`. + +Edit `locales//LC_MESSAGES/template.to`. You will find several lines of +metadata and after a serie of groups of rows like the following: + + #: main.py:59 msgid "help" msgstr "" + +The meaning is the following. +* `main.py` is the source file the string comes from. +* `59 ` is the number of the line in the source file where the string begins. +* In `msgid "help"`, `msgid` tells that what follows is the string as it is + written in the source code, `help` is the string itself. The string is always +written between quotation marks ( `"..."`). +* In `msgstr` tells that what follow is the string translation, `aide` is the + translation itself. + +To translate you must edit the content of the quotation marks after `msgstr`, +adding the translation. For example, if you were translating to French the +lines above would become + + #: main.py:59 msgid "help" msgstr "aide" + +Any not translates string will be printed as it is written in the source code. +For example, if you didn't translate to French the example above the Albatrobot +would have printed `help` instead of `aide`. + +When you finish the translation, go to `locales//LC_MESSAGES` and run +`msgfmt template.po`. This will produce `messages.mo`: it is a binary file with +your translation. You need it to test your translation, but you must *not* +commit it. + +## Update an existing translation + +### Existing strings + +If you just want to update the translation of already translated strings, an +existing translation, just edit `locales//LC_MESSAGES/template.po`, where +`` is the two-letter code of the language you are updating. For an +explanation of the content of that file, see [Translate to a new +language](#Translate to a new language). + +When you are happy with your work, run `msgfmt template.to`. This will produce +`messages.mo`: it is a binary file with your translation. You need it to test +your translation, but you must *not* commit it. + +### New strings + +If you want to translate strings that are present in the source code but not in +`locales/template.pot`, you must update that file. To do so: + +1. run `xgettext main.py albatrobot.py -o locales/template.pot`: this will + update `locales/template.pot` with the new strings; +2. run `msgmerge locales//LC_MESSAGES/template.po locales/template.pot + --update`: this will update the translation file of the language you are + translating to. + +You can now go on as desribed in [Existing strings](#Existing strings). + +### String removal + +If a string is removed from the main source code, the next run of `msgmerge` on +each translation will move the translation of such string to the bottom of the +`.po` file and prepend each of its lines with `#~`. You should remove them +before merging the updated translation file. However, if you forget to do so it +will be done before the next release. + +## Metadata + +The first lines of `template.pot` (and `template.po`) contain metadata. The +parts that must be edited are those in uppercase and their values should be +changed to the following. + +metadata value +------------------------------------- ----------------------------------------- +`SOME DESCRIPTIVE TITLE` `Albatrabot translation` +`YEAR THE PACKAGE'S COPYRIGHT HOLDER` `2021 bursa-pastoris` +`PACKAGE` `Albatrobot` +`FIRST AUTHOR , YEAR` `bursa-pastoris + , 2021` +`PACKAGE VERSION` `1.2` +`YEAR-MO-DA HO:MI+ZONE` `-- + :+` the + translation was created at and in. + You can invent from day on, nobody + really minds about that. Please, do so + if you have privacy concerns. +`FULL NAME ` ` + ` +`LANGUAGE ` ` + ` +`CHARSET` `UTF-8` diff --git a/albatrobot.py b/albatrobot.py new file mode 100644 index 0000000..6c66a6a --- /dev/null +++ b/albatrobot.py @@ -0,0 +1,308 @@ +''' + Albatrobot - Telegram bot for RPG groups and similar + Copyright (C) 2019-2021 bursa-pastoris + + This file is part of Albatrobot. + + Albatrobot is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, version 3 of the License. + + Albatrobot is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with Albatrobot. If not, see . +''' + +from telegram import ParseMode, ChatAction +import random +import glob +import Levenshtein +import time + +# Logging +import os +import logging +from datetime import datetime + +if not os.path.exists('log'): + os.mkdir('log') +formatter = logging.Formatter( + '(%(asctime)s) %(levelname)s: %(message)s') + +def set_logger(name, log_file, level=logging.INFO): + '''Creates logger more easily.''' + + handler = logging.FileHandler(log_file) + handler.setFormatter(formatter) + + logger = logging.getLogger(name) + logger.setLevel(level) + logger.addHandler(handler) + + return logger + +action_logger = set_logger('action_logger', 'log/albatrobot.log') +system_logger = set_logger( + 'system_logger', 'log/python.log', + logging.DEBUG) + + +# Settings +auth_users = [] +cite_path = '' +img_path = '' + + +# Internal functions +def closest(good_list,item): + distances={i:Levenshtein.distance(i,item) for i in good_list} + lowest_distance=distances[min(list(distances.keys()),key=distances.__getitem__)] + closest_keys=[i for i, distance in distances.items() if distance == lowest_distance] + return closest_keys + + +# Private use filter +from functools import wraps +def restricted(func): + '''User restriction decorator. + + This decorators limits the users that are allowed to use the + functions it is applied to, i.e. all the ones for which isn't + specified anything else, to the ones whose ID is in the appropriate + list. + ''' + @wraps(func) + def wrapped(update, context, *args, **kwargs): + user_id = update.effective_user.id + if user_id not in auth_users: + context.bot.send_message( + chat_id=update.effective_chat.id, + text='This bot is for private use only!') + return + return func(update, context, *args, **kwargs) + return wrapped + + +# Albatrobot functions +@restricted +def start(update, context): + '''Shows a message when a user contacts the bot for the firs time.''' + context.bot.send_message( + chat_id=update.effective_chat.id, + text=_("Hello, I'm Albatrobot! Type /help for help!")) + + +@restricted +def help(update, context): + '''Shows a help message. + + This message doesn't correspond to the inline suggestion set in + @BotFather, that must be set manually through a Telegram client. + ''' + instructions = ( + _("*Officially supported commands*\n" + "/help: show officialy supported commands\n" + "/roll: rolls dice following DnD notation\n" + "/source: sends the bot's source code")) + + context.bot.send_message( + chat_id=update.effective_chat.id, + text=instructions, + parse_mode=ParseMode.MARKDOWN_V2) + + +@restricted +def roll(update, context): + '''Roll a dice following DnD notation: d. + + The function supports any dice number and any faces number, but bot + the modifiers. + ''' + to_roll = str(context.args[0]) # Gets the argument + dnum = int(to_roll.split('d')[0]) + dfac = int(to_roll.split('d')[1]) + rolls = [] # Single rolls list + if dnum > 1000 or dfac > 1000: + context.bot.send_message( + chat_id=update.effective_chat.id, + text=_("{}, you can roll at most 1000 dice with at most 1000 faces" + " at once!").format(update.message.from_user.first_name)) + + else: + for n in range(dnum): + rolls.append(random.randint(1,dfac)) + if len(rolls) == 1: + result = str(rolls[0]) + elif len(rolls) > 1: + result = [str(roll) for roll in rolls] + result = '+'.join(result) + result = result + ' = ' + str(sum(rolls)) + context.bot.send_message( + chat_id=update.effective_chat.id, + text=_("{user_name} rolled {result}").format( + user_name=update.message.from_user.first_name, + result=result + ) + ) + + +@restricted +def version(update, context): + '''Sends Albatrobot's current version.''' + context.bot.send_message( + chat_id=update.effective_chat.id, + text=_("*Albatrobot's version:* {}'").format('0\.1'), + parse_mode=ParseMode.MARKDOWN_V2 + ) + + +@restricted +def source(update, context): + '''Sends the instructions to get a copy of @Albatrobot's source code.''' + context.bot.send_message( + chat_id=update.effective_chat.id, + text=_("Albatrobot's source code is available on" + " [Disroot](https:\/\/git.disroot.org\/bursapastoris\/albatrobot)\."), + parse_mode=ParseMode.MARKDOWN_V2) + action_logger.info( + 'User {} requested Albatrobot\'s source code.'.format( + update.effective_user.id)) + + +@restricted +def easter(update, context): + '''Sends a citation from the archive + + User can either choose the source or let the bot pick a random one. + ''' + try: + last_msg = context.user_data['last_easter'] + if datetime.now()-last_msg < msg_cooldown: + context.bot.send_message( + chat_id=update.effective_user.id, + text=_("Easter is good, but you can't invoke it so often!" + " Retry in some seconds...")) + action_logger.info('User {} wants too much Easter.'.format( + update.effective_user.id) + ) + return + except KeyError: + pass + + from resources.citations import citations + cits_archive = citations.citations + + if len(context.args) > 0: + if context.args[0] in list(cits_archive.keys()): + author = str(context.args[0]) + else: + closest_authors = closest(list(cits_archive.keys()),context.args[0]) + if len(closest_authors) == 1: + suggestion = _("The most similar is {}.").format(closest_authors[0]) + else: + suggestion = _("The most similar are {}.").format( + str(', '.join(i for i in closest_authors[:-1]) + + ' e ' + + closest_authors[-1]) + ) + context.bot.send_message( + chat_id=update.effective_chat.id, + text=_("Author {required_author} is not present in the archive!" + " {suggestion}\n" + "\n" + "N.b.: CaSe Is ImPoRtAnT!").format( + required_author=context.args[0], + suggestion=suggestion + )) + action_logger.info('User {user_name} wants easter from non' + ' registered author {author}.'.format( + user_name=update.effective_user.id, + author=context.args[0]) + ) + return + else: + author = random.choice(list(cits_archive.keys())) + + context.bot.send_message( + chat_id=update.effective_chat.id, + text='{cit}\n\n~{author}'.format( + cit=random.choice(cits_archive[author]), + author=author + ) + ) + context.user_data['last_easter'] = datetime.now() + + +@restricted +def christmas(update, context): + '''Sens a (hopefully funny) image from the archive.''' + imgs = glob.glob(img_path) + try: + last_msg = context.user_data['last_christmas'] + if datetime.now()-last_msg < msg_cooldown: + context.bot.send_message( + chat_id=update.effective_user.id, + text=_("Christmas is good, but you can't invoke it so often!" + " Try again in some seconds...'")) + action_logger.info( + 'User {} wants too much Christmas.'.format(update.effective_user.id)) + return + except KeyError: + pass + + context.bot.send_chat_action( + chat_id=update.effective_chat.id, + action=ChatAction.UPLOAD_PHOTO) + context.bot.send_photo( + chat_id=update.effective_chat.id, + photo=open(random.choice(imgs), 'rb')) + context.user_data['last_christmas'] = datetime.now() + +@restricted +def end_of_year_dinner(update, context): + '''Sends a user each citation from the archive.''' + from resources.citations import citations + cits_archive = citations.citations + + cits_number = 0 + dest = random.choice(auth_users) + + context.bot.send_message( + chat_id=dest, + text=_("Hello there, here an end of year dinner offered by {} !").format( + update.message.from_user.first_name + ) + ) + for author in list(cits_archive.keys()): + for cit in cits_archive[author]: + context.bot.send_message( + chat_id=dest, + text='{cit}\n\n~{author}'.format(cit=cit,author=author) + ) + cits_number += 1 + time.sleep(1.1) + + context.bot.send_message( + chat_id=update.effective_chat.id, + text=_("End of year dinner of {cits_number} plates delvered to {dest}!").format( + cits_number=cits_number, + dest=context.bot.getChatMember(chat_id=dest,user_id=dest).user.first_name + ) + ) + action_logger.info( + 'User {} sent a end of year dinner to user {}.'.format( + update.effective_user.id, + dest) + ) + + +@restricted +def unknown_command(update, context): + context.bot.send_message( + chat_id=update.effective_chat.id, + text=_("Unknown command.")) + diff --git a/icon/attribution.md b/icon/attribution.md new file mode 100644 index 0000000..f76903e --- /dev/null +++ b/icon/attribution.md @@ -0,0 +1,7 @@ +The icone is a derivative work of +* Jifutari, + [Short tailed Albatross1.jpg](https://commons.wikimedia.org/wiki/File:Short_tailed_Albatross1.jpg) + (GFDL 1.2+) +* Anbox team, redraw by SweetCanadianMullet, + [Anbox logo.svg](https://commons.wikimedia.org/wiki/File:Anbox_logo.svg) + (GPL 3+) diff --git a/icon/icon.svg b/icon/icon.svg new file mode 100644 index 0000000..b70f5a0 --- /dev/null +++ b/icon/icon.svg @@ -0,0 +1,185 @@ + + + Albatrobot icon v2.0 + + + + + + + + + + + + + + + + image/svg+xml + + Albatrobot icon v2.0 + + + + GPL 3.0 + + + Derivative of: +* Jifutari, Short tailed Albatross1.jpg (CC-BY-SA 3.0) <https://commons.wikimedia.org/wiki/File:Short_tailed_Albatross1.jpg> +* Anbox team, redraw by SweetCanadianMullet, Anbox logo.svg (GPL 3+) <https://commons.wikimedia.org/wiki/File:Anbox_logo.svg> + + + Jifutari +Anbox team +SweetCanadianMullet + + + Latest revision: 2020-11-13 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/locales/en/LC_MESSAGES/template.po b/locales/en/LC_MESSAGES/template.po new file mode 100644 index 0000000..b5861c9 --- /dev/null +++ b/locales/en/LC_MESSAGES/template.po @@ -0,0 +1,117 @@ +# Albatrobot translation. +# Copyright (C) 2021 bursa-pastoris +# This file is distributed under the same license as the Albatrobot package. +# bursa-pastoris , 2021. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2021-12-02 00:00+0000\n" +"PO-Revision-Date: 2021-12-02 00:00+0000\n" +"Last-Translator: bursa-pastoris \n" +"Language-Team: Englsih \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: main.py:59 +msgid "help" +msgstr "" + +#: main.py:62 +msgid "roll" +msgstr "" + +#: main.py:65 +msgid "source" +msgstr "" + +#: main.py:68 +msgid "version" +msgstr "" + +#: main.py:72 +msgid "easter" +msgstr "" + +#: main.py:76 +msgid "christmas" +msgstr "" + +#: main.py:81 +msgid "end_of_year_dinner" +msgstr "" + +#: albatrobot.py:96 +msgid "Hello, I'm Albatrobot! Type /help for help!" +msgstr "" + +#: albatrobot.py:107 +msgid "" +"*Officially supported commands*\n" +"/help: show officialy supported commands\n" +"/roll: rolls dice following DnD notation\n" +"/source: sends the bot's source code" +msgstr "" + +#: albatrobot.py:132 +msgid "{}, you can roll at most 1000 dice with at most 1000 faces at once!" +msgstr "" + +#: albatrobot.py:146 +#, python-brace-format +msgid "{user_name} rolled {result}" +msgstr "" + +#: albatrobot.py:158 +msgid "*Albatrobot's version:* {}'" +msgstr "" + +#: albatrobot.py:168 +msgid "" +"Albatrobot's source code is available on [Disroot](https:\\/\\/git.disroot." +"org\\/bursapastoris\\/albatrobot)\\." +msgstr "" + +#: albatrobot.py:187 +msgid "" +"Easter is good, but you can't invoke it so often! Retry in some seconds..." +msgstr "" + +#: albatrobot.py:205 +msgid "The most similar is {}." +msgstr "" + +#: albatrobot.py:207 +msgid "The most similar are {}." +msgstr "" + +#: albatrobot.py:214 +#, python-brace-format +msgid "" +"Author {required_author} is not present in the archive! {suggestion}\n" +"\n" +"N.b.: CaSe Is ImPoRtAnT!" +msgstr "" + +#: albatrobot.py:249 +msgid "" +"Christmas is good, but you can't invoke it so often! Try again in some " +"seconds...'" +msgstr "" + +#: albatrobot.py:276 +msgid "Hello there, here an end of year dinner offered by {} !" +msgstr "" + +#: albatrobot.py:291 +#, python-brace-format +msgid "End of year dinner of {cits_number} plates delvered to {dest}!" +msgstr "" + +#: albatrobot.py:307 +msgid "Unknown command." +msgstr "" diff --git a/locales/it/LC_MESSAGES/template.po b/locales/it/LC_MESSAGES/template.po new file mode 100644 index 0000000..8927310 --- /dev/null +++ b/locales/it/LC_MESSAGES/template.po @@ -0,0 +1,132 @@ +# Albatrobot translation. +# Copyright (C) 2021 bursa-pastoris +# This file is distributed under the same license as the Albatrobot package. +# bursa-pastoris , 2021. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2021-12-02 00:00+0000\n" +"PO-Revision-Date: 2021-12-02 00:00+0000\n" +"Last-Translator: bursa-pastoris \n" +"Language-Team: Italian \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: main.py:59 +msgid "help" +msgstr "aiuto" + +#: main.py:62 +msgid "roll" +msgstr "tira" + +#: main.py:65 +msgid "source" +msgstr "sorgente" + +#: main.py:68 +msgid "version" +msgstr "versione" + +#: main.py:72 +msgid "easter" +msgstr "pasqua" + +#: main.py:76 +msgid "christmas" +msgstr "natale" + +#: main.py:81 +msgid "end_of_year_dinner" +msgstr "cenone_di_fine_anno" + +#: albatrobot.py:96 +msgid "Hello, I'm Albatrobot! Type /help for help!" +msgstr "Ciao, sono Albatrobot! Scrivi /aiuto per aiuto!" + +#: albatrobot.py:107 +#, fuzzy +msgid "" +"*Officially supported commands*\n" +"/help: show officialy supported commands\n" +"/roll: rolls dice following DnD notation\n" +"/source: sends the bot's source code" +msgstr "" +"*Comandi ufficialmente supportati*\n" +"/aiuto: mostra i comandi ufficialmente supportati\n" +"/tira: tira dadi secondo la notaizone di DnD\n" +"/sorgente: manda il codice sorgente del bot" + +#: albatrobot.py:132 +msgid "{}, you can roll at most 1000 dice with at most 1000 faces at once!" +msgstr "" +"{}, puoi tirare al massimo 1000 dadi con al massimo 1000 facce per volta!" + +#: albatrobot.py:146 +#, python-brace-format +msgid "{user_name} rolled {result}" +msgstr "{user_name} ha tirato {result}" + +#: albatrobot.py:158 +msgid "*Albatrobot's version:* {}'" +msgstr "*Versione dell'Albatrobot:* {}" + +#: albatrobot.py:168 +msgid "" +"Albatrobot's source code is available on [Disroot](https:\\/\\/git.disroot." +"org\\/bursapastoris\\/albatrobot)\\." +msgstr "" +"Il codice sorgente dell'Albatrobot è disponibile su" +" [Disroot](https:\\/\\/git.disroot.org\\/bursapastoris\\/albatrobot)\\." + +#: albatrobot.py:187 +msgid "" +"Easter is good, but you can't invoke it so often! Retry in some seconds..." +msgstr "" +"La Pasqua è bella, ma non puoi invocarla così spesso! Riprova tra qualche " +"secondo..." + +#: albatrobot.py:205 +msgid "The most similar is {}." +msgstr "Il più simile è {}." + +#: albatrobot.py:207 +msgid "The most similar are {}." +msgstr "I più simili sono {}." + +#: albatrobot.py:214 +#, python-brace-format +msgid "" +"Author {required_author} is not present in the archive! {suggestion}\n" +"\n" +"N.b.: CaSe Is ImPoRtAnT!" +msgstr "" +"L'autore {required_authr} non è presente nell'archivio! {suggestion}\n" +"\n" +"N.b.: Le MaIuScOlE sOnO iMpOrTaNtI!" + +#: albatrobot.py:249 +msgid "" +"Christmas is good, but you can't invoke it so often! Try again in some " +"seconds...'" +msgstr "" +"Il Natale è bello, ma non puoi invocarlo così spesso! RIprova tra qualche " +"secondo..." + +#: albatrobot.py:276 +msgid "Hello there, here an end of year dinner offered by {} !" +msgstr "" + +#: albatrobot.py:291 +#, python-brace-format +msgid "End of year dinner of {cits_number} plates delvered to {dest}!" +msgstr "" + +#: albatrobot.py:307 +msgid "Unknown command." +msgstr "" diff --git a/locales/template.pot b/locales/template.pot new file mode 100644 index 0000000..4f18ef2 --- /dev/null +++ b/locales/template.pot @@ -0,0 +1,117 @@ +# Albatrobot translation. +# Copyright (C) 2021 bursa-pastoris +# This file is distributed under the same license as the Albatrobot package. +# bursa-pastoris , 2021. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2021-12-02 00:00+0000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: main.py:59 +msgid "help" +msgstr "" + +#: main.py:62 +msgid "roll" +msgstr "" + +#: main.py:65 +msgid "source" +msgstr "" + +#: main.py:68 +msgid "version" +msgstr "" + +#: main.py:72 +msgid "easter" +msgstr "" + +#: main.py:76 +msgid "christmas" +msgstr "" + +#: main.py:81 +msgid "end_of_year_dinner" +msgstr "" + +#: albatrobot.py:96 +msgid "Hello, I'm Albatrobot! Type /help for help!" +msgstr "" + +#: albatrobot.py:107 +msgid "" +"*Officially supported commands*\n" +"/help: show officialy supported commands\n" +"/roll: rolls dice following DnD notation\n" +"/source: sends the bot's source code" +msgstr "" + +#: albatrobot.py:132 +msgid "{}, you can roll at most 1000 dice with at most 1000 faces at once!" +msgstr "" + +#: albatrobot.py:146 +#, python-brace-format +msgid "{user_name} rolled {result}" +msgstr "" + +#: albatrobot.py:158 +msgid "*Albatrobot's version:* {}'" +msgstr "" + +#: albatrobot.py:168 +msgid "" +"Albatrobot's source code is available on [Disroot](https:\\/\\/git.disroot." +"org\\/bursapastoris\\/albatrobot)\\." +msgstr "" + +#: albatrobot.py:187 +msgid "" +"Easter is good, but you can't invoke it so often! Retry in some seconds..." +msgstr "" + +#: albatrobot.py:205 +msgid "The most similar is {}." +msgstr "" + +#: albatrobot.py:207 +msgid "The most similar are {}." +msgstr "" + +#: albatrobot.py:214 +#, python-brace-format +msgid "" +"Author {required_author} is not present in the archive! {suggestion}\n" +"\n" +"N.b.: CaSe Is ImPoRtAnT!" +msgstr "" + +#: albatrobot.py:249 +msgid "" +"Christmas is good, but you can't invoke it so often! Try again in some " +"seconds...'" +msgstr "" + +#: albatrobot.py:276 +msgid "Hello there, here an end of year dinner offered by {} !" +msgstr "" + +#: albatrobot.py:291 +#, python-brace-format +msgid "End of year dinner of {cits_number} plates delvered to {dest}!" +msgstr "" + +#: albatrobot.py:307 +msgid "Unknown command." +msgstr "" diff --git a/main.py b/main.py new file mode 100755 index 0000000..fe18ef8 --- /dev/null +++ b/main.py @@ -0,0 +1,92 @@ +#!/bin/python3 + +''' + Albatrobot - Telegram bot for RPG groups and similar + Copyright (C) 2019-2021 bursa-pastoris + + This file is part of Albatrobot. + + Albatrobot is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, version 3 of the License. + + Albatrobot is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with Albatrobot. If not, see . +''' + +from telegram.ext import Updater, CommandHandler, MessageHandler, Filters +import albatrobot +from datetime import timedelta + +# Settings +import configparser +config = configparser.ConfigParser() +config.read('settings.ini') + +token = config['Bot']['Token'] +for var in config['Settings']['AuthUsers'].split(','): + albatrobot.auth_users.append(int(var)) +albatrobot.msg_cooldown = timedelta( + seconds=int(config['Settings']['MsgCooldown'])) + +albatrobot.cite_path = config['Resources']['CitePath']+'/*' +albatrobot.img_path = config['Resources']['ImgPath']+'/*' + +lang = config['Settings']['Language'] + + +# Localization +import gettext + +transl = gettext.translation('messages', localedir='locales',languages=[lang]) +transl.install() + +_ = transl.gettext +# Link to bot platform +updater = Updater(token=token, use_context=True) +dispatcher = updater.dispatcher + + +# Bot building - Basic functions +start_handler = CommandHandler('start', albatrobot.start) +dispatcher.add_handler(start_handler) + +help_handler = CommandHandler(["help",_("help")], albatrobot.help) +dispatcher.add_handler(help_handler) + +roll_handler = CommandHandler(["roll",_("roll")], albatrobot.roll) +dispatcher.add_handler(roll_handler) + +source_handler = CommandHandler(["source",_("source")], albatrobot.source) +dispatcher.add_handler(source_handler) + +version_handler = CommandHandler(["version",_("version")], albatrobot.version) +dispatcher.add_handler(version_handler) + +# Bot building - Secret functions +easter_handler = CommandHandler(["easter",_("easter")], albatrobot.easter) +dispatcher.add_handler(easter_handler) + +christmas_handler = CommandHandler( + ["christmas",_("christmas")], + albatrobot.christmas) +dispatcher.add_handler(christmas_handler) + +end_of_year_dinner_handler = CommandHandler( + ["end_of_year_dinner",_("end_of_year_dinner")], + albatrobot.end_of_year_dinner) +dispatcher.add_handler(end_of_year_dinner_handler) + +unknown_handler = MessageHandler( + Filters.command, + albatrobot.unknown_command) +dispatcher.add_handler(unknown_handler) + +# Start bot +updater.start_polling() + diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..995ac5d --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +python-telegram-bot==13.0 +python-Levenshtein==0.12.2 diff --git a/resources/citations/citations.py b/resources/citations/citations.py new file mode 100644 index 0000000..3106cb2 --- /dev/null +++ b/resources/citations/citations.py @@ -0,0 +1 @@ +citations = {'Albatrobot':['no citations available']} diff --git a/resources/imgs/no-available-images.png b/resources/imgs/no-available-images.png new file mode 100644 index 0000000..5e44c15 Binary files /dev/null and b/resources/imgs/no-available-images.png differ diff --git a/resources/imgs/no-imgs.svg b/resources/imgs/no-imgs.svg new file mode 100644 index 0000000..40b9f54 --- /dev/null +++ b/resources/imgs/no-imgs.svg @@ -0,0 +1,71 @@ + + + + + + + + noavailableimages + + diff --git a/settings.ini b/settings.ini new file mode 100644 index 0000000..3790ce9 --- /dev/null +++ b/settings.ini @@ -0,0 +1,11 @@ +[Bot] +Token: + +[Settings] +AuthUsers: +MsgCooldown: 5 + +[Resources] +CitePath: resources/citations +ImgPath: resources/imgs +