diff --git a/docker-compose.yml b/docker-compose.yml index 06ebfcf..adb2feb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,34 +1,28 @@ version: '3' services: mysql: + container_name: database build: - context: ../bot-detector-mysql - dockerfile: Dockerfile - image: bot-detector/bd-mysql:latest + context: ./mysql + image: mysql environment: - MYSQL_ROOT_PASSWORD=root_bot_buster - - MYSQL_USER=botssuck - - MYSQL_PASSWORD=botdetector volumes: - - ../bot-detector-mysql/mount:/var/lib/mysql - - '../bot-detector-mysql/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d' + - ./mysql/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d + - ./mysql/conf.d:/etc/mysql/conf.d + # - ./mysql/mount:/var/lib/mysql # creates persistence ports: - - "3306:3306" + - 3307:3306 networks: - botdetector-network - - kafka: - image: bitnami/kafka:latest - environment: - - ALLOW_PLAINTEXT_LISTENER=yes - - KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093,EXTERNAL://:9094 - - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,EXTERNAL:PLAINTEXT - - KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://kafka:9092,EXTERNAL://localhost:9094 - - KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE=true - ports: - - 9094:9094 - networks: - - botdetector-network + healthcheck: + test: "mysqladmin ping -h localhost -u root -proot_bot_buster" + # during this period fails are not considered + start_period: 30s + # time between cmd + interval: 30s + # time given to the cmd + timeout: 5s api: build: @@ -41,18 +35,17 @@ services: command: uvicorn src.core.server:app --host 0.0.0.0 --reload --reload-include src/* container_name: bd-dev-api environment: - - sql_uri=mysql+asyncmy://root:root_bot_buster@mysql:3306/playerdata - - discord_sql_uri=mysql+asyncmy://root:root_bot_buster@mysql:3306/discord + - sql_uri=mysql+asyncmy://root:root_bot_buster@mysql/playerdata + - discord_sql_uri=mysql+asyncmy://root:root_bot_buster@mysql/discord - token=verify_ban volumes: - - ../Bot-Detector-Core-Files/src:/project/src:rw + - ./src:/project/src:rw ports: - 5000:5000 networks: - botdetector-network depends_on: - - mysql - - kafka - + mysql: + condition: service_healthy networks: botdetector-network: diff --git a/mysql/Dockerfile b/mysql/Dockerfile new file mode 100644 index 0000000..4244cbe --- /dev/null +++ b/mysql/Dockerfile @@ -0,0 +1,3 @@ +FROM mysql:8.0.32 + +EXPOSE 3306 \ No newline at end of file diff --git a/mysql/docker-entrypoint-initdb.d/00_init.sql b/mysql/docker-entrypoint-initdb.d/00_init.sql new file mode 100644 index 0000000..7d82066 --- /dev/null +++ b/mysql/docker-entrypoint-initdb.d/00_init.sql @@ -0,0 +1 @@ +CREATE DATABASE playerdata; \ No newline at end of file diff --git a/mysql/docker-entrypoint-initdb.d/01_tables.sql b/mysql/docker-entrypoint-initdb.d/01_tables.sql new file mode 100644 index 0000000..9d59bbb --- /dev/null +++ b/mysql/docker-entrypoint-initdb.d/01_tables.sql @@ -0,0 +1,128 @@ +USE playerdata; +-- Create a table for Players +CREATE TABLE Players ( + id INT PRIMARY KEY AUTO_INCREMENT, + name TEXT, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP, + possible_ban BOOLEAN, + confirmed_ban BOOLEAN, + confirmed_player BOOLEAN, + label_id INTEGER, + label_jagex INTEGER, + ironman BOOLEAN, + hardcore_ironman BOOLEAN, + ultimate_ironman BOOLEAN, + normalized_name TEXT +); + +CREATE TABLE `Labels` ( + `id` int NOT NULL AUTO_INCREMENT, + `label` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `Unique_label` (`label`) USING BTREE +) +; + +-- Create a table for Reports +CREATE TABLE Reports ( + ID BIGINT PRIMARY KEY AUTO_INCREMENT, + created_at TIMESTAMP, + reportedID INT, + reportingID INT, + region_id INT, + x_coord INT, + y_coord INT, + z_coord INT, + timestamp TIMESTAMP, + manual_detect SMALLINT, + on_members_world INT, + on_pvp_world SMALLINT, + world_number INT, + equip_head_id INT, + equip_amulet_id INT, + equip_torso_id INT, + equip_legs_id INT, + equip_boots_id INT, + equip_cape_id INT, + equip_hands_id INT, + equip_weapon_id INT, + equip_shield_id INT, + equip_ge_value BIGINT, + CONSTRAINT `FK_Reported_Players_id` FOREIGN KEY (`reportedID`) REFERENCES `Players` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT, + CONSTRAINT `FK_Reporting_Players_id` FOREIGN KEY (`reportingID`) REFERENCES `Players` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT +); +-- Create a table for Predictions +CREATE TABLE Predictions ( + id INT PRIMARY KEY AUTO_INCREMENT, + name VARCHAR(12), + prediction VARCHAR(50), + created TIMESTAMP, + predicted_confidence DECIMAL(5, 2), + real_player DECIMAL(5, 2) DEFAULT 0, + pvm_melee_bot DECIMAL(5, 2) DEFAULT 0, + smithing_bot DECIMAL(5, 2) DEFAULT 0, + magic_bot DECIMAL(5, 2) DEFAULT 0, + fishing_bot DECIMAL(5, 2) DEFAULT 0, + mining_bot DECIMAL(5, 2) DEFAULT 0, + crafting_bot DECIMAL(5, 2) DEFAULT 0, + pvm_ranged_magic_bot DECIMAL(5, 2) DEFAULT 0, + pvm_ranged_bot DECIMAL(5, 2) DEFAULT 0, + hunter_bot DECIMAL(5, 2) DEFAULT 0, + fletching_bot DECIMAL(5, 2) DEFAULT 0, + clue_scroll_bot DECIMAL(5, 2) DEFAULT 0, + lms_bot DECIMAL(5, 2) DEFAULT 0, + agility_bot DECIMAL(5, 2) DEFAULT 0, + wintertodt_bot DECIMAL(5, 2) DEFAULT 0, + runecrafting_bot DECIMAL(5, 2) DEFAULT 0, + zalcano_bot DECIMAL(5, 2) DEFAULT 0, + woodcutting_bot DECIMAL(5, 2) DEFAULT 0, + thieving_bot DECIMAL(5, 2) DEFAULT 0, + soul_wars_bot DECIMAL(5, 2) DEFAULT 0, + cooking_bot DECIMAL(5, 2) DEFAULT 0, + vorkath_bot DECIMAL(5, 2) DEFAULT 0, + barrows_bot DECIMAL(5, 2) DEFAULT 0, + herblore_bot DECIMAL(5, 2) DEFAULT 0, + zulrah_bot DECIMAL(5, 2) DEFAULT 0, + gauntlet_bot DECIMAL(5, 2) DEFAULT 0, + nex_bot DECIMAL(5, 2) DEFAULT 0, + unknown_bot DECIMAL(5, 2) DEFAULT 0 +); +-- Create a table for Feedback +CREATE TABLE PredictionsFeedback ( + id INT PRIMARY KEY AUTO_INCREMENT, + ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + voter_id INT NOT NULL, + subject_id INT NOT NULL, + prediction VARCHAR(50) NOT NULL, + confidence FLOAT NOT NULL, + vote INT NOT NULL DEFAULT '0', + feedback_text TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci, + reviewed TINYINT NOT NULL DEFAULT '0', + reviewer_id INT DEFAULT NULL, + user_notified TINYINT NOT NULL DEFAULT '0', + proposed_label VARCHAR(50) DEFAULT NULL, + UNIQUE KEY Unique_Vote ( + prediction, + subject_id, + voter_id + ) USING BTREE, + CONSTRAINT `FK_Subject_ID` FOREIGN KEY (`subject_id`) REFERENCES `Players` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT, + CONSTRAINT `FK_Voter_ID` FOREIGN KEY (`voter_id`) REFERENCES `Players` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT +); + +CREATE TABLE report_sighting ( + `report_sighting_id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `reporting_id` INT UNSIGNED NOT NULL, + `reported_id` INT UNSIGNED NOT NULL, + `manual_detect` TINYINT(1) DEFAULT 0, + PRIMARY key (`report_sighting_id`), + UNIQUE KEY unique_sighting (`reporting_id`, `reported_id`, `manual_detect`), + KEY idx_reported_id (`reported_id`) +); + +CREATE TABLE report_migrated ( + `reporting_id` INT UNSIGNED NOT NULL, + `migrated` TINYINT UNSIGNED, + PRIMARY KEY (`reporting_id`) +); \ No newline at end of file diff --git a/mysql/docker-entrypoint-initdb.d/02_data.sql b/mysql/docker-entrypoint-initdb.d/02_data.sql new file mode 100644 index 0000000..0b4e593 --- /dev/null +++ b/mysql/docker-entrypoint-initdb.d/02_data.sql @@ -0,0 +1,275 @@ +USE playerdata; + +-- Insert data into the Players table +DELIMITER $$ + +CREATE PROCEDURE InsertRandomPlayers(IN NUM INT, IN possible_ban BOOL, IN confirmed_ban BOOL, IN confirmed_player BOOL) +BEGIN + DECLARE i INT DEFAULT 1; + + WHILE i <= NUM DO + INSERT INTO Players ( + name, + created_at, + updated_at, + possible_ban, + confirmed_ban, + confirmed_player, + label_id, + label_jagex, + ironman, + hardcore_ironman, + ultimate_ironman, + normalized_name + ) + SELECT + UUID() AS name, -- updated later + NOW() AS created_at, -- updated later + NOW() AS updated_at, -- updated later + possible_ban, + confirmed_ban, + confirmed_player, + 0 AS label_id, + ROUND(RAND() * 1) AS label_jagex, -- doesn't matter? + null AS ironman, + null AS hardcore_ironman, + null AS ultimate_ironman, + UUID() AS normalized_name -- updated later + FROM dual; + + SET i = i + 1; + END WHILE; +END $$ + +DELIMITER ; + + +call InsertRandomPlayers(100, 1,0,0); +call InsertRandomPlayers(100, 1,1,0); +call InsertRandomPlayers(100, 0,0,1); + +UPDATE Players +SET + name = CONCAT('player', id), + normalized_name = CONCAT('player', id) +; + + +-- Insert data into the Reports table +INSERT INTO + Reports ( + created_at, + reportedID, + reportingID, + region_id, + x_coord, + y_coord, + z_coord, + timestamp, + manual_detect, + on_members_world, + on_pvp_world, + world_number, + equip_head_id, + equip_amulet_id, + equip_torso_id, + equip_legs_id, + equip_boots_id, + equip_cape_id, + equip_hands_id, + equip_weapon_id, + equip_shield_id, + equip_ge_value + ) +SELECT + NOW() - INTERVAL FLOOR(RAND(42) * 365) DAY AS created_at, + p1.id AS reportedID, + p2.id AS reportingID, + ROUND(RAND(42) * 1000) AS region_id, + -- Random region_id + ROUND(RAND(42) * 1000) AS x_coord, + -- Random x_coord + ROUND(RAND(42) * 1000) AS y_coord, + -- Random y_coord + ROUND(RAND(42) * 1000) AS z_coord, + -- Random z_coord + NOW() - INTERVAL FLOOR(RAND(42) * 365) DAY AS timestamp, + ROUND(RAND(42)) AS manual_detect, + -- Random manual_detect (0 or 1) + ROUND(RAND(42) * 1000) AS on_members_world, + -- Random on_members_world + ROUND(RAND(42)) AS on_pvp_world, + -- Random on_pvp_world (0 or 1) + ROUND(RAND(42) * 100) AS world_number, + -- Random world_number + ROUND(RAND(42) * 1000) AS equip_head_id, + -- Random equip_head_id + ROUND(RAND(42) * 1000) AS equip_amulet_id, + -- Random equip_amulet_id + ROUND(RAND(42) * 1000) AS equip_torso_id, + -- Random equip_torso_id + ROUND(RAND(42) * 1000) AS equip_legs_id, + -- Random equip_legs_id + ROUND(RAND(42) * 1000) AS equip_boots_id, + -- Random equip_boots_id + ROUND(RAND(42) * 1000) AS equip_cape_id, + -- Random equip_cape_id + ROUND(RAND(42) * 1000) AS equip_hands_id, + -- Random equip_hands_id + ROUND(RAND(42) * 1000) AS equip_weapon_id, + -- Random equip_weapon_id + ROUND(RAND(42) * 1000) AS equip_shield_id, + -- Random equip_shield_id + ROUND(RAND(42) * 10000) AS equip_ge_value -- Random equip_ge_value +FROM Players p1 + CROSS JOIN Players p2 +WHERE + p1.id <> p2.id -- Ensure reportedID and reportingID are different +ORDER BY + RAND(42) -- Randomize the order of the combinations +LIMIT + 10000 -- Limit the number of combinations to insert +; + +INSERT INTO Predictions (name, predicted_confidence, prediction, created) +SELECT + name, + FLOOR(RAND(6)*(100-1)+1), + CASE FLOOR(RAND(6)*(25-1)+1) + WHEN 1 THEN 'real_player' + WHEN 2 THEN 'pvm_melee_bot' + WHEN 3 THEN 'smithing_bot' + WHEN 4 THEN 'magic_bot' + WHEN 5 THEN 'fishing_bot' + WHEN 6 THEN 'mining_bot' + WHEN 7 THEN 'crafting_bot' + WHEN 8 THEN 'pvm_ranged_magic_bot' + WHEN 9 THEN 'pvm_ranged_bot' + WHEN 10 THEN 'hunter_bot' + WHEN 11 THEN 'fletching_bot' + WHEN 12 THEN 'clue_scroll_bot' + WHEN 13 THEN 'lms_bot' + WHEN 14 THEN 'agility_bot' + WHEN 15 THEN 'wintertodt_bot' + WHEN 16 THEN 'runecrafting_bot' + WHEN 17 THEN 'zalcano_bot' + WHEN 18 THEN 'woodcutting_bot' + WHEN 19 THEN 'thieving_bot' + WHEN 20 THEN 'soul_wars_bot' + WHEN 21 THEN 'cooking_bot' + WHEN 22 THEN 'vorkath_bot' + WHEN 23 THEN 'barrows_bot' + WHEN 24 THEN 'herblore_bot' + ELSE 'unknown_bot' + END , + FROM_UNIXTIME( + TIMESTAMPDIFF(SECOND, '2020-01-01 00:00:00', '2022-12-31 23:59:59') * RAND(42) + + UNIX_TIMESTAMP('2020-01-01 00:00:00') + ) +FROM `Players` +where 1=1 + AND name not LIKE 'anonymoususer%' +ORDER BY RAND(42) +LIMIT 250 +; + +INSERT INTO playerdata.Labels (label) VALUES + ('Agility_bot'), + ('Barrows_bot'), + ('Blast_mine_bot'), + ('Clue_Scroll_bot'), + ('Construction_Magic_bot'), + ('Cooking_bot'), + ('Crafting_bot'), + ('Fishing_bot'), + ('Fishing_Cooking_bot'), + ('Fletching_bot'), + ('Herblore_bot'), + ('Hunter_bot'), + ('LMS_bot'), + ('Mage_Guild_Store_bot'), + ('Magic_bot'), + ('Mining_bot'), + ('mort_myre_fungus_bot'), + ('Phosani_bot'), + ('PVM_Melee_bot'), + ('PVM_Ranged_bot'), + ('PVM_Ranged_Magic_bot'), + ('Real_Player'), + ('Runecrafting_bot'), + ('Smithing_bot'), + ('Soul_Wars_bot'), + ('temp_real_player'), + ('test_label'), + ('Thieving_bot'), + ('Unknown'), + ('Unknown_bot'), + ('Vorkath_bot'), + ('Wintertodt_bot'), + ('Woodcutting_bot'), + ('Woodcutting_Firemaking_bot'), + ('Woodcutting_Mining_bot'), + ('Zalcano_bot'), + ('Zulrah_bot') +; + +INSERT INTO PredictionsFeedback (voter_id, subject_id, prediction, confidence, feedback_text, vote, proposed_label) +SELECT + pl1.id AS voter_id, + pl2.id AS subject_id, + pr.prediction, + FLOOR(RAND(6)*(100-1)+1)/100 AS confidence, -- Generate a random confidence value between 0 and 1 + "" AS feedback_text, + CASE + WHEN FLOOR(RAND(6)*(100-1)+1) < 33 THEN -1 + WHEN FLOOR(RAND(6)*(100-1)+1) < 66 THEN 0 + ELSE 1 + END AS vote, + (SELECT label FROM Labels ORDER BY RAND(42) LIMIT 1) AS proposed_label +FROM (SELECT * FROM Players ORDER BY RAND(42) LIMIT 1000) pl1 +JOIN (SELECT * FROM Players ORDER BY RAND(42) LIMIT 1000) pl2 ON pl1.id <> pl2.id +JOIN Predictions pr ON pr.id = pl2.id +ORDER BY RAND(42) +LIMIT 100; + +UPDATE PredictionsFeedback + SET proposed_label = prediction +WHERE 1=1 + AND vote = 1 +; + +DELIMITER $$ + +INSERT INTO Players ( + name, + created_at, + updated_at, + possible_ban, + confirmed_ban, + confirmed_player, + label_id, + label_jagex +) VALUES + ("anonymoususer 382e728f 87ea 11ee aab6 0242ac120002", NOW(), NOW(), 0, 0, 0, 0, 0), + ("anonymoususer 382e7259 87ea 11ee aab6 0242ac120002", NOW(), NOW(), 0, 0, 0, 0, 0), + ("anonymoususer 382e7221 87ea 11ee aab6 0242ac120002", NOW(), NOW(), 0, 0, 0, 0, 0), + ("anonymoususer 382e71ee 87ea 11ee aab6 0242ac120002", NOW(), NOW(), 0, 0, 0, 0, 0), + ("anonymoususer 382e71bb 87ea 11ee aab6 0242ac120002", NOW(), NOW(), 0, 0, 0, 0, 0), + ("anonymoususer 382e7179 87ea 11ee aab6 0242ac120002", NOW(), NOW(), 0, 0, 0, 0, 0), + ("anonymoususer 382e7133 87ea 11ee aab6 0242ac120002", NOW(), NOW(), 0, 0, 0, 0, 0), + ("anonymoususer 382e70ef 87ea 11ee aab6 0242ac120002", NOW(), NOW(), 0, 0, 0, 0, 0), + ("anonymoususer 382e7089 87ea 11ee aab6 0242ac120002", NOW(), NOW(), 0, 0, 0, 0, 0), + ("anonymoususer 382e6def 87ea 11ee aab6 0242ac120002", NOW(), NOW(), 0, 0, 0, 0, 0) +; + +UPDATE `Players` +SET + created_at = NOW() - INTERVAL FLOOR(RAND(42) * 365) DAY, + updated_at = NOW() - INTERVAL FLOOR(RAND(41) * 365) DAY +; +UPDATE `Players` +SET + name=replace(name,'-',' '), + normalized_name=replace(name,'-',' ') +WHERE name LIKE 'anonymoususer%' +; \ No newline at end of file diff --git a/src/api/v1/report.py b/src/api/v1/report.py index 11fe9d0..38fff08 100644 --- a/src/api/v1/report.py +++ b/src/api/v1/report.py @@ -14,7 +14,7 @@ from pydantic.fields import Field from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.orm import aliased -from sqlalchemy.sql import func +from sqlalchemy.sql import func, text from sqlalchemy.sql.expression import Select, select, update import aiohttp import traceback @@ -24,6 +24,7 @@ upper_gear_cost = 1_000_000_000_000 + # TODO: cleanup thse functions class equipment(BaseModel): equip_head_id: int = Field(0, ge=0) @@ -99,6 +100,7 @@ async def get_reports( data = functions.sqlalchemy_result(data) return data.rows2dict() + @router.put("/report", tags=["Report"]) async def update_reports( old_user_id: int, new_user_id: int, token: str, request: Request @@ -125,24 +127,32 @@ async def update_reports( return {"detail": f"{data.rowcount} rows updated to reportingID = {new_user_id}."} + async def insert_report_v2(detections: list[detection]): - url = 'http://public-api-svc.bd-prd.svc:5000/v2/report' + url = "http://public-api-svc.bd-prd.svc:5000/v2/report" try: data = [d.dict() for d in detections] async with aiohttp.ClientSession() as session: async with session.post(url=url, json=data) as response: if not response.ok: response_text = await response.text() - logger.warning(f"Request to {url} failed with status {response.status} and response: {response_text}") + logger.warning( + f"Request to {url} failed with status {response.status} and response: {response_text}" + ) except aiohttp.ClientError as e: # Log client-specific errors with request details - logger.error(f"Client error during request to {url} with payload {data}: {str(e)}") + logger.error( + f"Client error during request to {url} with payload {data}: {str(e)}" + ) logger.debug(f"Traceback: {traceback.format_exc()}") except Exception as e: # Log general exceptions with traceback - logger.error(f"Unexpected error during request to {url} with payload {data}: {str(e)}") + logger.error( + f"Unexpected error during request to {url} with payload {data}: {str(e)}" + ) logger.debug(f"Traceback: {traceback.format_exc()}") + @router.post("/report", status_code=status.HTTP_201_CREATED, tags=["Report"]) async def insert_report( detections: List[detection], @@ -154,7 +164,8 @@ async def insert_report( asyncio.create_task(insert_report_v2(detections)) return {"detail": "ok"} -async def select_report_count_v1(name:str, manual_detect:int): + +async def select_report_count_v1(name: str, manual_detect: int): name = await functions.to_jagex_name(name) voter: Player = aliased(Player, name="voter") @@ -191,17 +202,84 @@ async def select_report_count_v1(name:str, manual_detect:int): data = [{k: v for k, v in zip(keys, d)} for d in data] return data -@router.get("/report/count", tags=["Report"]) -async def get_report_count_v1(name: str): + +async def select_or_insert_migration(name: str): + sql_select = """ + SELECT + migrated + FROM report_migrated mg + JOIN Players pl ON mg.reporting_id = pl.id + WHERE pl.name = :name """ + sql_insert = """ + INSERT report_migrated (reporting_id, migrated) + SELECT id, 0 as migrated FROM Players pl where pl.name = :name + """ + + params = {"name": name} + async with PLAYERDATA_ENGINE.get_session() as session: + session: AsyncSession = session + async with session.begin(): + data = await session.execute(text(sql_select), params=params) + result = data.mappings().first() + if not result: + logger.debug(f"start migration: {name}") + await session.execute(text(sql_insert), params=params) + data = await session.execute(text(sql_select), params=params) + result = data.mappings().first() + return result + + +async def select_report_count_v2(name: str, manual_detect: int): + sql_select = """ + select + count(sr.reporting_id) as count, + subject.confirmed_ban, + subject.possible_ban, + subject.confirmed_player + from report_sighting sr + join Players voter ON sr.reporting_id = voter.id + join Players subject ON sr.reported_id = subject.id + WHERE voter.name = :name and sr.manual_detect = :manual_detect + GROUP BY + subject.confirmed_ban, + subject.possible_ban, + subject.confirmed_player """ - data = await select_report_count_v1(name=name, manual_detect=0) + params = {"name": name, "manual_detect": manual_detect} + + async with PLAYERDATA_ENGINE.get_session() as session: + session: AsyncSession = session + async with session.begin(): + data = await session.execute(text(sql_select), params=params) + result = data.mappings().all() + return result + +@router.get("/report/count", tags=["Report"]) +async def get_report_count_v1(name: str): + """ """ + migrated_record = await select_or_insert_migration(name=name) + is_migrated = migrated_record.get("migrated") + if is_migrated: + logger.debug("v2") + data = await select_report_count_v2(name=name, manual_detect=0) + else: + logger.debug("v1") + data = await select_report_count_v1(name=name, manual_detect=0) return data + @router.get("/report/manual/count", tags=["Report"]) async def get_report_manual_count_v1(name: str): """ Get the calculated player report count """ - data = await select_report_count_v1(name=name, manual_detect=1) - return data \ No newline at end of file + migrated_record = await select_or_insert_migration(name=name) + is_migrated = migrated_record.get("migrated") + if is_migrated: + logger.debug(f"v2 - {name=}") + data = await select_report_count_v2(name=name, manual_detect=1) + else: + logger.debug(f"v1 - {name=}") + data = await select_report_count_v1(name=name, manual_detect=1) + return data