Fixed .false file extension.
This commit is contained in:
@@ -27,6 +27,17 @@ function safeFormat(date, dateFormat, label) {
|
|||||||
return dateFns.format(date, dateFormat);
|
return dateFns.format(date, dateFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mime.extension() returns the boolean `false` (not undefined/null) for a mime type it
|
||||||
|
// doesn't recognize - reddit's gallery API is a known offender, sending the non-standard
|
||||||
|
// 'image/jpg' instead of 'image/jpeg' - which without this check ends up interpolated
|
||||||
|
// verbatim as the literal filename extension '.false'. Fall back to whatever extension the
|
||||||
|
// URL itself has instead, same as when there's no type at all.
|
||||||
|
function resolveExt(item) {
|
||||||
|
const extFromType = item.type && mime.extension(item.type);
|
||||||
|
|
||||||
|
return extFromType ? `.${extFromType}` : path.extname(url.parse(item.url).pathname);
|
||||||
|
}
|
||||||
|
|
||||||
function interpolate(pattern, item = null, content = null, host = null, post = null, user = null, strip = true, dateFormat = config.library.dateFormat) {
|
function interpolate(pattern, item = null, content = null, host = null, post = null, user = null, strip = true, dateFormat = config.library.dateFormat) {
|
||||||
const data = {
|
const data = {
|
||||||
tags: {},
|
tags: {},
|
||||||
@@ -41,9 +52,7 @@ function interpolate(pattern, item = null, content = null, host = null, post = n
|
|||||||
date: safeFormat(item.datetime, dateFormat, 'item'),
|
date: safeFormat(item.datetime, dateFormat, 'item'),
|
||||||
index: item.index + config.library.indexOffset,
|
index: item.index + config.library.indexOffset,
|
||||||
},
|
},
|
||||||
ext: item.type
|
ext: resolveExt(item),
|
||||||
? `.${mime.extension(item.type)}`
|
|
||||||
: path.extname(url.parse(item.url).pathname),
|
|
||||||
tags: {
|
tags: {
|
||||||
...data.tags,
|
...data.tags,
|
||||||
extracted: item.extracted && config.library.tags.extracted,
|
extracted: item.extracted && config.library.tags.extracted,
|
||||||
|
|||||||
@@ -8,22 +8,41 @@ function resolveMediaUrl(media) {
|
|||||||
return url ? url.replace(/&/g, '&') : null;
|
return url ? url.replace(/&/g, '&') : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reddit sends the non-standard 'image/jpg' instead of the real IANA 'image/jpeg' for
|
||||||
|
// gallery items - left as-is, this silently breaks anything matching against real mime
|
||||||
|
// types downstream (interpolate.js's extension lookup ends up with a '.false' extension,
|
||||||
|
// fetch/content.js's addMeta() skips embedding metadata since it only matches 'image/jpeg')
|
||||||
|
function normalizeType(type) {
|
||||||
|
return type === 'image/jpg' ? 'image/jpeg' : type;
|
||||||
|
}
|
||||||
|
|
||||||
async function redditAlbum(host, post, { reddit }) {
|
async function redditAlbum(host, post, { reddit }) {
|
||||||
// fetched through the authenticated/throttled client, not a raw fetch()/bhttp request -
|
// fetched through the authenticated/throttled client, not a raw fetch()/bhttp request -
|
||||||
// reddit's anonymous-traffic bot challenge blocks plain unauthenticated .json requests
|
// reddit's anonymous-traffic bot challenge blocks plain unauthenticated .json requests
|
||||||
const data = await reddit.getSubmission(post.id);
|
const data = await reddit.getSubmission(post.id);
|
||||||
|
const mediaMetadata = data.media_metadata || {};
|
||||||
|
|
||||||
const items = (data.gallery_data?.items || [])
|
// gallery_data (the ordered {media_id, is_deleted, ...} list for this gallery) has been
|
||||||
|
// seen coming back null on a freshly-posted gallery even though media_metadata itself
|
||||||
|
// was already fully populated - fall back to media_metadata's own keys, in the order the
|
||||||
|
// JSON provided them (reddit sends them in gallery order, and object key order is
|
||||||
|
// preserved through JSON.parse), skipping anything not (yet, or any longer) valid
|
||||||
|
const galleryItems = data.gallery_data?.items
|
||||||
|
|| Object.entries(mediaMetadata)
|
||||||
|
.filter(([, media]) => media.status === 'valid')
|
||||||
|
.map(([mediaId]) => ({ media_id: mediaId }));
|
||||||
|
|
||||||
|
const items = galleryItems
|
||||||
.filter((item) => !item.is_deleted)
|
.filter((item) => !item.is_deleted)
|
||||||
.map((item) => {
|
.map((item) => {
|
||||||
const media = data.media_metadata?.[item.media_id];
|
const media = mediaMetadata[item.media_id];
|
||||||
const url = resolveMediaUrl(media);
|
const url = resolveMediaUrl(media);
|
||||||
|
|
||||||
return url && {
|
return url && {
|
||||||
id: item.media_id,
|
id: item.media_id,
|
||||||
url,
|
url,
|
||||||
datetime: post.datetime,
|
datetime: post.datetime,
|
||||||
type: media.m || 'image/jpeg',
|
type: normalizeType(media.m) || 'image/jpeg',
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.filter(Boolean);
|
.filter(Boolean);
|
||||||
|
|||||||
Reference in New Issue
Block a user