Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hitler winner and spectator poll options #7

Merged
merged 9 commits into from
Feb 6, 2024
Merged

hitler winner and spectator poll options #7

merged 9 commits into from
Feb 6, 2024

Conversation

Alex-Kopylov
Copy link
Owner

@Alex-Kopylov Alex-Kopylov commented Feb 6, 2024

Summary by CodeRabbit

  • New Features
    • Implemented a CI/CD pipeline using Docker Compose for streamlined development and deployment.
    • Enhanced the application's error handling and logging for better troubleshooting and monitoring.
    • Added new game poll outcomes and logic for processing poll answers, improving the game's interactivity.
    • Introduced saving functionality for games, players, and playrooms, enriching the game's data management.
  • Bug Fixes
    • Updated the SQLite database connection configuration for consistency.
    • Fixed role mapping in the game data model to include new roles and handle edge cases.
  • Documentation
    • Updated setup instructions in README.md to reflect changes in the path configuration for the SQLite database file.
  • Chores
    • Adjusted environment variables and deployment settings to enhance security and deployment efficiency.
    • Made minor code style and formatting adjustments for better code readability and maintenance.

Copy link
Contributor

coderabbitai bot commented Feb 6, 2024

Walkthrough

This update enhances a Telegram bot project with improved error handling, logging, and database management. It introduces a CI/CD pipeline for the develop branch, integrates Telegram notifications, and updates data models to support new game functionalities. The deployment process now includes environment variables for smoother operations. Overall, these changes aim to streamline development, deployment, and the user experience within the bot's ecosystem.

Changes

Files Change Summary
.dockerignore Excludes __pycache__, .venv, venv directories.
.github/workflows/deploy.yml Adds environment variables for deployment script, modifies container checks.
.github/workflows/develop.yml Sets up CI/CD with Docker Compose, SSH actions, Telegram integration, Docker container management.
README.md Updates SQLite database file path instructions.
src/__main__.py, src/callbacks/... Adjusts error handling, logging, poll answer logic, simplifies method calls.
src/config.py, src/data_models/... Updates default values, renames variables, adds fields, introduces validation methods.
src/db.py, src/handlers/..., src/services/db_service.py Modifies database connections, error handling, adds saving functions.
src/sql/init.sql Renames fields, modifies table structures, adds new fields, formatting changes.
src/get_handlers.py, src/handlers/error_handler.py Minor adjustments in function implementations.

🐇✨
Changes abound, the code does hop,
Through fields of logic, nonstop.
With every line, we aim to improve,
A bot's journey, smooth and groove.
🌟🐾

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share

Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit-tests for this file.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit tests for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository from git and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit tests.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • The JSON schema for the configuration file is available here.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/coderabbit-overrides.v2.json

CodeRabbit Discord Community

Join our Discord Community to get help, request features, and share feedback.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 6

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between b38aa4b and 979df68.
Files ignored due to path filters (2)
  • docker-compose.yaml is excluded by: !**/*.yaml
  • pyproject.toml is excluded by: !**/*.toml
Files selected for processing (17)
  • .dockerignore (1 hunks)
  • .github/workflows/deploy.yml (2 hunks)
  • .github/workflows/develop.yml (1 hunks)
  • README.md (1 hunks)
  • src/main.py (2 hunks)
  • src/callbacks/receive_poll_answer.py (1 hunks)
  • src/config.py (2 hunks)
  • src/data_models/Game.py (1 hunks)
  • src/data_models/Player.py (1 hunks)
  • src/data_models/Record.py (3 hunks)
  • src/db.py (1 hunks)
  • src/get_handlers.py (1 hunks)
  • src/handlers/error_handler.py (3 hunks)
  • src/handlers/game.py (2 hunks)
  • src/handlers/save.py (3 hunks)
  • src/services/db_service.py (1 hunks)
  • src/sql/init.sql (3 hunks)
Files skipped from review due to trivial changes (3)
  • .dockerignore
  • README.md
  • src/get_handlers.py
Additional comments: 12
src/data_models/Game.py (1)
  • 13-24: The validate_results method's return type Literal["CH", "DH", "FW", "LW"] does not match the method's documentation or expected outcomes based on the game's logic. Ensure the return type accurately reflects all possible outcomes and that the method's logic correctly identifies these outcomes.

Consider verifying the method's logic against all possible game outcomes to ensure it covers all scenarios accurately.

src/config.py (2)
  • 10-14: Setting default values for TELEGRAM_BOT_TOKEN and DEVELOPER_CHAT_ID to None is appropriate for optional environment variables. However, ensure that downstream code properly handles None values for these variables to avoid runtime errors.
  • 27-31: The addition of new game poll outcomes is consistent with the PR's objectives. Ensure that all references to these outcomes in the codebase are updated to match the new options.
Verification successful

The examination of src/data_models/Record.py and src/handlers/game.py confirms that the references to GAME_POLL_OUTCOMES are correctly updated to match the new options added in src/config.py. The code dynamically handles these outcomes, ensuring compatibility with the new options. Therefore, the addition of new game poll outcomes is consistent with the PR's objectives, and all references in the codebase are appropriately updated to match the new options.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Verify that all references to GAME_POLL_OUTCOMES are updated.
grep -R "GAME_POLL_OUTCOMES" src/

Length of output: 268



Script:

#!/bin/bash
# Examine the usage of GAME_POLL_OUTCOMES in src/data_models/Record.py and src/handlers/game.py
cat src/data_models/Record.py
cat src/handlers/game.py

Length of output: 2735

src/__main__.py (1)
  • 33-37: Moving the logging configuration within the exception handling block is a good practice to ensure that logging is set up before any potential errors occur. However, ensure that this change does not affect logging configurations in other parts of the application.
src/data_models/Record.py (1)
  • 13-28: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [16-41]

The update to the shorten_role method to handle additional role mappings and allow for None as a return value is consistent with the PR's objectives. However, ensure that all possible roles are covered and that the method's documentation is updated to reflect these changes.

src/handlers/game.py (1)
  • 35-39: The addition of saving a Playroom instance is consistent with the PR's objectives. Ensure that the save_playroom function properly handles all edge cases, such as duplicate entries, to avoid database integrity errors.
src/callbacks/receive_poll_answer.py (1)
  • 16-40: The update to handle poll retractions by deleting previous votes and saving player information upon receiving a poll answer is consistent with the PR's objectives. Ensure that the save_player function properly handles all edge cases, such as duplicate entries, to avoid database integrity errors.
src/db.py (1)
  • 10-10: Updating the parameter passed to the aiosqlite.connect function to use config.SQLITE_DB_FILE_PATH is consistent with the PR's objectives and ensures that the database connection uses the correct path.
src/sql/init.sql (1)
  • 3-12: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [6-53]

The schema changes, including renaming fields, adding new fields, and modifying existing fields, are consistent with the PR's objectives. Ensure that all references to these fields in the application code are updated to match the new schema.

src/handlers/error_handler.py (1)
  • 41-50: Adding a conditional check for config.DEVELOPER_CHAT_ID before sending error messages via Telegram is a good practice to avoid attempting to send messages when the developer chat ID is not set. Ensure that the error logging provides sufficient information for troubleshooting in the absence of Telegram notifications.
src/services/db_service.py (1)
  • 30-69: The addition of save_playroom, save_player, and save_game functions is consistent with the PR's objectives. Ensure that these functions properly handle sqlite3.IntegrityError to log appropriate messages without crashing the application. Additionally, verify that the SQL statements are correct and match the database schema.
src/handlers/save.py (1)
  • 88-97: The enhancements to include saving a game in addition to saving a record are consistent with the PR's objectives. Ensure that the save_game function is correctly implemented and that all necessary data is accurately saved to the database.

Comment on lines 9 to 13
first_name: Optional[str | None]
full_name: Optional[str | None]
last_name: Optional[str | None]
is_bot: Optional[bool] = False
language_code: Optional[str | None]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of Optional[str | None] is redundant. Optional[str] already implies that the value can be None. Simplify the type annotations for first_name, full_name, last_name, and language_code.

- first_name: Optional[str | None]
+ first_name: Optional[str]
- full_name: Optional[str | None]
+ full_name: Optional[str]
- last_name: Optional[str | None]
+ last_name: Optional[str]
- language_code: Optional[str | None]
+ language_code: Optional[str]

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
first_name: Optional[str | None]
full_name: Optional[str | None]
last_name: Optional[str | None]
is_bot: Optional[bool] = False
language_code: Optional[str | None]
first_name: Optional[str]
full_name: Optional[str]
last_name: Optional[str]
is_bot: Optional[bool] = False
language_code: Optional[str]

Comment on lines 15 to 18
@field_validator("is_bot", mode="after")
@classmethod
def validate_bot(cls, v: bool) -> str:
return "TRUE" if v else "FALSE" # sqlite3 does not support boolean type
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The validate_bot method is supposed to return a bool but is annotated to return str. This is incorrect based on the method's purpose and the comment indicating SQLite's lack of boolean support. The method should return a boolean value, and the conversion to a string (if necessary) should be handled where SQLite queries are executed.

- def validate_bot(cls, v: bool) -> str:
+ def validate_bot(cls, v: bool) -> bool:
-     return "TRUE" if v else "FALSE"
+     return v

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
@field_validator("is_bot", mode="after")
@classmethod
def validate_bot(cls, v: bool) -> str:
return "TRUE" if v else "FALSE" # sqlite3 does not support boolean type
@field_validator("is_bot", mode="after")
@classmethod
def validate_bot(cls, v: bool) -> bool:
return v # sqlite3 does not support boolean type

Comment on lines 8 to 11
poll_id: int
chat_id: int
results: dict # Literal["Hitler Canceler", "Fascist Law", "Hitler Death", "Liberal Law"]
creator_id: int
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The results field is annotated as a dict without specifying key and value types. For better type safety and clarity, specify the expected types for keys and values.

- results: dict
+ results: dict[str, str]

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
poll_id: int
chat_id: int
results: dict # Literal["Hitler Canceler", "Fascist Law", "Hitler Death", "Liberal Law"]
creator_id: int
poll_id: int
chat_id: int
results: dict[str, str] # Literal["Hitler Canceler", "Fascist Law", "Hitler Death", "Liberal Law"]
creator_id: int

src/__main__.py Outdated

def main() -> None:
if not config.TELEGRAM_BOT_TOKEN:
raise ValueError("TELEGRAM_BOT_TOKEN env variable" "wasn't porpoused.")
raise ValueError("TELEGRAM_BOT_TOKEN env variable" "wasn't purposed.")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message concatenation is unnecessary and could be simplified.

- raise ValueError("TELEGRAM_BOT_TOKEN env variable" "wasn't purposed.")
+ raise ValueError("TELEGRAM_BOT_TOKEN env variable wasn't purposed.")

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
raise ValueError("TELEGRAM_BOT_TOKEN env variable" "wasn't purposed.")
raise ValueError("TELEGRAM_BOT_TOKEN env variable wasn't purposed.")

Comment on lines 30 to 39
steps:
- name: SSH into production server and deploy
uses: appleboy/ssh-action@master
env:
TELEGRAM_BOT_TOKEN: ${{ secrets.PROD_TELEGRAM_BOT_TOKEN }}
DEVELOPER_CHAT_ID: ${{ secrets.DEVELOPER_CHAT_ID }}
SQLITE_DB_FILE_PATH: ${{ vars.SQLITE_DB_FILE_PATH }}
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 NOTE
This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [33-47]

The addition of environment variables TELEGRAM_BOT_TOKEN, DEVELOPER_CHAT_ID, and SQLITE_DB_FILE_PATH is appropriate for the deployment script. However, there's a typo in the environment variable reference for SQLITE_DB_FILE_PATH. It should use secrets instead of vars.

- SQLITE_DB_FILE_PATH: ${{ vars.SQLITE_DB_FILE_PATH }}
+ SQLITE_DB_FILE_PATH: ${{ secrets.SQLITE_DB_FILE_PATH }}

Comment on lines 33 to 47
env:
TELEGRAM_BOT_TOKEN: ${{ secrets.DEV_TELEGRAM_BOT_TOKEN }}
DEVELOPER_CHAT_ID: ${{ secrets.DEVELOPER_CHAT_ID }}
SQLITE_DB_FILE_PATH: ${{ vars.SQLITE_DB_FILE_PATH }}
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
password: ${{ secrets.PASSWORD }}
key: ${{ secrets.PRIVATE_KEY }}
script: |
cd ./_work/${{ env.REPO_NAME }}/${{ env.REPO_NAME }}
docker compose down
docker compose up -d
docker compose ps
envs: TELEGRAM_BOT_TOKEN,DEVELOPER_CHAT_ID,SQLITE_DB_FILE_PATH
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The addition of environment variables TELEGRAM_BOT_TOKEN, DEVELOPER_CHAT_ID, and SQLITE_DB_FILE_PATH is appropriate for the deployment script. However, there's a typo in the environment variable reference for SQLITE_DB_FILE_PATH. It should use secrets instead of vars, similar to the issue in deploy.yml.

- SQLITE_DB_FILE_PATH: ${{ vars.SQLITE_DB_FILE_PATH }}
+ SQLITE_DB_FILE_PATH: ${{ secrets.SQLITE_DB_FILE_PATH }}

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
env:
TELEGRAM_BOT_TOKEN: ${{ secrets.DEV_TELEGRAM_BOT_TOKEN }}
DEVELOPER_CHAT_ID: ${{ secrets.DEVELOPER_CHAT_ID }}
SQLITE_DB_FILE_PATH: ${{ vars.SQLITE_DB_FILE_PATH }}
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
password: ${{ secrets.PASSWORD }}
key: ${{ secrets.PRIVATE_KEY }}
script: |
cd ./_work/${{ env.REPO_NAME }}/${{ env.REPO_NAME }}
docker compose down
docker compose up -d
docker compose ps
envs: TELEGRAM_BOT_TOKEN,DEVELOPER_CHAT_ID,SQLITE_DB_FILE_PATH
env:
TELEGRAM_BOT_TOKEN: ${{ secrets.DEV_TELEGRAM_BOT_TOKEN }}
DEVELOPER_CHAT_ID: ${{ secrets.DEVELOPER_CHAT_ID }}
SQLITE_DB_FILE_PATH: ${{ secrets.SQLITE_DB_FILE_PATH }}
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
password: ${{ secrets.PASSWORD }}
key: ${{ secrets.PRIVATE_KEY }}
script: |
cd ./_work/${{ env.REPO_NAME }}/${{ env.REPO_NAME }}
docker compose down
docker compose up -d
docker compose ps
envs: TELEGRAM_BOT_TOKEN,DEVELOPER_CHAT_ID,SQLITE_DB_FILE_PATH

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 3

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between b38aa4b and 88608cc.
Files ignored due to path filters (1)
  • pyproject.toml is excluded by: !**/*.toml
Files selected for processing (4)
  • src/config.py (1 hunks)
  • src/data_models/Record.py (3 hunks)
  • src/handlers/save.py (2 hunks)
  • src/services/db_service.py (2 hunks)
Files skipped from review as they are similar to previous changes (3)
  • src/config.py
  • src/data_models/Record.py
  • src/handlers/save.py

Comment on lines +4 to +9
from src.data_models.Playroom import Playroom
import logging
import sqlite3

from src.data_models.Game import Game
from src.data_models.Player import Player
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate imports for logging, sqlite3, and data models Game, Player, and Playroom. Remove the redundant lines to clean up the code.

- import logging
- import sqlite3
- from src.data_models.Game import Game
- from src.data_models.Player import Player
- from src.data_models.Playroom import Playroom

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
from src.data_models.Playroom import Playroom
import logging
import sqlite3
from src.data_models.Game import Game
from src.data_models.Player import Player

Comment on lines +18 to +33
try:
await execute(
"""INSERT INTO records (creator_id, player_id, playroom_id, game_id, role)
VALUES (?, ?, ?, ?, ?)""",
(
record.creator_id,
record.player_id,
record.playroom_id,
record.game_id,
record.role,
),
)
except sqlite3.IntegrityError:
logging.info(
f"Something went wrong with game: {record.game_id} in playroom {record.playroom_id}"
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The save_record function correctly handles sqlite3.IntegrityError with a try-except block and logs an informative message. However, consider enhancing the log message to include more details about the error for better debugging.

-        logging.info(
+        logging.error(

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
try:
await execute(
"""INSERT INTO records (creator_id, player_id, playroom_id, game_id, role)
VALUES (?, ?, ?, ?, ?)""",
(
record.creator_id,
record.player_id,
record.playroom_id,
record.game_id,
record.role,
),
)
except sqlite3.IntegrityError:
logging.info(
f"Something went wrong with game: {record.game_id} in playroom {record.playroom_id}"
)
try:
await execute(
"""INSERT INTO records (creator_id, player_id, playroom_id, game_id, role)
VALUES (?, ?, ?, ?, ?)""",
(
record.creator_id,
record.player_id,
record.playroom_id,
record.game_id,
record.role,
),
)
except sqlite3.IntegrityError:
logging.error(
f"Something went wrong with game: {record.game_id} in playroom {record.playroom_id}"
)

Comment on lines +36 to +44
async def save_playroom(playroom: Playroom) -> None:
"""Add a game room to the bot_data"""
try:
await execute(
"INSERT INTO playrooms (id, name) VALUES (?, ?)",
(playroom.telegram_chat_id, playroom.name),
)
except sqlite3.IntegrityError:
logging.info(f"Playroom {playroom.name} already exists in the database")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The save_playroom function is duplicated. Remove the duplicate definition to maintain code cleanliness and avoid confusion.

- async def save_playroom(playroom: Playroom) -> None:
-     """Add a game room to the bot_data"""
-     try:
-         await execute(
-             "INSERT INTO playrooms (id, name) VALUES (?, ?)",
-             (playroom.telegram_chat_id, playroom.name),
-         )
-     except sqlite3.IntegrityError:
-         logging.info(f"Playroom {playroom.name} already exists in the database")

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
async def save_playroom(playroom: Playroom) -> None:
"""Add a game room to the bot_data"""
try:
await execute(
"INSERT INTO playrooms (id, name) VALUES (?, ?)",
(playroom.telegram_chat_id, playroom.name),
)
except sqlite3.IntegrityError:
logging.info(f"Playroom {playroom.name} already exists in the database")

@Alex-Kopylov Alex-Kopylov merged commit b57d6ec into main Feb 6, 2024
2 checks passed
@Alex-Kopylov Alex-Kopylov deleted the develop branch February 6, 2024 23:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant