from collections import defaultdict from datetime import date, timedelta from typing import Dict, List, Union import config import dsp_api import main_db from constants import common as consts from logger import logger class MetricData: def __init__(self, table_type: str): self.table_type = table_type self.db = main_db.db[table_type] self.latest_date = self.get_latest_date() self.previous_date = main_db.get_date_value(self.db.key_name, config.DATE_FROM) def get_latest_date(self) -> date: """Get the latest available date. Returns: The latest date. """ latest_date = ( dsp_api.get_latest_date() if self.table_type == consts.Table.STREAMS else main_db.followers.get_latest_date() ) if latest_date > config.DATE_TO: latest_date = config.DATE_TO return latest_date @staticmethod def __update_result(result: Dict[str, Dict[str, Dict[str, int]]], data: List[dict], field_name: str): """Set streams count to the result dict. Args: result: Result dict. data: Streams data. field_name: Field name. """ for item in data: country_code = item["country_code"] if country_code in consts.COUNTRY_CODE_LIST or country_code == consts.WORLDWIDE: playlist_id = item["playlist_id"].replace(f"{consts.SPOTIFY}_", "") result[playlist_id][item["country_code"]][field_name] = item["streams"] def get_data(self, playlist_id_list, current_date, day_7_date, day_14_date) -> Union[list, dict]: """Get metrics data. Args: playlist_id_list: Playlist ID list. current_date: Current date. day_7_date: Current date - 7 days. day_14_date: Current date - 14 days. Returns: Streams/followers data. """ if self.table_type == consts.Table.STREAMS: result = defaultdict(lambda: defaultdict(lambda: {"current": 0, "previous": 0})) data = dsp_api.get_playlists_streams(playlist_id_list, current_date - timedelta(days=6), current_date) self.__update_result(result, data, "current") data = dsp_api.get_playlists_streams(playlist_id_list, day_7_date - timedelta(days=6), day_7_date) self.__update_result(result, data, "previous") return result else: return self.db.get_data(playlist_id_list, current_date, day_7_date, day_14_date) def __str__(self): return f"{self.db.name}: current {self.previous_date}, latest {self.latest_date}" __metric_data = {} def get_metric_data(table_type: str) -> MetricData: """Get metric data object. Args: table_type: Table type. Returns: Metric data. """ if not __metric_data.get(table_type): data = MetricData(table_type) __metric_data[table_type] = data logger.debug(data) return __metric_data[table_type]