podverse-parser 5.0.0-beta.2 → 5.0.0-beta.3
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.
- package/package.json +4 -1
- package/.nvmrc +0 -1
- package/eslint.config.mjs +0 -38
- package/src/index.ts +0 -3
- package/src/lib/chapters/chapters.ts +0 -54
- package/src/lib/compat/channel.ts +0 -287
- package/src/lib/compat/chapters/chapters.ts +0 -23
- package/src/lib/compat/partytime/channel.ts +0 -289
- package/src/lib/compat/partytime/compatFull.ts +0 -7
- package/src/lib/compat/partytime/funding.ts +0 -8
- package/src/lib/compat/partytime/item.ts +0 -273
- package/src/lib/compat/partytime/liveItem.ts +0 -18
- package/src/lib/compat/partytime/value.ts +0 -64
- package/src/lib/rss/base/handleParsedManyData.ts +0 -16
- package/src/lib/rss/base/handleParsedOneData.ts +0 -17
- package/src/lib/rss/channel/channel.ts +0 -55
- package/src/lib/rss/channel/channelAbout.ts +0 -13
- package/src/lib/rss/channel/channelChat.ts +0 -14
- package/src/lib/rss/channel/channelDescription.ts +0 -14
- package/src/lib/rss/channel/channelFunding.ts +0 -14
- package/src/lib/rss/channel/channelImage.ts +0 -14
- package/src/lib/rss/channel/channelLicense.ts +0 -14
- package/src/lib/rss/channel/channelLocation.ts +0 -14
- package/src/lib/rss/channel/channelPerson.ts +0 -14
- package/src/lib/rss/channel/channelPodroll.ts +0 -21
- package/src/lib/rss/channel/channelRemoteItem.ts +0 -14
- package/src/lib/rss/channel/channelSeason.ts +0 -14
- package/src/lib/rss/channel/channelSocialInteract.ts +0 -14
- package/src/lib/rss/channel/channelTrailer.ts +0 -31
- package/src/lib/rss/channel/channelTxt.ts +0 -14
- package/src/lib/rss/channel/channelValue.ts +0 -30
- package/src/lib/rss/feed/feed.ts +0 -79
- package/src/lib/rss/hash/parsedFeed.ts +0 -9
- package/src/lib/rss/item/item.ts +0 -85
- package/src/lib/rss/item/itemAbout.ts +0 -13
- package/src/lib/rss/item/itemChaptersFeed.ts +0 -14
- package/src/lib/rss/item/itemChat.ts +0 -14
- package/src/lib/rss/item/itemContentLink.ts +0 -0
- package/src/lib/rss/item/itemDescription.ts +0 -14
- package/src/lib/rss/item/itemEnclosure.ts +0 -35
- package/src/lib/rss/item/itemImage.ts +0 -14
- package/src/lib/rss/item/itemLicense.ts +0 -14
- package/src/lib/rss/item/itemLocation.ts +0 -14
- package/src/lib/rss/item/itemPerson.ts +0 -14
- package/src/lib/rss/item/itemSeason.ts +0 -26
- package/src/lib/rss/item/itemSeasonEpisode.ts +0 -14
- package/src/lib/rss/item/itemSocialInteract.ts +0 -14
- package/src/lib/rss/item/itemSoundbite.ts +0 -14
- package/src/lib/rss/item/itemTranscript.ts +0 -14
- package/src/lib/rss/item/itemTxt.ts +0 -14
- package/src/lib/rss/item/itemValue.ts +0 -60
- package/src/lib/rss/liveItem/liveItem.ts +0 -34
- package/src/lib/rss/parser.ts +0 -85
- package/src/module-alias-config.ts +0 -8
- package/tsconfig.json +0 -25
package/package.json
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "podverse-parser",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.3",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist/**/*"
|
|
9
|
+
],
|
|
7
10
|
"scripts": {
|
|
8
11
|
"dev:watch": "nodemon --watch 'src' --watch $(realpath node_modules/podverse-external-services) --watch $(realpath node_modules/podverse-orm) --watch $(realpath node_modules/podverse-shared) -x \"npm run build\"",
|
|
9
12
|
"build": "tsc",
|
package/.nvmrc
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
v20.16.0
|
package/eslint.config.mjs
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import globals from "globals";
|
|
2
|
-
import pluginJs from "@eslint/js";
|
|
3
|
-
import tseslint from "@typescript-eslint/eslint-plugin";
|
|
4
|
-
import tsParser from "@typescript-eslint/parser";
|
|
5
|
-
|
|
6
|
-
const pluginJsRecommended = {
|
|
7
|
-
rules: {
|
|
8
|
-
...pluginJs.configs.recommended.rules,
|
|
9
|
-
},
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
const tseslintRecommended = {
|
|
13
|
-
rules: {
|
|
14
|
-
...tseslint.configs.recommended.rules,
|
|
15
|
-
},
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export default [
|
|
19
|
-
{
|
|
20
|
-
files: ["src/**/*.{js,ts}"],
|
|
21
|
-
languageOptions: {
|
|
22
|
-
globals: globals.node,
|
|
23
|
-
parser: tsParser,
|
|
24
|
-
},
|
|
25
|
-
plugins: {
|
|
26
|
-
"@typescript-eslint": tseslint,
|
|
27
|
-
},
|
|
28
|
-
rules: {
|
|
29
|
-
...pluginJsRecommended.rules,
|
|
30
|
-
...tseslintRecommended.rules,
|
|
31
|
-
"semi": ["error", "always"],
|
|
32
|
-
"indent": ["error", 2],
|
|
33
|
-
"@typescript-eslint/no-require-imports": "off",
|
|
34
|
-
},
|
|
35
|
-
ignores: ["**/eslint.config.mjs"],
|
|
36
|
-
}
|
|
37
|
-
];
|
|
38
|
-
|
package/src/index.ts
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { request, throwRequestError } from "podverse-helpers";
|
|
2
|
-
import { Item, ItemChaptersFeed, ItemChapterService, ItemChaptersFeedLogService } from "podverse-orm";
|
|
3
|
-
import { compatParsedChapters, PIChapter } from "@parser/lib/compat/chapters/chapters";
|
|
4
|
-
|
|
5
|
-
const getParsedChapters = async (item_chapters_feed: ItemChaptersFeed) => {
|
|
6
|
-
const itemChaptersFeedLogService = new ItemChaptersFeedLogService();
|
|
7
|
-
try {
|
|
8
|
-
const response: { chapters: PIChapter[] } = await request(item_chapters_feed.url);
|
|
9
|
-
await itemChaptersFeedLogService.update(item_chapters_feed, {
|
|
10
|
-
last_http_status: 200,
|
|
11
|
-
last_good_http_status_time: new Date()
|
|
12
|
-
});
|
|
13
|
-
return compatParsedChapters(response.chapters);
|
|
14
|
-
} catch (error) {
|
|
15
|
-
// TODO: how to handle errors?
|
|
16
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
17
|
-
const statusCode = (error as any).statusCode as number;
|
|
18
|
-
const item_chapters_feed_log = await itemChaptersFeedLogService.get(item_chapters_feed);
|
|
19
|
-
if (statusCode) {
|
|
20
|
-
await itemChaptersFeedLogService.update(item_chapters_feed, {
|
|
21
|
-
last_http_status: statusCode,
|
|
22
|
-
parse_errors: (item_chapters_feed_log?.parse_errors || 0) + 1,
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
return throwRequestError(error);
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export const parseChapters = async (item: Item): Promise<void> => {
|
|
30
|
-
const item_chapters_feed = item.item_chapters_feed;
|
|
31
|
-
|
|
32
|
-
if (!item_chapters_feed) {
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const parsedChapters = await getParsedChapters(item_chapters_feed);
|
|
37
|
-
|
|
38
|
-
const itemChapterService = new ItemChapterService();
|
|
39
|
-
|
|
40
|
-
const existingChapters = await itemChapterService.getAll(item_chapters_feed, { select: ['id'] });
|
|
41
|
-
const existingChaptersIds = existingChapters.map(item_chapter => item_chapter.id);
|
|
42
|
-
const updatedChaptersIds: number[] = [];
|
|
43
|
-
|
|
44
|
-
for (const parsedChapter of parsedChapters) {
|
|
45
|
-
await itemChapterService.update(item_chapters_feed, parsedChapter);
|
|
46
|
-
updatedChaptersIds.push(item_chapters_feed.id);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const itemChapterIdsToDelete = existingChaptersIds.filter(id => !updatedChaptersIds.includes(id));
|
|
50
|
-
await itemChapterService.deleteMany(itemChapterIdsToDelete);
|
|
51
|
-
|
|
52
|
-
const itemChaptersFeedLogService = new ItemChaptersFeedLogService();
|
|
53
|
-
await itemChaptersFeedLogService.update(item_chapters_feed, { last_finished_parse_time: new Date() });
|
|
54
|
-
};
|
|
@@ -1,287 +0,0 @@
|
|
|
1
|
-
import { FeedObject, Phase4Medium } from "podcast-partytime";
|
|
2
|
-
import { Phase4PodcastImage } from "podcast-partytime/dist/parser/phase/phase-4";
|
|
3
|
-
import { createSortableTitle, getBooleanOrNull } from "podverse-helpers";
|
|
4
|
-
import { getChannelItunesTypeItunesTypeEnumValue, getMediumEnumValue } from "podverse-orm";
|
|
5
|
-
import { compatChannelValue } from "@parser/lib/compat/partytime/value";
|
|
6
|
-
|
|
7
|
-
export const compatChannelDto = (parsedFeed: FeedObject) => ({
|
|
8
|
-
podcast_guid: parsedFeed.guid,
|
|
9
|
-
title: parsedFeed.title,
|
|
10
|
-
sortable_title: createSortableTitle(parsedFeed.title),
|
|
11
|
-
medium: getMediumEnumValue(parsedFeed.medium ?? Phase4Medium.Podcast)
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
export const compatChannelAboutDto = (parsedFeed: FeedObject) => ({
|
|
15
|
-
author: (Array.isArray(parsedFeed.author) ? parsedFeed.author : parsedFeed.author ? [parsedFeed.author] : [])?.join(', ') || null,
|
|
16
|
-
explicit: getBooleanOrNull(parsedFeed.explicit),
|
|
17
|
-
language: parsedFeed.language || null,
|
|
18
|
-
website_link_url: parsedFeed.link || null,
|
|
19
|
-
itunes_type: getChannelItunesTypeItunesTypeEnumValue(parsedFeed.itunesType || 'episodic')
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
export const compatChannelChatDto = (parsedFeed: FeedObject) => {
|
|
23
|
-
if (!parsedFeed.chat) {
|
|
24
|
-
return null;
|
|
25
|
-
}
|
|
26
|
-
return {
|
|
27
|
-
server: parsedFeed.chat.server,
|
|
28
|
-
protocol: parsedFeed.chat.protocol,
|
|
29
|
-
account_id: parsedFeed.chat.accountId || null,
|
|
30
|
-
space: parsedFeed.chat.space || null
|
|
31
|
-
};
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
export const compatChannelDescriptionDto = (parsedFeed: FeedObject) => {
|
|
35
|
-
if (!parsedFeed.description) {
|
|
36
|
-
return null;
|
|
37
|
-
}
|
|
38
|
-
return {
|
|
39
|
-
value: parsedFeed.description
|
|
40
|
-
};
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
export const compatChannelFundingDtos = (parsedFeed: FeedObject) => {
|
|
44
|
-
const dtos = [];
|
|
45
|
-
|
|
46
|
-
if (Array.isArray(parsedFeed.podcastFunding)) {
|
|
47
|
-
for (const f of parsedFeed.podcastFunding) {
|
|
48
|
-
if (f.url) {
|
|
49
|
-
dtos.push({
|
|
50
|
-
url: f.url,
|
|
51
|
-
title: f.message || null
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return dtos;
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
export const compatChannelImageDtos = (parsedFeed: FeedObject) => {
|
|
61
|
-
const dtos = [];
|
|
62
|
-
if (parsedFeed.itunesImage) {
|
|
63
|
-
dtos.push({
|
|
64
|
-
url: parsedFeed.itunesImage,
|
|
65
|
-
image_width_size: null
|
|
66
|
-
});
|
|
67
|
-
} else if (parsedFeed.image?.url) {
|
|
68
|
-
dtos.push({
|
|
69
|
-
url: parsedFeed.image.url,
|
|
70
|
-
image_width_size: null
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function hasWidth(image: Phase4PodcastImage['parsed']): image is { url: string; width: number } {
|
|
75
|
-
return (image as { width: number }).width !== undefined;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
if (Array.isArray(parsedFeed.podcastImages)) {
|
|
79
|
-
for (const image of parsedFeed.podcastImages) {
|
|
80
|
-
if (image.parsed.url && hasWidth(image.parsed)) {
|
|
81
|
-
dtos.push({
|
|
82
|
-
url: image.parsed.url,
|
|
83
|
-
image_width_size: image.parsed.width
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
return dtos;
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
export const compatChannelLicenseDto = (parsedFeed: FeedObject) => {
|
|
93
|
-
if (!parsedFeed?.license?.identifier) {
|
|
94
|
-
return null;
|
|
95
|
-
}
|
|
96
|
-
return {
|
|
97
|
-
identifier: parsedFeed.license.identifier,
|
|
98
|
-
url: parsedFeed.license.url || null
|
|
99
|
-
};
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
export const compatChannelLocationDto = (parsedFeed: FeedObject) => {
|
|
103
|
-
if (!parsedFeed?.podcastLocation?.geo && !parsedFeed?.podcastLocation?.osm) {
|
|
104
|
-
return null;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
return {
|
|
108
|
-
geo: parsedFeed.podcastLocation.geo || null,
|
|
109
|
-
osm: parsedFeed.podcastLocation.osm || null,
|
|
110
|
-
name: parsedFeed.podcastLocation.name || null
|
|
111
|
-
};
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
export const compatChannelPersonDtos = (parsedFeed: FeedObject) => {
|
|
115
|
-
const dtos = [];
|
|
116
|
-
|
|
117
|
-
if (Array.isArray(parsedFeed.podcastPeople)) {
|
|
118
|
-
for (const p of parsedFeed.podcastPeople) {
|
|
119
|
-
if (p.name) {
|
|
120
|
-
dtos.push({
|
|
121
|
-
name: p.name,
|
|
122
|
-
role: p.role?.toLowerCase() || null,
|
|
123
|
-
person_group: p.group?.toLowerCase() || 'cast',
|
|
124
|
-
img: p.img || null,
|
|
125
|
-
href: p.href || null
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
return dtos;
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
export const compatChannelPodrollRemoteItemDtos = (parsedFeed: FeedObject) => {
|
|
135
|
-
const dtos = [];
|
|
136
|
-
|
|
137
|
-
if (Array.isArray(parsedFeed.podroll)) {
|
|
138
|
-
for (const ri of parsedFeed.podroll) {
|
|
139
|
-
if (ri.feedGuid) {
|
|
140
|
-
dtos.push({
|
|
141
|
-
feed_guid: ri.feedGuid,
|
|
142
|
-
feed_url: ri.feedUrl || null,
|
|
143
|
-
item_guid: null,
|
|
144
|
-
title: /* PTDO: ri.title || */ null
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
return dtos;
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
export const compatChannelPublisherRemoteItemDtos = (parsedFeed: FeedObject) => {
|
|
154
|
-
const dtos = [];
|
|
155
|
-
|
|
156
|
-
if (Array.isArray(parsedFeed.podroll)) {
|
|
157
|
-
for (const ri of parsedFeed.podroll) {
|
|
158
|
-
if (ri.feedGuid) {
|
|
159
|
-
dtos.push({
|
|
160
|
-
feed_guid: ri.feedGuid,
|
|
161
|
-
feed_url: ri.feedUrl || null,
|
|
162
|
-
item_guid: null,
|
|
163
|
-
title: /* PTDO: ri.title || */ null
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
return dtos;
|
|
170
|
-
};
|
|
171
|
-
|
|
172
|
-
export const compatChannelRemoteItemDtos = (parsedFeed: FeedObject) => {
|
|
173
|
-
const dtos = [];
|
|
174
|
-
|
|
175
|
-
if (Array.isArray(parsedFeed.podcastRemoteItems)) {
|
|
176
|
-
for (const ri of parsedFeed.podcastRemoteItems) {
|
|
177
|
-
if (ri.feedGuid) {
|
|
178
|
-
dtos.push({
|
|
179
|
-
feed_guid: ri.feedGuid,
|
|
180
|
-
feed_url: ri.feedUrl || null,
|
|
181
|
-
item_guid: null,
|
|
182
|
-
title: /* PTDO: ri.title || */ null
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
return dtos;
|
|
189
|
-
};
|
|
190
|
-
|
|
191
|
-
export const compatChannelSocialInteractDtos = (parsedFeed: FeedObject) => {
|
|
192
|
-
const dtos = [];
|
|
193
|
-
|
|
194
|
-
if (parsedFeed?.podcastSocial?.length) {
|
|
195
|
-
for (const ps of parsedFeed.podcastSocial) {
|
|
196
|
-
dtos.push({
|
|
197
|
-
// PTDO: fix keys mismatch between partytime and podverse
|
|
198
|
-
protocol: ps.platform,
|
|
199
|
-
uri: ps.url,
|
|
200
|
-
account_id: ps.id || null,
|
|
201
|
-
account_url: ps.name || null,
|
|
202
|
-
priority: ps.priority || null
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
return dtos;
|
|
208
|
-
};
|
|
209
|
-
|
|
210
|
-
export const compatChannelSeasonDtos = (parsedFeed: FeedObject) => {
|
|
211
|
-
const dtos = [];
|
|
212
|
-
|
|
213
|
-
const parsedItems = parsedFeed?.items || [];
|
|
214
|
-
|
|
215
|
-
const seasonsIndex: { [key: number]: { name: string | null } } = {};
|
|
216
|
-
|
|
217
|
-
for (const parsedItem of parsedItems) {
|
|
218
|
-
const seasonNumber = parsedItem?.podcastSeason?.number || parsedItem?.itunesSeason;
|
|
219
|
-
const seasonName = parsedItem?.podcastSeason?.name || null;
|
|
220
|
-
if (Number.isInteger(seasonNumber)) {
|
|
221
|
-
const seasonNumberAsNumber = seasonNumber as number;
|
|
222
|
-
seasonsIndex[seasonNumberAsNumber] = {
|
|
223
|
-
name: seasonName
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
for (const [number, { name }] of Object.entries(seasonsIndex)) {
|
|
229
|
-
dtos.push({
|
|
230
|
-
number: parseInt(number),
|
|
231
|
-
name: name || null
|
|
232
|
-
});
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
return dtos;
|
|
236
|
-
};
|
|
237
|
-
|
|
238
|
-
export const compatChannelTrailerDtos = (parsedFeed: FeedObject) => {
|
|
239
|
-
const dtos = [];
|
|
240
|
-
if (parsedFeed?.trailers?.length) {
|
|
241
|
-
for (const pt of parsedFeed.trailers) {
|
|
242
|
-
dtos.push({
|
|
243
|
-
url: pt.url,
|
|
244
|
-
title: /* PTDO: add pt.title || */ null,
|
|
245
|
-
pubdate: pt.pubdate,
|
|
246
|
-
length: pt.length || null,
|
|
247
|
-
type: pt.type || null,
|
|
248
|
-
season: pt.season || null
|
|
249
|
-
});
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
return dtos;
|
|
254
|
-
};
|
|
255
|
-
|
|
256
|
-
export const compatChannelTxtDtos = (parsedFeed: FeedObject) => {
|
|
257
|
-
const dtos = [];
|
|
258
|
-
if (parsedFeed?.podcastTxt?.length) {
|
|
259
|
-
for (const pt of parsedFeed.podcastTxt) {
|
|
260
|
-
dtos.push({
|
|
261
|
-
purpose: pt.purpose || null,
|
|
262
|
-
value: pt.value
|
|
263
|
-
});
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
return dtos;
|
|
268
|
-
};
|
|
269
|
-
|
|
270
|
-
export const compatChannelValueDtos = (parsedFeed: FeedObject) => {
|
|
271
|
-
let dtos = [];
|
|
272
|
-
if (parsedFeed.value) {
|
|
273
|
-
const dto = compatChannelValue(parsedFeed.value);
|
|
274
|
-
|
|
275
|
-
const formattedDto = {
|
|
276
|
-
channel_value: {
|
|
277
|
-
type: dto.type,
|
|
278
|
-
method: dto.method,
|
|
279
|
-
suggested: dto.suggested || null
|
|
280
|
-
},
|
|
281
|
-
channel_value_recipients: dto.channel_value_recipients
|
|
282
|
-
};
|
|
283
|
-
|
|
284
|
-
dtos.push(formattedDto);
|
|
285
|
-
}
|
|
286
|
-
return dtos;
|
|
287
|
-
};
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { ItemChapterDto } from 'podverse-orm';
|
|
2
|
-
|
|
3
|
-
export type PIChapter = {
|
|
4
|
-
startTime: string
|
|
5
|
-
endTime: string | null
|
|
6
|
-
title: string | null
|
|
7
|
-
img: string | null
|
|
8
|
-
url: string | null
|
|
9
|
-
toc: boolean
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export const compatParsedChapters = (chapters: PIChapter[]): ItemChapterDto[] => {
|
|
13
|
-
return chapters.map(chapter => {
|
|
14
|
-
return {
|
|
15
|
-
start_time: chapter.startTime,
|
|
16
|
-
end_time: chapter.endTime || null,
|
|
17
|
-
title: chapter.title || null,
|
|
18
|
-
img: chapter.img || null,
|
|
19
|
-
web_url: chapter.url || null,
|
|
20
|
-
table_of_contents: chapter.toc || true
|
|
21
|
-
};
|
|
22
|
-
});
|
|
23
|
-
};
|
|
@@ -1,289 +0,0 @@
|
|
|
1
|
-
import { FeedObject, Phase4Medium } from "podcast-partytime";
|
|
2
|
-
import { createSortableTitle, getBooleanOrNull } from "podverse-helpers";
|
|
3
|
-
import { getMediumEnumValue, getChannelItunesTypeItunesTypeEnumValue } from "podverse-orm";
|
|
4
|
-
import { compatChannelValue } from "@parser/lib/compat/partytime/value";
|
|
5
|
-
import { Phase4PodcastImage } from "podcast-partytime/dist/parser/phase/phase-4";
|
|
6
|
-
|
|
7
|
-
export const compatChannelDto = (parsedFeed: FeedObject) => ({
|
|
8
|
-
podcast_guid: parsedFeed.guid,
|
|
9
|
-
title: parsedFeed.title,
|
|
10
|
-
sortable_title: createSortableTitle(parsedFeed.title),
|
|
11
|
-
medium: getMediumEnumValue(parsedFeed.medium ?? Phase4Medium.Podcast)
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
export const compatChannelAboutDto = (parsedFeed: FeedObject) => ({
|
|
15
|
-
author: (Array.isArray(parsedFeed.author) ? parsedFeed.author : parsedFeed.author ? [parsedFeed.author] : [])?.join(', ') || null,
|
|
16
|
-
explicit: getBooleanOrNull(parsedFeed.explicit),
|
|
17
|
-
language: parsedFeed.language || null,
|
|
18
|
-
last_pub_date: parsedFeed.pubDate || null,
|
|
19
|
-
website_link_url: parsedFeed.link || null,
|
|
20
|
-
itunes_type: getChannelItunesTypeItunesTypeEnumValue(parsedFeed.itunesType || 'episodic'),
|
|
21
|
-
episode_count: (parsedFeed.items?.length || 0) + (parsedFeed.podcastLiveItems?.length || 0),
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
export const compatChannelChatDto = (parsedFeed: FeedObject) => {
|
|
25
|
-
if (!parsedFeed.chat) {
|
|
26
|
-
return null;
|
|
27
|
-
}
|
|
28
|
-
return {
|
|
29
|
-
server: parsedFeed.chat.server,
|
|
30
|
-
protocol: parsedFeed.chat.protocol,
|
|
31
|
-
account_id: parsedFeed.chat.accountId || null,
|
|
32
|
-
space: parsedFeed.chat.space || null
|
|
33
|
-
};
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export const compatChannelDescriptionDto = (parsedFeed: FeedObject) => {
|
|
37
|
-
if (!parsedFeed.description) {
|
|
38
|
-
return null;
|
|
39
|
-
}
|
|
40
|
-
return {
|
|
41
|
-
value: parsedFeed.description
|
|
42
|
-
};
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
export const compatChannelFundingDtos = (parsedFeed: FeedObject) => {
|
|
46
|
-
const dtos = [];
|
|
47
|
-
|
|
48
|
-
if (Array.isArray(parsedFeed.podcastFunding)) {
|
|
49
|
-
for (const f of parsedFeed.podcastFunding) {
|
|
50
|
-
if (f.url) {
|
|
51
|
-
dtos.push({
|
|
52
|
-
url: f.url,
|
|
53
|
-
title: f.message || null
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
return dtos;
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
export const compatChannelImageDtos = (parsedFeed: FeedObject) => {
|
|
63
|
-
const dtos = [];
|
|
64
|
-
if (parsedFeed.itunesImage) {
|
|
65
|
-
dtos.push({
|
|
66
|
-
url: parsedFeed.itunesImage,
|
|
67
|
-
image_width_size: null
|
|
68
|
-
});
|
|
69
|
-
} else if (parsedFeed.image?.url) {
|
|
70
|
-
dtos.push({
|
|
71
|
-
url: parsedFeed.image.url,
|
|
72
|
-
image_width_size: null
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function hasWidth(image: Phase4PodcastImage['parsed']): image is { url: string; width: number } {
|
|
77
|
-
return (image as { width: number }).width !== undefined;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
if (Array.isArray(parsedFeed.podcastImages)) {
|
|
81
|
-
for (const image of parsedFeed.podcastImages) {
|
|
82
|
-
if (image.parsed.url && hasWidth(image.parsed)) {
|
|
83
|
-
dtos.push({
|
|
84
|
-
url: image.parsed.url,
|
|
85
|
-
image_width_size: image.parsed.width
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
return dtos;
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
export const compatChannelLicenseDto = (parsedFeed: FeedObject) => {
|
|
95
|
-
if (!parsedFeed?.license?.identifier) {
|
|
96
|
-
return null;
|
|
97
|
-
}
|
|
98
|
-
return {
|
|
99
|
-
identifier: parsedFeed.license.identifier,
|
|
100
|
-
url: parsedFeed.license.url || null
|
|
101
|
-
};
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
export const compatChannelLocationDto = (parsedFeed: FeedObject) => {
|
|
105
|
-
if (!parsedFeed?.podcastLocation?.geo && !parsedFeed?.podcastLocation?.osm) {
|
|
106
|
-
return null;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
return {
|
|
110
|
-
geo: parsedFeed.podcastLocation.geo || null,
|
|
111
|
-
osm: parsedFeed.podcastLocation.osm || null,
|
|
112
|
-
name: parsedFeed.podcastLocation.name || null
|
|
113
|
-
};
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
export const compatChannelPersonDtos = (parsedFeed: FeedObject) => {
|
|
117
|
-
const dtos = [];
|
|
118
|
-
|
|
119
|
-
if (Array.isArray(parsedFeed.podcastPeople)) {
|
|
120
|
-
for (const p of parsedFeed.podcastPeople) {
|
|
121
|
-
if (p.name) {
|
|
122
|
-
dtos.push({
|
|
123
|
-
name: p.name,
|
|
124
|
-
role: p.role?.toLowerCase() || null,
|
|
125
|
-
person_group: p.group?.toLowerCase() || 'cast',
|
|
126
|
-
img: p.img || null,
|
|
127
|
-
href: p.href || null
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
return dtos;
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
export const compatChannelPodrollRemoteItemDtos = (parsedFeed: FeedObject) => {
|
|
137
|
-
const dtos = [];
|
|
138
|
-
|
|
139
|
-
if (Array.isArray(parsedFeed.podroll)) {
|
|
140
|
-
for (const ri of parsedFeed.podroll) {
|
|
141
|
-
if (ri.feedGuid) {
|
|
142
|
-
dtos.push({
|
|
143
|
-
feed_guid: ri.feedGuid,
|
|
144
|
-
feed_url: ri.feedUrl || null,
|
|
145
|
-
item_guid: null,
|
|
146
|
-
title: /* PTDO: ri.title || */ null
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
return dtos;
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
export const compatChannelPublisherRemoteItemDtos = (parsedFeed: FeedObject) => {
|
|
156
|
-
const dtos = [];
|
|
157
|
-
|
|
158
|
-
if (Array.isArray(parsedFeed.podroll)) {
|
|
159
|
-
for (const ri of parsedFeed.podroll) {
|
|
160
|
-
if (ri.feedGuid) {
|
|
161
|
-
dtos.push({
|
|
162
|
-
feed_guid: ri.feedGuid,
|
|
163
|
-
feed_url: ri.feedUrl || null,
|
|
164
|
-
item_guid: null,
|
|
165
|
-
title: /* PTDO: ri.title || */ null
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
return dtos;
|
|
172
|
-
};
|
|
173
|
-
|
|
174
|
-
export const compatChannelRemoteItemDtos = (parsedFeed: FeedObject) => {
|
|
175
|
-
const dtos = [];
|
|
176
|
-
|
|
177
|
-
if (Array.isArray(parsedFeed.podcastRemoteItems)) {
|
|
178
|
-
for (const ri of parsedFeed.podcastRemoteItems) {
|
|
179
|
-
if (ri.feedGuid) {
|
|
180
|
-
dtos.push({
|
|
181
|
-
feed_guid: ri.feedGuid,
|
|
182
|
-
feed_url: ri.feedUrl || null,
|
|
183
|
-
item_guid: null,
|
|
184
|
-
title: /* PTDO: ri.title || */ null
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
return dtos;
|
|
191
|
-
};
|
|
192
|
-
|
|
193
|
-
export const compatChannelSocialInteractDtos = (parsedFeed: FeedObject) => {
|
|
194
|
-
const dtos = [];
|
|
195
|
-
|
|
196
|
-
if (parsedFeed?.podcastSocial?.length) {
|
|
197
|
-
for (const ps of parsedFeed.podcastSocial) {
|
|
198
|
-
dtos.push({
|
|
199
|
-
// PTDO: fix keys mismatch between partytime and podverse
|
|
200
|
-
protocol: ps.platform,
|
|
201
|
-
uri: ps.url,
|
|
202
|
-
account_id: ps.id || null,
|
|
203
|
-
account_url: ps.name || null,
|
|
204
|
-
priority: ps.priority || null
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
return dtos;
|
|
210
|
-
};
|
|
211
|
-
|
|
212
|
-
export const compatChannelSeasonDtos = (parsedFeed: FeedObject) => {
|
|
213
|
-
const dtos = [];
|
|
214
|
-
|
|
215
|
-
const parsedItems = parsedFeed?.items || [];
|
|
216
|
-
|
|
217
|
-
const seasonsIndex: { [key: number]: { name: string | null } } = {};
|
|
218
|
-
|
|
219
|
-
for (const parsedItem of parsedItems) {
|
|
220
|
-
const seasonNumber = parsedItem?.podcastSeason?.number || parsedItem?.itunesSeason;
|
|
221
|
-
const seasonName = parsedItem?.podcastSeason?.name || null;
|
|
222
|
-
if (Number.isInteger(seasonNumber)) {
|
|
223
|
-
const seasonNumberAsNumber = seasonNumber as number;
|
|
224
|
-
seasonsIndex[seasonNumberAsNumber] = {
|
|
225
|
-
name: seasonName
|
|
226
|
-
};
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
for (const [number, { name }] of Object.entries(seasonsIndex)) {
|
|
231
|
-
dtos.push({
|
|
232
|
-
number: parseInt(number),
|
|
233
|
-
name: name || null
|
|
234
|
-
});
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
return dtos;
|
|
238
|
-
};
|
|
239
|
-
|
|
240
|
-
export const compatChannelTrailerDtos = (parsedFeed: FeedObject) => {
|
|
241
|
-
const dtos = [];
|
|
242
|
-
if (parsedFeed?.trailers?.length) {
|
|
243
|
-
for (const pt of parsedFeed.trailers) {
|
|
244
|
-
dtos.push({
|
|
245
|
-
url: pt.url,
|
|
246
|
-
title: /* PTDO: add pt.title || */ null,
|
|
247
|
-
pubdate: pt.pubdate,
|
|
248
|
-
length: pt.length || null,
|
|
249
|
-
type: pt.type || null,
|
|
250
|
-
season: pt.season || null
|
|
251
|
-
});
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
return dtos;
|
|
256
|
-
};
|
|
257
|
-
|
|
258
|
-
export const compatChannelTxtDtos = (parsedFeed: FeedObject) => {
|
|
259
|
-
const dtos = [];
|
|
260
|
-
if (parsedFeed?.podcastTxt?.length) {
|
|
261
|
-
for (const pt of parsedFeed.podcastTxt) {
|
|
262
|
-
dtos.push({
|
|
263
|
-
purpose: pt.purpose || null,
|
|
264
|
-
value: pt.value
|
|
265
|
-
});
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
return dtos;
|
|
270
|
-
};
|
|
271
|
-
|
|
272
|
-
export const compatChannelValueDtos = (parsedFeed: FeedObject) => {
|
|
273
|
-
let dtos = [];
|
|
274
|
-
if (parsedFeed.value) {
|
|
275
|
-
const dto = compatChannelValue(parsedFeed.value);
|
|
276
|
-
|
|
277
|
-
const formattedDto = {
|
|
278
|
-
channel_value: {
|
|
279
|
-
type: dto.type,
|
|
280
|
-
method: dto.method,
|
|
281
|
-
suggested: dto.suggested || null
|
|
282
|
-
},
|
|
283
|
-
channel_value_recipients: dto.channel_value_recipients
|
|
284
|
-
};
|
|
285
|
-
|
|
286
|
-
dtos.push(formattedDto);
|
|
287
|
-
}
|
|
288
|
-
return dtos;
|
|
289
|
-
};
|