From 6158eee9b12c0861284ddd97cf5d029a5779bd92 Mon Sep 17 00:00:00 2001 From: Kepka Ludovic Date: Sat, 13 Sep 2025 09:08:09 +0200 Subject: [PATCH 1/4] Nouvelle api pour humble bundle --- database/models.py | 4 ++-- database/schema.sql | 5 ++--- discordbot/humblebundle.py | 23 +++++++++++++++-------- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/database/models.py b/database/models.py index ed24f51..308f11c 100644 --- a/database/models.py +++ b/database/models.py @@ -15,9 +15,9 @@ class GameAlias(db.Model): name = db.Column(db.String(256)) class GameBundle(db.Model): - id = db.Column(db.Integer, primary_key=True) + url = db.Column(db.String(2048), primary_key=True) name = db.Column(db.String(256)) - json = db.Column(db.String(1024)) + json = db.Column(db.String(2048)) class LiveAlert(db.Model): id = db.Column(db.Integer, primary_key=True) diff --git a/database/schema.sql b/database/schema.sql index 2777bba..de38db0 100644 --- a/database/schema.sql +++ b/database/schema.sql @@ -11,9 +11,9 @@ CREATE TABLE IF NOT EXISTS `game_alias` ( ); CREATE TABLE IF NOT EXISTS `game_bundle` ( - id INTEGER PRIMARY KEY, + url VARCHAR(2048) PRIMARY KEY, name VARCHAR(256) NOT NULL, - json VARCHAR(1024) NOT NULL + json VARCHAR(2048) NOT NULL ); CREATE TABLE IF NOT EXISTS `humeur` ( @@ -45,4 +45,3 @@ CREATE TABLE IF NOT EXISTS `commande` ( `trigger` VARCHAR(16) UNIQUE NOT NULL, `response` VARCHAR(2000) NOT NULL ); - diff --git a/discordbot/humblebundle.py b/discordbot/humblebundle.py index 7458752..f1887a8 100644 --- a/discordbot/humblebundle.py +++ b/discordbot/humblebundle.py @@ -13,16 +13,22 @@ def _isEnable(): helper = ConfigurationHelper() return helper.getValue('humble_bundle_enable') and helper.getIntValue('humble_bundle_channel') != 0 and helper.getValue('humble_bundle_api_key') -def _callHexas(): - headers = { "Content-Type": "application/json", "api-key":ConfigurationHelper().getValue('humble_bundle_api_key') } - response = requests.get("http://hexas.shionn.org/humble-bundle/json", headers=headers) +def _callGithub(): + response = requests.get("https://raw.githubusercontent.com/shionn/HumbleBundleGamePack/refs/heads/master/data/game-bundles.json") if response.status_code == 200: return response.json() - logging.error(f"Échec de la connexion à l'API Humble Bundle. Code de statut HTTP : {response.status_code}") + logging.error(f"Échec de la connexion à la ressource Humble Bundle. Code de statut HTTP : {response.status_code}") return None def _isNotAlreadyNotified(bundle): - return GameBundle.query.filter_by(id=bundle['id']).first() == None + return GameBundle.query.filter_by(url=bundle['url']).first() == None + +def _findFirstNotNotified(bundles) : + if bundles != None : + for bundle in bundles: + if _isNotAlreadyNotified(bundle) : + return bundle + return None def _formatMessage(bundle): choice = bundle['choices'][0] @@ -36,11 +42,12 @@ def _formatMessage(bundle): async def checkHumbleBundleAndNotify(bot: Client): if _isEnable() : try : - bundle = _callHexas() - if bundle != None and _isNotAlreadyNotified(bundle) : + bundles = _callGithub() + bundle = _findFirstNotNotified(bundles) + if bundle != None : message = _formatMessage(bundle) await bot.get_channel(ConfigurationHelper().getIntValue('humble_bundle_channel')).send(message) - db.session.add(GameBundle(id=bundle['id'], name=bundle['name'], json = json.dumps(bundle))) + db.session.add(GameBundle(url=bundle['url'], name=bundle['name'], json = json.dumps(bundle))) db.session.commit() except Exception as e: logging.error(f"Échec de la vérification des offres Humble Bundle : {e}") From 9f03d9130711f3be24fe59887d9a79ad9bfdb0b6 Mon Sep 17 00:00:00 2001 From: Kepka Ludovic Date: Sat, 13 Sep 2025 09:09:04 +0200 Subject: [PATCH 2/4] Suppression humble bundle api key --- discordbot/humblebundle.py | 2 +- webapp/templates/configurations.html | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/discordbot/humblebundle.py b/discordbot/humblebundle.py index f1887a8..7c5ebe5 100644 --- a/discordbot/humblebundle.py +++ b/discordbot/humblebundle.py @@ -11,7 +11,7 @@ from discord import Client def _isEnable(): helper = ConfigurationHelper() - return helper.getValue('humble_bundle_enable') and helper.getIntValue('humble_bundle_channel') != 0 and helper.getValue('humble_bundle_api_key') + return helper.getValue('humble_bundle_enable') and helper.getIntValue('humble_bundle_channel') != 0 def _callGithub(): response = requests.get("https://raw.githubusercontent.com/shionn/HumbleBundleGamePack/refs/heads/master/data/game-bundles.json") diff --git a/webapp/templates/configurations.html b/webapp/templates/configurations.html index c43917c..c8c43f3 100644 --- a/webapp/templates/configurations.html +++ b/webapp/templates/configurations.html @@ -53,8 +53,6 @@ {{channel.name}} {% endfor %} - - {% endblock %} \ No newline at end of file From 404d1cbda0af1a7c4b13236e727c7c6c4e35eab6 Mon Sep 17 00:00:00 2001 From: sky Date: Sun, 14 Sep 2025 00:01:29 +0200 Subject: [PATCH 3/4] Migre la table game_bundle si elle a l'ancienne structure --- database/__init__.py | 28 +++++++++++++++++++++++++++- database/database.db | 0 2 files changed, 27 insertions(+), 1 deletion(-) delete mode 100644 database/database.db diff --git a/database/__init__.py b/database/__init__.py index 36795f9..234698c 100644 --- a/database/__init__.py +++ b/database/__init__.py @@ -1,10 +1,36 @@ from flask_sqlalchemy import SQLAlchemy from webapp import webapp +import os -webapp.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database.db' +basedir = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) +webapp.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{os.path.join(basedir, "instance", "database.db")}' db = SQLAlchemy(webapp) +def migrate_game_bundle_if_needed(): + """Migre la table game_bundle si elle a l'ancienne structure (id comme clé primaire)""" + try: + connection = db.session.connection().connection + cursor = connection.cursor() + + cursor.execute("PRAGMA table_info(game_bundle)") + columns = cursor.fetchall() + + if columns: + has_id_primary = any(col[1] == 'id' and col[5] == 1 for col in columns) + + if has_id_primary: + print("Migration de game_bundle: ancienne structure détectée") + cursor.execute("DROP TABLE game_bundle") + connection.commit() + print("Ancienne table game_bundle supprimée") + + cursor.close() + except Exception as e: + print(f"Erreur lors de la vérification de migration: {e}") + with webapp.app_context(): + migrate_game_bundle_if_needed() + with open('database/schema.sql', 'r') as f: sql = f.read() connection = db.session.connection().connection diff --git a/database/database.db b/database/database.db deleted file mode 100644 index e69de29..0000000 From 016beb318c8ba423ac72ad6352dffe4226475985 Mon Sep 17 00:00:00 2001 From: Kepka Ludovic Date: Sun, 14 Sep 2025 10:46:57 +0200 Subject: [PATCH 4/4] =?UTF-8?q?Procedure=20de=20migration=20des=20donn?= =?UTF-8?q?=C3=A9e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- database/__init__.py | 72 +++++++++++++++++++++++++++----------------- 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/database/__init__.py b/database/__init__.py index 234698c..eb3a05b 100644 --- a/database/__init__.py +++ b/database/__init__.py @@ -1,42 +1,60 @@ -from flask_sqlalchemy import SQLAlchemy -from webapp import webapp +import logging +import json import os +from flask_sqlalchemy import SQLAlchemy +from sqlite3 import Cursor, Connection +from webapp import webapp + + basedir = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) webapp.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{os.path.join(basedir, "instance", "database.db")}' db = SQLAlchemy(webapp) -def migrate_game_bundle_if_needed(): - """Migre la table game_bundle si elle a l'ancienne structure (id comme clé primaire)""" - try: - connection = db.session.connection().connection - cursor = connection.cursor() - - cursor.execute("PRAGMA table_info(game_bundle)") - columns = cursor.fetchall() - - if columns: - has_id_primary = any(col[1] == 'id' and col[5] == 1 for col in columns) - - if has_id_primary: - print("Migration de game_bundle: ancienne structure détectée") - cursor.execute("DROP TABLE game_bundle") - connection.commit() - print("Ancienne table game_bundle supprimée") - - cursor.close() - except Exception as e: - print(f"Erreur lors de la vérification de migration: {e}") +def _tableHaveColumn(table_name:str, column_name:str, cursor:Cursor) -> bool: + cursor.execute(f'PRAGMA table_info({table_name})') + columns = cursor.fetchall() + return any(col[1] == column_name for col in columns) + +def _tableEmpty(table:str, cursor:Cursor) -> bool: + return cursor.execute(f'SELECT COUNT(*) FROM {table}').fetchone()[0] == 0 + +def _renameTable(old_name:str, new_name:str, cursor:Cursor) : + cursor.execute(f'ALTER TABLE {old_name} RENAME TO {new_name}') + +def _dropTable(table_name:str, cursor:Cursor) : + cursor.execute(f'DROP TABLE {table_name}') + +def _doPreImportMigration(cursor:Cursor): + if _tableHaveColumn('game_bundle', 'id', cursor) : + logging.info("Table game_bundle détécté, rennomage en game_bundle_old") + _renameTable('game_bundle', 'game_bundle_old', cursor) + +def _doPostImportMigration(cursor:Cursor): + if _tableEmpty('game_bundle', cursor) : + logging.info("remplir game_bundle avec game_bundle_old") + bundles = cursor.execute(f'SELECT * FROM game_bundle_old').fetchall() + for bundle in bundles : + name = bundle[1] + json_data = json.loads(bundle[2]) + url = json_data['url'] + logging.info(f'import du bundle {name}, {url}') + cursor.execute('INSERT INTO game_bundle(url, name, json) VALUES (?, ?, ?)', (url, name, json.dumps(json_data))) + logging.info("suppression de la table temporaire game_bundle_old") + _dropTable('game_bundle_old', cursor) with webapp.app_context(): - migrate_game_bundle_if_needed() - with open('database/schema.sql', 'r') as f: sql = f.read() - connection = db.session.connection().connection + connection : Connection = db.session.connection().connection try: - cursor = connection.cursor() + cursor : Cursor = connection.cursor() + _doPreImportMigration(cursor) cursor.executescript(sql) + _doPostImportMigration(cursor) + connection.commit() cursor.close() + except Exception as e: + logging.error(f"lors de l'import de la bdd : {e}") finally: connection.close()