podverse-external-services 5.1.1-alpha.3 → 5.1.1-alpha.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,11 +10,15 @@ export declare class PodcastIndexService {
10
10
  secretKey: string;
11
11
  constructor({ authKey, baseUrl, secretKey }: Constructor);
12
12
  podcastIndexAPIRequest: (url: string, config?: any) => Promise<any>;
13
- getRecentlyUpdatedData: () => Promise<any[]>;
14
- getPodcastByGuid: (podcastGuid: string) => Promise<PodcastByGuidResponse | null>;
15
- getValueTagEnabledPodcastIdsRecursively: (accumulatedPodcastIndexIds: number[], startAt?: number) => Promise<number[]>;
16
- getValueTagEnabledPodcastIds: () => Promise<number[]>;
17
- downloadAndExtractCSV: () => Promise<any[]>;
13
+ deadFeedsDownloadAndExtractCSV: () => Promise<any[]>;
14
+ podcastGetByGuid: (podcastGuid: string) => Promise<PodcastByGuidResponse | null>;
15
+ recentGetData: () => Promise<any[]>;
16
+ trendingGetPodcasts: (max?: number, since?: number, lang?: string, cat?: string) => Promise<{
17
+ feeds: any[];
18
+ nextSince?: number;
19
+ }>;
20
+ valueGetByPodcastIds: () => Promise<number[]>;
21
+ valueGetByPodcastIdsRecursively: (accumulatedPodcastIndexIds: number[], startAt?: number) => Promise<number[]>;
18
22
  }
19
23
  export {};
20
24
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/podcast-index/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAG9D,KAAK,WAAW,GAAG;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AASD,qBAAa,mBAAmB;IACtB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;gBAEZ,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,WAAW;IAMzD,sBAAsB,GAAU,KAAK,MAAM,EAAE,SAAS,GAAG,kBAkDxD;IAED,sBAAsB,uBA6BrB;IAED,gBAAgB,GAAU,aAAa,MAAM,KAAG,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAYpF;IAED,uCAAuC,GACrC,4BAA4B,MAAM,EAAE,EAAE,gBAAW,KAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAatE;IAED,4BAA4B,QAAa,OAAO,CAAC,MAAM,EAAE,CAAC,CAMzD;IAED,qBAAqB,QAAa,OAAO,CAAC,GAAG,EAAE,CAAC,CAwC/C;CACF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/podcast-index/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAG9D,KAAK,WAAW,GAAG;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AASD,qBAAa,mBAAmB;IACtB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;gBAEZ,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,WAAW;IAQzD,sBAAsB,GAAU,KAAK,MAAM,EAAE,SAAS,GAAG,kBA0BxD;IAID,8BAA8B,QAAa,OAAO,CAAC,GAAG,EAAE,CAAC,CAwCxD;IAID,gBAAgB,GAAU,aAAa,MAAM,KAAG,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAYpF;IAID,aAAa,uBA6BZ;IAID,mBAAmB,GACjB,MAAK,MAAW,EAChB,QAAQ,MAAM,EACd,OAAO,MAAM,EACb,MAAM,MAAM,KACX,OAAO,CAAC;QAAE,KAAK,EAAE,GAAG,EAAE,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAoB/C;IAID,oBAAoB,QAAa,OAAO,CAAC,MAAM,EAAE,CAAC,CAMjD;IAED,+BAA+B,GAC7B,4BAA4B,MAAM,EAAE,EAAE,gBAAW,KAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAatE;CACF"}
@@ -28,39 +28,17 @@ const config_1 = require("@external-services/config");
28
28
  */
29
29
  class PodcastIndexService {
30
30
  constructor({ authKey, baseUrl, secretKey }) {
31
+ // Request handler
31
32
  this.podcastIndexAPIRequest = (url, config) => __awaiter(this, void 0, void 0, function* () {
32
33
  var _a, _b, _c;
33
34
  const apiHeaderTime = Math.floor(Date.now() / 1000);
34
35
  const hash = (0, sha1_1.default)(this.authKey + this.secretKey + apiHeaderTime).toString(enc_hex_1.default);
35
- podverse_helpers_1.logger.info('[PodcastIndex] Request details', {
36
- url,
37
- apiHeaderTime,
38
- authKey: this.authKey,
39
- baseUrl: this.baseUrl,
40
- secretKeyPresent: !!this.secretKey,
41
- headers: {
42
- 'X-Auth-Key': this.authKey,
43
- 'X-Auth-Date': apiHeaderTime,
44
- Authorization: hash
45
- },
46
- config
47
- });
48
- // Log system time for drift debugging
49
- podverse_helpers_1.logger.info('[PodcastIndex] System time (UTC)', {
50
- iso: new Date().toISOString(),
51
- epoch: Math.floor(Date.now() / 1000)
52
- });
53
36
  try {
54
37
  const response = yield (0, podverse_helpers_1.request)(url, Object.assign({ headers: {
55
38
  'X-Auth-Key': this.authKey,
56
39
  'X-Auth-Date': apiHeaderTime,
57
40
  Authorization: hash
58
41
  } }, config));
59
- podverse_helpers_1.logger.info('[PodcastIndex] Response received', {
60
- status: response === null || response === void 0 ? void 0 : response.status,
61
- statusText: response === null || response === void 0 ? void 0 : response.statusText,
62
- dataKeys: (response === null || response === void 0 ? void 0 : response.data) ? Object.keys(response.data) : undefined
63
- });
64
42
  return response;
65
43
  }
66
44
  catch (error) {
@@ -75,8 +53,55 @@ class PodcastIndexService {
75
53
  throw error;
76
54
  }
77
55
  });
78
- this.getRecentlyUpdatedData = () => __awaiter(this, void 0, void 0, function* () {
79
- podverse_helpers_1.logger.info('getRecentlyUpdatedData beginning...');
56
+ // Dead Feeds
57
+ this.deadFeedsDownloadAndExtractCSV = () => __awaiter(this, void 0, void 0, function* () {
58
+ const url = 'https://public.podcastindex.org/podcastindex_dead_feeds.csv';
59
+ const tmpDir = path_1.default.join(__dirname, 'tmp');
60
+ const filePath = path_1.default.join(tmpDir, 'podcastindex_dead_feeds.csv');
61
+ if (!fs_1.default.existsSync(tmpDir)) {
62
+ fs_1.default.mkdirSync(tmpDir);
63
+ }
64
+ const data = yield this.podcastIndexAPIRequest(url, { responseType: 'stream' });
65
+ const writer = fs_1.default.createWriteStream(filePath);
66
+ data.pipe(writer);
67
+ yield new Promise((resolve, reject) => {
68
+ writer.on('finish', () => resolve());
69
+ writer.on('error', reject);
70
+ });
71
+ const results = [];
72
+ yield new Promise((resolve, reject) => {
73
+ fs_1.default.createReadStream(filePath)
74
+ .pipe((0, csv_parser_1.default)())
75
+ .on('data', (data) => results.push(data))
76
+ .on('end', resolve)
77
+ .on('error', reject);
78
+ });
79
+ fs_1.default.unlinkSync(filePath);
80
+ const parsedResults = results.map((row) => {
81
+ const [id, duplicateOf] = Object.values(row).map((value) => value.trim());
82
+ return {
83
+ podcast_index_id: parseInt(id, 10),
84
+ duplicateOf: duplicateOf ? parseInt(duplicateOf, 10) : null
85
+ };
86
+ });
87
+ return parsedResults;
88
+ });
89
+ // Podcast
90
+ this.podcastGetByGuid = (podcastGuid) => __awaiter(this, void 0, void 0, function* () {
91
+ const url = `${this.baseUrl}/podcasts/byguid?guid=${podcastGuid}`;
92
+ let podcastIndexPodcast = null;
93
+ try {
94
+ const data = yield this.podcastIndexAPIRequest(url);
95
+ podcastIndexPodcast = data;
96
+ }
97
+ catch (error) {
98
+ // assume a 404
99
+ }
100
+ return podcastIndexPodcast || null;
101
+ });
102
+ // Recent
103
+ this.recentGetData = () => __awaiter(this, void 0, void 0, function* () {
104
+ podverse_helpers_1.logger.info('recentGetData beginning...');
80
105
  const currentTimeInSeconds = Math.floor(Date.now() / 1000);
81
106
  const sinceRange = config_1.config.podcastIndex.recentlyUpdatedDataInterval;
82
107
  const sinceTimeInSeconds = currentTimeInSeconds - sinceRange;
@@ -100,67 +125,45 @@ class PodcastIndexService {
100
125
  });
101
126
  return fetchData(sinceTimeInSeconds);
102
127
  });
103
- this.getPodcastByGuid = (podcastGuid) => __awaiter(this, void 0, void 0, function* () {
104
- const url = `${this.baseUrl}/podcasts/byguid?guid=${podcastGuid}`;
105
- let podcastIndexPodcast = null;
106
- try {
107
- const data = yield this.podcastIndexAPIRequest(url);
108
- podcastIndexPodcast = data;
128
+ // Trending
129
+ this.trendingGetPodcasts = (...args_1) => __awaiter(this, [...args_1], void 0, function* (max = 25, since, lang, cat) {
130
+ const safeMax = Math.min(max, 1000);
131
+ let url = `${this.baseUrl}/podcasts/trending?max=${safeMax}`;
132
+ if (since) {
133
+ url += `&since=${since}`;
109
134
  }
110
- catch (error) {
111
- // assume a 404
135
+ if (lang) {
136
+ url += `&lang=${encodeURIComponent(lang)}`;
112
137
  }
113
- return podcastIndexPodcast || null;
138
+ if (cat) {
139
+ url += `&cat=${encodeURIComponent(cat)}`;
140
+ }
141
+ podverse_helpers_1.logger.info(`[PodcastIndex] Fetching trending feeds (max: ${safeMax}, since: ${since}, lang: ${lang}, cat: ${cat})`);
142
+ const response = yield this.podcastIndexAPIRequest(url);
143
+ console.log('Trending response:', response);
144
+ return {
145
+ feeds: response.feeds || [],
146
+ nextSince: response.nextSince
147
+ };
148
+ });
149
+ // Value
150
+ this.valueGetByPodcastIds = () => __awaiter(this, void 0, void 0, function* () {
151
+ const accumulatedPodcastIndexIds = [];
152
+ const nextStartAt = 1;
153
+ const podcastIndexIds = yield this.valueGetByPodcastIdsRecursively(accumulatedPodcastIndexIds, nextStartAt);
154
+ return podcastIndexIds;
114
155
  });
115
- this.getValueTagEnabledPodcastIdsRecursively = (accumulatedPodcastIndexIds_1, ...args_1) => __awaiter(this, [accumulatedPodcastIndexIds_1, ...args_1], void 0, function* (accumulatedPodcastIndexIds, startAt = 1) {
156
+ this.valueGetByPodcastIdsRecursively = (accumulatedPodcastIndexIds_1, ...args_1) => __awaiter(this, [accumulatedPodcastIndexIds_1, ...args_1], void 0, function* (accumulatedPodcastIndexIds, startAt = 1) {
116
157
  const url = `${this.baseUrl}/podcasts/bytag?podcast-valueTimeSplit=true&max=5000&start_at=${startAt}`;
117
158
  const data = yield this.podcastIndexAPIRequest(url);
118
159
  for (const feed of data.feeds) {
119
160
  accumulatedPodcastIndexIds.push(feed.id);
120
161
  }
121
162
  if (data.nextStartAt) {
122
- return yield this.getValueTagEnabledPodcastIdsRecursively(accumulatedPodcastIndexIds, data.nextStartAt);
163
+ return yield this.valueGetByPodcastIdsRecursively(accumulatedPodcastIndexIds, data.nextStartAt);
123
164
  }
124
165
  return accumulatedPodcastIndexIds;
125
166
  });
126
- this.getValueTagEnabledPodcastIds = () => __awaiter(this, void 0, void 0, function* () {
127
- const accumulatedPodcastIndexIds = [];
128
- const nextStartAt = 1;
129
- const podcastIndexIds = yield this.getValueTagEnabledPodcastIdsRecursively(accumulatedPodcastIndexIds, nextStartAt);
130
- return podcastIndexIds;
131
- });
132
- this.downloadAndExtractCSV = () => __awaiter(this, void 0, void 0, function* () {
133
- const url = 'https://public.podcastindex.org/podcastindex_dead_feeds.csv';
134
- const tmpDir = path_1.default.join(__dirname, 'tmp');
135
- const filePath = path_1.default.join(tmpDir, 'podcastindex_dead_feeds.csv');
136
- if (!fs_1.default.existsSync(tmpDir)) {
137
- fs_1.default.mkdirSync(tmpDir);
138
- }
139
- const data = yield this.podcastIndexAPIRequest(url, { responseType: 'stream' });
140
- const writer = fs_1.default.createWriteStream(filePath);
141
- data.pipe(writer);
142
- yield new Promise((resolve, reject) => {
143
- writer.on('finish', () => resolve());
144
- writer.on('error', reject);
145
- });
146
- const results = [];
147
- yield new Promise((resolve, reject) => {
148
- fs_1.default.createReadStream(filePath)
149
- .pipe((0, csv_parser_1.default)())
150
- .on('data', (data) => results.push(data))
151
- .on('end', resolve)
152
- .on('error', reject);
153
- });
154
- fs_1.default.unlinkSync(filePath);
155
- const parsedResults = results.map((row) => {
156
- const [id, duplicateOf] = Object.values(row).map((value) => value.trim());
157
- return {
158
- podcast_index_id: parseInt(id, 10),
159
- duplicateOf: duplicateOf ? parseInt(duplicateOf, 10) : null
160
- };
161
- });
162
- return parsedResults;
163
- });
164
167
  this.authKey = authKey;
165
168
  this.baseUrl = baseUrl;
166
169
  this.secretKey = secretKey;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "podverse-external-services",
3
- "version": "5.1.1-alpha.3",
3
+ "version": "5.1.1-alpha.5",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -34,7 +34,7 @@
34
34
  "module-alias": "^2.2.3",
35
35
  "paypal-rest-sdk": "2.0.0-rc.2",
36
36
  "podcast-partytime": "^4.8.3",
37
- "podverse-helpers": "^5.1.2-alpha.3",
37
+ "podverse-helpers": "^5.1.2-alpha.4",
38
38
  "web-push": "^3.6.3"
39
39
  }
40
40
  }