mirror of
https://github.com/lrnselfreliance/wrolpi.git
synced 2026-10-26 19:01:39 -04:00
Reworking Cards in the App so that they use the new FileGroup.files and .data.
This commit is contained in:
parent
b6e82cde26
commit
5d50562768
5 changed files with 62 additions and 26 deletions
|
|
@ -34,6 +34,7 @@ import {
|
|||
mimetypeColor,
|
||||
PageContainer,
|
||||
PreviewPath,
|
||||
resolveDataPath,
|
||||
SearchInput,
|
||||
SortButton,
|
||||
TabLinks,
|
||||
|
|
@ -104,11 +105,16 @@ function ArchivePage() {
|
|||
</>
|
||||
}
|
||||
|
||||
const {data, size} = archiveFile;
|
||||
const {data, size, directory} = archiveFile;
|
||||
|
||||
const singlefileUrl = data.singlefile_path ? `/media/${encodeMediaPath(data.singlefile_path)}` : null;
|
||||
const readabilityUrl = data.readability_path ? `/media/${encodeMediaPath(data.readability_path)}` : null;
|
||||
const screenshotUrl = data.screenshot_path ? `/media/${encodeMediaPath(data.screenshot_path)}` : null;
|
||||
// Resolve data paths (filename-only) to full relative paths using directory
|
||||
const singlefilePath = resolveDataPath(data.singlefile_path, directory);
|
||||
const readabilityPath = resolveDataPath(data.readability_path, directory);
|
||||
const screenshotPath = resolveDataPath(data.screenshot_path, directory);
|
||||
|
||||
const singlefileUrl = singlefilePath ? `/media/${encodeMediaPath(singlefilePath)}` : null;
|
||||
const readabilityUrl = readabilityPath ? `/media/${encodeMediaPath(readabilityPath)}` : null;
|
||||
const screenshotUrl = screenshotPath ? `/media/${encodeMediaPath(screenshotPath)}` : null;
|
||||
|
||||
const singlefileButton = <ExternalCardLink to={singlefileUrl}>
|
||||
<Button content='View' color='violet'/>
|
||||
|
|
@ -235,9 +241,11 @@ function ArchivePage() {
|
|||
</Tab.Pane>
|
||||
};
|
||||
|
||||
const localPreviewPath = (path, mimetype) => {
|
||||
if (path) {
|
||||
return <PreviewPath path={path} mimetype={mimetype} taggable={false}>{path}</PreviewPath>
|
||||
// Helper to resolve and preview a data path
|
||||
const localPreviewPath = (dataPath, mimetype) => {
|
||||
const resolvedPath = resolveDataPath(dataPath, directory);
|
||||
if (resolvedPath) {
|
||||
return <PreviewPath path={resolvedPath} mimetype={mimetype} taggable={false}>{resolvedPath}</PreviewPath>
|
||||
} else {
|
||||
return 'Unknown'
|
||||
}
|
||||
|
|
@ -258,8 +266,8 @@ function ArchivePage() {
|
|||
{localPreviewPath(data.readability_json_path, 'application/json')}
|
||||
|
||||
<Header as={'h3'}>Screenshot File</Header>
|
||||
{data.screenshot_path ?
|
||||
archiveFileLink(data.screenshot_path)
|
||||
{screenshotPath ?
|
||||
archiveFileLink(screenshotPath)
|
||||
: 'Unknown'}
|
||||
|
||||
<Header as={'h3'}>Directory</Header>
|
||||
|
|
@ -321,10 +329,14 @@ function ArchivePage() {
|
|||
|
||||
export function ArchiveCard({file}) {
|
||||
const {s} = useContext(ThemeContext);
|
||||
const {data} = file;
|
||||
const {data, directory} = file;
|
||||
|
||||
const imageSrc = data.screenshot_path ? `/media/${encodeMediaPath(data.screenshot_path)}` : null;
|
||||
const singlefileUrl = data.singlefile_path ? `/media/${encodeMediaPath(data.singlefile_path)}` : null;
|
||||
// Resolve data paths (filename-only) to full relative paths using directory
|
||||
const screenshotPath = resolveDataPath(data.screenshot_path, directory);
|
||||
const singlefilePath = resolveDataPath(data.singlefile_path, directory);
|
||||
|
||||
const imageSrc = screenshotPath ? `/media/${encodeMediaPath(screenshotPath)}` : null;
|
||||
const singlefileUrl = singlefilePath ? `/media/${encodeMediaPath(singlefilePath)}` : null;
|
||||
|
||||
let screenshot = <Card.Icon><FileIcon file={file}/></Card.Icon>;
|
||||
const imageLabel = file.tags && file.tags.length ? taggedImageLabel : null;
|
||||
|
|
|
|||
|
|
@ -656,11 +656,27 @@ export function CardGroupCentered(props) {
|
|||
</div>
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a filename-only path to a full relative path using the file's directory.
|
||||
* Paths in FileGroup.data are stored as filenames only for performance (fast moves/renames).
|
||||
* This function resolves them to full relative paths suitable for /media/ URLs.
|
||||
*
|
||||
* @param {string} path - The path to resolve (may be filename-only or already a full path)
|
||||
* @param {string} directory - The directory to prepend if path is filename-only
|
||||
* @returns {string|null} - The resolved path, or null if path is falsy
|
||||
*/
|
||||
export function resolveDataPath(path, directory) {
|
||||
if (!path) return null;
|
||||
if (path.includes('/')) return path; // Already a full relative path
|
||||
return directory ? `${directory}/${path}` : path;
|
||||
}
|
||||
|
||||
export function findPosterPath(file) {
|
||||
if (!file) {
|
||||
return;
|
||||
}
|
||||
const {files, poster_path, cover_path, screenshot_path, video} = file;
|
||||
const {files, poster_path, cover_path, screenshot_path, video, directory} = file;
|
||||
|
||||
if (poster_path) {
|
||||
return poster_path;
|
||||
}
|
||||
|
|
@ -670,18 +686,24 @@ export function findPosterPath(file) {
|
|||
if (screenshot_path) {
|
||||
return screenshot_path;
|
||||
}
|
||||
if (file['data'] && file['data']['cover_path']) {
|
||||
// Ebook.
|
||||
return file['data']['cover_path'];
|
||||
}
|
||||
if (file['data'] && file['data']['poster_path']) {
|
||||
// PDF.
|
||||
return file['data']['poster_path'];
|
||||
}
|
||||
// video.poster_path is already a full relative path (from Video.__json__)
|
||||
if (video && video['poster_path']) {
|
||||
// file is a video model.
|
||||
return video['poster_path'];
|
||||
}
|
||||
// data paths are filename-only, need to resolve with directory
|
||||
if (file['data'] && file['data']['cover_path']) {
|
||||
// Ebook.
|
||||
return resolveDataPath(file['data']['cover_path'], directory);
|
||||
}
|
||||
if (file['data'] && file['data']['poster_path']) {
|
||||
// PDF or Video (cached).
|
||||
return resolveDataPath(file['data']['poster_path'], directory);
|
||||
}
|
||||
if (file['data'] && file['data']['screenshot_path']) {
|
||||
// Archive.
|
||||
return resolveDataPath(file['data']['screenshot_path'], directory);
|
||||
}
|
||||
// files[].path is already resolved by my_files() on the backend
|
||||
if (!_.isEmpty(files)) {
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
const file = files[i];
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@ from sqlalchemy.orm.collections import InstrumentedList
|
|||
|
||||
from modules.videos.errors import UnknownVideo, UnknownChannel
|
||||
from wrolpi.captions import read_captions
|
||||
from wrolpi.common import Base, ModelHelper, logger, get_media_directory, background_task, replace_file
|
||||
from wrolpi.common import Base, ModelHelper, logger, get_media_directory, get_relative_to_media_directory, \
|
||||
background_task, replace_file
|
||||
from wrolpi.db import get_db_curs, get_db_session
|
||||
from wrolpi.downloader import Download
|
||||
from wrolpi.files.lib import refresh_files, split_path_stem_and_suffix
|
||||
|
|
|
|||
|
|
@ -152,10 +152,11 @@ async def pdf_modeler():
|
|||
file_group.model = 'pdf'
|
||||
|
||||
# Find an image with the same stem to use as the poster.
|
||||
# Store as filename only (consistent with other models, enables fast moves/renames).
|
||||
poster_files = file_group.my_poster_files()
|
||||
if poster_files:
|
||||
file_group.data = file_group.data or {}
|
||||
file_group.data['poster_path'] = str(poster_files[0]['path'])
|
||||
file_group.data['poster_path'] = poster_files[0]['path'].name
|
||||
except Exception as e:
|
||||
logger.error(f'Failed to index PDF {pdf_file}', exc_info=e)
|
||||
if PYTEST:
|
||||
|
|
|
|||
|
|
@ -90,5 +90,5 @@ async def test_pdf_poster(test_session, example_pdf):
|
|||
file_group = test_session.query(FileGroup).one()
|
||||
assert file_group.indexed is True
|
||||
assert file_group.data is not None
|
||||
# FancyJSON converts paths back to pathlib.Path when reading from DB.
|
||||
assert file_group.data.get('poster_path') == poster_path
|
||||
# data['poster_path'] stores filename only (for fast moves/renames).
|
||||
assert file_group.data.get('poster_path') == poster_path.name
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue