Add multi-env support

This commit is contained in:
VD15 2025-05-29 13:27:56 +01:00
parent 26f23a1354
commit 37ac7dbb0c
4 changed files with 147 additions and 12 deletions

5
.gitignore vendored
View file

@ -181,5 +181,6 @@ cython_debug/
.cursorindexingignore
# Custom stuff
gacha_game.db
config.ini
gacha_game*.db
gacha_game*.db.*
config*.ini

View file

@ -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']

View file

@ -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

View file

@ -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()