import json import redis from datetime import datetime from typing import Any, Tuple from apollo_main_db.apollo.models import ApolloGoVersion from smelog.factory import BoundLogger from retrieve_and_save_mobile_versions.config import Config from retrieve_and_save_mobile_versions.constants import ANDROID, IOS from retrieve_and_save_mobile_versions.main_db import get_latest_version_query, session_scope from retrieve_and_save_mobile_versions.utils import is_newer_version, send_request, validate_version, \ clean_cached_os_version, get_android_version def retrieve_play_store_version(logger: BoundLogger, url: str) -> str: logger.info(f"Retrieving Play Market ApolloGo version.") response = send_request(url=url, logger=logger) version = get_android_version(response.text) if version and validate_version(version, logger): logger.info(f"Scrapped Play Market version: {version}") return version logger.warning(f"No version found for os={ANDROID}") def retrieve_app_store_version(logger: BoundLogger, url: str) -> str: logger.info(f"Retrieving App Store ApolloGo version.") response = send_request(url=url, logger=logger) version = None try: data = json.loads(response.text) except json.JSONDecoder: logger.warning(f"Version scrapping error - JSON decoding. os = {IOS}") data = {} results = data.get("results", []) if results and len(results): version = results[0].get("version") if version and validate_version(version, logger): logger.info(f"Scrapped App Store version: {version}") if not version: logger.warning(f"No version found for os={IOS}") return version def get_latest_stored_versions(logger: BoundLogger) -> Tuple: latest_store_android = get_latest_version_query(ANDROID) latest_store_ios = get_latest_version_query(IOS) logger.info(f"Stored in DB versions: \n - {latest_store_ios}, \n - {latest_store_android}") return latest_store_android, latest_store_ios def compare_and_update_saved_versions( logger: BoundLogger, session: object, parsed_version: str, stored_version_obj: ApolloGoVersion, redis_client: redis.Redis or None, config: Config, os: str): if not parsed_version: logger.info(f"Parsed data for {os} app is missing.") return if not stored_version_obj or is_newer_version(stored_version_obj.version, parsed_version): clean_cached_os_version(os=os, config=config, redis_client=redis_client, logger=logger) session.add(ApolloGoVersion(os=os, version=parsed_version, created_at=datetime.now())) session.commit() logger.info(f"New {os} app version '{parsed_version}' was saved to DB.") return logger.info(f"Saved in DB {os} app version is up-to-date!") def handler(logger: BoundLogger, config: Config, redis_client: redis.Redis or None) -> Any: stored_android, stored_ios = get_latest_stored_versions(logger) parsed_ios_version = retrieve_app_store_version(logger, config.APP_STORE_URL) parsed_android_version = retrieve_play_store_version(logger, config.PLAY_MARKET_URL) with session_scope() as session: if parsed_ios_version: compare_and_update_saved_versions( logger, session, parsed_ios_version, stored_ios, redis_client, config, IOS ) if parsed_android_version: compare_and_update_saved_versions( logger, session, parsed_android_version, stored_android, redis_client, config, ANDROID ) return {}