fix(opds): correctly parse file extension for CBZ files from OPDS servers, closes #2765 (#2771)

This commit is contained in:
Huang Xin
2025-12-23 15:53:50 +08:00
committed by GitHub
parent 4ae1ab7dd0
commit 3abef6ea75
3 changed files with 25 additions and 5 deletions
+10 -3
View File
@@ -19,7 +19,13 @@ import { useLibrary } from '@/hooks/useLibrary';
import { eventDispatcher } from '@/utils/event';
import { getFileExtFromMimeType } from '@/libs/document';
import { OPDSFeed, OPDSPublication, OPDSSearch } from '@/types/opds';
import { isSearchLink, MIME, parseMediaType, resolveURL } from './utils/opdsUtils';
import {
getFileExtFromPath,
isSearchLink,
MIME,
parseMediaType,
resolveURL,
} from './utils/opdsUtils';
import { getProxiedURL, fetchWithAuth, probeAuth, needsProxy } from './utils/opdsReq';
import { READEST_OPDS_USER_AGENT } from '@/services/constants';
import { FeedView } from './components/FeedView';
@@ -403,8 +409,9 @@ export default function BrowserPage() {
}
return;
} else {
const ext = parsed?.mediaType ? getFileExtFromMimeType(parsed.mediaType) : '';
const basename = new URL(url).pathname.replaceAll('/', '_');
const pathname = new URL(url).pathname;
const ext = getFileExtFromMimeType(parsed?.mediaType) || getFileExtFromPath(pathname);
const basename = pathname.replaceAll('/', '_');
const filename = ext ? `${basename}.${ext}` : basename;
const dstFilePath = await appService?.resolveFilePath(filename, 'Cache');
if (dstFilePath) {
@@ -1,5 +1,6 @@
import { isOPDSCatalog } from 'foliate-js/opds.js';
import { OPDSLink } from '@/types/opds';
import { EXTS } from '@/libs/document';
import { fetchWithAuth } from './opdsReq';
export const groupByArray = <T, K>(arr: T[] | undefined, f: (el: T) => K | K[]): Map<K, T[]> => {
@@ -215,3 +216,13 @@ export const validateOPDSURL = async (
};
}
};
export const getFileExtFromPath = (pathname: string, delimiter = '/'): string => {
const parts = pathname.split(delimiter);
for (const ext of Object.values(EXTS)) {
if (parts.includes(ext)) {
return ext;
}
}
return '';
};
+4 -2
View File
@@ -87,7 +87,7 @@ export const MIMETYPES: Record<BookFormat, string[]> = {
MOBI: ['application/x-mobipocket-ebook'],
AZW: ['application/vnd.amazon.ebook'],
AZW3: ['application/vnd.amazon.mobi8-ebook', 'application/x-mobi8-ebook'],
CBZ: ['application/vnd.comicbook+zip', 'application/zip'],
CBZ: ['application/vnd.comicbook+zip', 'application/zip', 'application/x-cbz'],
FB2: ['application/x-fictionbook+xml', 'text/xml', 'application/xml'],
FBZ: ['application/x-zip-compressed-fb2', 'application/zip'],
};
@@ -243,7 +243,9 @@ export const getDirection = (doc: Document) => {
return { vertical, rtl };
};
export const getFileExtFromMimeType = (mimeType: string): string => {
export const getFileExtFromMimeType = (mimeType?: string): string => {
if (!mimeType) return '';
for (const format in MIMETYPES) {
const list = MIMETYPES[format as BookFormat];
if (list.includes(mimeType)) {