From 37ac7dbb0cfd2077af42b353584465607d6f307d Mon Sep 17 00:00:00 2001 From: VD15 Date: Thu, 29 May 2025 13:27:56 +0100 Subject: [PATCH 1/5] Add multi-env support --- .gitignore | 5 +-- bot/config.py | 21 ++++++++++- readme.md | 99 +++++++++++++++++++++++++++++++++++++++++++++++---- setup_db.py | 34 ++++++++++++++++-- 4 files changed, 147 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 960a84d..5b5cba0 100644 --- a/.gitignore +++ b/.gitignore @@ -181,5 +181,6 @@ cython_debug/ .cursorindexingignore # Custom stuff -gacha_game.db -config.ini +gacha_game*.db +gacha_game*.db.* +config*.ini diff --git a/bot/config.py b/bot/config.py index 643aeb1..16b2f1f 100644 --- a/bot/config.py +++ b/bot/config.py @@ -1,7 +1,26 @@ '''Essentials for the bot to function''' import configparser +from os import environ, path + +class ConfigError(Exception): + '''Could not find config file''' + +def get_config_file() -> str: + '''Gets the path to the config file in the current environment''' + env: str | None = environ.get('KEMOVERSE_ENV') + if not env: + raise ConfigError('Error: KEMOVERSE_ENV is unset') + if not (env in ['prod', 'dev']): + raise ConfigError(f'Error: Invalid environment: {env}') + + config_path: str = f'config_{env}.ini' + + if not path.isfile(config_path): + raise ConfigError(f'Could not find {config_path}') + return config_path + config = configparser.ConfigParser() -config.read('config.ini') +config.read(get_config_file()) # Username for the bot USER = config['credentials']['User'] diff --git a/readme.md b/readme.md index cf4470c..68a5985 100644 --- a/readme.md +++ b/readme.md @@ -1,6 +1,10 @@ # Kemoverse A gacha-style bot for the Fediverse built with Python. Users can roll for characters, trade, duel, and perhaps engage with popularity-based mechanics. Currently designed for use with Misskey. Name comes from Kemonomimi and Fediverse. +======= +## Installation + +## Roadmap ![Fediverse Gacha Bot Logo](./web/static/logo.png) @@ -11,18 +15,23 @@ A gacha-style bot for the Fediverse built with Python. Users can roll for charac - ๐ŸŽด Cards stats system - ๐Ÿง  Core database structure for characters and stats - ๐Ÿ“ฆ Basic support for storing pulls per user +- โฑ๏ธ Time-based limitations on rolls ### ๐Ÿงฉ In Progress - ๐Ÿ“ Whitelist system to limit access -- โฑ๏ธ Time-based limitations on rolls -- โš”๏ธ Dueling system +- โš ๏ธ Explicit account creation/deletion -## ๐Ÿง  Planned Features (Long Term) +## ๐Ÿง  Roadmap + +[See our v2.0 board for more details](https://git.waifuism.life/waifu/kemoverse/projects/3) ### ๐Ÿ›’ Gameplay & Collection - ๐Ÿ” **Trading system** between users - โญ **Favorite characters** (pin them or set profiles) - ๐Ÿ“ข **Public post announcements** for rare card pulls +- ๐Ÿ“Š **Stats** for cards +- ๐ŸŽฎ **Games** to play + - โš”๏ธ Dueling - ๐Ÿงฎ **Leaderboards** - Most traded Characters - Most owned Characters @@ -39,7 +48,7 @@ A gacha-style bot for the Fediverse built with Python. Users can roll for charac ## ๐Ÿ—ƒ๏ธ Tech Stack -- Python (3.11+) +- Python (3.12+) - SQLite - Fediverse API integration (via Misskey endpoints) - Flask @@ -49,10 +58,88 @@ A gacha-style bot for the Fediverse built with Python. Users can roll for charac The bot is meant to feel *light, fun, and competitive*. Mixing social, gacha and duel tactics. -## ๐Ÿงช Getting Started (coming soon) +## ๐Ÿงช Installation -Instructions on installing dependencies, initializing the database, and running the bot locally will go here. +1. Download and install dependencies +Clone the repo + +```sh +git clone https://git.waifuism.life/waifu/kemoverse.git +cd kemoverse +``` + +Setup a virtual environment (Optional, recommended) + +```sh +python3 -m venv venv +source venv/bin/activate +``` + +Install project dependencies via pip + +```sh +python3 -m pip install -r requirements.txt +``` + +2. Setup config file + +A sample config file is included with the project as a template: `example_config.ini` + +Create a copy of this file and replace its' values with your own. Consult the +template for more information about individual config values and their meaning. + +Config files are environment-specific. Use `config_dev.ini` for development and +`config_prod.ini` for production. Switch between environments using the +`KEMOVERSE_ENV` environment variable. + +```sh +cp example_config.ini config_dev.ini +# Edit config_dev.ini +``` + +4. Setup database + +To set up the database, run: + +```sh +KEMOVERSE_ENV=dev python3 setup_db.py +``` + +5. Run the bot + +```sh +KEMOVERSE_ENV=dev ./startup.sh +``` + +If all goes well, you should now be able to interact with the bot. + +6. Running in production + +To run the the in a production environment, use `KEMOVERSE_ENV=prod`. You will +also need to create a `config_prod.ini` file and run the database setup step +again if pointing prod to a different database. (you are pointing dev and prod +to different databases, right? ๐Ÿคจ) + +7. Updating + +To update the bot, first pull new changes from upstream: + +```sh +git pull +``` + +Then run any database migrations. We recommend testing in dev beforehand to +make sure nothing breaks in the update process. + +**Always backup your prod database before running any migrations!** + +```sh +# Backup database file +cp gacha_game_dev.db gacha_game_dev.db.bak +# Run migrations +KEMOVERSE_ENV=dev python3 setup_db.py +``` ```mermaid flowchart TD diff --git a/setup_db.py b/setup_db.py index fbb264e..241bb4e 100644 --- a/setup_db.py +++ b/setup_db.py @@ -11,6 +11,12 @@ class DBNotFoundError(Exception): class InvalidMigrationError(Exception): '''Migration file has an invalid name''' +class KemoverseEnvUnset(Exception): + '''KEMOVERSE_ENV is not set or has an invalid value''' + +class ConfigError(Exception): + '''Could not find the config file for the current environment''' + def get_migrations() -> List[Tuple[int, str]] | InvalidMigrationError: '''Returns a list of migration files in numeric order.''' # Store transaction id and filename separately @@ -50,11 +56,22 @@ def perform_migration(cursor: sqlite3.Cursor, migration: tuple[int, str]) -> Non def get_db_path() -> str | DBNotFoundError: '''Gets the DB path from config.ini''' + env = os.environ.get('KEMOVERSE_ENV') + if not (env and env in ['prod', 'dev']): + raise KemoverseEnvUnset + + print(f'Running in "{env}" mode') + + config_path = f'config_{env}.ini' + + if not os.path.isfile(config_path): + raise ConfigError(f'Could not find {config_path}') + config = ConfigParser() - config.read('config.ini') + config.read(config_path) db_path = config['application']['DatabaseLocation'] if not db_path: - raise DBNotFoundError + raise DBNotFoundError() return db_path def get_current_migration(cursor: sqlite3.Cursor) -> int: @@ -71,7 +88,18 @@ def get_current_migration(cursor: sqlite3.Cursor) -> int: def main(): '''Does the thing''' # Connect to the DB - db_path = get_db_path() + db_path = '' + try: + db_path = get_db_path() + except ConfigError as ex: + print(ex) + return + except KemoverseEnvUnset: + print('Error: KEMOVERSE_ENV is either not set or has an invalid value.') + print('Please set KEMOVERSE_ENV to either "dev" or "prod" before running.') + print(traceback.format_exc()) + return + conn = sqlite3.connect(db_path, autocommit=False) conn.row_factory = sqlite3.Row cursor = conn.cursor() From 8fb91f77543b8df97db655e2ad1642040c1cec0f Mon Sep 17 00:00:00 2001 From: VD15 Date: Thu, 29 May 2025 13:32:26 +0100 Subject: [PATCH 2/5] Fix spacing in readme --- readme.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/readme.md b/readme.md index 68a5985..f7b9a38 100644 --- a/readme.md +++ b/readme.md @@ -1,7 +1,9 @@ # Kemoverse A gacha-style bot for the Fediverse built with Python. Users can roll for characters, trade, duel, and perhaps engage with popularity-based mechanics. Currently designed for use with Misskey. Name comes from Kemonomimi and Fediverse. + ======= + ## Installation ## Roadmap From 4f853df32c61eeb008eab061bde5d5948e6c1db8 Mon Sep 17 00:00:00 2001 From: VD15 Date: Thu, 29 May 2025 13:32:48 +0100 Subject: [PATCH 3/5] Fix spacing in readme again --- readme.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/readme.md b/readme.md index f7b9a38..3b04aa7 100644 --- a/readme.md +++ b/readme.md @@ -2,8 +2,6 @@ A gacha-style bot for the Fediverse built with Python. Users can roll for characters, trade, duel, and perhaps engage with popularity-based mechanics. Currently designed for use with Misskey. Name comes from Kemonomimi and Fediverse. -======= - ## Installation ## Roadmap From 846130771e780829e8431858584dd9abe6cb040a Mon Sep 17 00:00:00 2001 From: VD15 Date: Thu, 29 May 2025 13:34:39 +0100 Subject: [PATCH 4/5] Update vocabulary --- readme.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/readme.md b/readme.md index 3b04aa7..3f2cbc0 100644 --- a/readme.md +++ b/readme.md @@ -12,9 +12,8 @@ A gacha-style bot for the Fediverse built with Python. Users can roll for charac ### โœ… Implemented - ๐ŸŽฒ Character roll system -- ๐ŸŽด Cards stats system -- ๐Ÿง  Core database structure for characters and stats -- ๐Ÿ“ฆ Basic support for storing pulls per user +- ๐Ÿง  Core database structure for cards +- ๐Ÿ“ฆ Basic support for storing pulls per player - โฑ๏ธ Time-based limitations on rolls ### ๐Ÿงฉ In Progress @@ -26,18 +25,18 @@ A gacha-style bot for the Fediverse built with Python. Users can roll for charac [See our v2.0 board for more details](https://git.waifuism.life/waifu/kemoverse/projects/3) ### ๐Ÿ›’ Gameplay & Collection -- ๐Ÿ” **Trading system** between users +- ๐Ÿ” **Trading system** between players - โญ **Favorite characters** (pin them or set profiles) - ๐Ÿ“ข **Public post announcements** for rare card pulls - ๐Ÿ“Š **Stats** for cards - ๐ŸŽฎ **Games** to play - โš”๏ธ Dueling - ๐Ÿงฎ **Leaderboards** - - Most traded Characters - - Most owned Characters - - Most voted Characters - - Most popular Characters (via usage-based popularity metrics) - - Users with the rarest Characters + - Most traded cards + - Most owned cards + - Most voted cards + - Most popular cards (via usage-based popularity metrics) + - Users with the rarest cards ### ๐ŸŽจ Card Aesthetics - ๐Ÿ–ผ๏ธ Simple card template for character rendering From de7670204adb8594cd8df2e9c576bfe9c0a22140 Mon Sep 17 00:00:00 2001 From: VD15 Date: Thu, 29 May 2025 13:36:30 +0100 Subject: [PATCH 5/5] Replace numbered list with h3 --- readme.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/readme.md b/readme.md index 3f2cbc0..40d723d 100644 --- a/readme.md +++ b/readme.md @@ -59,7 +59,7 @@ The bot is meant to feel *light, fun, and competitive*. Mixing social, gacha and ## ๐Ÿงช Installation -1. Download and install dependencies +### Download and install dependencies Clone the repo @@ -81,7 +81,7 @@ Install project dependencies via pip python3 -m pip install -r requirements.txt ``` -2. Setup config file +### Setup config file A sample config file is included with the project as a template: `example_config.ini` @@ -97,7 +97,7 @@ cp example_config.ini config_dev.ini # Edit config_dev.ini ``` -4. Setup database +### Setup database To set up the database, run: @@ -105,7 +105,7 @@ To set up the database, run: KEMOVERSE_ENV=dev python3 setup_db.py ``` -5. Run the bot +### Run the bot ```sh KEMOVERSE_ENV=dev ./startup.sh @@ -113,14 +113,14 @@ KEMOVERSE_ENV=dev ./startup.sh If all goes well, you should now be able to interact with the bot. -6. Running in production +### Running in production To run the the in a production environment, use `KEMOVERSE_ENV=prod`. You will also need to create a `config_prod.ini` file and run the database setup step again if pointing prod to a different database. (you are pointing dev and prod to different databases, right? ๐Ÿคจ) -7. Updating +### Updating To update the bot, first pull new changes from upstream: