import json from flask import Flask from .databaseController import DatabaseController from .endpoints.query import Query from .endpoints.command import Command from .endpoints.commands import Commands from .endpoints.post import GetPost from .endpoints.posts import GetPosts from .endpoints.new_query import NewQuery from .endpoints.set_action import SetAction from .endpoints.posts_count import GetPostsCount from .endpoints.account_stats import AccountStats class Database: db : DatabaseController = None app : Flask = None def __init__(self, api) -> None: self.app = api.app if "Archive" in self.app.databases: del self.app.databases["Archive"] self.reload_data("/home/pi/python/Katbots/JapariArchive/database.db") self.app.databases["Archive"] = self api.add_resource(Query, "/Archive/Query") api.add_resource(NewQuery, "/Archive/NewQuery") api.add_resource(Command, "/Archive/Command") api.add_resource(Commands, "/Archive/Commands") api.add_resource(GetPost, "/Archive/GetPost/") api.add_resource(GetPosts, "/Archive/GetPosts") api.add_resource(GetPostsCount, "/Archive/GetPosts/Count") api.add_resource(AccountStats, "/Archive/AccountStats") api.add_resource(SetAction, "/Archive/SetAction") def get_accounts(self): query = f''' SELECT x_handle, id FROM accounts ORDER BY x_handle ASC''' return self.db.run_query(query) def get_account_stats(self): query = '''SELECT x_handle, SUM(IIF(x_posts.action_taken = 0, 1, 0)) as undecided, SUM(IIF(x_posts.action_taken = 1, 1, 0)) as approved, SUM(IIF(x_posts.action_taken = 2, 1, 0)) as deleted, SUM(IIF(x_posts.action_taken = 3, 1, 0)) as hidden, SUM(IIF(x_post_details.id is NULL, 1, 0)) as invalid FROM accounts LEFT JOIN x_posts on accounts.id = x_posts.account_id LEFT JOIN x_post_details on x_post_details.id = x_posts.id WHERE accounts.download_mode != 4 GROUP BY account_id ORDER BY x_handle''' return self.db.run_query(query) def get_post(self, id): query = f'''SELECT x_posts.id, cast(x_posts.id as TEXT) as id_str, x_posts.error_id, x_posts.action_taken, x_posts.is_saved, x_post_details.text, x_post_details.files, x_post_details.date, accounts.x_handle, accounts.rating from x_posts LEFT JOIN x_post_details ON x_posts.id = x_post_details.id LEFT JOIN accounts ON x_posts.account_id = accounts.id WHERE x_posts.id = {id} LIMIT 1''' result = self.db.run_query(query) if len(result) == 0: return None else: #return most recent post return result[-1] def build_where_query(self, artist, actions_taken = [0, 1, 2, 3], last_id = -1, include_ratings = ["SFW", "NSFW"]): where_query = "WHERE x_post_details.id NOT NULL AND x_posts.error_id = 0" if last_id != -1: where_query += f" AND x_posts.id < {last_id}" if actions_taken != [0, 1, 2, 3]: where_query += " AND (" + " OR ".join([f"x_posts.action_taken = {action}" for action in actions_taken]) + ")" if include_ratings != ["SFW", "NSFW", "NSFL"]: where_query += " AND (" + " OR ".join([f'accounts.rating = "{rating}"' for rating in include_ratings]) + ")" if artist is not None and artist != "": where_query += f' AND accounts.x_handle = "{artist}"' return where_query def get_posts_count(self, artist, actions_taken = [0, 1, 2, 3], last_id = -1, include_ratings = ["SFW", "NSFW"]): where_query = self.build_where_query(artist, actions_taken, last_id, include_ratings) query = f''' SELECT count(*) as count FROM x_posts LEFT JOIN x_post_details ON x_posts.id = x_post_details.id LEFT JOIN accounts ON x_posts.account_id = accounts.id {where_query}''' result = self.db.run_query(query) return result[0]["count"] def get_posts(self, num_posts, artist, actions_taken = [0, 1, 2, 3], last_id = -1, offset = 0, include_ratings = ["SFW", "NSFW"], order = "DESC"): num_posts = max(1, min(num_posts, 100)) order_by = "RANDOM()" if order == "RAND" else "x_posts.id ASC" if order == "ASC" else "x_posts.id DESC" where_query = self.build_where_query(artist, actions_taken, last_id, include_ratings) query = f''' SELECT x_posts.id, cast(x_posts.id as TEXT) as id_str, x_posts.action_taken, x_posts.is_saved, x_post_details.text, x_post_details.files, x_post_details.date, accounts.x_handle, accounts.rating FROM x_posts LEFT JOIN x_post_details ON x_posts.id = x_post_details.id LEFT JOIN accounts ON x_posts.account_id = accounts.id {where_query} ORDER BY {order_by} LIMIT {num_posts} OFFSET {offset}''' return self.db.run_query(query) def wrap_query_response(self, result, mode = "json"): if result is None: response = self.app.response_class(status=400) else: if mode == "json": response = self.app.response_class( response=json.dumps(result, ensure_ascii=False, indent=1), status=200, mimetype='application/json' ) elif mode == "text": response = self.app.response_class( response=str(result), status=200, mimetype='text/plain' ) response.headers.add("Access-Control-Allow-Origin", "*") return response def reload_data(self, database_path): self.db = DatabaseController(database_path)