Merge pull request 'Added table and general functions for stats system' (#21) from stats_system into dev

Some notes:
- Set the default value for card stats as 0, as we don't know the max we want
- Added a get_cards function that takes a list of ids and returns all the card information from the database, there's probably better ways to implement it though
Tested and works correctly
Reviewed-on: #21
This commit is contained in:
waifu 2025-06-25 20:45:12 -07:00
commit c59edbcf4f
4 changed files with 92 additions and 11 deletions

View file

@ -19,7 +19,7 @@ import config
from fediverse_factory import get_fediverse_service from fediverse_factory import get_fediverse_service
import db_utils import db_utils
def add_card(name: str, rarity: int, image_url: str) -> tuple[int, str]: def add_card(name: str, rarity: int, image_url: str, power: int, charm: int, wit: int) -> tuple[int, str]:
""" """
Adds a card to the database, uploading the image from a public URL to the Fediverse instance. Adds a card to the database, uploading the image from a public URL to the Fediverse instance.
@ -27,6 +27,9 @@ def add_card(name: str, rarity: int, image_url: str) -> tuple[int, str]:
name (str): Card name. name (str): Card name.
rarity (int): Card rarity (e.g., 1-5). rarity (int): Card rarity (e.g., 1-5).
image_url (str): Public URL of the image from the post. image_url (str): Public URL of the image from the post.
power (int): Card power value.
charm (int): Card charm value.
wit (int): Card wit value.
Returns: Returns:
tuple[int, str]: Card ID and file_id. tuple[int, str]: Card ID and file_id.
@ -47,7 +50,8 @@ def add_card(name: str, rarity: int, image_url: str) -> tuple[int, str]:
raise ValueError(f'Invalid rarity: {rarity}') raise ValueError(f'Invalid rarity: {rarity}')
if not image_url: if not image_url:
raise ValueError('Image URL must be provided.') raise ValueError('Image URL must be provided.')
if power < 0 or charm < 0 or wit < 0:
raise ValueError('Power, charm, and wit must be non-negative integers.')
try: try:
# Download image # Download image
response = requests.get(image_url, stream=True, timeout=30) response = requests.get(image_url, stream=True, timeout=30)
@ -66,7 +70,10 @@ def add_card(name: str, rarity: int, image_url: str) -> tuple[int, str]:
card_id = db_utils.insert_card( card_id = db_utils.insert_card(
stripped_name, stripped_name,
rarity, rarity,
file_id file_id,
power,
charm,
wit
) )
return card_id, file_id return card_id, file_id

View file

@ -1,5 +1,5 @@
# Kemoverse - a gacha-style bot for the Fediverse. # Kemoverse - a gacha-style bot for the Fediverse.
# Copyright © 2025 Waifu VD15, Moon, and contributors. # Copyright © 2025 Waifu, VD15, Moon, and contributors.
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -75,6 +75,19 @@ def get_random_card() -> Card | None:
'image_url': chosen['file_id'] 'image_url': chosen['file_id']
} }
def get_cards(card_ids: list[int]) -> list[tuple]:
'''
Retrieves stats for a list of card IDs.
Returns a list of tuples: (id, name, rarity, file_id, power, charm, wit, ...)
'''
if not card_ids:
return []
placeholders = ','.join('?' for _ in card_ids)
query = f'SELECT * FROM cards WHERE id IN ({placeholders})'
CURSOR.execute(query, card_ids)
return CURSOR.fetchall()
def get_player(username: str) -> int: def get_player(username: str) -> int:
'''Retrieve a player ID by username, or return None if not found.''' '''Retrieve a player ID by username, or return None if not found.'''
@ -166,12 +179,25 @@ def is_player_administrator(username: str) -> bool:
def insert_card( def insert_card(
name: str, rarity: int, file_id: str) -> int: name: str, rarity: int, file_id: str,
power: int =None, charm: int = None, wit: int = None) -> int:
'''Inserts a card''' '''Inserts a card'''
CURSOR.execute( if power is not None and charm is not None and wit is not None:
'INSERT INTO cards (name, rarity, file_id) VALUES (?, ?, ?)', CURSOR.execute(
(name, rarity, file_id) '''
) INSERT INTO cards (name, rarity, file_id, power, charm, wit)
VALUES (?, ?, ?, ?, ?, ?)
''',
(name, rarity, file_id, power, charm, wit)
)
else:
CURSOR.execute(
'''
INSERT INTO cards (name, rarity, file_id)
VALUES (?, ?, ?)
''',
(name, rarity, file_id)
)
card_id = CURSOR.lastrowid card_id = CURSOR.lastrowid
return card_id if card_id else 0 return card_id if card_id else 0
@ -193,6 +219,7 @@ DESC",
row = CURSOR.fetchone() row = CURSOR.fetchone()
return row[0] if row else 0 return row[0] if row else 0
# Configuration
def add_to_whitelist(instance: str) -> bool: def add_to_whitelist(instance: str) -> bool:
'''Adds an instance to the whitelist, returns false if instance was already '''Adds an instance to the whitelist, returns false if instance was already

View file

@ -123,10 +123,10 @@ dumbass.',
'attachment_urls': None 'attachment_urls': None
} }
if len(arguments) != 2: if not(len(arguments) in (2,5)):
return { return {
'message': f'{author} Please specify the following attributes \ 'message': f'{author} Please specify the following attributes \
in order: name, rarity', in order: name, rarity. Optionally add [power, charm, wit].',
'attachment_urls': None 'attachment_urls': None
} }
@ -137,6 +137,27 @@ be a number between 1 and 5',
'attachment_urls': None 'attachment_urls': None
} }
if len(arguments) == 2:
pass
else:
if not all(arg.isnumeric() for arg in arguments[2:]):
return {
'message': f'{author} Invalid attributes: power, charm and \
wit must be numbers.',
'attachment_urls': None
}
card_id, file_id = add_card(
name=arguments[0],
rarity=int(arguments[1]),
image_url=image_url,
power=int(arguments[2]),
charm=int(arguments[3]),
wit=int(arguments[4])
)
return {
'message': f'{author} Added {arguments[0]}, ID {card_id}.',
'attachment_urls': [file_id]
}
card_id, file_id = add_card( card_id, file_id = add_card(
name=arguments[0], name=arguments[0],
rarity=int(arguments[1]), rarity=int(arguments[1]),

View file

@ -0,0 +1,26 @@
/*
Kemoverse - a gacha-style bot for the Fediverse.
Copyright © 2025 Waifu
This program 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, either version 3 of the
License, or (at your option) any later version.
This program 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 this program. If not, see https://www.gnu.org/licenses/.
*/
ALTER TABLE cards
ADD COLUMN power INTEGER NOT NULL DEFAULT 0;
ALTER TABLE cards
ADD COLUMN charm INTEGER NOT NULL DEFAULT 0;
ALTER TABLE cards
ADD COLUMN wit INTEGER NOT NULL DEFAULT 0;