feedsmith
Version:
Robust and fast parser and generator for RSS, Atom, JSON Feed, and RDF feeds, with support for Podcast, iTunes, Dublin Core, and OPML files.
387 lines • 12.9 kB
JavaScript
import { isNonEmptyStringOrNumber, isObject, isPresent, parseArrayOf, parseBoolean, parseCsvOf, parseNumber, parseSingularOf, parseString, parseTextString, retrieveText, trimArray, trimObject, } from '../../common/utils.js';
export const parseRating = (value) => {
const rating = {
value: parseString(retrieveText(value)),
scheme: parseString(value?.['@scheme']),
};
if (isPresent(rating.value)) {
return trimObject(rating);
}
};
export const retrieveRatings = (value) => {
if (!isObject(value)) {
return;
}
if (value['media:rating']) {
return parseArrayOf(value['media:rating'], parseRating);
}
// Handle migration from media:adult to media:rating:
// <media:adult>true</media:adult> → <media:rating scheme="urn:simple">adult</media:rating>
// <media:adult>false</media:adult> → <media:rating scheme="urn:simple">nonadult</media:rating>
if (value['media:adult']) {
const isAdult = parseBoolean(retrieveText(value['media:adult']));
const rating = {
value: isAdult ? 'adult' : 'nonadult',
scheme: 'urn:simple',
};
return [rating];
}
};
export const parseTitleOrDescription = (value) => {
const title = {
value: parseString(retrieveText(value)),
type: parseString(value?.['@type']),
};
if (isPresent(title.value)) {
return trimObject(title);
}
};
export const parseThumbnail = (value) => {
if (!isObject(value)) {
return;
}
const thumbnail = {
url: parseString(value['@url']),
height: parseNumber(value['@height']),
width: parseNumber(value['@width']),
time: parseString(value['@time']),
};
if (isPresent(thumbnail.url)) {
return trimObject(thumbnail);
}
};
export const parseCategory = (value) => {
const category = {
name: parseString(retrieveText(value)),
scheme: parseString(value?.['@scheme']),
label: parseString(value?.['@label']),
};
if (isPresent(category.name)) {
return trimObject(category);
}
};
export const parseHash = (value) => {
const hash = {
value: parseString(retrieveText(value)),
algo: parseString(value?.['@algo']),
};
if (isPresent(hash.value)) {
return trimObject(hash);
}
};
export const parsePlayer = (value) => {
if (!isObject(value)) {
return;
}
const player = {
url: parseString(value['@url']),
height: parseNumber(value['@height']),
width: parseNumber(value['@width']),
};
if (isPresent(player.url)) {
return trimObject(player);
}
};
export const parseCredit = (value) => {
const credit = {
value: parseString(retrieveText(value)),
role: parseString(value?.['@role']),
scheme: parseString(value?.['@scheme']),
};
if (isPresent(credit.value)) {
return trimObject(credit);
}
};
export const parseCopyright = (value) => {
const copyright = {
value: parseString(retrieveText(value)),
url: parseString(value?.['@url']),
};
if (isPresent(copyright.value)) {
return trimObject(copyright);
}
};
export const parseText = (value) => {
const text = {
value: parseString(retrieveText(value)),
type: parseString(value?.['@type']),
lang: parseString(value?.['@lang']),
start: parseString(value?.['@start']),
end: parseString(value?.['@end']),
};
if (isPresent(text.value)) {
return trimObject(text);
}
};
export const parseRestriction = (value) => {
if (!isObject(value)) {
return;
}
const restriction = {
value: parseString(retrieveText(value)),
relationship: parseString(value['@relationship']),
type: parseString(value['@type']),
};
if (isPresent(restriction.value) && isPresent(restriction.relationship)) {
return trimObject(restriction);
}
};
export const parseStarRating = (value) => {
if (!isObject(value)) {
return;
}
const starRating = {
average: parseNumber(value['@average']),
count: parseNumber(value['@count']),
min: parseNumber(value['@min']),
max: parseNumber(value['@max']),
};
return trimObject(starRating);
};
export const parseStatistics = (value) => {
if (!isObject(value)) {
return;
}
const statistics = {
views: parseNumber(value['@views']),
favorites: parseNumber(value['@favorites']),
};
return trimObject(statistics);
};
export const parseTags = (value) => {
if (!isNonEmptyStringOrNumber(value)) {
return;
}
const segments = parseString(value)?.split(',');
if (segments) {
return trimArray(segments, (segment) => {
const split = segment.split(':');
return {
name: parseString(split[0]) ?? '',
weight: parseNumber(split[1]) ?? 1,
};
});
}
};
export const parseCommunity = (value) => {
if (!isObject(value)) {
return;
}
const community = {
starRating: parseSingularOf(value['media:starrating'], parseStarRating),
statistics: parseSingularOf(value['media:statistics'], parseStatistics),
tags: parseSingularOf(value['media:tags'], parseTags),
};
return trimObject(community);
};
export const parseComments = (value) => {
return parseArrayOf(value?.['media:comment'], parseTextString);
};
export const parseParam = (value) => {
if (!isObject(value)) {
return;
}
const param = {
name: parseString(value['@name']),
value: parseString(retrieveText(value)),
};
if (isPresent(param.name) && isPresent(param.value)) {
return param;
}
};
export const parseEmbed = (value) => {
if (!isObject(value)) {
return;
}
const embed = {
url: parseString(value['@url']),
width: parseNumber(value['@width']),
height: parseNumber(value['@height']),
params: parseArrayOf(value['media:param'], parseParam),
};
if (isPresent(embed.url)) {
return trimObject(embed);
}
};
export const parseResponses = (value) => {
return parseArrayOf(value?.['media:response'], parseTextString);
};
export const parseBackLinks = (value) => {
return parseArrayOf(value?.['media:backlink'], parseTextString);
};
export const parseStatus = (value) => {
if (!isObject(value)) {
return;
}
const status = {
state: parseString(value['@state']),
reason: parseString(value['@reason']),
};
if (isPresent(status.state)) {
return trimObject(status);
}
};
export const parsePrice = (value) => {
if (!isObject(value)) {
return;
}
const price = {
type: parseString(value['@type']),
info: parseString(value['@info']),
price: parseNumber(value['@price']),
currency: parseString(value['@currency']),
};
if (isPresent(price.type)) {
return trimObject(price);
}
};
export const parseLicense = (value) => {
const license = {
name: parseString(retrieveText(value)),
type: parseString(value?.['@type']),
href: parseString(value?.['@href']),
};
if (isPresent(license.name) || isPresent(license.href)) {
return trimObject(license);
}
};
export const parseSubTitle = (value) => {
if (!isObject(value)) {
return;
}
const subTitle = {
type: parseString(value['@type']),
lang: parseString(value['@lang']),
href: parseString(value['@href']),
};
if (isPresent(subTitle.href)) {
return trimObject(subTitle);
}
};
export const parsePeerLink = (value) => {
if (!isObject(value)) {
return;
}
const peerLink = {
type: parseString(value['@type']),
href: parseString(value['@href']),
};
if (isPresent(peerLink.href)) {
return trimObject(peerLink);
}
};
export const parseRights = (value) => {
if (!isObject(value)) {
return;
}
const rights = {
status: parseString(value['@status']),
};
return trimObject(rights);
};
export const parseScene = (value) => {
if (!isObject(value)) {
return;
}
const scene = {
title: parseSingularOf(value.scenetitle, parseTextString),
description: parseSingularOf(value.scenedescription, parseTextString),
startTime: parseSingularOf(value.scenestarttime, parseTextString),
endTime: parseSingularOf(value.sceneendtime, parseTextString),
};
return trimObject(scene);
};
export const parseScenes = (value) => {
return parseArrayOf(value?.['media:scene'], parseScene);
};
export const parseLocation = (value) => {
// TODO: Extend parseLocation according to the specification of media:location:
// https://www.rssboard.org/media-rss#media-peerlink after implementing GeoRSS GML support.
// For cases where the location is simply a string within the <media:location> tag.
if (isNonEmptyStringOrNumber(value) || isObject(value)) {
return {
description: parseString(retrieveText(value)),
};
}
return undefined;
};
export const retrieveCommonElements = (value) => {
if (!isObject(value)) {
return;
}
const commonElements = {
ratings: retrieveRatings(value),
title: parseSingularOf(value['media:title'], parseTitleOrDescription),
description: parseSingularOf(value['media:description'], parseTitleOrDescription),
keywords: parseSingularOf(value['media:keywords'], (value) => parseCsvOf(retrieveText(value), parseString)),
thumbnails: parseArrayOf(value['media:thumbnail'], parseThumbnail),
categories: parseArrayOf(value['media:category'], parseCategory),
hashes: parseArrayOf(value['media:hash'], parseHash),
player: parseSingularOf(value['media:player'], parsePlayer),
credits: parseArrayOf(value['media:credit'], parseCredit),
copyright: parseSingularOf(value['media:copyright'], parseCopyright),
texts: parseArrayOf(value['media:text'], parseText),
restrictions: parseArrayOf(value['media:restriction'], parseRestriction),
community: parseSingularOf(value['media:community'], parseCommunity),
comments: parseSingularOf(value['media:comments'], parseComments),
embed: parseSingularOf(value['media:embed'], parseEmbed),
responses: parseSingularOf(value['media:responses'], parseResponses),
backLinks: parseSingularOf(value['media:backlinks'], parseBackLinks),
status: parseSingularOf(value['media:status'], parseStatus),
prices: parseArrayOf(value['media:price'], parsePrice),
licenses: parseArrayOf(value['media:license'], parseLicense),
subTitles: parseArrayOf(value['media:subtitle'], parseSubTitle),
peerLinks: parseArrayOf(value['media:peerlink'], parsePeerLink),
locations: parseArrayOf(value['media:location'], parseLocation),
rights: parseSingularOf(value['media:rights'], parseRights),
scenes: parseSingularOf(value['media:scenes'], parseScenes),
};
return trimObject(commonElements);
};
export const parseContent = (value) => {
if (!isObject(value)) {
return;
}
const content = {
url: parseString(value['@url']),
fileSize: parseNumber(value['@filesize']),
type: parseString(value['@type']),
medium: parseString(value['@medium']),
isDefault: parseBoolean(value['@isdefault']),
expression: parseString(value['@expression']),
bitrate: parseNumber(value['@bitrate']),
framerate: parseNumber(value['@framerate']),
samplingrate: parseNumber(value['@samplingrate']),
channels: parseNumber(value['@channels']),
duration: parseNumber(value['@duration']),
height: parseNumber(value['@height']),
width: parseNumber(value['@width']),
lang: parseString(value['@lang']),
...retrieveCommonElements(value),
};
if (isPresent(content.url)) {
return trimObject(content);
}
};
export const parseGroup = (value) => {
if (!isObject(value)) {
return;
}
const group = {
contents: parseArrayOf(value['media:content'], parseContent),
...retrieveCommonElements(value),
};
return trimObject(group);
};
export const retrieveItemOrFeed = (value) => {
if (!isObject(value)) {
return;
}
const itemOrFeed = {
group: parseSingularOf(value['media:group'], parseGroup),
contents: parseArrayOf(value['media:content'], parseContent),
...retrieveCommonElements(value),
};
return trimObject(itemOrFeed);
};
//# sourceMappingURL=utils.js.map