diff --git a/README.md b/README.md index 28cc862..ed9ef7c 100644 --- a/README.md +++ b/README.md @@ -96,13 +96,13 @@ The bot will keep the command line open, sending all its logs to the standard ou  ## Multilanguage support  -The bot is created originally to talk either on Spanish or English. More languages can be added setting up more translation files on the "lang" directory. No more setup needed. VOLUNTEER TRANSLATORS WELCOME! +The bot is created originally to talk either on Spanish or English. More languages can be added setting up more translation files on the "lang" directory. No more setup needed (texts in `texts.yml` are language-independent). VOLUNTEER TRANSLATORS WELCOME!  The bot will respond to commands in the same language in which they are written. Therefore, when creating new languages, it is important to always use different words for commands.  ## Using the bot  -Any Mastodon user (including from other federated instances) can reply to puzzles. The replies must be sent private (direct message) to respect other users and not to spoil the solutions. The bot will reject any non-private message. +Any Mastodon user (from any federated instance) can reply to puzzles. The replies must be sent private (direct message) to respect other users and not to spoil the solutions. The bot will reject any non-private message.  You can reply to a puzzle with the next move that you consider the best. You can use PGN notation (such as Kh8) or UCI (such as h7h8). Use the correct capitalization, according to the rules of the notation.   diff --git a/chesspuzzlebot.py b/chesspuzzlebot.py index 69147bb..76f803f 100644 --- a/chesspuzzlebot.py +++ b/chesspuzzlebot.py @@ -106,17 +106,20 @@ def translate(language, string):   def get_puzzle_played_so_far(reply_id, user): - current_id = reply_id - played = find_played(current_id, user) - while played is None: - # Try reply by reply - replied = mastodon.status(current_id) - if replied.in_reply_to_id is None: - break - else: - current_id = replied.in_reply_to_id - played = find_played(current_id, user) - return played + if reply_id is not None: + current_id = reply_id + played = find_played(current_id, user) + while played is None: + # Try reply by reply + replied = mastodon.status(current_id) + if replied.in_reply_to_id is None: + break + else: + current_id = replied.in_reply_to_id + played = find_played(current_id, user) + return played + else: + return None   def post_fake_daily_puzzle(id, fen, moves, user, points): @@ -215,7 +218,7 @@ class ChessbotListener(StreamListener): logger.debug(f"Resolve next move") played = get_puzzle_played_so_far(status.status.in_reply_to_id, user) if played is None: - response = translate(language, 'bad_command') + response = translate(language, 'no_reply') else: id, fen, moves, rating, tags, order_num, moves_so_far, completed = played if completed == 1 or get_puzzle_completed_points(id, user) is not None: @@ -247,7 +250,7 @@ class ChessbotListener(StreamListener): # Find puzzle played and expected next move played = get_puzzle_played_so_far(status.status.in_reply_to_id, user) if played is None: - response = translate(language, 'bad_command') + response = translate(language, 'no_reply') else: id, fen, moves, rating, tags, order_num, moves_so_far, completed = played if completed == 1 or get_puzzle_completed_points(id, user) is not None: @@ -329,42 +332,47 @@ class ChessbotListener(StreamListener): logger.warning("Can't tell any response")   -logger.info('Listening...') +beat = 0 while True: try: handler = mastodon.stream_user(ChessbotListener(), run_async=True, reconnect_async=True) + logger.info('Listening...') while True: - time.sleep(3600) + beat += 1 + time.sleep(60) if handler.is_alive(): - logger.debug('Starting hourly routine.') - if datetime.now().hour == 9: - logger.info('Finding daily puzzle') - # Daily puzzle - p = get_daily_puzzle() - if p is not None: - id, fen, moves = p - png, image_fen, side = get_board_image(fen, moves.split()[0:1]) - text = texts['daily'].format(side_en=lang['en'][side], side_es=lang['es'][side]) - logger.info(f'Sending daily puzzle: {id}') - media = mastodon.media_post(png, mime_type='image/png', description=image_fen) - status = mastodon.status_post(text, media_ids=media, visibility='unlisted') - logger.info(f"Posted {status.url}") - update_daily_puzzle(id, status.id) - else: - logger.warning('Daily puzzle not generated.') - else: - # Post challenge one third of hours - if random.random() < 1/3: - logger.info('Looking for a challenge') - p = find_challenge() + if beat >= 60: + beat = 0 + logger.debug('Starting hourly routine.') + if datetime.now().hour == 9: + logger.info('Finding daily puzzle') + # Daily puzzle + p = get_daily_puzzle() if p is not None: - logger.info('Posting challenge') - id, fen, moves, user, points = p - post_fake_daily_puzzle(id, fen, moves, user, points) + id, fen, moves = p + png, image_fen, side = get_board_image(fen, moves.split()[0:1]) + text = texts['daily'].format(side_en=lang['en'][side], side_es=lang['es'][side]) + logger.info(f'Sending daily puzzle: {id}') + media = mastodon.media_post(png, mime_type='image/png', description=image_fen) + status = mastodon.status_post(text, media_ids=media, visibility='unlisted') + logger.info(f"Posted {status.url}") + update_daily_puzzle(id, status.id) else: - logger.info('No challenge found.') + logger.warning('Daily puzzle not generated.') + else: + # Post challenge one third of hours + if random.random() < 1/3: + logger.info('Looking for a challenge') + p = find_challenge() + if p is not None: + logger.info('Posting challenge') + id, fen, moves, user, points = p + post_fake_daily_puzzle(id, fen, moves, user, points) + else: + logger.info('No challenge found.') else: logger.warning('Handler is dead.') + break except MastodonError as ex: logger.error(f"Error listening to stream: {str(ex)}") time.sleep(30) diff --git a/lang/en.yml b/lang/en.yml index 734fef6..a07e0c4 100644 --- a/lang/en.yml +++ b/lang/en.yml @@ -17,6 +17,7 @@ commands: messages: too_many_commands: Sorry, I can't understand more than one command at a time! bad_command: Sorry, I can't understand what you're saying. Send "help" for available commands. + no_reply: Please answer an exercise so I can identify it. public_rejected: Sorry, I respond only to private messages (DM), out of respect for other users. Send "help" for further instructions. already_completed: This exercise is already completed. Send "new" if you want more. correct: GOOD! Continue with the next move. diff --git a/lang/es.yml b/lang/es.yml index 956c0d9..dd2e7e3 100644 --- a/lang/es.yml +++ b/lang/es.yml @@ -19,6 +19,7 @@ commands: messages: too_many_commands: Lo siento, no puedo entender más de un comando a la vez. bad_command: Lo siento, no puedo entender lo que me dices. Envía "ayuda" para conocer los comandos disponibles. + no_reply: Por favor, responde a un ejercicio para que pueda identificarlo. public_rejected: Lo siento, solo respondo a mensajes privados (DM), por respeto a otros usuarios. Envía "ayuda" para más instrucciones. already_completed: Este ejercicio ya está completado. Envía "nuevo" si deseas más. correct: ¡CORRECTO! Continúa con el siguiente movimiento.