index.ts 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. import { fetchList, fetchStatistic } from '@api/statistics';
  2. import { StoreType, storage } from 'src/storage';
  3. const NAMESPACE = 'statistics';
  4. function saveData<T>(key: string, data: T) {
  5. const namespacedKey = `${NAMESPACE}:${key}`;
  6. const jsonData = JSON.stringify(data);
  7. storage.set(namespacedKey, jsonData);
  8. }
  9. function loadData<T>(key: string): T | null {
  10. const namespacedKey = `${NAMESPACE}:${key}`;
  11. const jsonData = storage.get(namespacedKey, StoreType.STRING) as string;
  12. return jsonData ? JSON.parse(jsonData) : null;
  13. }
  14. function structureList(listData: Sublist[]) {
  15. const structuredData: StructuredData = {};
  16. const baseCategoryName = 'NOMADS STATISTICS';
  17. const list = [];
  18. listData.forEach((category) => {
  19. const categoryName = category.name.split('<br/>')[0];
  20. if (categoryName === baseCategoryName) {
  21. if (!structuredData[baseCategoryName]) {
  22. structuredData[baseCategoryName] = {
  23. name: baseCategoryName,
  24. sublists: []
  25. };
  26. }
  27. const descriptor = category.name.split('<br/>')[1].replace(/<[^>]*>?/gm, '');
  28. const sublist: Sublist | null =
  29. structuredData[baseCategoryName].sublists?.find((el) => el.name === descriptor) || null;
  30. if (!sublist) {
  31. structuredData[baseCategoryName].sublists?.push({
  32. name: descriptor,
  33. list: category.list.map((item) => ({
  34. name: item.name,
  35. url1: item.url1,
  36. url2: item.url2 || null
  37. }))
  38. });
  39. }
  40. } else {
  41. list.push(category);
  42. }
  43. });
  44. structuredData[baseCategoryName] && list.push(structuredData[baseCategoryName]);
  45. saveData('list', list);
  46. }
  47. export async function fetchAndSaveStatistics(token: string) {
  48. const list = await fetchList(token);
  49. if (list && list.result === 'OK') {
  50. structureList(list.data);
  51. for (const category of list.data) {
  52. for (const item of category.list) {
  53. const statsData = await fetchStatistic(token, item.url1, item.url2 ?? 'null');
  54. if (statsData && statsData.result === 'OK') {
  55. const statsKey = item.url2
  56. ? `stats_${item.url1}_${item.url2}`
  57. : `stats_${item.url1}`;
  58. saveData(statsKey, JSON.stringify(statsData.data));
  59. }
  60. }
  61. }
  62. }
  63. }
  64. export function getStatistic(url1: string, url2?: string | null): Statistic | null {
  65. const statsKey = `stats_${url1}${url2 ? `_${url2}` : ''}`;
  66. return loadData<Statistic>(statsKey);
  67. }
  68. export function getList(): List | null {
  69. return loadData<List>('list');
  70. }
  71. interface ListData {
  72. name: string;
  73. url1: string;
  74. url2?: string | null;
  75. }
  76. interface List {
  77. name: string;
  78. list?: ListData[];
  79. sublists?: Sublist[];
  80. }
  81. interface Sublist {
  82. name: string;
  83. list: ListData[];
  84. }
  85. interface StructuredData {
  86. [key: string]: List;
  87. }
  88. interface Statistic {
  89. data: {
  90. url1: string;
  91. url2: string;
  92. type: number;
  93. name: string;
  94. comment: string;
  95. ranking: Type1[] | Type2[] | Type3[];
  96. }[];
  97. }
  98. interface Type1 {
  99. region_id: number;
  100. cnt: number;
  101. region_name: string;
  102. country: string;
  103. flag: string;
  104. }
  105. interface Type2 {
  106. cnt: number;
  107. mega_id: number;
  108. mega_name: string;
  109. dare_name: string;
  110. dare_flag: string;
  111. dare_id: number;
  112. }
  113. interface Type3 {
  114. year: number;
  115. user: number;
  116. cnt: number;
  117. first_name: string;
  118. last_name: string;
  119. flag: string;
  120. }