diff --git a/doc.txt b/doc.txt index b9157c4..721e162 100644 --- a/doc.txt +++ b/doc.txt @@ -55,18 +55,18 @@ DB tables 3. news # history of news is tracked by news_id so we don't need a news_history table squad_id int (squadron id) type_of_news text (one of "public_statements", "internal_statements", "recent_activities") - news_id int (id field) - date int (date field) - category text (category field. One of "Squadrons_History_Category_Membership", + news_id int (`id` field) + date int (`date` field) + category text (`category` field. One of "Squadrons_History_Category_Membership", "Squadrons_History_Category_Leaderboards", "Squadrons_History_Category_BookmarkShare", "Squadrons_History_Category_Squadron", "Squadrons_History_Category_PublicStatement") - activity text (activity field) - season text (season field) - bookmark text (bookmark field) - motd text (motd field) - author text (author field) - cmdr_id int (cmdr_id field, for what and what is it??) - user_id int (user_id field) + activity text (`activity` field) + season int (`season` field) + bookmark text (`bookmark` field) + motd text (`motd` field) + author text (`author` field) + cmdr_id int (`cmdr_id` field, for what and what is it, FDEV??) + user_id int (`user_id` field) inserted_timestamp datetime default current_timestamp implementation notes: diff --git a/main.py b/main.py index 6f6122d..cfd9205 100644 --- a/main.py +++ b/main.py @@ -13,13 +13,73 @@ db = sqlite3.connect('squads.sqlite') with open('sql_schema.sql', 'r', encoding='utf-8') as schema_file: db.executescript(''.join(schema_file.readlines())) -ruTag: int = 32 +ruTag = 32 BASE_URL = 'https://api.orerve.net/2.0/website/squadron/' INFO_ENDPOINT = 'info' +NEWS_ENDPOINT = 'news/list' -def update_squad(squad_id: int, db_conn: sqlite3.Connection) -> bool: - r"""Update/insert information about squadron with specified id in our DB +def update_squad_news(squad_id: int, db_conn: sqlite3.Connection) -> bool: + """Update news for squad with specified ID + + :param squad_id: id of squad to insert news + :param db_conn: connection to sqlite DB + :return: True if squad exists, False if not + :rtype: bool + """ + + """ + How it should works? + Request news + if squad doesn't exists + return False + + else + insert all news even if it already exist in DB + return True + """ + news_request: requests.Response = utils.authed_request(BASE_URL + NEWS_ENDPOINT, params={'squadronId': squad_id}) + if news_request.status_code != 200: # must not happen + logger.warning(f'Got not 200 status code on requesting news, content: {news_request.content}') + # we will not break it, let next code break it by itself + + squad_news: dict = news_request.json()['squadron'] + + if 'id' not in squad_news.keys(): # squadron doesn't FDEV + return False + + else: # squadron exists FDEV + del squad_news['id'] + + for type_of_news_key in squad_news: + one_type_of_news: list = squad_news[type_of_news_key] + + news: dict + for news in one_type_of_news: + with db_conn: + db_conn.execute( + sql_requests.insert_news, + ( + squad_id, + type_of_news_key, + news.get('id'), + news.get('date'), + news.get('category'), + news.get('activity'), + news.get('season'), + news.get('bookmark'), + news.get('motd'), + news.get('author'), + news.get('cmdr_id'), + news.get('user_id') + ) + ) + + return True + + +def update_squad_info(squad_id: int, db_conn: sqlite3.Connection) -> bool: + """Update/insert information about squadron with specified id in our DB :param squad_id: id of squad to update/insert :param db_conn: connection to sqlite DB @@ -36,7 +96,7 @@ def update_squad(squad_id: int, db_conn: sqlite3.Connection) -> bool: return True if squad doesn't exists FDEV - if squad in DB and isn't deleted + if squad in DB and isn't deleted in our DB write to squads_states record with all null except ID (it will mean that squad was deleted) return False @@ -90,6 +150,29 @@ def update_squad(squad_id: int, db_conn: sqlite3.Connection) -> bool: ) ) + update_squad_news(squad_id, db_conn) + return True -update_squad(65555, db) -update_squad(65555, db) + elif squad_request.status_code == 404: # squad doesn't exists FDEV + if db_conn.execute( + sql_requests.check_if_squad_exists_in_db, + (squad_id,)).fetchone()[0] > 0: # we have it in DB + + if db_conn.execute(sql_requests.check_if_we_already_deleted_squad_in_db, (squad_id,)).fetchone()[0] == 0: + # we don't have it deleted in DB + with db_conn: + db_conn.execute(sql_requests.properly_delete_squad, (squad_id,)) + + return False # squadron stop their existing or never exists... it doesn't exists anyway + + else: # any other codes (except 418, that one handles in authed_request), never should happen + logger.warning(f'Unknown squad info status_code: {squad_request.status_code}, content: {squad_request.content}') + raise utils.FAPIUnknownStatusCode + + + + + + + +update_squad_info(47999, db) diff --git a/sql_requests.py b/sql_requests.py index 579dcd7..50790ec 100644 --- a/sql_requests.py +++ b/sql_requests.py @@ -37,3 +37,27 @@ insert_squad_states: str = """insert into squads_states ( previous_season_aegis_score) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);""" +insert_news: str = """insert into news ( +squad_id, +type_of_news, +news_id, +date, +category, +activity, +season, +bookmark, +motd, +author, +cmdr_id, +user_id) +values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);""" + +check_if_squad_exists_in_db: str = """select count(*) +from squads_states +where squad_id = ?;""" + +properly_delete_squad: str = """insert into squads_states (squad_id) values (?);""" + +check_if_we_already_deleted_squad_in_db: str = """select count(*) +from squads_states +where squad_id = ? and tag is null""" \ No newline at end of file diff --git a/sql_schema.sql b/sql_schema.sql index 61926da..a0d51f8 100644 --- a/sql_schema.sql +++ b/sql_schema.sql @@ -54,7 +54,7 @@ news_id int, date int, category text, activity text, -season text, +season int, bookmark text, motd text, author text, diff --git a/utils.py b/utils.py index ac3f750..ad57672 100644 --- a/utils.py +++ b/utils.py @@ -4,6 +4,14 @@ from EDMCLogging import get_main_logger logger = get_main_logger() +class FAPIDownForMaintenance(Exception): + pass + + +class FAPIUnknownStatusCode(Exception): + pass + + def authed_request(url: str, method: str = 'get', **kwargs) -> requests.Response: """Makes request to any url with valid bearer token""" bearer: str = _get_bearer() @@ -19,6 +27,10 @@ def authed_request(url: str, method: str = 'get', **kwargs) -> requests.Response logger.debug(f'Request complete, code {fapiRequest.status_code!r}, len {len(fapiRequest.content)}') + if fapiRequest.request == 418: # it does it on maintenance + logger.warning(f'{method.upper()} {fapiRequest.url} returned 418, content dump:\n{fapiRequest.content}') + raise FAPIDownForMaintenance + return fapiRequest