diff --git a/docs/changelog.rst b/docs/changelog.rst
index 2e3ed07f6..b6c88be92 100644
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -19,6 +19,7 @@ This release focusses primarily on many small issues with the UI.
* There's a new filter to filter for documents that do *not* have a certain tag.
* The file upload box now shows upload progress.
* The document edit page was reorganized.
+ * The document edit page shows various information about a document.
* Table issues with too long document titles fixed.
* API
diff --git a/src-ui/src/app/app.module.ts b/src-ui/src/app/app.module.ts
index e186cde50..ad12c9c47 100644
--- a/src-ui/src/app/app.module.ts
+++ b/src-ui/src/app/app.module.ts
@@ -47,6 +47,7 @@ import { UploadFileWidgetComponent } from './components/dashboard/widgets/upload
import { WidgetFrameComponent } from './components/dashboard/widgets/widget-frame/widget-frame.component';
import { WelcomeWidgetComponent } from './components/dashboard/widgets/welcome-widget/welcome-widget.component';
import { YesNoPipe } from './pipes/yes-no.pipe';
+import { FileSizePipe } from './pipes/file-size.pipe';
@NgModule({
declarations: [
@@ -86,7 +87,8 @@ import { YesNoPipe } from './pipes/yes-no.pipe';
UploadFileWidgetComponent,
WidgetFrameComponent,
WelcomeWidgetComponent,
- YesNoPipe
+ YesNoPipe,
+ FileSizePipe
],
imports: [
BrowserModule,
diff --git a/src-ui/src/app/components/document-detail/document-detail.component.html b/src-ui/src/app/components/document-detail/document-detail.component.html
index e905c35e6..774ea8869 100644
--- a/src-ui/src/app/components/document-detail/document-detail.component.html
+++ b/src-ui/src/app/components/document-detail/document-detail.component.html
@@ -83,25 +83,29 @@
Date added |
{{document.added | date}} |
+
+ Media filename |
+ {{metadata?.media_filename}} |
+
Original MD5 Checksum |
{{metadata?.original_checksum}} |
- Archive MD5 Checksum |
- {{metadata?.archived_checksum}} |
+ Original file size |
+ {{metadata?.original_size | fileSize}} |
Original mime type |
{{metadata?.original_mime_type}} |
-
- Is archived? |
- {{metadata?.has_archive_version | yesno}} |
+
+ Archive MD5 Checksum |
+ {{metadata?.archive_checksum}} |
-
- Media filename |
- {{metadata?.media_filename}} |
+
+ Archive file size |
+ {{metadata?.archive_size | fileSize}} |
diff --git a/src-ui/src/app/pipes/file-size.pipe.spec.ts b/src-ui/src/app/pipes/file-size.pipe.spec.ts
new file mode 100644
index 000000000..8c7a39d22
--- /dev/null
+++ b/src-ui/src/app/pipes/file-size.pipe.spec.ts
@@ -0,0 +1,8 @@
+import { FileSizePipe } from './file-size.pipe';
+
+describe('FileSizePipe', () => {
+ it('create an instance', () => {
+ const pipe = new FileSizePipe();
+ expect(pipe).toBeTruthy();
+ });
+});
diff --git a/src-ui/src/app/pipes/file-size.pipe.ts b/src-ui/src/app/pipes/file-size.pipe.ts
new file mode 100644
index 000000000..7d742c876
--- /dev/null
+++ b/src-ui/src/app/pipes/file-size.pipe.ts
@@ -0,0 +1,77 @@
+/**
+ * https://gist.github.com/JonCatmull/ecdf9441aaa37336d9ae2c7f9cb7289a
+ *
+ * @license
+ * Copyright (c) 2019 Jonathan Catmull.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+import { Pipe, PipeTransform } from '@angular/core';
+
+type unit = 'bytes' | 'KB' | 'MB' | 'GB' | 'TB' | 'PB';
+type unitPrecisionMap = {
+ [u in unit]: number;
+};
+
+const defaultPrecisionMap: unitPrecisionMap = {
+ bytes: 0,
+ KB: 0,
+ MB: 1,
+ GB: 1,
+ TB: 2,
+ PB: 2
+};
+
+/*
+ * Convert bytes into largest possible unit.
+ * Takes an precision argument that can be a number or a map for each unit.
+ * Usage:
+ * bytes | fileSize:precision
+ * @example
+ * // returns 1 KB
+ * {{ 1500 | fileSize }}
+ * @example
+ * // returns 2.1 GB
+ * {{ 2100000000 | fileSize }}
+ * @example
+ * // returns 1.46 KB
+ * {{ 1500 | fileSize:2 }}
+ */
+@Pipe({ name: 'fileSize' })
+export class FileSizePipe implements PipeTransform {
+ private readonly units: unit[] = ['bytes', 'KB', 'MB', 'GB', 'TB', 'PB'];
+
+ transform(bytes: number = 0, precision: number | unitPrecisionMap = defaultPrecisionMap): string {
+ if (isNaN(parseFloat(String(bytes))) || !isFinite(bytes)) return '?';
+
+ let unitIndex = 0;
+
+ while (bytes >= 1024) {
+ bytes /= 1024;
+ unitIndex++;
+ }
+
+ const unit = this.units[unitIndex];
+
+ if (typeof precision === 'number') {
+ return `${bytes.toFixed(+precision)} ${unit}`;
+ }
+ return `${bytes.toFixed(precision[unit])} ${unit}`;
+ }
+}
diff --git a/src/documents/tests/test_api.py b/src/documents/tests/test_api.py
index c2f9c950c..572667406 100644
--- a/src/documents/tests/test_api.py
+++ b/src/documents/tests/test_api.py
@@ -496,7 +496,7 @@ class TestDocumentApi(DirectoriesMixin, APITestCase):
async_task.assert_not_called()
def test_get_metadata(self):
- doc = Document.objects.create(title="test", filename="file.pdf", mime_type="image/png")
+ doc = Document.objects.create(title="test", filename="file.pdf", mime_type="image/png", archive_checksum="A")
shutil.copy(os.path.join(os.path.dirname(__file__), "samples", "documents", "thumbnails", "0000001.png"), doc.source_path)
shutil.copy(os.path.join(os.path.dirname(__file__), "samples", "simple.pdf"), doc.archive_path)
diff --git a/src/documents/views.py b/src/documents/views.py
index e058b0f56..8dbb61dc7 100755
--- a/src/documents/views.py
+++ b/src/documents/views.py
@@ -196,17 +196,28 @@ class DocumentViewSet(RetrieveModelMixin,
def metadata(self, request, pk=None):
try:
doc = Document.objects.get(pk=pk)
- return Response({
+
+ meta = {
"original_checksum": doc.checksum,
- "archived_checksum": doc.archive_checksum,
+ "original_size": os.stat(doc.source_path).st_size,
"original_mime_type": doc.mime_type,
"media_filename": doc.filename,
"has_archive_version": os.path.isfile(doc.archive_path),
"original_metadata": self.get_metadata(
- doc.source_path, doc.mime_type),
- "archive_metadata": self.get_metadata(
+ doc.source_path, doc.mime_type)
+ }
+
+ if doc.archive_checksum and os.path.isfile(doc.archive_path):
+ meta['archive_checksum'] = doc.archive_checksum
+ meta['archive_size'] = os.stat(doc.archive_path).st_size,
+ meta['archive_metadata'] = self.get_metadata(
doc.archive_path, "application/pdf")
- })
+ else:
+ meta['archive_checksum'] = None
+ meta['archive_size'] = None
+ meta['archive_metadata'] = None
+
+ return Response(meta)
except Document.DoesNotExist:
raise Http404()