|
@@ -0,0 +1,146 @@
|
|
|
+import { fetchList, fetchStatistic } from '@api/statistics';
|
|
|
+import { StoreType, storage } from 'src/storage';
|
|
|
+
|
|
|
+const NAMESPACE = 'statistics';
|
|
|
+
|
|
|
+function saveData<T>(key: string, data: T) {
|
|
|
+ const namespacedKey = `${NAMESPACE}:${key}`;
|
|
|
+ const jsonData = JSON.stringify(data);
|
|
|
+ storage.set(namespacedKey, jsonData);
|
|
|
+}
|
|
|
+
|
|
|
+function loadData<T>(key: string): T | null {
|
|
|
+ const namespacedKey = `${NAMESPACE}:${key}`;
|
|
|
+ const jsonData = storage.get(namespacedKey, StoreType.STRING) as string;
|
|
|
+
|
|
|
+ return jsonData ? JSON.parse(jsonData) : null;
|
|
|
+}
|
|
|
+
|
|
|
+function structureList(listData: Sublist[]) {
|
|
|
+ const structuredData: StructuredData = {};
|
|
|
+ const baseCategoryName = 'NOMADS STATISTICS';
|
|
|
+ const list = [];
|
|
|
+
|
|
|
+ listData.forEach((category) => {
|
|
|
+ const categoryName = category.name.split('<br/>')[0];
|
|
|
+
|
|
|
+ if (categoryName === baseCategoryName) {
|
|
|
+ if (!structuredData[baseCategoryName]) {
|
|
|
+ structuredData[baseCategoryName] = {
|
|
|
+ name: baseCategoryName,
|
|
|
+ sublists: []
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ const descriptor = category.name.split('<br/>')[1].replace(/<[^>]*>?/gm, '');
|
|
|
+
|
|
|
+ const sublist: Sublist | null =
|
|
|
+ structuredData[baseCategoryName].sublists?.find((el) => el.name === descriptor) || null;
|
|
|
+
|
|
|
+ if (!sublist) {
|
|
|
+ structuredData[baseCategoryName].sublists?.push({
|
|
|
+ name: descriptor,
|
|
|
+ list: category.list.map((item) => ({
|
|
|
+ name: item.name,
|
|
|
+ url1: item.url1,
|
|
|
+ url2: item.url2 || null
|
|
|
+ }))
|
|
|
+ });
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ list.push(category);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ structuredData[baseCategoryName] && list.push(structuredData[baseCategoryName]);
|
|
|
+ saveData('list', list);
|
|
|
+}
|
|
|
+
|
|
|
+export async function fetchAndSaveStatistics(token: string) {
|
|
|
+ const list = await fetchList(token);
|
|
|
+
|
|
|
+ if (list && list.result === 'OK') {
|
|
|
+ structureList(list.data);
|
|
|
+
|
|
|
+ for (const category of list.data) {
|
|
|
+ for (const item of category.list) {
|
|
|
+ const statsData = await fetchStatistic(token, item.url1, item.url2 ?? 'null');
|
|
|
+
|
|
|
+ if (statsData && statsData.result === 'OK') {
|
|
|
+ const statsKey = item.url2
|
|
|
+ ? `stats_${item.url1}_${item.url2}`
|
|
|
+ : `stats_${item.url1}`;
|
|
|
+
|
|
|
+ saveData(statsKey, JSON.stringify(statsData.data));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+export function getStatistic(url1: string, url2?: string | null): Statistic | null {
|
|
|
+ const statsKey = `stats_${url1}${url2 ? `_${url2}` : ''}`;
|
|
|
+ return loadData<Statistic>(statsKey);
|
|
|
+}
|
|
|
+
|
|
|
+export function getList(): List | null {
|
|
|
+ return loadData<List>('list');
|
|
|
+}
|
|
|
+
|
|
|
+interface ListData {
|
|
|
+ name: string;
|
|
|
+ url1: string;
|
|
|
+ url2?: string | null;
|
|
|
+}
|
|
|
+
|
|
|
+interface List {
|
|
|
+ name: string;
|
|
|
+ list?: ListData[];
|
|
|
+ sublists?: Sublist[];
|
|
|
+}
|
|
|
+
|
|
|
+interface Sublist {
|
|
|
+ name: string;
|
|
|
+ list: ListData[];
|
|
|
+}
|
|
|
+
|
|
|
+interface StructuredData {
|
|
|
+ [key: string]: List;
|
|
|
+}
|
|
|
+
|
|
|
+interface Statistic {
|
|
|
+ data: {
|
|
|
+ url1: string;
|
|
|
+ url2: string;
|
|
|
+ type: number;
|
|
|
+ name: string;
|
|
|
+ comment: string;
|
|
|
+ ranking: Type1[] | Type2[] | Type3[];
|
|
|
+ }[];
|
|
|
+}
|
|
|
+
|
|
|
+interface Type1 {
|
|
|
+ region_id: number;
|
|
|
+ cnt: number;
|
|
|
+ region_name: string;
|
|
|
+ country: string;
|
|
|
+ flag: string;
|
|
|
+}
|
|
|
+
|
|
|
+interface Type2 {
|
|
|
+ cnt: number;
|
|
|
+ mega_id: number;
|
|
|
+ mega_name: string;
|
|
|
+ dare_name: string;
|
|
|
+ dare_flag: string;
|
|
|
+ dare_id: number;
|
|
|
+}
|
|
|
+
|
|
|
+interface Type3 {
|
|
|
+ year: number;
|
|
|
+ user: number;
|
|
|
+ cnt: number;
|
|
|
+ first_name: string;
|
|
|
+ last_name: string;
|
|
|
+ flag: string;
|
|
|
+}
|