diff --git a/app/src/components/Archive.js b/app/src/components/Archive.js
index e70d4b88..8f4ff5cd 100644
--- a/app/src/components/Archive.js
+++ b/app/src/components/Archive.js
@@ -23,6 +23,7 @@ import {
APIButton,
BackButton,
CardLink,
+ DirectoryLink,
encodeMediaPath,
ErrorMessage,
ExternalCardLink,
@@ -89,19 +90,6 @@ import {CollectionEditForm} from "./collections/CollectionEditForm";
import {RecurringDownloadsTable} from "./admin/Downloads";
import {DestinationForm} from "./Download";
-function archiveFileLink(path, directory = false) {
- if (path) {
- const href = directory ?
- `/media/${encodeMediaPath(path)}/`
- : `/media/${encodeMediaPath(path)}`;
- return
- {path}
-
- } else {
- return
Unknown
- }
-}
-
function ArchivePage() {
const navigate = useNavigate();
const {fileGroupId} = useParams();
@@ -258,37 +246,63 @@ function ArchivePage() {
};
+ // Helper to find file size from the files array by resolved path
+ const findFileSize = (resolvedPath) => {
+ if (!resolvedPath || !archiveFile.files) return null;
+ const file = archiveFile.files.find(i => String(i.path) === String(resolvedPath));
+ return file && file.size
+ ? ({humanFileSize(file.size)})
+ : null;
+ };
+
// Helper to resolve and preview a data path
const localPreviewPath = (dataPath, mimetype) => {
const resolvedPath = resolveDataPath(dataPath, directory);
if (resolvedPath) {
- return {resolvedPath}
+ return <>{resolvedPath}{findFileSize(resolvedPath)}>
} else {
return 'Unknown'
}
}
+ const tableStyle = {width: '100%', borderCollapse: 'separate', borderSpacing: '0 0.7em'};
+ const labelStyle = {whiteSpace: 'nowrap', paddingRight: '1.5em', verticalAlign: 'top'};
const filesPane = {
menuItem: 'Files', render: () =>
-
- {localPreviewPath(data.singlefile_path, 'text/html')}
-
-
- {localPreviewPath(data.readability_path, 'text/html')}
-
-
- {localPreviewPath(data.readability_txt_path, 'text/plain')}
-
-
- {localPreviewPath(data.readability_json_path, 'application/json')}
-
-
- {screenshotPath ?
- archiveFileLink(screenshotPath)
- : 'Unknown'}
-
-
- {archiveFileLink(archiveFile.directory, true)}
+
+
+
+ | Singlefile File |
+ {localPreviewPath(data.singlefile_path, 'text/html')} |
+
+
+ | Readability File |
+ {localPreviewPath(data.readability_path, 'text/html')} |
+
+
+ | Readability Text File |
+ {localPreviewPath(data.readability_txt_path, 'text/plain')} |
+
+
+ | Readability JSON File |
+ {localPreviewPath(data.readability_json_path, 'application/json')} |
+
+
+ | Screenshot File |
+
+ {screenshotPath
+ ? <>{screenshotPath}{findFileSize(screenshotPath)}>
+ : 'Unknown'}
+ |
+
+
+ | Directory |
+ |
+
+
+
};
diff --git a/app/src/components/Common.js b/app/src/components/Common.js
index 34e27d3f..efae402f 100644
--- a/app/src/components/Common.js
+++ b/app/src/components/Common.js
@@ -246,6 +246,15 @@ export function PreviewPath({path, mimetype, taggable = true, ...props}) {
return
}
+export function DirectoryLink({path}) {
+ if (!path) return Unknown;
+ const href = `/media/${encodeMediaPath(path)}/`;
+ return
+ {path}
+
+}
+
export function RequiredAsterisk() {
return *
}
diff --git a/app/src/components/Docs.js b/app/src/components/Docs.js
index f8c949e3..d7d6886e 100644
--- a/app/src/components/Docs.js
+++ b/app/src/components/Docs.js
@@ -6,6 +6,7 @@ import {Media, ThemeContext} from "../contexts/contexts";
import {
APIButton,
BackButton,
+ DirectoryLink,
encodeMediaPath,
ErrorMessage,
humanFileSize,
@@ -288,21 +289,33 @@ function DocPage() {
};
// Files pane.
+ const tableStyle = {width: '100%', borderCollapse: 'separate', borderSpacing: '0 0.7em'};
+ const labelStyle = {whiteSpace: 'nowrap', paddingRight: '1.5em', verticalAlign: 'top'};
const filesPane = {
menuItem: 'Files', render: () =>
- {docFile.files && docFile.files.map((file, idx) =>
-
-
- {file.path}
-
- {file.size &&
- ({humanFileSize(file.size)})
- }
-
- )}
-
-
- {directory || 'Unknown'}
+
+
+ {docFile.files && docFile.files.map((file, idx) =>
+
+ |
+ {file.path.split('.').pop().toUpperCase()}
+ |
+
+
+ {file.path}
+
+ {file.size &&
+ ({humanFileSize(file.size)})
+ }
+ |
+
+ )}
+
+ | Directory |
+ |
+
+
+
};
diff --git a/app/src/components/VideoPlayer.js b/app/src/components/VideoPlayer.js
index eff72205..c4ba63ef 100644
--- a/app/src/components/VideoPlayer.js
+++ b/app/src/components/VideoPlayer.js
@@ -6,6 +6,7 @@ import _ from "lodash";
import {
APIButton,
BackButton,
+ DirectoryLink,
encodeMediaPath,
humanFileSize,
humanNumber,
@@ -29,19 +30,6 @@ import {Comment, CommentGroup, Input, Label} from "semantic-ui-react";
const MEDIA_PATH = '/media';
-function videoFileLink(path, directory = false) {
- if (path) {
- const href = directory ?
- // Add / to end of directory.
- `${MEDIA_PATH}/${encodeMediaPath(path)}/` :
- `${MEDIA_PATH}/${encodeMediaPath(path)}`;
- return
- {path}
-
- } else {
- return 'Unknown'
- }
-}
export function CaptionTrack({src, ...props}) {
if (src.endsWith('.de.vtt')) {
@@ -311,44 +299,84 @@ function VideoPage({videoFile, prevFile, nextFile, fetchVideo, ...props}) {
};
const getFile = (suffix) => videoFile.files.find(i => i.path.toLowerCase().endsWith(suffix));
+ const fileSize = (file) => file && file.size
+ ? ({humanFileSize(file.size)})
+ : null;
const {poster_file, info_json_file} = video;
+ const videoPathFile = videoFile.files.find(i => i.path === video['video_path']);
const ffprobeJsonFile = getFile('.ffprobe.json');
+ const tableStyle = {width: '100%', borderCollapse: 'separate', borderSpacing: '0 0.7em'};
+ const labelStyle = {whiteSpace: 'nowrap', paddingRight: '1.5em', verticalAlign: 'top'};
const filesPane = {
menuItem: 'Files', render: () =>
- Video File
- {videoFileLink(video['video_path'])}
+
+
+
+ | Video File |
+
+ {video['video_path']
+ ? <>
+ {video['video_path']}
+ {fileSize(videoPathFile)}>
+ : 'Unknown'}
+ |
+
- Caption Files
- {caption_files ?
- caption_files.map(i =>
- {i['path']}
-
) : 'No caption files'
- }
+
+ | Caption Files |
+
+ {caption_files
+ ? caption_files.map(i =>
+ {i['path']}
+ {fileSize(i)}
+ )
+ : 'No caption files'}
+ |
+
- Poster File
- {poster_file ?
-
- {poster_file['path']}
- : 'No poster file'
- }
+
+ | Poster File |
+
+ {poster_file
+ ? <>
+ {poster_file['path']}
+ {fileSize(poster_file)}>
+ : 'No poster file'}
+ |
+
- Info JSON File
- {info_json_file ?
-
- {info_json_file['path']}
- : 'No yt-dlp info json file'
- }
+
+ | Info JSON File |
+
+ {info_json_file
+ ? <>
+ {info_json_file['path']}
+ {fileSize(info_json_file)}>
+ : 'No yt-dlp info json file'}
+ |
+
- ffprobe JSON File
- {ffprobeJsonFile ?
-
- {ffprobeJsonFile['path']}
- : 'No ffprobe json file'
- }
+
+ | ffprobe JSON File |
+
+ {ffprobeJsonFile
+ ? <>
+ {ffprobeJsonFile['path']}
+ {fileSize(ffprobeJsonFile)}>
+ : 'No ffprobe json file'}
+ |
+
- Directory
- {videoFileLink(videoFile['directory'], true)}
+
+ | Directory |
+ |
+
+
+
}
diff --git a/wrolpi/files/models.py b/wrolpi/files/models.py
index 169f08f9..badc9c9d 100644
--- a/wrolpi/files/models.py
+++ b/wrolpi/files/models.py
@@ -272,7 +272,8 @@ class FileGroup(ModelHelper, Base):
new_files = list(self.files) if self.files else list()
for path in paths:
# Store just the filename, not the full path
- new_files.append(dict(path=path.name, mimetype=get_mimetype(path)))
+ size = path.stat().st_size if path.exists() else None
+ new_files.append(dict(path=path.name, mimetype=get_mimetype(path), size=size))
self.files = unique_by_predicate(new_files, lambda i: i['path'])
# Update modification_datetime to include the new files' mtimes
if paths: