From 88e9dcbc1b94f0afbff0edfc1f2f08f2cd4c8d95 Mon Sep 17 00:00:00 2001 From: Michael Shamoon <4887959+nikonratm@users.noreply.github.com> Date: Sun, 27 Dec 2020 23:05:19 -0800 Subject: [PATCH 001/197] Dark mode settings logic --- src-ui/src/app/app.component.ts | 6 ++-- .../manage/settings/settings.component.html | 27 ++++++++++++----- .../manage/settings/settings.component.ts | 27 ++++++++++++++--- src-ui/src/app/data/storage-keys.ts | 8 +++-- .../src/app/services/app-view.service.spec.ts | 16 ++++++++++ src-ui/src/app/services/app-view.service.ts | 29 +++++++++++++++++++ 6 files changed, 98 insertions(+), 15 deletions(-) create mode 100644 src-ui/src/app/services/app-view.service.spec.ts create mode 100644 src-ui/src/app/services/app-view.service.ts diff --git a/src-ui/src/app/app.component.ts b/src-ui/src/app/app.component.ts index 84c173a18..9cd9fb3ec 100644 --- a/src-ui/src/app/app.component.ts +++ b/src-ui/src/app/app.component.ts @@ -1,4 +1,5 @@ import { Component } from '@angular/core'; +import { AppViewService } from './services/app-view.service'; @Component({ selector: 'app-root', @@ -6,8 +7,9 @@ import { Component } from '@angular/core'; styleUrls: ['./app.component.scss'] }) export class AppComponent { - - constructor () { + + constructor (appViewService: AppViewService) { + appViewService.updateDarkModeSettings() } diff --git a/src-ui/src/app/components/manage/settings/settings.component.html b/src-ui/src/app/components/manage/settings/settings.component.html index 6c16cfaa8..9b999c0dc 100644 --- a/src-ui/src/app/components/manage/settings/settings.component.html +++ b/src-ui/src/app/components/manage/settings/settings.component.html @@ -10,21 +10,34 @@ General settings -

Document list

- +

Appearance

+
Items per page
- + - + +
+
+ +
+
+ Dark mode +
+
+ +
+ + +
@@ -35,7 +48,7 @@
- +
@@ -61,7 +74,7 @@
No saved views defined.
- +
@@ -71,4 +84,4 @@
- \ No newline at end of file + diff --git a/src-ui/src/app/components/manage/settings/settings.component.ts b/src-ui/src/app/components/manage/settings/settings.component.ts index bec85e039..acb456f1c 100644 --- a/src-ui/src/app/components/manage/settings/settings.component.ts +++ b/src-ui/src/app/components/manage/settings/settings.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, Renderer2 } from '@angular/core'; import { FormControl, FormGroup } from '@angular/forms'; import { PaperlessSavedView } from 'src/app/data/paperless-saved-view'; import { GENERAL_SETTINGS } from 'src/app/data/storage-keys'; import { DocumentListViewService } from 'src/app/services/document-list-view.service'; import { SavedViewService } from 'src/app/services/rest/saved-view.service'; import { Toast, ToastService } from 'src/app/services/toast.service'; +import { AppViewService } from 'src/app/services/app-view.service'; @Component({ selector: 'app-settings', @@ -17,17 +18,24 @@ export class SettingsComponent implements OnInit { settingsForm = new FormGroup({ 'documentListItemPerPage': new FormControl(+localStorage.getItem(GENERAL_SETTINGS.DOCUMENT_LIST_SIZE) || GENERAL_SETTINGS.DOCUMENT_LIST_SIZE_DEFAULT), + 'darkModeUseSystem': new FormControl( + localStorage.getItem(GENERAL_SETTINGS.DARK_MODE_USE_SYSTEM) == undefined ? GENERAL_SETTINGS.DARK_MODE_USE_SYSTEM_DEFAULT : JSON.parse(localStorage.getItem(GENERAL_SETTINGS.DARK_MODE_USE_SYSTEM)) + ), + 'darkModeEnabled': new FormControl( + localStorage.getItem(GENERAL_SETTINGS.DARK_MODE_ENABLED) == undefined ? GENERAL_SETTINGS.DARK_MODE_ENABLED_DEFAULT : JSON.parse(localStorage.getItem(GENERAL_SETTINGS.DARK_MODE_ENABLED)) + ), 'savedViews': this.savedViewGroup }) + savedViews: PaperlessSavedView[] + constructor( public savedViewService: SavedViewService, private documentListViewService: DocumentListViewService, - private toastService: ToastService + private toastService: ToastService, + private appViewService: AppViewService ) { } - savedViews: PaperlessSavedView[] - ngOnInit() { this.savedViewService.listAll().subscribe(r => { this.savedViews = r.results @@ -50,9 +58,20 @@ export class SettingsComponent implements OnInit { }) } + toggleDarkModeSetting() { + if (this.settingsForm.value.darkModeUseSystem) { + (this.settingsForm.controls.darkModeEnabled as FormControl).disable() + } else { + (this.settingsForm.controls.darkModeEnabled as FormControl).enable() + } + } + private saveLocalSettings() { localStorage.setItem(GENERAL_SETTINGS.DOCUMENT_LIST_SIZE, this.settingsForm.value.documentListItemPerPage) + localStorage.setItem(GENERAL_SETTINGS.DARK_MODE_USE_SYSTEM, this.settingsForm.value.darkModeUseSystem) + localStorage.setItem(GENERAL_SETTINGS.DARK_MODE_ENABLED, (this.settingsForm.value.darkModeEnabled == true).toString()) this.documentListViewService.updatePageSize() + this.appViewService.updateDarkModeSettings() this.toastService.showToast(Toast.make("Information", $localize`Settings saved successfully.`)) } diff --git a/src-ui/src/app/data/storage-keys.ts b/src-ui/src/app/data/storage-keys.ts index 13b41d4a7..057d68d70 100644 --- a/src-ui/src/app/data/storage-keys.ts +++ b/src-ui/src/app/data/storage-keys.ts @@ -8,5 +8,9 @@ export const DOCUMENT_LIST_SERVICE = { export const GENERAL_SETTINGS = { DOCUMENT_LIST_SIZE: 'general-settings:documentListSize', - DOCUMENT_LIST_SIZE_DEFAULT: 50 -} \ No newline at end of file + DOCUMENT_LIST_SIZE_DEFAULT: 50, + DARK_MODE_USE_SYSTEM: 'general-settings:darkModeUseSystem', + DARK_MODE_USE_SYSTEM_DEFAULT: true, + DARK_MODE_ENABLED: 'general-settings:darkModeEnabled', + DARK_MODE_ENABLED_DEFAULT: false +} diff --git a/src-ui/src/app/services/app-view.service.spec.ts b/src-ui/src/app/services/app-view.service.spec.ts new file mode 100644 index 000000000..fc44ed3a4 --- /dev/null +++ b/src-ui/src/app/services/app-view.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { AppViewService } from './app-view.service'; + +describe('AppViewService', () => { + let service: AppViewService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(AppViewService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src-ui/src/app/services/app-view.service.ts b/src-ui/src/app/services/app-view.service.ts new file mode 100644 index 000000000..c6faa5603 --- /dev/null +++ b/src-ui/src/app/services/app-view.service.ts @@ -0,0 +1,29 @@ +import { Inject, Injectable, Renderer2, RendererFactory2 } from '@angular/core'; +import { DOCUMENT } from '@angular/common'; +import { GENERAL_SETTINGS } from 'src/app/data/storage-keys'; + +@Injectable({ + providedIn: 'root' +}) +export class AppViewService { + private renderer: Renderer2; + + constructor(rendererFactory: RendererFactory2, @Inject(DOCUMENT) private document) { + this.renderer = rendererFactory.createRenderer(null, null); + } + + updateDarkModeSettings() { + let darkModeUseSystem = JSON.parse(localStorage.getItem(GENERAL_SETTINGS.DARK_MODE_USE_SYSTEM)) && GENERAL_SETTINGS.DARK_MODE_USE_SYSTEM_DEFAULT + let darkModeEnabled = JSON.parse(localStorage.getItem(GENERAL_SETTINGS.DARK_MODE_ENABLED)) || GENERAL_SETTINGS.DARK_MODE_ENABLED_DEFAULT + + if (darkModeUseSystem) { + this.renderer.addClass(this.document.body, 'dark-mode-preferred') + this.renderer.removeClass(this.document.body, 'dark-mode') + } else { + this.renderer.removeClass(this.document.body, 'dark-mode-preferred') + darkModeEnabled ? this.renderer.addClass(this.document.body, 'dark-mode') : this.renderer.removeClass(this.document.body, 'dark-mode') + } + + } + +} From c2249da1a809cf06d1d276eca11f7e51121ffbb2 Mon Sep 17 00:00:00 2001 From: Michael Shamoon <4887959+nikonratm@users.noreply.github.com> Date: Sun, 27 Dec 2020 23:05:34 -0800 Subject: [PATCH 002/197] Logo svg inline --- .../app-frame/app-frame.component.html | 4 +- src-ui/src/assets/logo-dark-notext.svg | 86 ++++--------------- src-ui/src/assets/logo-white-notext.svg | 69 +++++++++++++++ 3 files changed, 90 insertions(+), 69 deletions(-) create mode 100644 src-ui/src/assets/logo-white-notext.svg diff --git a/src-ui/src/app/components/app-frame/app-frame.component.html b/src-ui/src/app/components/app-frame/app-frame.component.html index d191ec0de..6fd2a579e 100644 --- a/src-ui/src/app/components/app-frame/app-frame.component.html +++ b/src-ui/src/app/components/app-frame/app-frame.component.html @@ -1,6 +1,8 @@
diff --git a/src-ui/src/app/components/manage/tag-list/tag-list.component.html b/src-ui/src/app/components/manage/tag-list/tag-list.component.html index bbe2c6dd2..83bf211a6 100644 --- a/src-ui/src/app/components/manage/tag-list/tag-list.component.html +++ b/src-ui/src/app/components/manage/tag-list/tag-list.component.html @@ -1,7 +1,5 @@ - - + +
diff --git a/src-ui/src/app/components/search/search.component.html b/src-ui/src/app/components/search/search.component.html index 7047a3144..547c8a475 100644 --- a/src-ui/src/app/components/search/search.component.html +++ b/src-ui/src/app/components/search/search.component.html @@ -1,4 +1,4 @@ - +
Invalid search query: {{errorMessage}}
From 7da1215edc9bdf6d9ffc2507f0c5bdee82445fe6 Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Tue, 29 Dec 2020 23:37:33 +0100 Subject: [PATCH 035/197] more localization #123 --- .../common/date-dropdown/date-dropdown.component.ts | 8 ++++---- .../filterable-dropdown/filterable-dropdown.component.ts | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src-ui/src/app/components/common/date-dropdown/date-dropdown.component.ts b/src-ui/src/app/components/common/date-dropdown/date-dropdown.component.ts index 1bf5d0216..27472bdc7 100644 --- a/src-ui/src/app/components/common/date-dropdown/date-dropdown.component.ts +++ b/src-ui/src/app/components/common/date-dropdown/date-dropdown.component.ts @@ -21,10 +21,10 @@ const LAST_YEAR = 3 export class DateDropdownComponent implements OnInit, OnDestroy { quickFilters = [ - {id: LAST_7_DAYS, name: "Last 7 days"}, - {id: LAST_MONTH, name: "Last month"}, - {id: LAST_3_MONTHS, name: "Last 3 months"}, - {id: LAST_YEAR, name: "Last year"} + {id: LAST_7_DAYS, name: $localize`Last 7 days`}, + {id: LAST_MONTH, name: $localize`Last month`}, + {id: LAST_3_MONTHS, name: $localize`Last 3 months`}, + {id: LAST_YEAR, name: $localize`Last year`} ] @Input() diff --git a/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts b/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts index 0e075ff19..915d10677 100644 --- a/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts +++ b/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts @@ -142,7 +142,7 @@ export class FilterableDropdownComponent { if (items) { this._selectionModel.items = Array.from(items) this._selectionModel.items.unshift({ - name: "None", + name: $localize`Not assigned`, id: null }) } From ae7cbd8bbfd133e16ce5093ca577cef1b2564f4a Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Tue, 29 Dec 2020 23:41:59 +0100 Subject: [PATCH 036/197] more localization tags --- .../document-detail.component.html | 2 +- .../manage/tag-list/tag-list.component.html | 19 ++++++++----------- 2 files changed, 9 insertions(+), 12 deletions(-) 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 daf01249f..eae3367c1 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 @@ -132,7 +132,7 @@
  -   +    
diff --git a/src-ui/src/app/components/manage/tag-list/tag-list.component.html b/src-ui/src/app/components/manage/tag-list/tag-list.component.html index 83bf211a6..43126f7b2 100644 --- a/src-ui/src/app/components/manage/tag-list/tag-list.component.html +++ b/src-ui/src/app/components/manage/tag-list/tag-list.component.html @@ -10,11 +10,11 @@ - - - - - + + + + + @@ -29,21 +29,18 @@ From 0119c247f65a97caa1745cf21953a9037feaaa79 Mon Sep 17 00:00:00 2001 From: Fabian Koller Date: Tue, 29 Dec 2020 23:52:27 +0100 Subject: [PATCH 037/197] Fix ENV var name for user args in example config The actual string used when looking up the user arguments ends with an S: `PAPERLESS_OCR_USER_ARGS` --- paperless.conf.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paperless.conf.example b/paperless.conf.example index 910fc22a0..cc4cc0eb7 100644 --- a/paperless.conf.example +++ b/paperless.conf.example @@ -39,7 +39,7 @@ #PAPERLESS_OCR_OUTPUT_TYPE=pdfa #PAPERLESS_OCR_PAGES=1 #PAPERLESS_OCR_IMAGE_DPI=300 -#PAPERLESS_OCR_USER_ARG={} +#PAPERLESS_OCR_USER_ARGS={} #PAPERLESS_CONVERT_MEMORY_LIMIT=0 #PAPERLESS_CONVERT_TMPDIR=/var/tmp/paperless From 634b63628d29a65c2cc66cbc09500e425b189053 Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Wed, 30 Dec 2020 00:24:42 +0100 Subject: [PATCH 038/197] angular message file --- src-ui/messages.xlf | 1562 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1562 insertions(+) create mode 100644 src-ui/messages.xlf diff --git a/src-ui/messages.xlf b/src-ui/messages.xlf new file mode 100644 index 000000000..6270f5373 --- /dev/null +++ b/src-ui/messages.xlf @@ -0,0 +1,1562 @@ + + + + + + Documents + + src/app/components/document-list/document-list.component.ts + 38 + + + + View "" saved successfully. + + src/app/components/document-list/document-list.component.ts + 84 + + + + View "" created successfully. + + src/app/components/document-list/document-list.component.ts + 103 + + + + Select + + src/app/components/document-list/document-list.component.html + 7 + + + + Select none + + src/app/components/document-list/document-list.component.html + 11 + + + + Select page + + src/app/components/document-list/document-list.component.html + 12 + + + + Select all + + src/app/components/document-list/document-list.component.html + 13 + + + + Sort by + + src/app/components/document-list/document-list.component.html + 41 + + + + Views + + src/app/components/document-list/document-list.component.html + 64 + + + + Save as... + + src/app/components/document-list/document-list.component.html + 72 + + + + Save "" + + src/app/components/document-list/document-list.component.html + 71 + + + + {VAR_PLURAL, plural, =1 {document} other {documents}} + + src/app/components/document-list/document-list.component.html + 86 + + + + Selected of + + src/app/components/document-list/document-list.component.html + 86 + + + + {VAR_PLURAL, plural, =1 {1 document} other { documents}} + + src/app/components/document-list/document-list.component.html + 87 + + + + ASN + + src/app/components/document-list/document-list.component.html + 100 + + + + Correspondent + + src/app/components/document-list/document-list.component.html + 101 + + + + Title + + src/app/components/document-list/document-list.component.html + 102 + + + + Document type + + src/app/components/document-list/document-list.component.html + 103 + + + + Created + + src/app/components/document-list/document-list.component.html + 104 + + + + Added + + src/app/components/document-list/document-list.component.html + 105 + + + + Confirm delete + + src/app/components/document-detail/document-detail.component.ts + 161 + + + + Do you really want to delete document ''? + + src/app/components/document-detail/document-detail.component.ts + 162 + + + + The files for this document will be deleted permanently. This operation cannot be undone. + + src/app/components/document-detail/document-detail.component.ts + 163 + + + + Delete document + + src/app/components/document-detail/document-detail.component.ts + 165 + + + + Delete + + src/app/components/document-detail/document-detail.component.html + 15 + + + + Download + + src/app/components/document-detail/document-detail.component.html + 23 + + + + More like this + + src/app/components/document-detail/document-detail.component.html + 38 + + + + Close + + src/app/components/document-detail/document-detail.component.html + 44 + + + + Details + + src/app/components/document-detail/document-detail.component.html + 56 + + + + Content + + src/app/components/document-detail/document-detail.component.html + 76 + + + + Metadata + + src/app/components/document-detail/document-detail.component.html + 85 + + + + Discard + + src/app/components/document-detail/document-detail.component.html + 134 + + + + Save + + src/app/components/document-detail/document-detail.component.html + 136 + + + + Page + + src/app/components/document-detail/document-detail.component.html + 4 + + + + of + + src/app/components/document-detail/document-detail.component.html + 8 + + + + Download original + + src/app/components/document-detail/document-detail.component.html + 29 + + + + Archive serial number + + src/app/components/document-detail/document-detail.component.html + 61 + + + + Date created + + src/app/components/document-detail/document-detail.component.html + 65 + + + + Tags + + src/app/components/document-detail/document-detail.component.html + 70 + + + + Date modified + + src/app/components/document-detail/document-detail.component.html + 91 + + + + Date added + + src/app/components/document-detail/document-detail.component.html + 95 + + + + Media filename + + src/app/components/document-detail/document-detail.component.html + 99 + + + + Original MD5 checksum + + src/app/components/document-detail/document-detail.component.html + 103 + + + + Original file size + + src/app/components/document-detail/document-detail.component.html + 107 + + + + Original mime type + + src/app/components/document-detail/document-detail.component.html + 111 + + + + Archive MD5 checksum + + src/app/components/document-detail/document-detail.component.html + 115 + + + + Archive file size + + src/app/components/document-detail/document-detail.component.html + 119 + + + + Original document metadata + + src/app/components/document-detail/document-detail.component.html + 125 + + + + Archived document metadata + + src/app/components/document-detail/document-detail.component.html + 126 + + + + Save & next + + src/app/components/document-detail/document-detail.component.html + 135 + + + + Hello , welcome to Paperless-ng! + + src/app/components/dashboard/dashboard.component.ts + 33 + + + + Welcome to Paperless-ng! + + src/app/components/dashboard/dashboard.component.ts + 35 + + + + Dashboard + + src/app/components/dashboard/dashboard.component.html + 1 + + + + Do you really want to delete the tag ? + + src/app/components/manage/tag-list/tag-list.component.ts + 30 + + + + Create + + src/app/components/manage/tag-list/tag-list.component.html + 2 + + + + Name + + src/app/components/manage/tag-list/tag-list.component.html + 13 + + + + Color + + src/app/components/manage/tag-list/tag-list.component.html + 14 + + + + Matching + + src/app/components/manage/tag-list/tag-list.component.html + 15 + + + + Document count + + src/app/components/manage/tag-list/tag-list.component.html + 16 + + + + Actions + + src/app/components/manage/tag-list/tag-list.component.html + 17 + + + + Documents + + src/app/components/manage/tag-list/tag-list.component.html + 32 + + + + Edit + + src/app/components/manage/tag-list/tag-list.component.html + 37 + + + + Do you really want to delete the document type ? + + src/app/components/manage/document-type-list/document-type-list.component.ts + 26 + + + + Document types + + src/app/components/manage/document-type-list/document-type-list.component.html + 1 + + + + Logs + + src/app/components/manage/logs/logs.component.html + 1 + + + + Filter + + src/app/components/manage/logs/logs.component.html + 7 + + + + Saved view " deleted. + + src/app/components/manage/settings/settings.component.ts + 52 + + + + Settings saved successfully. + + src/app/components/manage/settings/settings.component.ts + 61 + + + + Error while storing settings on server: + + src/app/components/manage/settings/settings.component.ts + 73 + + + + General settings + + src/app/components/manage/settings/settings.component.html + 10 + + + + Saved views + + src/app/components/manage/settings/settings.component.html + 41 + + + + Document list + + src/app/components/manage/settings/settings.component.html + 13 + + + + Items per page + + src/app/components/manage/settings/settings.component.html + 17 + + + + Bulk editing + + src/app/components/manage/settings/settings.component.html + 33 + + + + Show confirmation dialogs + + src/app/components/manage/settings/settings.component.html + 35 + + + + Deleting documents will always ask for confirmation. + + src/app/components/manage/settings/settings.component.html + 35 + + + + Apply on close + + src/app/components/manage/settings/settings.component.html + 36 + + + + Appears on + + src/app/components/manage/settings/settings.component.html + 53 + + + + Show on dashboard + + src/app/components/manage/settings/settings.component.html + 56 + + + + Show in sidebar + + src/app/components/manage/settings/settings.component.html + 60 + + + + No saved views defined. + + src/app/components/manage/settings/settings.component.html + 70 + + + + 404 Not Found + + src/app/components/not-found/not-found.component.html + 7 + + + + Do you really want to delete the correspondent ? + + src/app/components/manage/correspondent-list/correspondent-list.component.ts + 26 + + + + Correspondents + + src/app/components/manage/correspondent-list/correspondent-list.component.html + 1 + + + + Last correspondence + + src/app/components/manage/correspondent-list/correspondent-list.component.html + 15 + + + + Confirmation + + src/app/components/common/confirm-dialog/confirm-dialog.component.ts + 17 + + + + Confirm + + src/app/components/common/confirm-dialog/confirm-dialog.component.ts + 29 + + + + Create new correspondent + + src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.ts + 21 + + + + Edit correspondent + + src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.ts + 25 + + + + Could not save correspondent: + + src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.ts + 29 + + + + Matching algorithm + + src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.html + 11 + + + + Match + + src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.html + 12 + + + + Auto matching does not require you to fill in this field. + + src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.html + 12 + + + + Case insensitive + + src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.html + 13 + + + + Auto matching ignores this option. + + src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.html + 13 + + + + Cancel + + src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.html + 16 + + + + Create new tag + + src/app/components/manage/tag-list/tag-edit-dialog/tag-edit-dialog.component.ts + 21 + + + + Edit tag + + src/app/components/manage/tag-list/tag-edit-dialog/tag-edit-dialog.component.ts + 25 + + + + Could not save tag: + + src/app/components/manage/tag-list/tag-edit-dialog/tag-edit-dialog.component.ts + 29 + + + + Inbox tag + + src/app/components/manage/tag-list/tag-edit-dialog/tag-edit-dialog.component.html + 21 + + + + Inbox tags are automatically assigned to all consumed documents. + + src/app/components/manage/tag-list/tag-edit-dialog/tag-edit-dialog.component.html + 21 + + + + Create new document type + + src/app/components/manage/document-type-list/document-type-edit-dialog/document-type-edit-dialog.component.ts + 21 + + + + Edit document type + + src/app/components/manage/document-type-list/document-type-edit-dialog/document-type-edit-dialog.component.ts + 25 + + + + Could not save document type: + + src/app/components/manage/document-type-list/document-type-edit-dialog/document-type-edit-dialog.component.ts + 29 + + + + Search results + + src/app/components/search/search.component.html + 1 + + + + Invalid search query: + + src/app/components/search/search.component.html + 4 + + + + Showing documents similar to + + src/app/components/search/search.component.html + 7 + + + + Search query: + + src/app/components/search/search.component.html + 11 + + + + Did you mean ""? + + src/app/components/search/search.component.html + 13 + + + + {VAR_PLURAL, plural, =0 {No results} =1 {One result} other { results}} + + src/app/components/search/search.component.html + 18 + + + + Paperless-ng + + src/app/components/app-frame/app-frame.component.html + 4 + + app title + + + Search for documents + + src/app/components/app-frame/app-frame.component.html + 12 + + + + Manage + + src/app/components/app-frame/app-frame.component.html + 77 + + + + Settings + + src/app/components/app-frame/app-frame.component.html + 112 + + + + Admin + + src/app/components/app-frame/app-frame.component.html + 119 + + + + Misc + + src/app/components/app-frame/app-frame.component.html + 125 + + + + Documentation + + src/app/components/app-frame/app-frame.component.html + 132 + + + + GitHub + + src/app/components/app-frame/app-frame.component.html + 139 + + + + Logout + + src/app/components/app-frame/app-frame.component.html + 146 + + + + Open documents + + src/app/components/app-frame/app-frame.component.html + 57 + + + + Close all + + src/app/components/app-frame/app-frame.component.html + 71 + + + + Correspondent: + + src/app/components/document-list/filter-editor/filter-editor.component.ts + 28 + + + + Type: + + src/app/components/document-list/filter-editor/filter-editor.component.ts + 31 + + + + Tag: + + src/app/components/document-list/filter-editor/filter-editor.component.ts + 34 + + + + Filter by: + + src/app/components/document-list/filter-editor/filter-editor.component.html + 4 + + + + Clear all filters + + src/app/components/document-list/filter-editor/filter-editor.component.html + 23 + + + + Not assigned + + src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts + 145 + + + + Apply + + src/app/components/common/filterable-dropdown/filterable-dropdown.component.html + 28 + + + + Last 7 days + + src/app/components/common/date-dropdown/date-dropdown.component.ts + 24 + + + + Last month + + src/app/components/common/date-dropdown/date-dropdown.component.ts + 25 + + + + Last 3 months + + src/app/components/common/date-dropdown/date-dropdown.component.ts + 26 + + + + Last year + + src/app/components/common/date-dropdown/date-dropdown.component.ts + 27 + + + + After + + src/app/components/common/date-dropdown/date-dropdown.component.html + 13 + + + + Before + + src/app/components/common/date-dropdown/date-dropdown.component.html + 29 + + + + Clear + + src/app/components/common/date-dropdown/date-dropdown.component.html + 18 + + + + View + + src/app/components/document-list/document-card-large/document-card-large.component.html + 50 + + + + Score: + + src/app/components/document-list/document-card-large/document-card-large.component.html + 61 + + + + Created: + + src/app/components/document-list/document-card-large/document-card-large.component.html + 65 + + + + Filter by correspondent + + src/app/components/document-list/document-card-large/document-card-large.component.html + 20 + + + + Filter by tag + + src/app/components/document-list/document-card-large/document-card-large.component.html + 24 + + + + View in browser + + src/app/components/document-list/document-card-small/document-card-small.component.html + 40 + + + + and + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 103 + + + + , + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 105 + + + + Confirm tags assignment + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 115 + + + + This operation will add the tag to all selected document(s). + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 118 + + + + This operation will add the tags to all selected document(s). + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 120 + + + + This operation will remove the tag from all selected document(s). + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 123 + + + + This operation will remove the tags from all selected document(s). + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 125 + + + + This operation will add the tags and remove the tags on all selected document(s). + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 127 + + + + Confirm correspondent assignment + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 157 + + + + This operation will assign the correspondent to all selected document(s). + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 159 + + + + This operation will remove the correspondent from all selected document(s). + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 161 + + + + Confirm document type assignment + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 190 + + + + This operation will assign the document type to all selected document(s). + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 192 + + + + This operation will remove the document type from all selected document(s). + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 194 + + + + Delete confirm + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 219 + + + + This operation will permanently delete all selected document(s). + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 220 + + + + This operation cannot be undone. + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 221 + + + + Delete document(s) + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 223 + + + + Select: + + src/app/components/document-list/bulk-editor/bulk-editor.component.html + 11 + + + + All + + src/app/components/document-list/bulk-editor/bulk-editor.component.html + 21 + + + + Edit: + + src/app/components/document-list/bulk-editor/bulk-editor.component.html + 28 + + + + Save current view + + src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.html + 3 + + + + Show all + + src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html + 3 + + + + Statistics + + src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html + 1 + + + + Documents in inbox: + + src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html + 3 + + + + Total documents: + + src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html + 4 + + + + The document has been uploaded and will be processed by the consumer shortly. + + src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.ts + 63 + + + + There was an error while uploading the document: + + src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.ts + 71 + + + + An error has occurred while uploading the document. Sorry! + + src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.ts + 75 + + + + Upload new documents + + src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html + 1 + + + + Drop documents here or + + src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html + 5 + + + + Browse files + + src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html + 5 + + + + Uploading file(s) + + src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html + 13 + + + + First steps + + src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html + 1 + + + + Paperless is running! :) + + src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html + 5 + + + + You can start uploading documents by dropping them in the file upload box to the right or by dropping them in the configured consumption folder and they'll start showing up in the documents list. After you've added some metadata to your documents, use the filtering mechanisms of paperless to create custom views (such as 'Recently added', 'Tagged TODO') and have them displayed on the dashboard instead of this message. + + src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html + 6,7 + + + + Paperless offers some more features that try to make your life easier, such as: + + src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html + 8 + + + + Once you've got a couple documents in paperless and added metadata to them, paperless can assign that metadata to new documents automatically. + + src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html + 10 + + + + You can configure paperless to read your mails and add documents from attached files. + + src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html + 11 + + + + Consult the documentation on how to use these features. The section on basic usage also has some information on how to use paperless in general. + + src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html + 13 + + + + Metadata + + src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts + 18 + + + + Select + + src/app/components/common/select-dialog/select-dialog.component.ts + 18 + + + + Please select an object + + src/app/components/common/select-dialog/select-dialog.component.ts + 21 + + + + Yes + + src/app/pipes/yes-no.pipe.ts + 9 + + + + No + + src/app/pipes/yes-no.pipe.ts + 9 + + + + (no title) + + src/app/pipes/document-title.pipe.ts + 12 + + + + Error + + src/app/services/toast.service.ts + 31 + + + + Information + + src/app/services/toast.service.ts + 35 + + + + Correspondent + + src/app/services/rest/document.service.ts + 16 + + + + Document type + + src/app/services/rest/document.service.ts + 17 + + + + Title + + src/app/services/rest/document.service.ts + 18 + + + + ASN + + src/app/services/rest/document.service.ts + 19 + + + + Created + + src/app/services/rest/document.service.ts + 20 + + + + Added + + src/app/services/rest/document.service.ts + 21 + + + + Modified + + src/app/services/rest/document.service.ts + 22 + + + + Light blue + + src/app/data/paperless-tag.ts + 6 + + + + Blue + + src/app/data/paperless-tag.ts + 7 + + + + Light green + + src/app/data/paperless-tag.ts + 8 + + + + Green + + src/app/data/paperless-tag.ts + 9 + + + + Light red + + src/app/data/paperless-tag.ts + 10 + + + + Red + + src/app/data/paperless-tag.ts + 11 + + + + Light orange + + src/app/data/paperless-tag.ts + 12 + + + + Orange + + src/app/data/paperless-tag.ts + 13 + + + + Light violet + + src/app/data/paperless-tag.ts + 14 + + + + Violet + + src/app/data/paperless-tag.ts + 15 + + + + Brown + + src/app/data/paperless-tag.ts + 16 + + + + Black + + src/app/data/paperless-tag.ts + 17 + + + + Light grey + + src/app/data/paperless-tag.ts + 18 + + + + Create new item + + src/app/components/common/edit-dialog/edit-dialog.component.ts + 38 + + + + Edit item + + src/app/components/common/edit-dialog/edit-dialog.component.ts + 42 + + + + Could not save element: + + src/app/components/common/edit-dialog/edit-dialog.component.ts + 46 + + + + Automatic + + src/app/components/manage/generic-list/generic-list.component.ts + 31 + + + + Do you really want to delete this element? + + src/app/components/manage/generic-list/generic-list.component.ts + 88 + + + + Associated documents will not be deleted. + + src/app/components/manage/generic-list/generic-list.component.ts + 95 + + + + Delete + + src/app/components/manage/generic-list/generic-list.component.ts + 97 + + + + Any + + src/app/data/matching-model.ts + 12 + + + + All + + src/app/data/matching-model.ts + 13 + + + + Literal + + src/app/data/matching-model.ts + 14 + + + + Regular expression + + src/app/data/matching-model.ts + 15 + + + + Fuzzy match + + src/app/data/matching-model.ts + 16 + + + + Auto + + src/app/data/matching-model.ts + 17 + + + + + From 05d4ca06fe9282d6cdcbe6a4afbdb8825f995bef Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Wed, 30 Dec 2020 00:26:06 +0100 Subject: [PATCH 039/197] add initial localization support for the front end #215 --- src-ui/angular.json | 7 +++++++ src/documents/templates/index.html | 8 ++++---- src/documents/views.py | 5 +++++ src/paperless/settings.py | 8 ++++++++ src/paperless/urls.py | 3 ++- 5 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src-ui/angular.json b/src-ui/angular.json index 79233eeda..514b351fc 100644 --- a/src-ui/angular.json +++ b/src-ui/angular.json @@ -13,6 +13,12 @@ "root": "", "sourceRoot": "src", "prefix": "app", + "i18n": { + "sourceLocale": "en-US", + "locales": { + "de": "src/locale/messages.de-DE.xlf" + } + }, "architect": { "build": { "builder": "@angular-devkit/build-angular:browser", @@ -23,6 +29,7 @@ "main": "src/main.ts", "polyfills": "src/polyfills.ts", "tsConfig": "tsconfig.app.json", + "localize": true, "aot": true, "assets": [ "src/favicon.ico", diff --git a/src/documents/templates/index.html b/src/documents/templates/index.html index 47a352cd5..c95e4b15f 100644 --- a/src/documents/templates/index.html +++ b/src/documents/templates/index.html @@ -12,11 +12,11 @@ - + Loading... - - - + + + diff --git a/src/documents/views.py b/src/documents/views.py index 32b88a18f..7dc3ae3e6 100755 --- a/src/documents/views.py +++ b/src/documents/views.py @@ -7,6 +7,7 @@ from django.conf import settings from django.db.models import Count, Max, Case, When, IntegerField from django.db.models.functions import Lower from django.http import HttpResponse, HttpResponseBadRequest, Http404 +from django.utils.translation import get_language from django.views.decorators.cache import cache_control from django.views.generic import TemplateView from django_filters.rest_framework import DjangoFilterBackend @@ -61,6 +62,10 @@ class IndexView(TemplateView): context['cookie_prefix'] = settings.COOKIE_PREFIX context['username'] = self.request.user.username context['full_name'] = self.request.user.get_full_name() + context['styles_css'] = f"frontend/{get_language()}/styles.css" + context['runtime_js'] = f"frontend/{get_language()}/runtime.js" + context['polyfills_js'] = f"frontend/{get_language()}/polyfills.js" + context['main_js'] = f"frontend/{get_language()}/main.js" return context diff --git a/src/paperless/settings.py b/src/paperless/settings.py index 5af1be85e..b59968dea 100644 --- a/src/paperless/settings.py +++ b/src/paperless/settings.py @@ -6,6 +6,8 @@ import re from dotenv import load_dotenv +from django.utils.translation import gettext_lazy as _ + # Tap paperless.conf if it's available if os.path.exists("../paperless.conf"): load_dotenv("../paperless.conf") @@ -117,6 +119,7 @@ MIDDLEWARE = [ 'whitenoise.middleware.WhiteNoiseMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'corsheaders.middleware.CorsMiddleware', + 'django.middleware.locale.LocaleMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', @@ -246,6 +249,11 @@ if os.getenv("PAPERLESS_DBHOST"): LANGUAGE_CODE = 'en-us' +LANGUAGES = [ + ("en-us", _("English")), + ("de", _("German")) +] + TIME_ZONE = os.getenv("PAPERLESS_TIME_ZONE", "UTC") USE_I18N = True diff --git a/src/paperless/urls.py b/src/paperless/urls.py index 39e99a7a4..e44762aee 100755 --- a/src/paperless/urls.py +++ b/src/paperless/urls.py @@ -88,7 +88,8 @@ urlpatterns = [ # Frontend assets TODO: this is pretty bad, but it works. path('assets/', - RedirectView.as_view(url='/static/frontend/assets/%(path)s')), + RedirectView.as_view(url='/static/frontend/en-us/assets/%(path)s')), + # TODO: with localization, this is even worse! :/ # login, logout path('accounts/', include('django.contrib.auth.urls')), From 29730a9c13c303a6c0bc772d6b1fd4cf06bb6e92 Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Wed, 30 Dec 2020 01:39:06 +0100 Subject: [PATCH 040/197] add translation support to the backend #215 --- src/locale/de/LC_MESSAGES/django.po | 27 +++++++++++++++++++++++++++ src/paperless/settings.py | 4 ++++ 2 files changed, 31 insertions(+) create mode 100644 src/locale/de/LC_MESSAGES/django.po diff --git a/src/locale/de/LC_MESSAGES/django.po b/src/locale/de/LC_MESSAGES/django.po new file mode 100644 index 000000000..bbab220a7 --- /dev/null +++ b/src/locale/de/LC_MESSAGES/django.po @@ -0,0 +1,27 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-12-30 00:37+0000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: paperless/settings.py:253 +msgid "English" +msgstr "" + +#: paperless/settings.py:254 +msgid "German" +msgstr "" diff --git a/src/paperless/settings.py b/src/paperless/settings.py index b59968dea..783da188a 100644 --- a/src/paperless/settings.py +++ b/src/paperless/settings.py @@ -254,6 +254,10 @@ LANGUAGES = [ ("de", _("German")) ] +LOCALE_PATHS = [ + os.path.join(BASE_DIR, "locale") +] + TIME_ZONE = os.getenv("PAPERLESS_TIME_ZONE", "UTC") USE_I18N = True From edc07ec65f0f0a48a2135642c77de03f96b291b0 Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Wed, 30 Dec 2020 00:24:42 +0100 Subject: [PATCH 041/197] angular message file --- src-ui/messages.xlf | 1562 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1562 insertions(+) create mode 100644 src-ui/messages.xlf diff --git a/src-ui/messages.xlf b/src-ui/messages.xlf new file mode 100644 index 000000000..6270f5373 --- /dev/null +++ b/src-ui/messages.xlf @@ -0,0 +1,1562 @@ + + + + + + Documents + + src/app/components/document-list/document-list.component.ts + 38 + + + + View "" saved successfully. + + src/app/components/document-list/document-list.component.ts + 84 + + + + View "" created successfully. + + src/app/components/document-list/document-list.component.ts + 103 + + + + Select + + src/app/components/document-list/document-list.component.html + 7 + + + + Select none + + src/app/components/document-list/document-list.component.html + 11 + + + + Select page + + src/app/components/document-list/document-list.component.html + 12 + + + + Select all + + src/app/components/document-list/document-list.component.html + 13 + + + + Sort by + + src/app/components/document-list/document-list.component.html + 41 + + + + Views + + src/app/components/document-list/document-list.component.html + 64 + + + + Save as... + + src/app/components/document-list/document-list.component.html + 72 + + + + Save "" + + src/app/components/document-list/document-list.component.html + 71 + + + + {VAR_PLURAL, plural, =1 {document} other {documents}} + + src/app/components/document-list/document-list.component.html + 86 + + + + Selected of + + src/app/components/document-list/document-list.component.html + 86 + + + + {VAR_PLURAL, plural, =1 {1 document} other { documents}} + + src/app/components/document-list/document-list.component.html + 87 + + + + ASN + + src/app/components/document-list/document-list.component.html + 100 + + + + Correspondent + + src/app/components/document-list/document-list.component.html + 101 + + + + Title + + src/app/components/document-list/document-list.component.html + 102 + + + + Document type + + src/app/components/document-list/document-list.component.html + 103 + + + + Created + + src/app/components/document-list/document-list.component.html + 104 + + + + Added + + src/app/components/document-list/document-list.component.html + 105 + + + + Confirm delete + + src/app/components/document-detail/document-detail.component.ts + 161 + + + + Do you really want to delete document ''? + + src/app/components/document-detail/document-detail.component.ts + 162 + + + + The files for this document will be deleted permanently. This operation cannot be undone. + + src/app/components/document-detail/document-detail.component.ts + 163 + + + + Delete document + + src/app/components/document-detail/document-detail.component.ts + 165 + + + + Delete + + src/app/components/document-detail/document-detail.component.html + 15 + + + + Download + + src/app/components/document-detail/document-detail.component.html + 23 + + + + More like this + + src/app/components/document-detail/document-detail.component.html + 38 + + + + Close + + src/app/components/document-detail/document-detail.component.html + 44 + + + + Details + + src/app/components/document-detail/document-detail.component.html + 56 + + + + Content + + src/app/components/document-detail/document-detail.component.html + 76 + + + + Metadata + + src/app/components/document-detail/document-detail.component.html + 85 + + + + Discard + + src/app/components/document-detail/document-detail.component.html + 134 + + + + Save + + src/app/components/document-detail/document-detail.component.html + 136 + + + + Page + + src/app/components/document-detail/document-detail.component.html + 4 + + + + of + + src/app/components/document-detail/document-detail.component.html + 8 + + + + Download original + + src/app/components/document-detail/document-detail.component.html + 29 + + + + Archive serial number + + src/app/components/document-detail/document-detail.component.html + 61 + + + + Date created + + src/app/components/document-detail/document-detail.component.html + 65 + + + + Tags + + src/app/components/document-detail/document-detail.component.html + 70 + + + + Date modified + + src/app/components/document-detail/document-detail.component.html + 91 + + + + Date added + + src/app/components/document-detail/document-detail.component.html + 95 + + + + Media filename + + src/app/components/document-detail/document-detail.component.html + 99 + + + + Original MD5 checksum + + src/app/components/document-detail/document-detail.component.html + 103 + + + + Original file size + + src/app/components/document-detail/document-detail.component.html + 107 + + + + Original mime type + + src/app/components/document-detail/document-detail.component.html + 111 + + + + Archive MD5 checksum + + src/app/components/document-detail/document-detail.component.html + 115 + + + + Archive file size + + src/app/components/document-detail/document-detail.component.html + 119 + + + + Original document metadata + + src/app/components/document-detail/document-detail.component.html + 125 + + + + Archived document metadata + + src/app/components/document-detail/document-detail.component.html + 126 + + + + Save & next + + src/app/components/document-detail/document-detail.component.html + 135 + + + + Hello , welcome to Paperless-ng! + + src/app/components/dashboard/dashboard.component.ts + 33 + + + + Welcome to Paperless-ng! + + src/app/components/dashboard/dashboard.component.ts + 35 + + + + Dashboard + + src/app/components/dashboard/dashboard.component.html + 1 + + + + Do you really want to delete the tag ? + + src/app/components/manage/tag-list/tag-list.component.ts + 30 + + + + Create + + src/app/components/manage/tag-list/tag-list.component.html + 2 + + + + Name + + src/app/components/manage/tag-list/tag-list.component.html + 13 + + + + Color + + src/app/components/manage/tag-list/tag-list.component.html + 14 + + + + Matching + + src/app/components/manage/tag-list/tag-list.component.html + 15 + + + + Document count + + src/app/components/manage/tag-list/tag-list.component.html + 16 + + + + Actions + + src/app/components/manage/tag-list/tag-list.component.html + 17 + + + + Documents + + src/app/components/manage/tag-list/tag-list.component.html + 32 + + + + Edit + + src/app/components/manage/tag-list/tag-list.component.html + 37 + + + + Do you really want to delete the document type ? + + src/app/components/manage/document-type-list/document-type-list.component.ts + 26 + + + + Document types + + src/app/components/manage/document-type-list/document-type-list.component.html + 1 + + + + Logs + + src/app/components/manage/logs/logs.component.html + 1 + + + + Filter + + src/app/components/manage/logs/logs.component.html + 7 + + + + Saved view " deleted. + + src/app/components/manage/settings/settings.component.ts + 52 + + + + Settings saved successfully. + + src/app/components/manage/settings/settings.component.ts + 61 + + + + Error while storing settings on server: + + src/app/components/manage/settings/settings.component.ts + 73 + + + + General settings + + src/app/components/manage/settings/settings.component.html + 10 + + + + Saved views + + src/app/components/manage/settings/settings.component.html + 41 + + + + Document list + + src/app/components/manage/settings/settings.component.html + 13 + + + + Items per page + + src/app/components/manage/settings/settings.component.html + 17 + + + + Bulk editing + + src/app/components/manage/settings/settings.component.html + 33 + + + + Show confirmation dialogs + + src/app/components/manage/settings/settings.component.html + 35 + + + + Deleting documents will always ask for confirmation. + + src/app/components/manage/settings/settings.component.html + 35 + + + + Apply on close + + src/app/components/manage/settings/settings.component.html + 36 + + + + Appears on + + src/app/components/manage/settings/settings.component.html + 53 + + + + Show on dashboard + + src/app/components/manage/settings/settings.component.html + 56 + + + + Show in sidebar + + src/app/components/manage/settings/settings.component.html + 60 + + + + No saved views defined. + + src/app/components/manage/settings/settings.component.html + 70 + + + + 404 Not Found + + src/app/components/not-found/not-found.component.html + 7 + + + + Do you really want to delete the correspondent ? + + src/app/components/manage/correspondent-list/correspondent-list.component.ts + 26 + + + + Correspondents + + src/app/components/manage/correspondent-list/correspondent-list.component.html + 1 + + + + Last correspondence + + src/app/components/manage/correspondent-list/correspondent-list.component.html + 15 + + + + Confirmation + + src/app/components/common/confirm-dialog/confirm-dialog.component.ts + 17 + + + + Confirm + + src/app/components/common/confirm-dialog/confirm-dialog.component.ts + 29 + + + + Create new correspondent + + src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.ts + 21 + + + + Edit correspondent + + src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.ts + 25 + + + + Could not save correspondent: + + src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.ts + 29 + + + + Matching algorithm + + src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.html + 11 + + + + Match + + src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.html + 12 + + + + Auto matching does not require you to fill in this field. + + src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.html + 12 + + + + Case insensitive + + src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.html + 13 + + + + Auto matching ignores this option. + + src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.html + 13 + + + + Cancel + + src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.html + 16 + + + + Create new tag + + src/app/components/manage/tag-list/tag-edit-dialog/tag-edit-dialog.component.ts + 21 + + + + Edit tag + + src/app/components/manage/tag-list/tag-edit-dialog/tag-edit-dialog.component.ts + 25 + + + + Could not save tag: + + src/app/components/manage/tag-list/tag-edit-dialog/tag-edit-dialog.component.ts + 29 + + + + Inbox tag + + src/app/components/manage/tag-list/tag-edit-dialog/tag-edit-dialog.component.html + 21 + + + + Inbox tags are automatically assigned to all consumed documents. + + src/app/components/manage/tag-list/tag-edit-dialog/tag-edit-dialog.component.html + 21 + + + + Create new document type + + src/app/components/manage/document-type-list/document-type-edit-dialog/document-type-edit-dialog.component.ts + 21 + + + + Edit document type + + src/app/components/manage/document-type-list/document-type-edit-dialog/document-type-edit-dialog.component.ts + 25 + + + + Could not save document type: + + src/app/components/manage/document-type-list/document-type-edit-dialog/document-type-edit-dialog.component.ts + 29 + + + + Search results + + src/app/components/search/search.component.html + 1 + + + + Invalid search query: + + src/app/components/search/search.component.html + 4 + + + + Showing documents similar to + + src/app/components/search/search.component.html + 7 + + + + Search query: + + src/app/components/search/search.component.html + 11 + + + + Did you mean ""? + + src/app/components/search/search.component.html + 13 + + + + {VAR_PLURAL, plural, =0 {No results} =1 {One result} other { results}} + + src/app/components/search/search.component.html + 18 + + + + Paperless-ng + + src/app/components/app-frame/app-frame.component.html + 4 + + app title + + + Search for documents + + src/app/components/app-frame/app-frame.component.html + 12 + + + + Manage + + src/app/components/app-frame/app-frame.component.html + 77 + + + + Settings + + src/app/components/app-frame/app-frame.component.html + 112 + + + + Admin + + src/app/components/app-frame/app-frame.component.html + 119 + + + + Misc + + src/app/components/app-frame/app-frame.component.html + 125 + + + + Documentation + + src/app/components/app-frame/app-frame.component.html + 132 + + + + GitHub + + src/app/components/app-frame/app-frame.component.html + 139 + + + + Logout + + src/app/components/app-frame/app-frame.component.html + 146 + + + + Open documents + + src/app/components/app-frame/app-frame.component.html + 57 + + + + Close all + + src/app/components/app-frame/app-frame.component.html + 71 + + + + Correspondent: + + src/app/components/document-list/filter-editor/filter-editor.component.ts + 28 + + + + Type: + + src/app/components/document-list/filter-editor/filter-editor.component.ts + 31 + + + + Tag: + + src/app/components/document-list/filter-editor/filter-editor.component.ts + 34 + + + + Filter by: + + src/app/components/document-list/filter-editor/filter-editor.component.html + 4 + + + + Clear all filters + + src/app/components/document-list/filter-editor/filter-editor.component.html + 23 + + + + Not assigned + + src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts + 145 + + + + Apply + + src/app/components/common/filterable-dropdown/filterable-dropdown.component.html + 28 + + + + Last 7 days + + src/app/components/common/date-dropdown/date-dropdown.component.ts + 24 + + + + Last month + + src/app/components/common/date-dropdown/date-dropdown.component.ts + 25 + + + + Last 3 months + + src/app/components/common/date-dropdown/date-dropdown.component.ts + 26 + + + + Last year + + src/app/components/common/date-dropdown/date-dropdown.component.ts + 27 + + + + After + + src/app/components/common/date-dropdown/date-dropdown.component.html + 13 + + + + Before + + src/app/components/common/date-dropdown/date-dropdown.component.html + 29 + + + + Clear + + src/app/components/common/date-dropdown/date-dropdown.component.html + 18 + + + + View + + src/app/components/document-list/document-card-large/document-card-large.component.html + 50 + + + + Score: + + src/app/components/document-list/document-card-large/document-card-large.component.html + 61 + + + + Created: + + src/app/components/document-list/document-card-large/document-card-large.component.html + 65 + + + + Filter by correspondent + + src/app/components/document-list/document-card-large/document-card-large.component.html + 20 + + + + Filter by tag + + src/app/components/document-list/document-card-large/document-card-large.component.html + 24 + + + + View in browser + + src/app/components/document-list/document-card-small/document-card-small.component.html + 40 + + + + and + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 103 + + + + , + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 105 + + + + Confirm tags assignment + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 115 + + + + This operation will add the tag to all selected document(s). + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 118 + + + + This operation will add the tags to all selected document(s). + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 120 + + + + This operation will remove the tag from all selected document(s). + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 123 + + + + This operation will remove the tags from all selected document(s). + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 125 + + + + This operation will add the tags and remove the tags on all selected document(s). + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 127 + + + + Confirm correspondent assignment + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 157 + + + + This operation will assign the correspondent to all selected document(s). + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 159 + + + + This operation will remove the correspondent from all selected document(s). + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 161 + + + + Confirm document type assignment + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 190 + + + + This operation will assign the document type to all selected document(s). + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 192 + + + + This operation will remove the document type from all selected document(s). + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 194 + + + + Delete confirm + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 219 + + + + This operation will permanently delete all selected document(s). + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 220 + + + + This operation cannot be undone. + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 221 + + + + Delete document(s) + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 223 + + + + Select: + + src/app/components/document-list/bulk-editor/bulk-editor.component.html + 11 + + + + All + + src/app/components/document-list/bulk-editor/bulk-editor.component.html + 21 + + + + Edit: + + src/app/components/document-list/bulk-editor/bulk-editor.component.html + 28 + + + + Save current view + + src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.html + 3 + + + + Show all + + src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html + 3 + + + + Statistics + + src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html + 1 + + + + Documents in inbox: + + src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html + 3 + + + + Total documents: + + src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html + 4 + + + + The document has been uploaded and will be processed by the consumer shortly. + + src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.ts + 63 + + + + There was an error while uploading the document: + + src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.ts + 71 + + + + An error has occurred while uploading the document. Sorry! + + src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.ts + 75 + + + + Upload new documents + + src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html + 1 + + + + Drop documents here or + + src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html + 5 + + + + Browse files + + src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html + 5 + + + + Uploading file(s) + + src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html + 13 + + + + First steps + + src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html + 1 + + + + Paperless is running! :) + + src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html + 5 + + + + You can start uploading documents by dropping them in the file upload box to the right or by dropping them in the configured consumption folder and they'll start showing up in the documents list. After you've added some metadata to your documents, use the filtering mechanisms of paperless to create custom views (such as 'Recently added', 'Tagged TODO') and have them displayed on the dashboard instead of this message. + + src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html + 6,7 + + + + Paperless offers some more features that try to make your life easier, such as: + + src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html + 8 + + + + Once you've got a couple documents in paperless and added metadata to them, paperless can assign that metadata to new documents automatically. + + src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html + 10 + + + + You can configure paperless to read your mails and add documents from attached files. + + src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html + 11 + + + + Consult the documentation on how to use these features. The section on basic usage also has some information on how to use paperless in general. + + src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html + 13 + + + + Metadata + + src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts + 18 + + + + Select + + src/app/components/common/select-dialog/select-dialog.component.ts + 18 + + + + Please select an object + + src/app/components/common/select-dialog/select-dialog.component.ts + 21 + + + + Yes + + src/app/pipes/yes-no.pipe.ts + 9 + + + + No + + src/app/pipes/yes-no.pipe.ts + 9 + + + + (no title) + + src/app/pipes/document-title.pipe.ts + 12 + + + + Error + + src/app/services/toast.service.ts + 31 + + + + Information + + src/app/services/toast.service.ts + 35 + + + + Correspondent + + src/app/services/rest/document.service.ts + 16 + + + + Document type + + src/app/services/rest/document.service.ts + 17 + + + + Title + + src/app/services/rest/document.service.ts + 18 + + + + ASN + + src/app/services/rest/document.service.ts + 19 + + + + Created + + src/app/services/rest/document.service.ts + 20 + + + + Added + + src/app/services/rest/document.service.ts + 21 + + + + Modified + + src/app/services/rest/document.service.ts + 22 + + + + Light blue + + src/app/data/paperless-tag.ts + 6 + + + + Blue + + src/app/data/paperless-tag.ts + 7 + + + + Light green + + src/app/data/paperless-tag.ts + 8 + + + + Green + + src/app/data/paperless-tag.ts + 9 + + + + Light red + + src/app/data/paperless-tag.ts + 10 + + + + Red + + src/app/data/paperless-tag.ts + 11 + + + + Light orange + + src/app/data/paperless-tag.ts + 12 + + + + Orange + + src/app/data/paperless-tag.ts + 13 + + + + Light violet + + src/app/data/paperless-tag.ts + 14 + + + + Violet + + src/app/data/paperless-tag.ts + 15 + + + + Brown + + src/app/data/paperless-tag.ts + 16 + + + + Black + + src/app/data/paperless-tag.ts + 17 + + + + Light grey + + src/app/data/paperless-tag.ts + 18 + + + + Create new item + + src/app/components/common/edit-dialog/edit-dialog.component.ts + 38 + + + + Edit item + + src/app/components/common/edit-dialog/edit-dialog.component.ts + 42 + + + + Could not save element: + + src/app/components/common/edit-dialog/edit-dialog.component.ts + 46 + + + + Automatic + + src/app/components/manage/generic-list/generic-list.component.ts + 31 + + + + Do you really want to delete this element? + + src/app/components/manage/generic-list/generic-list.component.ts + 88 + + + + Associated documents will not be deleted. + + src/app/components/manage/generic-list/generic-list.component.ts + 95 + + + + Delete + + src/app/components/manage/generic-list/generic-list.component.ts + 97 + + + + Any + + src/app/data/matching-model.ts + 12 + + + + All + + src/app/data/matching-model.ts + 13 + + + + Literal + + src/app/data/matching-model.ts + 14 + + + + Regular expression + + src/app/data/matching-model.ts + 15 + + + + Fuzzy match + + src/app/data/matching-model.ts + 16 + + + + Auto + + src/app/data/matching-model.ts + 17 + + + + + From 39988fd5b5efc98239f54e3b1325570820b729e5 Mon Sep 17 00:00:00 2001 From: Michael Shamoon <4887959+nikonratm@users.noreply.github.com> Date: Tue, 29 Dec 2020 16:53:42 -0800 Subject: [PATCH 042/197] Compatability with new settings service --- src-ui/src/app/services/app-view.service.ts | 14 +++++++++----- src-ui/src/app/services/settings.service.ts | 6 +++++- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src-ui/src/app/services/app-view.service.ts b/src-ui/src/app/services/app-view.service.ts index b44c8965f..6af2e43af 100644 --- a/src-ui/src/app/services/app-view.service.ts +++ b/src-ui/src/app/services/app-view.service.ts @@ -1,6 +1,6 @@ import { Inject, Injectable, Renderer2, RendererFactory2 } from '@angular/core'; import { DOCUMENT } from '@angular/common'; -import { GENERAL_SETTINGS } from 'src/app/data/storage-keys'; +import { SettingsService, SETTINGS_KEYS } from './settings.service'; @Injectable({ providedIn: 'root' @@ -8,22 +8,26 @@ import { GENERAL_SETTINGS } from 'src/app/data/storage-keys'; export class AppViewService { private renderer: Renderer2; - constructor(rendererFactory: RendererFactory2, @Inject(DOCUMENT) private document) { + constructor( + private settings: SettingsService, + private rendererFactory: RendererFactory2, + @Inject(DOCUMENT) private document + ) { this.renderer = rendererFactory.createRenderer(null, null); this.updateDarkModeSettings() } updateDarkModeSettings() { - let darkModeUseSystem = JSON.parse(localStorage.getItem(GENERAL_SETTINGS.DARK_MODE_USE_SYSTEM)) && GENERAL_SETTINGS.DARK_MODE_USE_SYSTEM_DEFAULT - let darkModeEnabled = JSON.parse(localStorage.getItem(GENERAL_SETTINGS.DARK_MODE_ENABLED)) || GENERAL_SETTINGS.DARK_MODE_ENABLED_DEFAULT + let darkModeUseSystem = this.settings.get(SETTINGS_KEYS.DARK_MODE_USE_SYSTEM) + let darkModeEnabled = this.settings.get(SETTINGS_KEYS.DARK_MODE_ENABLED) if (darkModeUseSystem) { this.renderer.addClass(this.document.body, 'color-scheme-system') this.renderer.removeClass(this.document.body, 'color-scheme-dark') } else { this.renderer.removeClass(this.document.body, 'color-scheme-system') - darkModeEnabled ? this.renderer.addClass(this.document.body, 'color-scheme-dark') : this.renderer.removeClass(this.document.body, 'dark-mode') + darkModeEnabled ? this.renderer.addClass(this.document.body, 'color-scheme-dark') : this.renderer.removeClass(this.document.body, 'color-scheme-dark') } } diff --git a/src-ui/src/app/services/settings.service.ts b/src-ui/src/app/services/settings.service.ts index 00e6ff639..7b1cfe9e3 100644 --- a/src-ui/src/app/services/settings.service.ts +++ b/src-ui/src/app/services/settings.service.ts @@ -10,12 +10,16 @@ export const SETTINGS_KEYS = { BULK_EDIT_CONFIRMATION_DIALOGS: 'general-settings:bulk-edit:confirmation-dialogs', BULK_EDIT_APPLY_ON_CLOSE: 'general-settings:bulk-edit:apply-on-close', DOCUMENT_LIST_SIZE: 'general-settings:documentListSize', + DARK_MODE_USE_SYSTEM: 'general-settings:dark-mode:use-system', + DARK_MODE_ENABLED: 'general-settings:dark-mode:enabled' } const SETTINGS: PaperlessSettings[] = [ {key: SETTINGS_KEYS.BULK_EDIT_CONFIRMATION_DIALOGS, type: "boolean", default: true}, {key: SETTINGS_KEYS.BULK_EDIT_APPLY_ON_CLOSE, type: "boolean", default: false}, - {key: SETTINGS_KEYS.DOCUMENT_LIST_SIZE, type: "number", default: 50} + {key: SETTINGS_KEYS.DOCUMENT_LIST_SIZE, type: "number", default: 50}, + {key: SETTINGS_KEYS.DARK_MODE_USE_SYSTEM, type: "boolean", default: true}, + {key: SETTINGS_KEYS.DARK_MODE_ENABLED, type: "boolean", default: false} ] @Injectable({ From e1f1d05bc8649989b380cd613c2beb2123607c70 Mon Sep 17 00:00:00 2001 From: Michael Shamoon <4887959+nikonratm@users.noreply.github.com> Date: Tue, 29 Dec 2020 16:58:19 -0800 Subject: [PATCH 043/197] Consistent settings screen --- .../manage/settings/settings.component.html | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src-ui/src/app/components/manage/settings/settings.component.html b/src-ui/src/app/components/manage/settings/settings.component.html index d15c7fe2b..93c7c98b4 100644 --- a/src-ui/src/app/components/manage/settings/settings.component.html +++ b/src-ui/src/app/components/manage/settings/settings.component.html @@ -39,14 +39,16 @@ - - -

Bulk editing

+

Bulk editing

- - +
+
+ + +
+
From 9a265791b6cd129dddb69b2bddeef8a143b09a78 Mon Sep 17 00:00:00 2001 From: Jonas Winkler Date: Wed, 30 Dec 2020 03:39:25 +0100 Subject: [PATCH 044/197] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index eea41ce05..5c5fa4a76 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Build Status](https://travis-ci.org/jonaswinkler/paperless-ng.svg?branch=master)](https://travis-ci.org/jonaswinkler/paperless-ng) +[![Build Status](https://travis-ci.com/jonaswinkler/paperless-ng.svg?branch=master)](https://travis-ci.com/jonaswinkler/paperless-ng) [![Documentation Status](https://readthedocs.org/projects/paperless-ng/badge/?version=latest)](https://paperless-ng.readthedocs.io/en/latest/?badge=latest) [![Gitter](https://badges.gitter.im/paperless-ng/community.svg)](https://gitter.im/paperless-ng/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Docker Hub Pulls](https://img.shields.io/docker/pulls/jonaswinkler/paperless-ng.svg)](https://hub.docker.com/r/jonaswinkler/paperless-ng) From c7cb47413343e8725eefb1defe2cf2ca63b15a9b Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Wed, 30 Dec 2020 11:33:56 +0100 Subject: [PATCH 045/197] more translation work --- src-ui/messages.xlf | 94 ++++++++++++++----- .../filterable-dropdown.component.html | 2 +- .../filterable-dropdown.component.ts | 5 +- .../upload-file-widget.component.html | 2 +- .../welcome-widget.component.html | 4 +- .../bulk-editor/bulk-editor.component.html | 9 +- .../bulk-editor/bulk-editor.component.ts | 14 +-- .../filter-editor.component.html | 38 ++++++-- .../correspondent-list.component.ts | 2 +- .../document-type-list.component.ts | 2 +- .../manage/tag-list/tag-list.component.ts | 3 +- 11 files changed, 126 insertions(+), 49 deletions(-) diff --git a/src-ui/messages.xlf b/src-ui/messages.xlf index 6270f5373..18eeec0ef 100644 --- a/src-ui/messages.xlf +++ b/src-ui/messages.xlf @@ -373,11 +373,11 @@ 1 - - Do you really want to delete the tag ? + + Do you really want to delete the tag ""? src/app/components/manage/tag-list/tag-list.component.ts - 30 + 31 @@ -436,8 +436,8 @@ 37 - - Do you really want to delete the document type ? + + Do you really want to delete the document type ""? src/app/components/manage/document-type-list/document-type-list.component.ts 26 @@ -576,8 +576,8 @@ 7 - - Do you really want to delete the correspondent ? + + Do you really want to delete the correspondent ""? src/app/components/manage/correspondent-list/correspondent-list.component.ts 26 @@ -878,11 +878,32 @@ 4 + + Filter tags + + src/app/components/document-list/filter-editor/filter-editor.component.html + 12 + + + + Filter correspondents + + src/app/components/document-list/filter-editor/filter-editor.component.html + 19 + + + + Filter document types + + src/app/components/document-list/filter-editor/filter-editor.component.html + 25 + + Clear all filters src/app/components/document-list/filter-editor/filter-editor.component.html - 23 + 47 @@ -891,6 +912,7 @@ src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts 145 + Filter drop down element to filter for documents with no correspondent/type/tag assigned Apply @@ -990,12 +1012,20 @@ 40 - - and + + "" and "" src/app/components/document-list/bulk-editor/bulk-editor.component.ts 103 + This is for messages like 'modify "tag1" and "tag2"' + + + "" + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 105 + , @@ -1003,6 +1033,15 @@ src/app/components/document-list/bulk-editor/bulk-editor.component.ts 105 + this is used to separate enumerations and should probably be a comma and a whitespace in most languages + + + and "" + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 106 + + this is for messages like 'modify "tag1", "tag2" and "tag3"' Confirm tags assignment @@ -1011,8 +1050,8 @@ 115 - - This operation will add the tag to all selected document(s). + + This operation will add the tag "" to all selected document(s). src/app/components/document-list/bulk-editor/bulk-editor.component.ts 118 @@ -1025,8 +1064,8 @@ 120 - - This operation will remove the tag from all selected document(s). + + This operation will remove the tag "" from all selected document(s). src/app/components/document-list/bulk-editor/bulk-editor.component.ts 123 @@ -1053,8 +1092,8 @@ 157 - - This operation will assign the correspondent to all selected document(s). + + This operation will assign the correspondent "" to all selected document(s). src/app/components/document-list/bulk-editor/bulk-editor.component.ts 159 @@ -1074,8 +1113,8 @@ 190 - - This operation will assign the document type to all selected document(s). + + This operation will assign the document type "" to all selected document(s). src/app/components/document-list/bulk-editor/bulk-editor.component.ts 192 @@ -1214,8 +1253,15 @@ 5 - - Uploading file(s) + + {VAR_PLURAL, plural, =1 {file} =other { files}} + + src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html + 13 + + + + Uploading ... src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html 13 @@ -1235,15 +1281,15 @@ 5 - - You can start uploading documents by dropping them in the file upload box to the right or by dropping them in the configured consumption folder and they'll start showing up in the documents list. After you've added some metadata to your documents, use the filtering mechanisms of paperless to create custom views (such as 'Recently added', 'Tagged TODO') and have them displayed on the dashboard instead of this message. + + You can start uploading documents by dropping them in the file upload box to the right or by dropping them in the configured consumption folder and they'll start showing up in the documents list. After you've added some metadata to your documents, use the filtering mechanisms of paperless to create custom views (such as 'Recently added', 'Tagged TODO') and have they will be shown on the dashboard instead of this message. src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html 6,7 - - Paperless offers some more features that try to make your life easier, such as: + + Paperless offers some more features that try to make your life easier: src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html 8 diff --git a/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.html b/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.html index 7215faa79..015269c17 100644 --- a/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.html +++ b/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -16,7 +16,7 @@
- +
diff --git a/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts b/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts index 915d10677..e1aa6a06a 100644 --- a/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts +++ b/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts @@ -142,7 +142,7 @@ export class FilterableDropdownComponent { if (items) { this._selectionModel.items = Array.from(items) this._selectionModel.items.unshift({ - name: $localize`Not assigned`, + name: $localize`:Filter drop down element to filter for documents with no correspondent/type/tag assigned:Not assigned`, id: null }) } @@ -186,6 +186,9 @@ export class FilterableDropdownComponent { @Input() title: string + @Input() + filterPlaceholder: string = "" + @Input() icon: string diff --git a/src-ui/src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html b/src-ui/src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html index 91fff4e83..38aff96ab 100644 --- a/src-ui/src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html +++ b/src-ui/src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html @@ -10,7 +10,7 @@
-

Uploading {{uploadStatus.length}} file(s)

+

Uploading {uploadStatus.length, plural, =1 {file} =other {{{uploadStatus.length}} files}}...

diff --git a/src-ui/src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html b/src-ui/src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html index 6c9c34d5b..7a2bbcb3c 100644 --- a/src-ui/src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html +++ b/src-ui/src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html @@ -4,8 +4,8 @@

Paperless is running! :)

You can start uploading documents by dropping them in the file upload box to the right or by dropping them in the configured consumption folder and they'll start showing up in the documents list. - After you've added some metadata to your documents, use the filtering mechanisms of paperless to create custom views (such as 'Recently added', 'Tagged TODO') and have them displayed on the dashboard instead of this message.

-

Paperless offers some more features that try to make your life easier, such as:

+ After you've added some metadata to your documents, use the filtering mechanisms of paperless to create custom views (such as 'Recently added', 'Tagged TODO') and have they will be shown on the dashboard instead of this message.

+

Paperless offers some more features that try to make your life easier:

  • Once you've got a couple documents in paperless and added metadata to them, paperless can assign that metadata to new documents automatically.
  • You can configure paperless to read your mails and add documents from attached files.
  • diff --git a/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.html b/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.html index 62a2bb95d..b9912ec1d 100644 --- a/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.html +++ b/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -26,7 +26,8 @@
    - - - i.name).join($localize`, `) - return $localize`${list} and ${items[items.length - 1].name}` + let list = items.slice(0, items.length - 1).map(i => $localize`"${i.name}"`).join($localize`:this is used to separate enumerations and should probably be a comma and a whitespace in most languages:, `) + return $localize`:this is for messages like 'modify "tag1", "tag2" and "tag3"':${list} and "${items[items.length - 1].name}"` } } @@ -115,12 +115,12 @@ export class BulkEditorComponent { modal.componentInstance.title = $localize`Confirm tags assignment` if (changedTags.itemsToAdd.length == 1 && changedTags.itemsToRemove.length == 0) { let tag = changedTags.itemsToAdd[0] - modal.componentInstance.message = $localize`This operation will add the tag ${tag.name} to all ${this.list.selected.size} selected document(s).` + modal.componentInstance.message = $localize`This operation will add the tag "${tag.name}" to all ${this.list.selected.size} selected document(s).` } else if (changedTags.itemsToAdd.length > 1 && changedTags.itemsToRemove.length == 0) { modal.componentInstance.message = $localize`This operation will add the tags ${this._localizeList(changedTags.itemsToAdd)} to all ${this.list.selected.size} selected document(s).` } else if (changedTags.itemsToAdd.length == 0 && changedTags.itemsToRemove.length == 1) { let tag = changedTags.itemsToRemove[0] - modal.componentInstance.message = $localize`This operation will remove the tag ${tag.name} from all ${this.list.selected.size} selected document(s).` + modal.componentInstance.message = $localize`This operation will remove the tag "${tag.name}" from all ${this.list.selected.size} selected document(s).` } else if (changedTags.itemsToAdd.length == 0 && changedTags.itemsToRemove.length > 1) { modal.componentInstance.message = $localize`This operation will remove the tags ${this._localizeList(changedTags.itemsToRemove)} from all ${this.list.selected.size} selected document(s).` } else { @@ -156,7 +156,7 @@ export class BulkEditorComponent { let modal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'}) modal.componentInstance.title = $localize`Confirm correspondent assignment` if (correspondent) { - modal.componentInstance.message = $localize`This operation will assign the correspondent ${correspondent.name} to all ${this.list.selected.size} selected document(s).` + modal.componentInstance.message = $localize`This operation will assign the correspondent "${correspondent.name}" to all ${this.list.selected.size} selected document(s).` } else { modal.componentInstance.message = $localize`This operation will remove the correspondent from all ${this.list.selected.size} selected document(s).` } @@ -189,7 +189,7 @@ export class BulkEditorComponent { let modal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'}) modal.componentInstance.title = $localize`Confirm document type assignment` if (documentType) { - modal.componentInstance.message = $localize`This operation will assign the document type ${documentType.name} to all ${this.list.selected.size} selected document(s).` + modal.componentInstance.message = $localize`This operation will assign the document type "${documentType.name}" to all ${this.list.selected.size} selected document(s).` } else { modal.componentInstance.message = $localize`This operation will remove the document type from all ${this.list.selected.size} selected document(s).` } diff --git a/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.html b/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.html index f0c83ae73..efbf6ce7e 100644 --- a/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.html +++ b/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.html @@ -6,13 +6,37 @@
    -
    -
    - - - - - +
    +
    + + + + +
    diff --git a/src-ui/src/app/components/manage/correspondent-list/correspondent-list.component.ts b/src-ui/src/app/components/manage/correspondent-list/correspondent-list.component.ts index bc3bf7b02..d3b71b4ab 100644 --- a/src-ui/src/app/components/manage/correspondent-list/correspondent-list.component.ts +++ b/src-ui/src/app/components/manage/correspondent-list/correspondent-list.component.ts @@ -23,7 +23,7 @@ export class CorrespondentListComponent extends GenericListComponent { } getDeleteMessage(object: PaperlessTag) { - return $localize`Do you really want to delete the tag ${object.name}?` + + return $localize`Do you really want to delete the tag "${object.name}"?` } filterDocuments(object: PaperlessTag) { From 730d42b145fd60680a034810bcab56335ec8c2bb Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Wed, 30 Dec 2020 12:21:13 +0100 Subject: [PATCH 046/197] bugfix --- src-ui/src/app/services/open-documents.service.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src-ui/src/app/services/open-documents.service.ts b/src-ui/src/app/services/open-documents.service.ts index c91031f83..9e5746c10 100644 --- a/src-ui/src/app/services/open-documents.service.ts +++ b/src-ui/src/app/services/open-documents.service.ts @@ -28,6 +28,9 @@ export class OpenDocumentsService { if (index > -1) { this.documentService.get(id).subscribe(doc => { this.openDocuments[index] = doc + }, error => { + this.openDocuments.splice(index, 1) + this.save() }) } } From b850bad03d8b8bb5180da5924c9363b34eeef4b2 Mon Sep 17 00:00:00 2001 From: Jan Wiebe Date: Wed, 30 Dec 2020 14:45:15 +0100 Subject: [PATCH 047/197] Add manifest file to add to home screen and launch in full screen mode. --- src-ui/angular.json | 264 ++++++++++++++++---------------- src-ui/src/index.html | 2 + src-ui/src/manifest.webmanifest | 14 ++ 3 files changed, 149 insertions(+), 131 deletions(-) create mode 100644 src-ui/src/manifest.webmanifest diff --git a/src-ui/angular.json b/src-ui/angular.json index 79233eeda..04a1bec50 100644 --- a/src-ui/angular.json +++ b/src-ui/angular.json @@ -1,133 +1,135 @@ { - "$schema": "./node_modules/@angular/cli/lib/config/schema.json", - "version": 1, - "newProjectRoot": "projects", - "projects": { - "paperless-ui": { - "projectType": "application", - "schematics": { - "@schematics/angular:component": { - "style": "scss" - } - }, - "root": "", - "sourceRoot": "src", - "prefix": "app", - "architect": { - "build": { - "builder": "@angular-devkit/build-angular:browser", - "options": { - "outputPath": "dist/paperless-ui", - "outputHashing": "none", - "index": "src/index.html", - "main": "src/main.ts", - "polyfills": "src/polyfills.ts", - "tsConfig": "tsconfig.app.json", - "aot": true, - "assets": [ - "src/favicon.ico", - "src/assets" - ], - "styles": [ - "src/styles.scss" - ], - "scripts": [], - "allowedCommonJsDependencies": [ - "ng2-pdf-viewer" - ] - }, - "configurations": { - "production": { - "fileReplacements": [ - { - "replace": "src/environments/environment.ts", - "with": "src/environments/environment.prod.ts" - } - ], - "optimization": true, - "outputHashing": "none", - "sourceMap": false, - "extractCss": true, - "namedChunks": false, - "extractLicenses": true, - "vendorChunk": false, - "buildOptimizer": true, - "budgets": [ - { - "type": "initial", - "maximumWarning": "2mb", - "maximumError": "5mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "6kb", - "maximumError": "10kb" - } - ] - } - } - }, - "serve": { - "builder": "@angular-devkit/build-angular:dev-server", - "options": { - "browserTarget": "paperless-ui:build" - }, - "configurations": { - "production": { - "browserTarget": "paperless-ui:build:production" - } - } - }, - "extract-i18n": { - "builder": "@angular-devkit/build-angular:extract-i18n", - "options": { - "browserTarget": "paperless-ui:build" - } - }, - "test": { - "builder": "@angular-devkit/build-angular:karma", - "options": { - "main": "src/test.ts", - "polyfills": "src/polyfills.ts", - "tsConfig": "tsconfig.spec.json", - "karmaConfig": "karma.conf.js", - "assets": [ - "src/favicon.ico", - "src/assets" - ], - "styles": [ - "src/styles.scss" - ], - "scripts": [] - } - }, - "lint": { - "builder": "@angular-devkit/build-angular:tslint", - "options": { - "tsConfig": [ - "tsconfig.app.json", - "tsconfig.spec.json", - "e2e/tsconfig.json" - ], - "exclude": [ - "**/node_modules/**" - ] - } - }, - "e2e": { - "builder": "@angular-devkit/build-angular:protractor", - "options": { - "protractorConfig": "e2e/protractor.conf.js", - "devServerTarget": "paperless-ui:serve" - }, - "configurations": { - "production": { - "devServerTarget": "paperless-ui:serve:production" - } - } - } - } - } - }, - "defaultProject": "paperless-ui" + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "paperless-ui": { + "projectType": "application", + "schematics": { + "@schematics/angular:component": { + "style": "scss" + } + }, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:browser", + "options": { + "outputPath": "dist/paperless-ui", + "outputHashing": "none", + "index": "src/index.html", + "main": "src/main.ts", + "polyfills": "src/polyfills.ts", + "tsConfig": "tsconfig.app.json", + "aot": true, + "assets": [ + "src/favicon.ico", + "src/assets", + "src/manifest.webmanifest" + ], + "styles": [ + "src/styles.scss" + ], + "scripts": [], + "allowedCommonJsDependencies": [ + "ng2-pdf-viewer" + ] + }, + "configurations": { + "production": { + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.prod.ts" + } + ], + "optimization": true, + "outputHashing": "none", + "sourceMap": false, + "extractCss": true, + "namedChunks": false, + "extractLicenses": true, + "vendorChunk": false, + "buildOptimizer": true, + "budgets": [ + { + "type": "initial", + "maximumWarning": "2mb", + "maximumError": "5mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "6kb", + "maximumError": "10kb" + } + ] + } + } + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "options": { + "browserTarget": "paperless-ui:build" + }, + "configurations": { + "production": { + "browserTarget": "paperless-ui:build:production" + } + } + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n", + "options": { + "browserTarget": "paperless-ui:build" + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "main": "src/test.ts", + "polyfills": "src/polyfills.ts", + "tsConfig": "tsconfig.spec.json", + "karmaConfig": "karma.conf.js", + "assets": [ + "src/favicon.ico", + "src/assets", + "src/manifest.webmanifest" + ], + "styles": [ + "src/styles.scss" + ], + "scripts": [] + } + }, + "lint": { + "builder": "@angular-devkit/build-angular:tslint", + "options": { + "tsConfig": [ + "tsconfig.app.json", + "tsconfig.spec.json", + "e2e/tsconfig.json" + ], + "exclude": [ + "**/node_modules/**" + ] + } + }, + "e2e": { + "builder": "@angular-devkit/build-angular:protractor", + "options": { + "protractorConfig": "e2e/protractor.conf.js", + "devServerTarget": "paperless-ui:serve" + }, + "configurations": { + "production": { + "devServerTarget": "paperless-ui:serve:production" + } + } + } + } + } + }, + "defaultProject": "paperless-ui" } diff --git a/src-ui/src/index.html b/src-ui/src/index.html index f82399ce6..08ab3d931 100644 --- a/src-ui/src/index.html +++ b/src-ui/src/index.html @@ -5,6 +5,8 @@ Paperless-ng + + diff --git a/src-ui/src/manifest.webmanifest b/src-ui/src/manifest.webmanifest new file mode 100644 index 000000000..60151bb5c --- /dev/null +++ b/src-ui/src/manifest.webmanifest @@ -0,0 +1,14 @@ +{ + "background_color": "white", + "description": "A supercharged version of paperless: scan, index and archive all your physical documents", + "display": "fullscreen", + "icons": [ + { + "src": "favicon.ico", + "sizes": "128x128" + } + ], + "name": "Paperless NG", + "short_name": "Paperless NG", + "start_url": "/" +} From 5184d80fe0d8a42a8203c23455f9e0566a7afaa1 Mon Sep 17 00:00:00 2001 From: Jan Wiebe Date: Wed, 30 Dec 2020 14:52:20 +0100 Subject: [PATCH 048/197] Fix indentation of angular.json --- src-ui/angular.json | 260 ++++++++++++++++++++++---------------------- 1 file changed, 130 insertions(+), 130 deletions(-) diff --git a/src-ui/angular.json b/src-ui/angular.json index 04a1bec50..6a689c115 100644 --- a/src-ui/angular.json +++ b/src-ui/angular.json @@ -1,135 +1,135 @@ { - "$schema": "./node_modules/@angular/cli/lib/config/schema.json", - "version": 1, - "newProjectRoot": "projects", - "projects": { - "paperless-ui": { - "projectType": "application", - "schematics": { - "@schematics/angular:component": { - "style": "scss" - } - }, - "root": "", - "sourceRoot": "src", - "prefix": "app", - "architect": { - "build": { - "builder": "@angular-devkit/build-angular:browser", - "options": { - "outputPath": "dist/paperless-ui", - "outputHashing": "none", - "index": "src/index.html", - "main": "src/main.ts", - "polyfills": "src/polyfills.ts", - "tsConfig": "tsconfig.app.json", - "aot": true, - "assets": [ - "src/favicon.ico", - "src/assets", - "src/manifest.webmanifest" - ], - "styles": [ - "src/styles.scss" - ], + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "paperless-ui": { + "projectType": "application", + "schematics": { + "@schematics/angular:component": { + "style": "scss" + } + }, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:browser", + "options": { + "outputPath": "dist/paperless-ui", + "outputHashing": "none", + "index": "src/index.html", + "main": "src/main.ts", + "polyfills": "src/polyfills.ts", + "tsConfig": "tsconfig.app.json", + "aot": true, + "assets": [ + "src/favicon.ico", + "src/assets", + "src/manifest.webmanifest" + ], + "styles": [ + "src/styles.scss" + ], "scripts": [], "allowedCommonJsDependencies": [ "ng2-pdf-viewer" ] - }, - "configurations": { - "production": { - "fileReplacements": [ - { - "replace": "src/environments/environment.ts", - "with": "src/environments/environment.prod.ts" - } - ], - "optimization": true, - "outputHashing": "none", - "sourceMap": false, - "extractCss": true, - "namedChunks": false, - "extractLicenses": true, - "vendorChunk": false, - "buildOptimizer": true, - "budgets": [ - { - "type": "initial", - "maximumWarning": "2mb", - "maximumError": "5mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "6kb", - "maximumError": "10kb" - } - ] - } - } - }, - "serve": { - "builder": "@angular-devkit/build-angular:dev-server", - "options": { - "browserTarget": "paperless-ui:build" - }, - "configurations": { - "production": { - "browserTarget": "paperless-ui:build:production" - } - } - }, - "extract-i18n": { - "builder": "@angular-devkit/build-angular:extract-i18n", - "options": { - "browserTarget": "paperless-ui:build" - } - }, - "test": { - "builder": "@angular-devkit/build-angular:karma", - "options": { - "main": "src/test.ts", - "polyfills": "src/polyfills.ts", - "tsConfig": "tsconfig.spec.json", - "karmaConfig": "karma.conf.js", - "assets": [ - "src/favicon.ico", - "src/assets", - "src/manifest.webmanifest" - ], - "styles": [ - "src/styles.scss" - ], - "scripts": [] - } - }, - "lint": { - "builder": "@angular-devkit/build-angular:tslint", - "options": { - "tsConfig": [ - "tsconfig.app.json", - "tsconfig.spec.json", - "e2e/tsconfig.json" - ], - "exclude": [ - "**/node_modules/**" - ] - } - }, - "e2e": { - "builder": "@angular-devkit/build-angular:protractor", - "options": { - "protractorConfig": "e2e/protractor.conf.js", - "devServerTarget": "paperless-ui:serve" - }, - "configurations": { - "production": { - "devServerTarget": "paperless-ui:serve:production" - } - } - } - } - } - }, - "defaultProject": "paperless-ui" -} + }, + "configurations": { + "production": { + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.prod.ts" + } + ], + "optimization": true, + "outputHashing": "none", + "sourceMap": false, + "extractCss": true, + "namedChunks": false, + "extractLicenses": true, + "vendorChunk": false, + "buildOptimizer": true, + "budgets": [ + { + "type": "initial", + "maximumWarning": "2mb", + "maximumError": "5mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "6kb", + "maximumError": "10kb" + } + ] + } + } + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "options": { + "browserTarget": "paperless-ui:build" + }, + "configurations": { + "production": { + "browserTarget": "paperless-ui:build:production" + } + } + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n", + "options": { + "browserTarget": "paperless-ui:build" + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "main": "src/test.ts", + "polyfills": "src/polyfills.ts", + "tsConfig": "tsconfig.spec.json", + "karmaConfig": "karma.conf.js", + "assets": [ + "src/favicon.ico", + "src/assets", + "src/manifest.webmanifest" + ], + "styles": [ + "src/styles.scss" + ], + "scripts": [] + } + }, + "lint": { + "builder": "@angular-devkit/build-angular:tslint", + "options": { + "tsConfig": [ + "tsconfig.app.json", + "tsconfig.spec.json", + "e2e/tsconfig.json" + ], + "exclude": [ + "**/node_modules/**" + ] + } + }, + "e2e": { + "builder": "@angular-devkit/build-angular:protractor", + "options": { + "protractorConfig": "e2e/protractor.conf.js", + "devServerTarget": "paperless-ui:serve" + }, + "configurations": { + "production": { + "devServerTarget": "paperless-ui:serve:production" + } + } + } + } + } + }, + "defaultProject": "paperless-ui" +} \ No newline at end of file From ae2a75056c7fe394f0a349fe42a0ffb62e9f79a7 Mon Sep 17 00:00:00 2001 From: Jan Wiebe Date: Wed, 30 Dec 2020 14:55:49 +0100 Subject: [PATCH 049/197] Fix indentation --- src-ui/angular.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src-ui/angular.json b/src-ui/angular.json index 6a689c115..f0acd5950 100644 --- a/src-ui/angular.json +++ b/src-ui/angular.json @@ -32,10 +32,10 @@ "styles": [ "src/styles.scss" ], - "scripts": [], - "allowedCommonJsDependencies": [ - "ng2-pdf-viewer" - ] + "scripts": [], + "allowedCommonJsDependencies": [ + "ng2-pdf-viewer" + ] }, "configurations": { "production": { From 13ea7b7c368a36701661cd634a2d22a18df316f3 Mon Sep 17 00:00:00 2001 From: Jan Wiebe Date: Wed, 30 Dec 2020 14:56:18 +0100 Subject: [PATCH 050/197] Add newline to end of file --- src-ui/angular.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src-ui/angular.json b/src-ui/angular.json index f0acd5950..ce2dd82f7 100644 --- a/src-ui/angular.json +++ b/src-ui/angular.json @@ -132,4 +132,4 @@ } }, "defaultProject": "paperless-ui" -} \ No newline at end of file +} From 4b7138f4776e31f4708e06f6ebb94fa2b55f09f9 Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Wed, 30 Dec 2020 15:12:16 +0100 Subject: [PATCH 051/197] fixes #218 --- src/documents/parsers.py | 2 ++ src/paperless_tesseract/parsers.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/documents/parsers.py b/src/documents/parsers.py index cbbb912de..725e605a2 100644 --- a/src/documents/parsers.py +++ b/src/documents/parsers.py @@ -117,6 +117,7 @@ def run_convert(input_file, trim=False, type=None, depth=None, + auto_orient=False, extra=None, logging_group=None): @@ -134,6 +135,7 @@ def run_convert(input_file, args += ['-trim'] if trim else [] args += ['-type', str(type)] if type else [] args += ['-depth', str(depth)] if depth else [] + args += ['-auto-orient'] if auto_orient else [] args += [input_file, output_file] logger.debug("Execute: " + " ".join(args), extra={'group': logging_group}) diff --git a/src/paperless_tesseract/parsers.py b/src/paperless_tesseract/parsers.py index 80e200f27..4da5af2c0 100644 --- a/src/paperless_tesseract/parsers.py +++ b/src/paperless_tesseract/parsers.py @@ -60,6 +60,7 @@ class RasterisedDocumentParser(DocumentParser): alpha="remove", strip=True, trim=False, + auto_orient=True, input_file="{}[0]".format(document_path), output_file=out_path, logging_group=self.logging_group) @@ -84,6 +85,7 @@ class RasterisedDocumentParser(DocumentParser): alpha="remove", strip=True, trim=False, + auto_orient=True, input_file=gs_out_path, output_file=out_path, logging_group=self.logging_group) From 58984737ef3d8130803267269ec473330a408c85 Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Wed, 30 Dec 2020 15:46:56 +0100 Subject: [PATCH 052/197] adds a command to regenerate thumbnails #218 --- .../commands/document_thumbnails.py | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 src/documents/management/commands/document_thumbnails.py diff --git a/src/documents/management/commands/document_thumbnails.py b/src/documents/management/commands/document_thumbnails.py new file mode 100644 index 000000000..41ddec86e --- /dev/null +++ b/src/documents/management/commands/document_thumbnails.py @@ -0,0 +1,65 @@ +import logging +import multiprocessing +import shutil + +import tqdm +from django import db +from django.core.management.base import BaseCommand + +from documents.models import Document +from ...mixins import Renderable +from ...parsers import get_parser_class_for_mime_type + + +def _process_document(doc_in): + document = Document.objects.get(id=doc_in) + parser = get_parser_class_for_mime_type(document.mime_type)( + logging_group=None) + try: + thumb = parser.get_optimised_thumbnail( + document.source_path, document.mime_type) + + shutil.move(thumb, document.thumbnail_path) + finally: + parser.cleanup() + +class Command(Renderable, BaseCommand): + + help = """ + This will regenerate the thumbnails for all documents. + """.replace(" ", "") + + def __init__(self, *args, **kwargs): + self.verbosity = 0 + BaseCommand.__init__(self, *args, **kwargs) + + def add_arguments(self, parser): + parser.add_argument( + "-d", "--document", + default=None, + type=int, + required=False, + help="Specify the ID of a document, and this command will only " + "run on this specific document." + ) + + def handle(self, *args, **options): + + self.verbosity = options["verbosity"] + + logging.getLogger().handlers[0].level = logging.ERROR + + if options['document']: + documents = Document.objects.filter(pk=options['document']) + else: + documents = Document.objects.all() + + ids = [doc.id for doc in documents] + + # Note to future self: this prevents django from reusing database + # conncetions between processes, which is bad and does not work + # with postgres. + db.connections.close_all() + + with multiprocessing.Pool() as pool: + list(tqdm.tqdm(pool.imap_unordered(_process_document, ids), total=len(ids))) From ca2ecd0d1aec3980de745f3da74ed84269f92db6 Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Wed, 30 Dec 2020 16:29:22 +0100 Subject: [PATCH 053/197] language fixes --- .../welcome-widget.component.html | 2 +- .../document-detail.component.ts | 2 +- .../bulk-editor/bulk-editor.component.ts | 20 +++++++++---------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src-ui/src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html b/src-ui/src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html index 7a2bbcb3c..6320189cc 100644 --- a/src-ui/src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html +++ b/src-ui/src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html @@ -4,7 +4,7 @@

    Paperless is running! :)

    You can start uploading documents by dropping them in the file upload box to the right or by dropping them in the configured consumption folder and they'll start showing up in the documents list. - After you've added some metadata to your documents, use the filtering mechanisms of paperless to create custom views (such as 'Recently added', 'Tagged TODO') and have they will be shown on the dashboard instead of this message.

    + After you've added some metadata to your documents, use the filtering mechanisms of paperless to create custom views (such as 'Recently added', 'Tagged TODO') and they will appear on the dashboard instead of this message.

    Paperless offers some more features that try to make your life easier:

    • Once you've got a couple documents in paperless and added metadata to them, paperless can assign that metadata to new documents automatically.
    • diff --git a/src-ui/src/app/components/document-detail/document-detail.component.ts b/src-ui/src/app/components/document-detail/document-detail.component.ts index 2efd32f27..053258f34 100644 --- a/src-ui/src/app/components/document-detail/document-detail.component.ts +++ b/src-ui/src/app/components/document-detail/document-detail.component.ts @@ -159,7 +159,7 @@ export class DocumentDetailComponent implements OnInit { delete() { let modal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'}) modal.componentInstance.title = $localize`Confirm delete` - modal.componentInstance.messageBold = $localize`Do you really want to delete document '${this.document.title}'?` + modal.componentInstance.messageBold = $localize`Do you really want to delete document "${this.document.title}"?` modal.componentInstance.message = $localize`The files for this document will be deleted permanently. This operation cannot be undone.` modal.componentInstance.btnClass = "btn-danger" modal.componentInstance.btnCaption = $localize`Delete document` diff --git a/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.ts b/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.ts index 1347cb138..e69ab241b 100644 --- a/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.ts +++ b/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.ts @@ -115,16 +115,16 @@ export class BulkEditorComponent { modal.componentInstance.title = $localize`Confirm tags assignment` if (changedTags.itemsToAdd.length == 1 && changedTags.itemsToRemove.length == 0) { let tag = changedTags.itemsToAdd[0] - modal.componentInstance.message = $localize`This operation will add the tag "${tag.name}" to all ${this.list.selected.size} selected document(s).` + modal.componentInstance.message = $localize`This operation will add the tag "${tag.name}" to ${this.list.selected.size} selected document(s).` } else if (changedTags.itemsToAdd.length > 1 && changedTags.itemsToRemove.length == 0) { - modal.componentInstance.message = $localize`This operation will add the tags ${this._localizeList(changedTags.itemsToAdd)} to all ${this.list.selected.size} selected document(s).` + modal.componentInstance.message = $localize`This operation will add the tags ${this._localizeList(changedTags.itemsToAdd)} to ${this.list.selected.size} selected document(s).` } else if (changedTags.itemsToAdd.length == 0 && changedTags.itemsToRemove.length == 1) { let tag = changedTags.itemsToRemove[0] - modal.componentInstance.message = $localize`This operation will remove the tag "${tag.name}" from all ${this.list.selected.size} selected document(s).` + modal.componentInstance.message = $localize`This operation will remove the tag "${tag.name}" from ${this.list.selected.size} selected document(s).` } else if (changedTags.itemsToAdd.length == 0 && changedTags.itemsToRemove.length > 1) { - modal.componentInstance.message = $localize`This operation will remove the tags ${this._localizeList(changedTags.itemsToRemove)} from all ${this.list.selected.size} selected document(s).` + modal.componentInstance.message = $localize`This operation will remove the tags ${this._localizeList(changedTags.itemsToRemove)} from ${this.list.selected.size} selected document(s).` } else { - modal.componentInstance.message = $localize`This operation will add the tags ${this._localizeList(changedTags.itemsToAdd)} and remove the tags ${this._localizeList(changedTags.itemsToRemove)} on all ${this.list.selected.size} selected document(s).` + modal.componentInstance.message = $localize`This operation will add the tags ${this._localizeList(changedTags.itemsToAdd)} and remove the tags ${this._localizeList(changedTags.itemsToRemove)} on ${this.list.selected.size} selected document(s).` } modal.componentInstance.btnClass = "btn-warning" @@ -156,9 +156,9 @@ export class BulkEditorComponent { let modal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'}) modal.componentInstance.title = $localize`Confirm correspondent assignment` if (correspondent) { - modal.componentInstance.message = $localize`This operation will assign the correspondent "${correspondent.name}" to all ${this.list.selected.size} selected document(s).` + modal.componentInstance.message = $localize`This operation will assign the correspondent "${correspondent.name}" to ${this.list.selected.size} selected document(s).` } else { - modal.componentInstance.message = $localize`This operation will remove the correspondent from all ${this.list.selected.size} selected document(s).` + modal.componentInstance.message = $localize`This operation will remove the correspondent from ${this.list.selected.size} selected document(s).` } modal.componentInstance.btnClass = "btn-warning" modal.componentInstance.btnCaption = $localize`Confirm` @@ -189,9 +189,9 @@ export class BulkEditorComponent { let modal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'}) modal.componentInstance.title = $localize`Confirm document type assignment` if (documentType) { - modal.componentInstance.message = $localize`This operation will assign the document type "${documentType.name}" to all ${this.list.selected.size} selected document(s).` + modal.componentInstance.message = $localize`This operation will assign the document type "${documentType.name}" to ${this.list.selected.size} selected document(s).` } else { - modal.componentInstance.message = $localize`This operation will remove the document type from all ${this.list.selected.size} selected document(s).` + modal.componentInstance.message = $localize`This operation will remove the document type from ${this.list.selected.size} selected document(s).` } modal.componentInstance.btnClass = "btn-warning" modal.componentInstance.btnCaption = $localize`Confirm` @@ -217,7 +217,7 @@ export class BulkEditorComponent { let modal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'}) modal.componentInstance.delayConfirm(5) modal.componentInstance.title = $localize`Delete confirm` - modal.componentInstance.messageBold = $localize`This operation will permanently delete all ${this.list.selected.size} selected document(s).` + modal.componentInstance.messageBold = $localize`This operation will permanently delete ${this.list.selected.size} selected document(s).` modal.componentInstance.message = $localize`This operation cannot be undone.` modal.componentInstance.btnClass = "btn-danger" modal.componentInstance.btnCaption = $localize`Delete document(s)` From 2f6cd869b5100688c8a42a0746f50039cf286114 Mon Sep 17 00:00:00 2001 From: "transifex-integration[bot]" <43880903+transifex-integration[bot]@users.noreply.github.com> Date: Wed, 30 Dec 2020 15:35:33 +0000 Subject: [PATCH 054/197] Translate /src-ui/messages.xlf in de_DE at least 50% translated for the source file '/src-ui/messages.xlf' on the 'de_DE' language. Manual sync of partially translated files: untranslated content is included with an empty translation or source language content depending on file format --- src-ui/src/locale/messages.de_DE.xlf | 1819 ++++++++++++++++++++++++++ 1 file changed, 1819 insertions(+) create mode 100644 src-ui/src/locale/messages.de_DE.xlf diff --git a/src-ui/src/locale/messages.de_DE.xlf b/src-ui/src/locale/messages.de_DE.xlf new file mode 100644 index 000000000..2b23832df --- /dev/null +++ b/src-ui/src/locale/messages.de_DE.xlf @@ -0,0 +1,1819 @@ + + + + + Documents + Dokumente + + src/app/components/document-list/document-list.component.ts + 38 + + + + View "" saved successfully. + Ansicht "" erfolgreich gespeichert. + + src/app/components/document-list/document-list.component.ts + 84 + + + + View "" created successfully. + Ansicht "" erfolgreich erstellt. + + src/app/components/document-list/document-list.component.ts + 103 + + + + Select + Auswählen + + src/app/components/document-list/document-list.component.html + 7 + + + + Select none + Nichts auswählen + + src/app/components/document-list/document-list.component.html + 11 + + + + Select page + Seite auswählen + + src/app/components/document-list/document-list.component.html + 12 + + + + Select all + Alles auswählen + + src/app/components/document-list/document-list.component.html + 13 + + + + Sort by + Sortieren + + src/app/components/document-list/document-list.component.html + 41 + + + + Views + Ansicht + + src/app/components/document-list/document-list.component.html + 64 + + + + Save as... + Speichern als... + + src/app/components/document-list/document-list.component.html + 72 + + + + Save "" + "" speichern + + src/app/components/document-list/document-list.component.html + 71 + + + + {VAR_PLURAL, plural, =1 {document} other {documents}} + {VAR_PLURAL, plural, =1 {Dokument} other {Dokumente}} + + src/app/components/document-list/document-list.component.html + 86 + + + + Selected of + von ausgewählt + + src/app/components/document-list/document-list.component.html + 86 + + + + {VAR_PLURAL, plural, =1 {1 document} other { documents}} + {VAR_PLURAL, plural, =1 {1 Dokument} other { Dokumente}} + + src/app/components/document-list/document-list.component.html + 87 + + + + ASN + ASN + + src/app/components/document-list/document-list.component.html + 100 + + + + Correspondent + Korrespondent + + src/app/components/document-list/document-list.component.html + 101 + + + + Title + Titel + + src/app/components/document-list/document-list.component.html + 102 + + + + Document type + Dokumenttyp + + src/app/components/document-list/document-list.component.html + 103 + + + + Created + Erstellt + + src/app/components/document-list/document-list.component.html + 104 + + + + Added + Hinzugefügt + + src/app/components/document-list/document-list.component.html + 105 + + + + Confirm delete + Löschen bestätigen + + src/app/components/document-detail/document-detail.component.ts + 161 + + + + Do you really want to delete document ''? + Möchten Sie das Dokument '' wirklich löschen? + + src/app/components/document-detail/document-detail.component.ts + 162 + + + + The files for this document will be deleted permanently. This operation cannot be undone. + Die Dateien dieses Dokuments werden permanent gelöscht. Diese Aktion kann nicht rückgängig gemacht werden. + + src/app/components/document-detail/document-detail.component.ts + 163 + + + + Delete document + Dokument löschen + + src/app/components/document-detail/document-detail.component.ts + 165 + + + + Delete + Löschen + + src/app/components/document-detail/document-detail.component.html + 15 + + + + Download + Herunterladen + + src/app/components/document-detail/document-detail.component.html + 23 + + + + More like this + Ähnliche Dokumente + + src/app/components/document-detail/document-detail.component.html + 38 + + + + Close + Schließen + + src/app/components/document-detail/document-detail.component.html + 44 + + + + Details + Details + + src/app/components/document-detail/document-detail.component.html + 56 + + + + Content + Inhalt + + src/app/components/document-detail/document-detail.component.html + 76 + + + + Metadata + Metadaten + + src/app/components/document-detail/document-detail.component.html + 85 + + + + Discard + Verwerfen + + src/app/components/document-detail/document-detail.component.html + 134 + + + + Save + Speichern + + src/app/components/document-detail/document-detail.component.html + 136 + + + + Page + Seite + + src/app/components/document-detail/document-detail.component.html + 4 + + + + of + von + + src/app/components/document-detail/document-detail.component.html + 8 + + + + Download original + Original herunterladen + + src/app/components/document-detail/document-detail.component.html + 29 + + + + Archive serial number + Archiv-Seriennummer + + src/app/components/document-detail/document-detail.component.html + 61 + + + + Date created + Erstellt am + + src/app/components/document-detail/document-detail.component.html + 65 + + + + Tags + Tags + + src/app/components/document-detail/document-detail.component.html + 70 + + + + Date modified + Geändert am + + src/app/components/document-detail/document-detail.component.html + 91 + + + + Date added + Hinzugefügt am + + src/app/components/document-detail/document-detail.component.html + 95 + + + + Media filename + Media-Dateiname + + src/app/components/document-detail/document-detail.component.html + 99 + + + + Original MD5 checksum + MD5-Prüfsumme Original + + src/app/components/document-detail/document-detail.component.html + 103 + + + + Original file size + Dateigröße Original + + src/app/components/document-detail/document-detail.component.html + 107 + + + + Original mime type + MIME-Typ Original + + src/app/components/document-detail/document-detail.component.html + 111 + + + + Archive MD5 checksum + MD5-Prüfsumme Archiv + + src/app/components/document-detail/document-detail.component.html + 115 + + + + Archive file size + Dateigröße Archiv + + src/app/components/document-detail/document-detail.component.html + 119 + + + + Original document metadata + Original-Metadaten + + src/app/components/document-detail/document-detail.component.html + 125 + + + + Archived document metadata + Metadaten des archivierten Dokuments + + src/app/components/document-detail/document-detail.component.html + 126 + + + + Save & next + Speichern & weiter + + src/app/components/document-detail/document-detail.component.html + 135 + + + + Hello , welcome to Paperless-ng! + Hallo , Willkommen zu Paperless-ng + + src/app/components/dashboard/dashboard.component.ts + 33 + + + + Welcome to Paperless-ng! + Willkommen zu Paperless-ng! + + src/app/components/dashboard/dashboard.component.ts + 35 + + + + Dashboard + Startseite + + src/app/components/dashboard/dashboard.component.html + 1 + + + + Do you really want to delete the tag ""? + Möchten Sie das Tag "" wirklich löschen? + + src/app/components/manage/tag-list/tag-list.component.ts + 31 + + + + Create + Erstellen + + src/app/components/manage/tag-list/tag-list.component.html + 2 + + + + Name + Name + + src/app/components/manage/tag-list/tag-list.component.html + 13 + + + + Color + Farbe + + src/app/components/manage/tag-list/tag-list.component.html + 14 + + + + Matching + + src/app/components/manage/tag-list/tag-list.component.html + 15 + + + + Document count + Anzahl Dokumente + + src/app/components/manage/tag-list/tag-list.component.html + 16 + + + + Actions + Aktionen + + src/app/components/manage/tag-list/tag-list.component.html + 17 + + + + Documents + Dokumente + + src/app/components/manage/tag-list/tag-list.component.html + 32 + + + + Edit + Bearbeiten + + src/app/components/manage/tag-list/tag-list.component.html + 37 + + + + Do you really want to delete the document type ""? + Möchten Sie den Dokumenttyp "" wirklich löschen? + + src/app/components/manage/document-type-list/document-type-list.component.ts + 26 + + + + Document types + Dokumenttypen + + src/app/components/manage/document-type-list/document-type-list.component.html + 1 + + + + Logs + Protokoll + + src/app/components/manage/logs/logs.component.html + 1 + + + + Filter + Filtern + + src/app/components/manage/logs/logs.component.html + 7 + + + + Saved view " deleted. + Ansicht gelöscht. + + src/app/components/manage/settings/settings.component.ts + 52 + + + + Settings saved successfully. + Einstellungen erfolgreich gespeichert. + + src/app/components/manage/settings/settings.component.ts + 61 + + + + Error while storing settings on server: + Fehler beim Speichern der Einstellungen auf dem Server: + + src/app/components/manage/settings/settings.component.ts + 73 + + + + General settings + Allgemeine Einstellungen + + src/app/components/manage/settings/settings.component.html + 10 + + + + Saved views + Gespeicherte Ansichten + + src/app/components/manage/settings/settings.component.html + 41 + + + + Document list + Dokumentliste + + src/app/components/manage/settings/settings.component.html + 13 + + + + Items per page + Dokumente pro Seite + + src/app/components/manage/settings/settings.component.html + 17 + + + + Bulk editing + Massenbearbeitung + + src/app/components/manage/settings/settings.component.html + 33 + + + + Show confirmation dialogs + Bestätigungsdialoge anzeigen + + src/app/components/manage/settings/settings.component.html + 35 + + + + Deleting documents will always ask for confirmation. + Beim Löschen von Dokumenten wird immer nach einer Bestätigung gefragt. + + src/app/components/manage/settings/settings.component.html + 35 + + + + Apply on close + Anwenden beim Schließen + + src/app/components/manage/settings/settings.component.html + 36 + + + + Appears on + Erscheint auf + + src/app/components/manage/settings/settings.component.html + 53 + + + + Show on dashboard + Auf Startseite zeigen + + src/app/components/manage/settings/settings.component.html + 56 + + + + Show in sidebar + In Seitenleiste zeigen + + src/app/components/manage/settings/settings.component.html + 60 + + + + No saved views defined. + Keine gespeicherten Ansichten vorhanden. + + src/app/components/manage/settings/settings.component.html + 70 + + + + 404 Not Found + 404 Nicht gefunden + + src/app/components/not-found/not-found.component.html + 7 + + + + Do you really want to delete the correspondent ""? + Möchten Sie den Korrespondenten "" wirklich löschen? + + src/app/components/manage/correspondent-list/correspondent-list.component.ts + 26 + + + + Correspondents + Korrespondenten + + src/app/components/manage/correspondent-list/correspondent-list.component.html + 1 + + + + Last correspondence + Letzter Kontakt + + src/app/components/manage/correspondent-list/correspondent-list.component.html + 15 + + + + Confirmation + Bestätigung + + src/app/components/common/confirm-dialog/confirm-dialog.component.ts + 17 + + + + Confirm + Bestätigen + + src/app/components/common/confirm-dialog/confirm-dialog.component.ts + 29 + + + + Create new correspondent + Neuen Korrespondenten erstellen + + src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.ts + 21 + + + + Edit correspondent + Korrespondenten bearbeiten + + src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.ts + 25 + + + + Could not save correspondent: + Konnte Korrespondent nicht speichern: + + src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.ts + 29 + + + + Matching algorithm + + src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.html + 11 + + + + Match + + src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.html + 12 + + + + Auto matching does not require you to fill in this field. + Für Automatische Zuweisung muss dieses Feld nicht ausgefüllt werden. + + src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.html + 12 + + + + Case insensitive + Groß-/Kleinschreibung irrelevant + + src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.html + 13 + + + + Auto matching ignores this option. + Automatische Zuweisung beachtet diese Einstellung nicht. + + src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.html + 13 + + + + Cancel + Abbrechen + + src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.html + 16 + + + + Create new tag + Neues Tag erstellen + + src/app/components/manage/tag-list/tag-edit-dialog/tag-edit-dialog.component.ts + 21 + + + + Edit tag + Tag bearbeiten + + src/app/components/manage/tag-list/tag-edit-dialog/tag-edit-dialog.component.ts + 25 + + + + Could not save tag: + Konnte Tag nicht speichern: + + src/app/components/manage/tag-list/tag-edit-dialog/tag-edit-dialog.component.ts + 29 + + + + Inbox tag + Posteingangs-Tag + + src/app/components/manage/tag-list/tag-edit-dialog/tag-edit-dialog.component.html + 21 + + + + Inbox tags are automatically assigned to all consumed documents. + Ein Tag mit dieser Option wird automatisch allen neuen Dokumenten zugewiesen. + + src/app/components/manage/tag-list/tag-edit-dialog/tag-edit-dialog.component.html + 21 + + + + Create new document type + Neuen Dokumenttyp erstellen + + src/app/components/manage/document-type-list/document-type-edit-dialog/document-type-edit-dialog.component.ts + 21 + + + + Edit document type + Dokumenttyp bearbeiten + + src/app/components/manage/document-type-list/document-type-edit-dialog/document-type-edit-dialog.component.ts + 25 + + + + Could not save document type: + Konnte Dokumenttyp nicht speichern: + + src/app/components/manage/document-type-list/document-type-edit-dialog/document-type-edit-dialog.component.ts + 29 + + + + Search results + Suchergebnisse + + src/app/components/search/search.component.html + 1 + + + + Invalid search query: + Ungültige Suchanfrage: + + src/app/components/search/search.component.html + 4 + + + + Showing documents similar to + Zeige ähnliche Dokumente zu + + src/app/components/search/search.component.html + 7 + + + + Search query: + Suchanfrage: + + src/app/components/search/search.component.html + 11 + + + + Did you mean ""? + Meinten Sie ""? + + src/app/components/search/search.component.html + 13 + + + + {VAR_PLURAL, plural, =0 {No results} =1 {One result} other { results}} + {VAR_PLURAL, plural, =0 {Keine Ergebnisse} =1 {Ein Ergebnis} other { Ergebnisse}} + + src/app/components/search/search.component.html + 18 + + + + Paperless-ng + Paperless-ng + + src/app/components/app-frame/app-frame.component.html + 4 + + app title + + + Search for documents + Nach Dokumenten suchen + + src/app/components/app-frame/app-frame.component.html + 12 + + + + Manage + Verwalten + + src/app/components/app-frame/app-frame.component.html + 77 + + + + Settings + Einstellungen + + src/app/components/app-frame/app-frame.component.html + 112 + + + + Admin + Administration + + src/app/components/app-frame/app-frame.component.html + 119 + + + + Misc + Weiteres + + src/app/components/app-frame/app-frame.component.html + 125 + + + + Documentation + Dokumentation + + src/app/components/app-frame/app-frame.component.html + 132 + + + + GitHub + GitHub + + src/app/components/app-frame/app-frame.component.html + 139 + + + + Logout + Abmelden + + src/app/components/app-frame/app-frame.component.html + 146 + + + + Open documents + Geöffnete Dokumente + + src/app/components/app-frame/app-frame.component.html + 57 + + + + Close all + Alle schließen + + src/app/components/app-frame/app-frame.component.html + 71 + + + + Correspondent: + Korrespondent: + + src/app/components/document-list/filter-editor/filter-editor.component.ts + 28 + + + + Type: + Typ: + + src/app/components/document-list/filter-editor/filter-editor.component.ts + 31 + + + + Tag: + Tag: + + src/app/components/document-list/filter-editor/filter-editor.component.ts + 34 + + + + Filter by: + Filtern nach: + + src/app/components/document-list/filter-editor/filter-editor.component.html + 4 + + + + Filter tags + Tags filtern + + src/app/components/document-list/filter-editor/filter-editor.component.html + 12 + + + + Filter correspondents + Korrespondenten filtern + + src/app/components/document-list/filter-editor/filter-editor.component.html + 19 + + + + Filter document types + Dokumenttypen filtern + + src/app/components/document-list/filter-editor/filter-editor.component.html + 25 + + + + Clear all filters + Filter zurücksetzen + + src/app/components/document-list/filter-editor/filter-editor.component.html + 47 + + + + Not assigned + Nicht zugewiesen + + src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts + 145 + + Filter drop down element to filter for documents with no correspondent/type/tag assigned + + + Apply + Anwenden + + src/app/components/common/filterable-dropdown/filterable-dropdown.component.html + 28 + + + + Last 7 days + Letzte 7 Tage + + src/app/components/common/date-dropdown/date-dropdown.component.ts + 24 + + + + Last month + Letzten Monat + + src/app/components/common/date-dropdown/date-dropdown.component.ts + 25 + + + + Last 3 months + Letzte 3 Monate + + src/app/components/common/date-dropdown/date-dropdown.component.ts + 26 + + + + Last year + Letztes Jahr + + src/app/components/common/date-dropdown/date-dropdown.component.ts + 27 + + + + After + Nach + + src/app/components/common/date-dropdown/date-dropdown.component.html + 13 + + + + Before + Vor + + src/app/components/common/date-dropdown/date-dropdown.component.html + 29 + + + + Clear + Zurücksetzen + + src/app/components/common/date-dropdown/date-dropdown.component.html + 18 + + + + View + Anzeigen + + src/app/components/document-list/document-card-large/document-card-large.component.html + 50 + + + + Score: + Relevanz: + + src/app/components/document-list/document-card-large/document-card-large.component.html + 61 + + + + Created: + Erstellt: + + src/app/components/document-list/document-card-large/document-card-large.component.html + 65 + + + + Filter by correspondent + Nach Korrespondent filtern + + src/app/components/document-list/document-card-large/document-card-large.component.html + 20 + + + + Filter by tag + Nach Tag filtern + + src/app/components/document-list/document-card-large/document-card-large.component.html + 24 + + + + View in browser + Im Browser anzeigen + + src/app/components/document-list/document-card-small/document-card-small.component.html + 40 + + + + "" and "" + "" und "" + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 103 + + This is for messages like 'modify "tag1" and "tag2"' + + + "" + "" + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 105 + + + + , + , + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 105 + + this is used to separate enumerations and should probably be a comma and a whitespace in most languages + + + and "" + und "" + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 106 + + this is for messages like 'modify "tag1", "tag2" and "tag3"' + + + Confirm tags assignment + Tag-Zuweisung bestätigen + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 115 + + + + This operation will add the tag "" to all selected document(s). + Diese Aktion wird das Tag "" allen ausgewählten Dokumenten hinzufügen. + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 118 + + + + This operation will add the tags to all selected document(s). + Diese Aktion wird die Tags allen ausgewählten Dokumenten hinzufügen. + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 120 + + + + This operation will remove the tag "" from all selected document(s). + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 123 + + + + This operation will remove the tags from all selected document(s). + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 125 + + + + This operation will add the tags and remove the tags on all selected document(s). + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 127 + + + + Confirm correspondent assignment + Korrespondent-Zuweisung bestätigen + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 157 + + + + This operation will assign the correspondent "" to all selected document(s). + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 159 + + + + This operation will remove the correspondent from all selected document(s). + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 161 + + + + Confirm document type assignment + Dokumenttyp-Zuweisung bestätigen + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 190 + + + + This operation will assign the document type "" to all selected document(s). + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 192 + + + + This operation will remove the document type from all selected document(s). + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 194 + + + + Delete confirm + Löschen bestätigen + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 219 + + + + This operation will permanently delete all selected document(s). + Diese Aktion wird alle ausgewählte(n) Dokument(e) entgültig löschen. + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 220 + + + + This operation cannot be undone. + Diese Aktion kann nicht rückgängig gemacht werden. + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 221 + + + + Delete document(s) + Dokument(e) löschen + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 223 + + + + Select: + Auswählen: + + src/app/components/document-list/bulk-editor/bulk-editor.component.html + 11 + + + + All + Alle + + src/app/components/document-list/bulk-editor/bulk-editor.component.html + 21 + + + + Edit: + Bearbeiten: + + src/app/components/document-list/bulk-editor/bulk-editor.component.html + 28 + + + + Save current view + Aktuelle Ansicht speichern + + src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.html + 3 + + + + Show all + Alle anzeigen + + src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html + 3 + + + + Statistics + Statistiken + + src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html + 1 + + + + Documents in inbox: + Dokumente im Posteingang: + + src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html + 3 + + + + Total documents: + Anzahl Dokumente gesamt: + + src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html + 4 + + + + The document has been uploaded and will be processed by the consumer shortly. + Das Dokument wurde hochgeladen und wird in Kürze durch Paperless-ng verarbeitet. + + src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.ts + 63 + + + + There was an error while uploading the document: + Konnte Dokument nicht hochladen: + + src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.ts + 71 + + + + An error has occurred while uploading the document. Sorry! + Beim Hochladen trat ein Fehler auf. Entschuldigung! + + src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.ts + 75 + + + + Upload new documents + Neue Dokumente hochladen + + src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html + 1 + + + + Drop documents here or + Dokumente hier ablegen oder + + src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html + 5 + + + + Browse files + Datei auswählen + + src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html + 5 + + + + {VAR_PLURAL, plural, =1 {file} =other { files}} + {VAR_PLURAL, plural, =1 {Datei} =other { Dateien}} + + src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html + 13 + + + + Uploading ... + Lade hoch... + + src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html + 13 + + + + First steps + Erste Schritte + + src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html + 1 + + + + Paperless is running! :) + Paperless ist startbereit! :) + + src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html + 5 + + + + You can start uploading documents by dropping them in the file upload box to the right or by dropping them in the configured consumption folder and they'll start showing up in the documents list. After you've added some metadata to your documents, use the filtering mechanisms of paperless to create custom views (such as 'Recently added', 'Tagged TODO') and have they will be shown on the dashboard instead of this message. + Sie können Ihre Dokumente hochladen, indem Sie sie in die Hochladebox auf der rechten Seite ziehen oder in den konfigurierten Ablageordner kopieren/verschieben. Danach werden sie inder Dokumentliste erscheinen. Nachdem Sie den Dokumenten einige Metadaten zugewiesen haben, können Sie die Filtermechanismen zur Erstellung individueller Ansichten benutzen (zum Beispiel "Kürzlich hinzugefügt" oder "Mit TODO markiert") und die Ansichten werden auf der Startseite erscheinen und diese Nachricht ersetzen. + + src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html + 6,7 + + + + Paperless offers some more features that try to make your life easier: + Paperless bietet darüber hinaus einige erweiterte Funktionen: + + src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html + 8 + + + + Once you've got a couple documents in paperless and added metadata to them, paperless can assign that metadata to new documents automatically. + Nachdem Sie einige Dokumente hochgeladen und mit Metadatebn haben, kann Paperless diese Metadaten automatisch passenden neuen Dokumenten zuweisen. + + src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html + 10 + + + + You can configure paperless to read your mails and add documents from attached files. + + src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html + 11 + + + + Consult the documentation on how to use these features. The section on basic usage also has some information on how to use paperless in general. + + src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html + 13 + + + + Metadata + Metadaten + + src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts + 18 + + + + Select + Auswählen + + src/app/components/common/select-dialog/select-dialog.component.ts + 18 + + + + Please select an object + Bitte wählen Sie ein Element aus + + src/app/components/common/select-dialog/select-dialog.component.ts + 21 + + + + Yes + Ja + + src/app/pipes/yes-no.pipe.ts + 9 + + + + No + Nein + + src/app/pipes/yes-no.pipe.ts + 9 + + + + (no title) + (kein Titel) + + src/app/pipes/document-title.pipe.ts + 12 + + + + Error + Fehler + + src/app/services/toast.service.ts + 31 + + + + Information + Information + + src/app/services/toast.service.ts + 35 + + + + Correspondent + Korrespondent + + src/app/services/rest/document.service.ts + 16 + + + + Document type + Dokumenttyp + + src/app/services/rest/document.service.ts + 17 + + + + Title + Titel + + src/app/services/rest/document.service.ts + 18 + + + + ASN + ASN + + src/app/services/rest/document.service.ts + 19 + + + + Created + Erstellt am + + src/app/services/rest/document.service.ts + 20 + + + + Added + Hinzugefügt am + + src/app/services/rest/document.service.ts + 21 + + + + Modified + Geändert am + + src/app/services/rest/document.service.ts + 22 + + + + Light blue + Hellblau + + src/app/data/paperless-tag.ts + 6 + + + + Blue + Blau + + src/app/data/paperless-tag.ts + 7 + + + + Light green + Hellgrün + + src/app/data/paperless-tag.ts + 8 + + + + Green + Grün + + src/app/data/paperless-tag.ts + 9 + + + + Light red + Hellrot + + src/app/data/paperless-tag.ts + 10 + + + + Red + Rot + + src/app/data/paperless-tag.ts + 11 + + + + Light orange + Hellorange + + src/app/data/paperless-tag.ts + 12 + + + + Orange + Orange + + src/app/data/paperless-tag.ts + 13 + + + + Light violet + Hellviolet + + src/app/data/paperless-tag.ts + 14 + + + + Violet + Violet + + src/app/data/paperless-tag.ts + 15 + + + + Brown + Braun + + src/app/data/paperless-tag.ts + 16 + + + + Black + Schwarz + + src/app/data/paperless-tag.ts + 17 + + + + Light grey + Hellgrau + + src/app/data/paperless-tag.ts + 18 + + + + Create new item + Neues Element erstellen + + src/app/components/common/edit-dialog/edit-dialog.component.ts + 38 + + + + Edit item + Element bearbeiten + + src/app/components/common/edit-dialog/edit-dialog.component.ts + 42 + + + + Could not save element: + Konnte Element nicht speichern: + + src/app/components/common/edit-dialog/edit-dialog.component.ts + 46 + + + + Automatic + Automatisch + + src/app/components/manage/generic-list/generic-list.component.ts + 31 + + + + Do you really want to delete this element? + Möchten Sie dieses Element wirklich löschen? + + src/app/components/manage/generic-list/generic-list.component.ts + 88 + + + + Associated documents will not be deleted. + Assoziierte Dokumente werden nicht gelöscht. + + src/app/components/manage/generic-list/generic-list.component.ts + 95 + + + + Delete + Löschen + + src/app/components/manage/generic-list/generic-list.component.ts + 97 + + + + Any + + src/app/data/matching-model.ts + 12 + + + + All + + src/app/data/matching-model.ts + 13 + + + + Literal + + src/app/data/matching-model.ts + 14 + + + + Regular expression + Regulärer Ausdruck + + src/app/data/matching-model.ts + 15 + + + + Fuzzy match + + src/app/data/matching-model.ts + 16 + + + + Auto + Automatisch + + src/app/data/matching-model.ts + 17 + + + + + \ No newline at end of file From 9439718bdcfe3d14b3e2e5236d413e1f7a116db1 Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Wed, 30 Dec 2020 17:14:08 +0100 Subject: [PATCH 055/197] update angular messages --- src-ui/messages.xlf | 48 ++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src-ui/messages.xlf b/src-ui/messages.xlf index 18eeec0ef..5f12c504c 100644 --- a/src-ui/messages.xlf +++ b/src-ui/messages.xlf @@ -149,8 +149,8 @@ 161 - - Do you really want to delete document ''? + + Do you really want to delete document ""? src/app/components/document-detail/document-detail.component.ts 162 @@ -1050,36 +1050,36 @@ 115 - - This operation will add the tag "" to all selected document(s). + + This operation will add the tag "" to selected document(s). src/app/components/document-list/bulk-editor/bulk-editor.component.ts 118 - - This operation will add the tags to all selected document(s). + + This operation will add the tags to selected document(s). src/app/components/document-list/bulk-editor/bulk-editor.component.ts 120 - - This operation will remove the tag "" from all selected document(s). + + This operation will remove the tag "" from selected document(s). src/app/components/document-list/bulk-editor/bulk-editor.component.ts 123 - - This operation will remove the tags from all selected document(s). + + This operation will remove the tags from selected document(s). src/app/components/document-list/bulk-editor/bulk-editor.component.ts 125 - - This operation will add the tags and remove the tags on all selected document(s). + + This operation will add the tags and remove the tags on selected document(s). src/app/components/document-list/bulk-editor/bulk-editor.component.ts 127 @@ -1092,15 +1092,15 @@ 157 - - This operation will assign the correspondent "" to all selected document(s). + + This operation will assign the correspondent "" to selected document(s). src/app/components/document-list/bulk-editor/bulk-editor.component.ts 159 - - This operation will remove the correspondent from all selected document(s). + + This operation will remove the correspondent from selected document(s). src/app/components/document-list/bulk-editor/bulk-editor.component.ts 161 @@ -1113,15 +1113,15 @@ 190 - - This operation will assign the document type "" to all selected document(s). + + This operation will assign the document type "" to selected document(s). src/app/components/document-list/bulk-editor/bulk-editor.component.ts 192 - - This operation will remove the document type from all selected document(s). + + This operation will remove the document type from selected document(s). src/app/components/document-list/bulk-editor/bulk-editor.component.ts 194 @@ -1134,8 +1134,8 @@ 219 - - This operation will permanently delete all selected document(s). + + This operation will permanently delete selected document(s). src/app/components/document-list/bulk-editor/bulk-editor.component.ts 220 @@ -1281,8 +1281,8 @@ 5 - - You can start uploading documents by dropping them in the file upload box to the right or by dropping them in the configured consumption folder and they'll start showing up in the documents list. After you've added some metadata to your documents, use the filtering mechanisms of paperless to create custom views (such as 'Recently added', 'Tagged TODO') and have they will be shown on the dashboard instead of this message. + + You can start uploading documents by dropping them in the file upload box to the right or by dropping them in the configured consumption folder and they'll start showing up in the documents list. After you've added some metadata to your documents, use the filtering mechanisms of paperless to create custom views (such as 'Recently added', 'Tagged TODO') and they will appear on the dashboard instead of this message. src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html 6,7 From d07241ea31f05528a51d69e4126a6d6a9c23b3e1 Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Wed, 30 Dec 2020 17:17:36 +0100 Subject: [PATCH 056/197] improve file renaming speed. --- src/documents/signals/handlers.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/documents/signals/handlers.py b/src/documents/signals/handlers.py index 586897585..f2743c212 100755 --- a/src/documents/signals/handlers.py +++ b/src/documents/signals/handlers.py @@ -276,13 +276,6 @@ def update_filename_and_move_files(sender, instance, **kwargs): Document.objects.filter(pk=instance.pk).update( filename=new_filename) - logging.getLogger(__name__).debug( - f"Moved file {old_source_path} to {new_source_path}.") - - if instance.archive_checksum: - logging.getLogger(__name__).debug( - f"Moved file {old_archive_path} to {new_archive_path}.") - except OSError as e: instance.filename = old_filename # this happens when we can't move a file. If that's the case for From b35b26077c936e6a2c8a8cae4c27d05e837c3b71 Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Wed, 30 Dec 2020 17:18:27 +0100 Subject: [PATCH 057/197] Do file renaming first, since this is the important step, and indexing takes a while. --- src/documents/tasks.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/documents/tasks.py b/src/documents/tasks.py index f9937c177..ba7010ea9 100644 --- a/src/documents/tasks.py +++ b/src/documents/tasks.py @@ -94,7 +94,10 @@ def bulk_update_documents(document_ids): documents = Document.objects.filter(id__in=document_ids) ix = index.open_index() + + for doc in documents: + post_save.send(Document, instance=doc, created=False) + with AsyncWriter(ix) as writer: for doc in documents: index.update_document(writer, doc) - post_save.send(Document, instance=doc, created=False) From fa24a6777437f865a44b7b9fd45aea70bd9addd3 Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Wed, 30 Dec 2020 17:20:03 +0100 Subject: [PATCH 058/197] codestyle --- src/documents/management/commands/document_thumbnails.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/documents/management/commands/document_thumbnails.py b/src/documents/management/commands/document_thumbnails.py index 41ddec86e..01df14624 100644 --- a/src/documents/management/commands/document_thumbnails.py +++ b/src/documents/management/commands/document_thumbnails.py @@ -23,6 +23,7 @@ def _process_document(doc_in): finally: parser.cleanup() + class Command(Renderable, BaseCommand): help = """ @@ -62,4 +63,6 @@ class Command(Renderable, BaseCommand): db.connections.close_all() with multiprocessing.Pool() as pool: - list(tqdm.tqdm(pool.imap_unordered(_process_document, ids), total=len(ids))) + list(tqdm.tqdm( + pool.imap_unordered(_process_document, ids), total=len(ids) + )) From 6a3012ca33f158b743c3ab48638a0df44e269a6a Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Wed, 30 Dec 2020 21:48:34 +0100 Subject: [PATCH 059/197] add more translation --- src/documents/models.py | 200 +++++++++------ src/locale/de/LC_MESSAGES/django.po | 298 ++++++++++++++++++++++- src/locale/en-us/LC_MESSAGES/django.po | 322 +++++++++++++++++++++++++ 3 files changed, 748 insertions(+), 72 deletions(-) create mode 100644 src/locale/en-us/LC_MESSAGES/django.po diff --git a/src/documents/models.py b/src/documents/models.py index 168dd8c7b..6395d66aa 100755 --- a/src/documents/models.py +++ b/src/documents/models.py @@ -13,6 +13,8 @@ from django.contrib.auth.models import User from django.db import models from django.utils import timezone +from django.utils.translation import gettext_lazy as _ + from documents.file_handling import archive_name_from_filename from documents.parsers import get_default_file_extension @@ -27,36 +29,31 @@ class MatchingModel(models.Model): MATCH_AUTO = 6 MATCHING_ALGORITHMS = ( - (MATCH_ANY, "Any"), - (MATCH_ALL, "All"), - (MATCH_LITERAL, "Literal"), - (MATCH_REGEX, "Regular Expression"), - (MATCH_FUZZY, "Fuzzy Match"), - (MATCH_AUTO, "Automatic Classification"), + (MATCH_ANY, _("Any")), + (MATCH_ALL, _("All")), + (MATCH_LITERAL, _("Literal")), + (MATCH_REGEX, _("Regular Expression")), + (MATCH_FUZZY, _("Fuzzy Match")), + (MATCH_AUTO, _("Automatic Classification")), ) - name = models.CharField(max_length=128, unique=True) + name = models.CharField( + _("name"), + max_length=128, unique=True) + + match = models.CharField( + _("match"), + max_length=256, blank=True) - match = models.CharField(max_length=256, blank=True) matching_algorithm = models.PositiveIntegerField( + _("matching algorithm"), choices=MATCHING_ALGORITHMS, - default=MATCH_ANY, - help_text=( - "Which algorithm you want to use when matching text to the OCR'd " - "PDF. Here, \"any\" looks for any occurrence of any word " - "provided in the PDF, while \"all\" requires that every word " - "provided appear in the PDF, albeit not in the order provided. A " - "\"literal\" match means that the text you enter must appear in " - "the PDF exactly as you've entered it, and \"regular expression\" " - "uses a regex to match the PDF. (If you don't know what a regex " - "is, you probably don't want this option.) Finally, a \"fuzzy " - "match\" looks for words or phrases that are mostly—but not " - "exactly—the same, which can be useful for matching against " - "documents containg imperfections that foil accurate OCR." - ) + default=MATCH_ANY ) - is_insensitive = models.BooleanField(default=True) + is_insensitive = models.BooleanField( + _("is insensitive"), + default=True) class Meta: abstract = True @@ -80,6 +77,8 @@ class Correspondent(MatchingModel): class Meta: ordering = ("name",) + verbose_name = _("correspondent") + verbose_name_plural = _("correspondents") class Tag(MatchingModel): @@ -100,18 +99,28 @@ class Tag(MatchingModel): (13, "#cccccc") ) - colour = models.PositiveIntegerField(choices=COLOURS, default=1) + colour = models.PositiveIntegerField( + _("color"), + choices=COLOURS, default=1) is_inbox_tag = models.BooleanField( + _("is inbox tag"), default=False, - help_text="Marks this tag as an inbox tag: All newly consumed " - "documents will be tagged with inbox tags." + help_text=_("Marks this tag as an inbox tag: All newly consumed " + "documents will be tagged with inbox tags.") ) + class Meta: + verbose_name = _("tag") + verbose_name_plural = _("tags") + class DocumentType(MatchingModel): - pass + class Meta: + verbose_name = _("document type") + verbose_name_plural = _("document types") + class Document(models.Model): @@ -119,8 +128,8 @@ class Document(models.Model): STORAGE_TYPE_UNENCRYPTED = "unencrypted" STORAGE_TYPE_GPG = "gpg" STORAGE_TYPES = ( - (STORAGE_TYPE_UNENCRYPTED, "Unencrypted"), - (STORAGE_TYPE_GPG, "Encrypted with GNU Privacy Guard") + (STORAGE_TYPE_UNENCRYPTED, _("Unencrypted")), + (STORAGE_TYPE_GPG, _("Encrypted with GNU Privacy Guard")) ) correspondent = models.ForeignKey( @@ -128,55 +137,68 @@ class Document(models.Model): blank=True, null=True, related_name="documents", - on_delete=models.SET_NULL + on_delete=models.SET_NULL, + verbose_name=_("correspondent") ) - title = models.CharField(max_length=128, blank=True, db_index=True) + title = models.CharField( + _("title"), + max_length=128, blank=True, db_index=True) document_type = models.ForeignKey( DocumentType, blank=True, null=True, related_name="documents", - on_delete=models.SET_NULL + on_delete=models.SET_NULL, + verbose_name=_("document type") ) content = models.TextField( + _("content"), blank=True, - help_text="The raw, text-only data of the document. This field is " - "primarily used for searching." + help_text=_("The raw, text-only data of the document. This field is " + "primarily used for searching.") ) mime_type = models.CharField( + _("mime type"), max_length=256, editable=False ) tags = models.ManyToManyField( - Tag, related_name="documents", blank=True) + Tag, related_name="documents", blank=True, + verbose_name=_("tags") + ) checksum = models.CharField( + _("checksum"), max_length=32, editable=False, unique=True, - help_text="The checksum of the original document." + help_text=_("The checksum of the original document.") ) archive_checksum = models.CharField( + _("archive checksum"), max_length=32, editable=False, blank=True, null=True, - help_text="The checksum of the archived document." + help_text=_("The checksum of the archived document.") ) created = models.DateTimeField( + _("created"), default=timezone.now, db_index=True) modified = models.DateTimeField( + _("modified"), auto_now=True, editable=False, db_index=True) storage_type = models.CharField( + _("storage type"), max_length=11, choices=STORAGE_TYPES, default=STORAGE_TYPE_UNENCRYPTED, @@ -184,27 +206,32 @@ class Document(models.Model): ) added = models.DateTimeField( + _("added"), default=timezone.now, editable=False, db_index=True) filename = models.FilePathField( + _("filename"), max_length=1024, editable=False, default=None, null=True, - help_text="Current filename in storage" + help_text=_("Current filename in storage") ) archive_serial_number = models.IntegerField( + _("archive serial number"), blank=True, null=True, unique=True, db_index=True, - help_text="The position of this document in your physical document " - "archive." + help_text=_("The position of this document in your physical document " + "archive.") ) class Meta: ordering = ("-created",) + verbose_name = _("Document") + verbose_name_plural = _("Documents") def __str__(self): created = datetime.date.isoformat(self.created) @@ -293,13 +320,22 @@ class Log(models.Model): (logging.CRITICAL, "Critical"), ) - group = models.UUIDField(blank=True, null=True) - message = models.TextField() - level = models.PositiveIntegerField(choices=LEVELS, default=logging.INFO) - created = models.DateTimeField(auto_now_add=True) + group = models.UUIDField( + _("group"), + blank=True, null=True) + + message = models.TextField(_("message")) + + level = models.PositiveIntegerField( + _("level"), + choices=LEVELS, default=logging.INFO) + + created = models.DateTimeField(_("created"), auto_now_add=True) class Meta: ordering = ("-created",) + verbose_name = _("log") + verbose_name_plural = _("logs") def __str__(self): return self.message @@ -310,48 +346,70 @@ class SavedView(models.Model): class Meta: ordering = ("name",) + verbose_name = _("saved view") + verbose_name_plural = _("saved views") - user = models.ForeignKey(User, on_delete=models.CASCADE) - name = models.CharField(max_length=128) + user = models.ForeignKey(User, on_delete=models.CASCADE, + verbose_name=_("user")) + name = models.CharField( + _("name"), + max_length=128) - show_on_dashboard = models.BooleanField() - show_in_sidebar = models.BooleanField() + show_on_dashboard = models.BooleanField( + _("show on dashboard"), + ) + show_in_sidebar = models.BooleanField( + _("show in sidebar"), + ) - sort_field = models.CharField(max_length=128) - sort_reverse = models.BooleanField(default=False) + sort_field = models.CharField( + _("sort field"), + max_length=128) + sort_reverse = models.BooleanField( + _("sort reverse"), + default=False) class SavedViewFilterRule(models.Model): RULE_TYPES = [ - (0, "Title contains"), - (1, "Content contains"), - (2, "ASN is"), - (3, "Correspondent is"), - (4, "Document type is"), - (5, "Is in inbox"), - (6, "Has tag"), - (7, "Has any tag"), - (8, "Created before"), - (9, "Created after"), - (10, "Created year is"), - (11, "Created month is"), - (12, "Created day is"), - (13, "Added before"), - (14, "Added after"), - (15, "Modified before"), - (16, "Modified after"), - (17, "Does not have tag"), + (0, _("title contains")), + (1, _("content contains")), + (2, _("ASN is")), + (3, _("correspondent is")), + (4, _("document type is")), + (5, _("is in inbox")), + (6, _("has tag")), + (7, _("has any tag")), + (8, _("created before")), + (9, _("created after")), + (10, _("created year is")), + (11, _("created month is")), + (12, _("created day is")), + (13, _("added before")), + (14, _("added after")), + (15, _("modified before")), + (16, _("modified after")), + (17, _("does not have tag")), ] saved_view = models.ForeignKey( SavedView, on_delete=models.CASCADE, - related_name="filter_rules" + related_name="filter_rules", + verbose_name=_("saved view") ) - rule_type = models.PositiveIntegerField(choices=RULE_TYPES) + rule_type = models.PositiveIntegerField( + _("rule type"), + choices=RULE_TYPES) - value = models.CharField(max_length=128) + value = models.CharField( + _("value"), + max_length=128) + + class Meta: + verbose_name = _("filter rule") + verbose_name_plural = _("filter rules") # TODO: why is this in the models file? diff --git a/src/locale/de/LC_MESSAGES/django.po b/src/locale/de/LC_MESSAGES/django.po index bbab220a7..db1d2c437 100644 --- a/src/locale/de/LC_MESSAGES/django.po +++ b/src/locale/de/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-12-30 00:37+0000\n" +"POT-Creation-Date: 2020-12-30 19:20+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -18,6 +18,302 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" +#: documents/models.py:32 +msgid "Any" +msgstr "" + +#: documents/models.py:33 +msgid "All" +msgstr "" + +#: documents/models.py:34 +msgid "Literal" +msgstr "" + +#: documents/models.py:35 +msgid "Regular Expression" +msgstr "" + +#: documents/models.py:36 +msgid "Fuzzy Match" +msgstr "" + +#: documents/models.py:37 +msgid "Automatic Classification" +msgstr "" + +#: documents/models.py:41 documents/models.py:355 +msgid "name" +msgstr "" + +#: documents/models.py:45 +msgid "match" +msgstr "" + +#: documents/models.py:49 +msgid "matching algorithm" +msgstr "" + +#: documents/models.py:55 +msgid "is insensitive" +msgstr "" + +#: documents/models.py:80 documents/models.py:141 +msgid "correspondent" +msgstr "" + +#: documents/models.py:81 +msgid "correspondents" +msgstr "" + +#: documents/models.py:103 +msgid "color" +msgstr "" + +#: documents/models.py:107 +msgid "is inbox tag" +msgstr "" + +#: documents/models.py:109 +msgid "" +"Marks this tag as an inbox tag: All newly consumed documents will be tagged " +"with inbox tags." +msgstr "" + +#: documents/models.py:114 +msgid "tag" +msgstr "" + +#: documents/models.py:115 documents/models.py:172 +msgid "tags" +msgstr "" + +#: documents/models.py:121 documents/models.py:154 +msgid "document type" +msgstr "Dokumenttyp" + +#: documents/models.py:122 +msgid "document types" +msgstr "Dokumenttypen" + +#: documents/models.py:131 +msgid "Unencrypted" +msgstr "" + +#: documents/models.py:132 +msgid "Encrypted with GNU Privacy Guard" +msgstr "" + +#: documents/models.py:145 +msgid "title" +msgstr "" + +#: documents/models.py:158 +msgid "content" +msgstr "" + +#: documents/models.py:160 +msgid "" +"The raw, text-only data of the document. This field is primarily used for " +"searching." +msgstr "" + +#: documents/models.py:165 +msgid "mime type" +msgstr "" + +#: documents/models.py:176 +msgid "checksum" +msgstr "" + +#: documents/models.py:180 +msgid "The checksum of the original document." +msgstr "" + +#: documents/models.py:184 +msgid "archive checksum" +msgstr "" + +#: documents/models.py:189 +msgid "The checksum of the archived document." +msgstr "" + +#: documents/models.py:193 documents/models.py:333 +msgid "created" +msgstr "" + +#: documents/models.py:197 +msgid "modified" +msgstr "" + +#: documents/models.py:201 +msgid "storage type" +msgstr "" + +#: documents/models.py:209 +msgid "added" +msgstr "" + +#: documents/models.py:213 +msgid "filename" +msgstr "" + +#: documents/models.py:218 +msgid "Current filename in storage" +msgstr "" + +#: documents/models.py:222 +msgid "archive serial number" +msgstr "" + +#: documents/models.py:227 +msgid "The position of this document in your physical document archive." +msgstr "" + +#: documents/models.py:233 +msgid "Document" +msgstr "" + +#: documents/models.py:234 +msgid "Documents" +msgstr "" + +#: documents/models.py:324 +msgid "group" +msgstr "" + +#: documents/models.py:327 +msgid "message" +msgstr "" + +#: documents/models.py:330 +msgid "level" +msgstr "" + +#: documents/models.py:337 +msgid "log" +msgstr "" + +#: documents/models.py:338 +msgid "logs" +msgstr "" + +#: documents/models.py:349 documents/models.py:399 +msgid "saved view" +msgstr "" + +#: documents/models.py:350 +msgid "saved views" +msgstr "" + +#: documents/models.py:353 +msgid "user" +msgstr "Benutzer" + +#: documents/models.py:359 +msgid "show on dashboard" +msgstr "" + +#: documents/models.py:362 +msgid "show in sidebar" +msgstr "" + +#: documents/models.py:366 +msgid "sort field" +msgstr "" + +#: documents/models.py:369 +msgid "sort reverse" +msgstr "" + +#: documents/models.py:375 +msgid "title contains" +msgstr "" + +#: documents/models.py:376 +msgid "content contains" +msgstr "" + +#: documents/models.py:377 +msgid "ASN is" +msgstr "" + +#: documents/models.py:378 +msgid "correspondent is" +msgstr "" + +#: documents/models.py:379 +msgid "document type is" +msgstr "" + +#: documents/models.py:380 +msgid "is in inbox" +msgstr "" + +#: documents/models.py:381 +msgid "has tag" +msgstr "" + +#: documents/models.py:382 +msgid "has any tag" +msgstr "" + +#: documents/models.py:383 +msgid "created before" +msgstr "" + +#: documents/models.py:384 +msgid "created after" +msgstr "" + +#: documents/models.py:385 +msgid "created year is" +msgstr "" + +#: documents/models.py:386 +msgid "created month is" +msgstr "" + +#: documents/models.py:387 +msgid "created day is" +msgstr "" + +#: documents/models.py:388 +msgid "added before" +msgstr "" + +#: documents/models.py:389 +msgid "added after" +msgstr "" + +#: documents/models.py:390 +msgid "modified before" +msgstr "" + +#: documents/models.py:391 +msgid "modified after" +msgstr "" + +#: documents/models.py:392 +msgid "does not have tag" +msgstr "" + +#: documents/models.py:403 +msgid "rule type" +msgstr "" + +#: documents/models.py:407 +msgid "value" +msgstr "" + +#: documents/models.py:411 +msgid "filter rule" +msgstr "" + +#: documents/models.py:412 +msgid "filter rules" +msgstr "Filterregeln" + #: paperless/settings.py:253 msgid "English" msgstr "" diff --git a/src/locale/en-us/LC_MESSAGES/django.po b/src/locale/en-us/LC_MESSAGES/django.po new file mode 100644 index 000000000..c3c76c5a4 --- /dev/null +++ b/src/locale/en-us/LC_MESSAGES/django.po @@ -0,0 +1,322 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-12-30 19:20+0000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: documents/models.py:32 +msgid "Any" +msgstr "" + +#: documents/models.py:33 +msgid "All" +msgstr "" + +#: documents/models.py:34 +msgid "Literal" +msgstr "" + +#: documents/models.py:35 +msgid "Regular Expression" +msgstr "" + +#: documents/models.py:36 +msgid "Fuzzy Match" +msgstr "" + +#: documents/models.py:37 +msgid "Automatic Classification" +msgstr "" + +#: documents/models.py:41 documents/models.py:355 +msgid "name" +msgstr "" + +#: documents/models.py:45 +msgid "match" +msgstr "" + +#: documents/models.py:49 +msgid "matching algorithm" +msgstr "" + +#: documents/models.py:55 +msgid "is insensitive" +msgstr "" + +#: documents/models.py:80 documents/models.py:141 +msgid "correspondent" +msgstr "" + +#: documents/models.py:81 +msgid "correspondents" +msgstr "" + +#: documents/models.py:103 +msgid "color" +msgstr "" + +#: documents/models.py:107 +msgid "is inbox tag" +msgstr "" + +#: documents/models.py:109 +msgid "" +"Marks this tag as an inbox tag: All newly consumed documents will be tagged " +"with inbox tags." +msgstr "" + +#: documents/models.py:114 +msgid "tag" +msgstr "" + +#: documents/models.py:115 documents/models.py:172 +msgid "tags" +msgstr "" + +#: documents/models.py:121 documents/models.py:154 +msgid "document type" +msgstr "" + +#: documents/models.py:122 +msgid "document types" +msgstr "" + +#: documents/models.py:131 +msgid "Unencrypted" +msgstr "" + +#: documents/models.py:132 +msgid "Encrypted with GNU Privacy Guard" +msgstr "" + +#: documents/models.py:145 +msgid "title" +msgstr "" + +#: documents/models.py:158 +msgid "content" +msgstr "" + +#: documents/models.py:160 +msgid "" +"The raw, text-only data of the document. This field is primarily used for " +"searching." +msgstr "" + +#: documents/models.py:165 +msgid "mime type" +msgstr "" + +#: documents/models.py:176 +msgid "checksum" +msgstr "" + +#: documents/models.py:180 +msgid "The checksum of the original document." +msgstr "" + +#: documents/models.py:184 +msgid "archive checksum" +msgstr "" + +#: documents/models.py:189 +msgid "The checksum of the archived document." +msgstr "" + +#: documents/models.py:193 documents/models.py:333 +msgid "created" +msgstr "" + +#: documents/models.py:197 +msgid "modified" +msgstr "" + +#: documents/models.py:201 +msgid "storage type" +msgstr "" + +#: documents/models.py:209 +msgid "added" +msgstr "" + +#: documents/models.py:213 +msgid "filename" +msgstr "" + +#: documents/models.py:218 +msgid "Current filename in storage" +msgstr "" + +#: documents/models.py:222 +msgid "archive serial number" +msgstr "" + +#: documents/models.py:227 +msgid "The position of this document in your physical document archive." +msgstr "" + +#: documents/models.py:233 +msgid "Document" +msgstr "" + +#: documents/models.py:234 +msgid "Documents" +msgstr "" + +#: documents/models.py:324 +msgid "group" +msgstr "" + +#: documents/models.py:327 +msgid "message" +msgstr "" + +#: documents/models.py:330 +msgid "level" +msgstr "" + +#: documents/models.py:337 +msgid "log" +msgstr "" + +#: documents/models.py:338 +msgid "logs" +msgstr "" + +#: documents/models.py:349 documents/models.py:399 +msgid "saved view" +msgstr "" + +#: documents/models.py:350 +msgid "saved views" +msgstr "" + +#: documents/models.py:353 +msgid "user" +msgstr "" + +#: documents/models.py:359 +msgid "show on dashboard" +msgstr "" + +#: documents/models.py:362 +msgid "show in sidebar" +msgstr "" + +#: documents/models.py:366 +msgid "sort field" +msgstr "" + +#: documents/models.py:369 +msgid "sort reverse" +msgstr "" + +#: documents/models.py:375 +msgid "title contains" +msgstr "" + +#: documents/models.py:376 +msgid "content contains" +msgstr "" + +#: documents/models.py:377 +msgid "ASN is" +msgstr "" + +#: documents/models.py:378 +msgid "correspondent is" +msgstr "" + +#: documents/models.py:379 +msgid "document type is" +msgstr "" + +#: documents/models.py:380 +msgid "is in inbox" +msgstr "" + +#: documents/models.py:381 +msgid "has tag" +msgstr "" + +#: documents/models.py:382 +msgid "has any tag" +msgstr "" + +#: documents/models.py:383 +msgid "created before" +msgstr "" + +#: documents/models.py:384 +msgid "created after" +msgstr "" + +#: documents/models.py:385 +msgid "created year is" +msgstr "" + +#: documents/models.py:386 +msgid "created month is" +msgstr "" + +#: documents/models.py:387 +msgid "created day is" +msgstr "" + +#: documents/models.py:388 +msgid "added before" +msgstr "" + +#: documents/models.py:389 +msgid "added after" +msgstr "" + +#: documents/models.py:390 +msgid "modified before" +msgstr "" + +#: documents/models.py:391 +msgid "modified after" +msgstr "" + +#: documents/models.py:392 +msgid "does not have tag" +msgstr "" + +#: documents/models.py:403 +msgid "rule type" +msgstr "" + +#: documents/models.py:407 +msgid "value" +msgstr "" + +#: documents/models.py:411 +msgid "filter rule" +msgstr "" + +#: documents/models.py:412 +msgid "filter rules" +msgstr "" + +#: paperless/settings.py:253 +msgid "English" +msgstr "" + +#: paperless/settings.py:254 +msgid "German" +msgstr "" From 2b4bcff59920caa86ad6890c6f139a68700db8c1 Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Wed, 30 Dec 2020 21:54:36 +0100 Subject: [PATCH 060/197] fixes #222 --- src/documents/consumer.py | 2 +- src/documents/management/commands/document_retagger.py | 2 +- src/documents/tasks.py | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/documents/consumer.py b/src/documents/consumer.py index 4bcb6d1d9..5a06194b7 100755 --- a/src/documents/consumer.py +++ b/src/documents/consumer.py @@ -158,7 +158,7 @@ class Consumer(LoggingMixin): try: classifier = DocumentClassifier() classifier.reload() - except (FileNotFoundError, IncompatibleClassifierVersionError) as e: + except (OSError, EOFError, IncompatibleClassifierVersionError) as e: self.log( "warning", f"Cannot classify documents: {e}.") diff --git a/src/documents/management/commands/document_retagger.py b/src/documents/management/commands/document_retagger.py index cf014dc6f..0fb9782c1 100755 --- a/src/documents/management/commands/document_retagger.py +++ b/src/documents/management/commands/document_retagger.py @@ -73,7 +73,7 @@ class Command(Renderable, BaseCommand): classifier = DocumentClassifier() try: classifier.reload() - except (FileNotFoundError, IncompatibleClassifierVersionError) as e: + except (OSError, EOFError, IncompatibleClassifierVersionError) as e: logging.getLogger(__name__).warning( f"Cannot classify documents: {e}.") classifier = None diff --git a/src/documents/tasks.py b/src/documents/tasks.py index ba7010ea9..38ff532b5 100644 --- a/src/documents/tasks.py +++ b/src/documents/tasks.py @@ -35,9 +35,9 @@ def train_classifier(): try: # load the classifier, since we might not have to train it again. classifier.reload() - except (FileNotFoundError, IncompatibleClassifierVersionError): + except (OSError, EOFError, IncompatibleClassifierVersionError): # This is what we're going to fix here. - pass + classifier = DocumentClassifier() try: if classifier.train(): From 9a1e659d4eeb41a29bb4546d5d7ff302b0593938 Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Wed, 30 Dec 2020 23:01:34 +0100 Subject: [PATCH 061/197] fixes #224 --- src-ui/src/app/components/common/input/tags/tags.component.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src-ui/src/app/components/common/input/tags/tags.component.html b/src-ui/src/app/components/common/input/tags/tags.component.html index 8a5dbc4f2..01b3fe755 100644 --- a/src-ui/src/app/components/common/input/tags/tags.component.html +++ b/src-ui/src/app/components/common/input/tags/tags.component.html @@ -5,7 +5,9 @@ From 8432f3a4f1c552dd641f46c65217a0644ce7f57c Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Wed, 30 Dec 2020 23:34:21 +0100 Subject: [PATCH 062/197] this immensely improves resposibility --- .../app/components/document-list/document-list.component.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src-ui/src/app/components/document-list/document-list.component.html b/src-ui/src/app/components/document-list/document-list.component.html index bc1047ba9..e627c428d 100644 --- a/src-ui/src/app/components/document-list/document-list.component.html +++ b/src-ui/src/app/components/document-list/document-list.component.html @@ -78,8 +78,8 @@
      - - + +
      From 74828a1238169c69031a4e5161f209bee2c87ffe Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Wed, 30 Dec 2020 23:34:50 +0100 Subject: [PATCH 063/197] fixes a bug with invisible selection --- .../correspondent-list.component.ts | 9 ++------- .../document-type-list.component.ts | 7 +------ .../components/manage/tag-list/tag-list.component.ts | 9 ++------- src-ui/src/app/services/document-list-view.service.ts | 11 ++++++++++- 4 files changed, 15 insertions(+), 21 deletions(-) diff --git a/src-ui/src/app/components/manage/correspondent-list/correspondent-list.component.ts b/src-ui/src/app/components/manage/correspondent-list/correspondent-list.component.ts index d3b71b4ab..37b6fa66e 100644 --- a/src-ui/src/app/components/manage/correspondent-list/correspondent-list.component.ts +++ b/src-ui/src/app/components/manage/correspondent-list/correspondent-list.component.ts @@ -1,5 +1,4 @@ -import { Component, OnInit } from '@angular/core'; -import { Router } from '@angular/router'; +import { Component } from '@angular/core'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { FILTER_CORRESPONDENT } from 'src/app/data/filter-rule-type'; import { PaperlessCorrespondent } from 'src/app/data/paperless-correspondent'; @@ -16,7 +15,6 @@ import { CorrespondentEditDialogComponent } from './correspondent-edit-dialog/co export class CorrespondentListComponent extends GenericListComponent { constructor(correspondentsService: CorrespondentService, modalService: NgbModal, - private router: Router, private list: DocumentListViewService ) { super(correspondentsService,modalService,CorrespondentEditDialogComponent) @@ -27,9 +25,6 @@ export class CorrespondentListComponent extends GenericListComponent { constructor(service: DocumentTypeService, modalService: NgbModal, - private router: Router, private list: DocumentListViewService ) { super(service, modalService, DocumentTypeEditDialogComponent) @@ -28,9 +26,6 @@ export class DocumentTypeListComponent extends GenericListComponent { constructor(tagService: TagService, modalService: NgbModal, - private router: Router, private list: DocumentListViewService ) { super(tagService, modalService, TagEditDialogComponent) @@ -27,14 +25,11 @@ export class TagListComponent extends GenericListComponent { } getDeleteMessage(object: PaperlessTag) { - return $localize`Do you really want to delete the tag "${object.name}"?` } filterDocuments(object: PaperlessTag) { - this.list.documentListView.filter_rules = [ - {rule_type: FILTER_HAS_TAG, value: object.id.toString()} - ] - this.router.navigate(["documents"]) + this.list.quickFilter([{rule_type: FILTER_HAS_TAG, value: object.id.toString()}]) + } } diff --git a/src-ui/src/app/services/document-list-view.service.ts b/src-ui/src/app/services/document-list-view.service.ts index dfcf9c0c5..eb69439ec 100644 --- a/src-ui/src/app/services/document-list-view.service.ts +++ b/src-ui/src/app/services/document-list-view.service.ts @@ -1,4 +1,5 @@ import { Injectable } from '@angular/core'; +import { Router } from '@angular/router'; import { Observable } from 'rxjs'; import { cloneFilterRules, FilterRule } from '../data/filter-rule'; import { PaperlessDocument } from '../data/paperless-document'; @@ -155,6 +156,14 @@ export class DocumentListViewService { sessionStorage.setItem(DOCUMENT_LIST_SERVICE.CURRENT_VIEW_CONFIG, JSON.stringify(this.documentListView)) } + quickFilter(filterRules: FilterRule[]) { + this.savedView = null + this.view.filter_rules = filterRules + this.reduceSelectionToFilter() + this.saveDocumentListView() + this.router.navigate(["documents"]) + } + getLastPage(): number { return Math.ceil(this.collectionSize / this.currentPageSize) } @@ -240,7 +249,7 @@ export class DocumentListViewService { } } - constructor(private documentService: DocumentService, private settings: SettingsService) { + constructor(private documentService: DocumentService, private settings: SettingsService, private router: Router) { let documentListViewConfigJson = sessionStorage.getItem(DOCUMENT_LIST_SERVICE.CURRENT_VIEW_CONFIG) if (documentListViewConfigJson) { try { From e893fe8c5c63bdfe9b668cd59c37a61f671a0c23 Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Thu, 31 Dec 2020 00:56:53 +0100 Subject: [PATCH 064/197] intelligent sorting of the bulk edit drop downs --- .../filterable-dropdown.component.html | 2 +- .../filterable-dropdown.component.ts | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.html b/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.html index 015269c17..b09491683 100644 --- a/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.html +++ b/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -20,7 +20,7 @@
    - +
    diff --git a/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts b/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts index e1aa6a06a..b51923c27 100644 --- a/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts +++ b/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts @@ -18,6 +18,18 @@ export class FilterableDropdownSelectionModel { items: MatchingModel[] = [] + get itemsSorted(): MatchingModel[] { + return this.items.sort((a,b) => { + if (this.getNonTemporary(a.id) == ToggleableItemState.NotSelected && this.getNonTemporary(b.id) != ToggleableItemState.NotSelected) { + return 1 + } else if (this.getNonTemporary(a.id) != ToggleableItemState.NotSelected && this.getNonTemporary(b.id) == ToggleableItemState.NotSelected) { + return -1 + } else { + return a.name.localeCompare(b.name) + } + }) + } + private selectionStates = new Map() private temporarySelectionStates = new Map() @@ -69,6 +81,10 @@ export class FilterableDropdownSelectionModel { } + private getNonTemporary(id: number) { + return this.selectionStates.get(id) || ToggleableItemState.NotSelected + } + get(id: number) { return this.temporarySelectionStates.get(id) || ToggleableItemState.NotSelected } From f81613c79c8e8025a8f4cd5d04b7eda4f9180b1a Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Thu, 31 Dec 2020 01:20:38 +0100 Subject: [PATCH 065/197] add the manifest to the frontend entry page #219 --- src/documents/templates/index.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/documents/templates/index.html b/src/documents/templates/index.html index 47a352cd5..83544b5e4 100644 --- a/src/documents/templates/index.html +++ b/src/documents/templates/index.html @@ -12,7 +12,9 @@ - + + + Loading... From 5f5d7b35cceb574aeedf7ae120b77fa0acb68185 Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Thu, 31 Dec 2020 01:43:04 +0100 Subject: [PATCH 066/197] fix sorting for "not assigned" --- .../filterable-dropdown/filterable-dropdown.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.html b/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.html index b09491683..a0e833c98 100644 --- a/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.html +++ b/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -20,7 +20,7 @@
- +
From 0ed2149f771333348f8ba526829e6db4d28f799b Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Thu, 31 Dec 2020 01:58:32 +0100 Subject: [PATCH 067/197] fix hover for check boxes --- .../document-card-small/document-card-small.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.html b/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.html index e0d8d28e1..f6128e077 100644 --- a/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.html +++ b/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.html @@ -1,5 +1,5 @@
-
+
From ec74a754c50a7b55c561262be23575c4bd75889a Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Thu, 31 Dec 2020 02:15:16 +0100 Subject: [PATCH 068/197] changelog --- docs/changelog.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index 4357a981b..bba0d087f 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -25,6 +25,8 @@ paperless-ng 0.9.10 * Added missing dependencies for Raspberry Pi builds. * Fixed an issue with plain text file consumption: Thumbnail generation failed due to missing fonts. * An issue with the search index reporting missing documents after bulk deletes was fixed. + * Issue with the tag selector not clearing input correctly. + * The consumer used to stop working when encountering an incomplete classifier model file. .. note:: From 20416f31d0fe67150e5e2366a5804a41185793c2 Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Thu, 31 Dec 2020 02:40:43 +0100 Subject: [PATCH 069/197] changelog --- docs/changelog.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index bba0d087f..fe4d89a55 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -15,6 +15,7 @@ paperless-ng 0.9.10 * Other changes and additions + * Thanks to `zjean`_, paperless now publishes a webmanifest, which is useful for adding the application to home screens on mobile devices. * The Paperless-ng logo now navigates to the dashboard. * Filter for documents that don't have any correspondents, types or tags assigned. * Tags, types and correspondents are now sorted case insensitive. @@ -958,6 +959,7 @@ bulk of the work on this big change. * Initial release +.. _zjean: https://github.com/zjean .. _rYR79435: https://github.com/rYR79435 .. _Michael Shamoon: https://github.com/shamoon .. _jayme-github: http://github.com/jayme-github From 7a09519a3f8e3fcaa0530455f70ad3a1416d006d Mon Sep 17 00:00:00 2001 From: Michael Shamoon <4887959+nikonratm@users.noreply.github.com> Date: Wed, 30 Dec 2020 23:16:30 -0800 Subject: [PATCH 070/197] Fix overflowing document titles on homepage mobile view --- .../saved-view-widget/saved-view-widget.component.scss | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.scss b/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.scss index e69de29bb..40d1c836b 100644 --- a/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.scss +++ b/src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.scss @@ -0,0 +1,7 @@ +table { + overflow-wrap: anywhere; +} + +th:first-child { + min-width: 5rem; +} From f5f415526a0e47930b4501d4057cb3cc57ae5571 Mon Sep 17 00:00:00 2001 From: Michael Shamoon <4887959+nikonratm@users.noreply.github.com> Date: Wed, 30 Dec 2020 23:39:07 -0800 Subject: [PATCH 071/197] Reorganized navbar Updated search field, new user menu --- .../app-frame/app-frame.component.html | 58 +++++++++++-------- .../app-frame/app-frame.component.scss | 45 ++++++++++---- 2 files changed, 70 insertions(+), 33 deletions(-) diff --git a/src-ui/src/app/components/app-frame/app-frame.component.html b/src-ui/src/app/components/app-frame/app-frame.component.html index d191ec0de..9d6c4924f 100644 --- a/src-ui/src/app/components/app-frame/app-frame.component.html +++ b/src-ui/src/app/components/app-frame/app-frame.component.html @@ -1,17 +1,43 @@ diff --git a/src-ui/src/app/components/app-frame/app-frame.component.scss b/src-ui/src/app/components/app-frame/app-frame.component.scss index 5ace8a2ff..433fe3054 100644 --- a/src-ui/src/app/components/app-frame/app-frame.component.scss +++ b/src-ui/src/app/components/app-frame/app-frame.component.scss @@ -72,17 +72,42 @@ padding-top: .75rem; padding-bottom: .75rem; font-size: 1rem; - background-color: rgba(0, 0, 0, .25); - box-shadow: inset -1px 0 0 rgba(0, 0, 0, .25); } -.navbar .navbar-toggler { - top: .25rem; - right: 1rem; -} +.navbar .search-form-container { + max-width: 550px; + position: relative; -.navbar .form-control { - padding: .75rem 1rem; - border-width: 0; - border-radius: 0; + svg { + position: absolute; + left: 1.8em; + color: rgba(255, 255, 255, 0.6); + } + + &:focus-within { + svg { + display: none; + } + } + + .form-control { + color: rgba(255, 255, 255, 0.5); + background-color: rgba(0, 0, 0, 0.2); + padding-left: 1.8rem; + border-color: rgba(255, 255, 255, 0.5); + transition: flex 0.3s ease; + max-width: 600px; + min-width: 300px; // 1/2 max + + &::placeholder { + color: rgba(255, 255, 255, 0.5); + } + + &:focus { + background-color: #fff; + color: initial; + flex-grow: 1; + padding-left: 0.5rem; + } + } } From 5a8f17ade0bed89b2f4c21a00bf3042c198e932e Mon Sep 17 00:00:00 2001 From: Michael Shamoon <4887959+nikonratm@users.noreply.github.com> Date: Thu, 31 Dec 2020 00:35:54 -0800 Subject: [PATCH 072/197] Toggle caret tweaks --- .../app-frame/app-frame.component.scss | 48 ++++++++++--------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/src-ui/src/app/components/app-frame/app-frame.component.scss b/src-ui/src/app/components/app-frame/app-frame.component.scss index 433fe3054..44b1531b1 100644 --- a/src-ui/src/app/components/app-frame/app-frame.component.scss +++ b/src-ui/src/app/components/app-frame/app-frame.component.scss @@ -1,23 +1,19 @@ - @import "/src/theme"; - - /* +/* * Sidebar */ - - .sidebar { +.sidebar { position: fixed; top: 0; bottom: 0; left: 0; z-index: 100; /* Behind the navbar */ - padding: 48px 0 0; /* Height of navbar */ + padding: 50px 0 0; /* Height of navbar */ box-shadow: inset -1px 0 0 rgba(0, 0, 0, .1); } - @media (max-width: 767.98px) { .sidebar { - top: 3rem; + top: 3.5rem; } } @@ -26,11 +22,11 @@ top: 0; /* height: calc(100vh - 48px); */ height: 100%; - padding-top: .5rem; + padding-top: 0.5rem; overflow-x: hidden; - overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */ + overflow-y: auto; + /* Scrollable contents if viewport is shorter than content. */ } - @supports ((position: -webkit-sticky) or (position: sticky)) { .sidebar-sticky { position: -webkit-sticky; @@ -53,27 +49,33 @@ font-weight: bold; } -.sidebar .nav-link:hover .sidebaricon, -.sidebar .nav-link.active .sidebaricon { +.sidebar .nav-link.active .sidebaricon, +.sidebar .nav-link:hover .sidebaricon { color: inherit; } .sidebar-heading { - font-size: .75rem; + font-size: 0.75rem; text-transform: uppercase; } - /* * Navbar */ - - .navbar-brand { - padding-top: .75rem; - padding-bottom: .75rem; +.navbar-brand { + padding-top: 0.75rem; + padding-bottom: 0.75rem; font-size: 1rem; } +.navbar-toggler { +} + +.dropdown-toggle::after { + margin-left: 0.4em; + vertical-align: 0.155em; +} + .navbar .search-form-container { max-width: 550px; position: relative; @@ -91,16 +93,16 @@ } .form-control { - color: rgba(255, 255, 255, 0.5); - background-color: rgba(0, 0, 0, 0.2); + color: rgba(255, 255, 255, 0.3); + background-color: rgba(0, 0, 0, 0.15); padding-left: 1.8rem; - border-color: rgba(255, 255, 255, 0.5); + border-color: rgba(255, 255, 255, 0.2); transition: flex 0.3s ease; max-width: 600px; min-width: 300px; // 1/2 max &::placeholder { - color: rgba(255, 255, 255, 0.5); + color: rgba(255, 255, 255, 0.4); } &:focus { From 454f617af79dc2af8d9383870745fb79fbee917f Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Thu, 31 Dec 2020 11:12:46 +0100 Subject: [PATCH 073/197] roll back changes #184 #227 --- docker/gunicorn.conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/gunicorn.conf.py b/docker/gunicorn.conf.py index 5c9c0eb37..edfb362d9 100644 --- a/docker/gunicorn.conf.py +++ b/docker/gunicorn.conf.py @@ -1,4 +1,4 @@ -bind = ['[::]:8000', 'localhost:8000'] +bind = '0.0.0.0:8000' backlog = 2048 workers = 3 worker_class = 'sync' From 0169d23eae9b7afb2eeced39b6613ebe041f8052 Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Thu, 31 Dec 2020 11:23:03 +0100 Subject: [PATCH 074/197] bump versions --- docker/hub/docker-compose.postgres.yml | 2 +- docker/hub/docker-compose.sqlite.yml | 2 +- docs/changelog.rst | 7 +++++++ src-ui/src/environments/environment.prod.ts | 2 +- src/paperless/version.py | 2 +- 5 files changed, 11 insertions(+), 4 deletions(-) diff --git a/docker/hub/docker-compose.postgres.yml b/docker/hub/docker-compose.postgres.yml index c2b599e52..0779cea22 100644 --- a/docker/hub/docker-compose.postgres.yml +++ b/docker/hub/docker-compose.postgres.yml @@ -15,7 +15,7 @@ services: POSTGRES_PASSWORD: paperless webserver: - image: jonaswinkler/paperless-ng:0.9.10 + image: jonaswinkler/paperless-ng:0.9.11 restart: always depends_on: - db diff --git a/docker/hub/docker-compose.sqlite.yml b/docker/hub/docker-compose.sqlite.yml index 429d42c06..3eed96cc3 100644 --- a/docker/hub/docker-compose.sqlite.yml +++ b/docker/hub/docker-compose.sqlite.yml @@ -5,7 +5,7 @@ services: restart: always webserver: - image: jonaswinkler/paperless-ng:0.9.10 + image: jonaswinkler/paperless-ng:0.9.11 restart: always depends_on: - broker diff --git a/docs/changelog.rst b/docs/changelog.rst index fe4d89a55..70f5cf683 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -5,6 +5,13 @@ Changelog ********* + +paperless-ng 0.9.11 +################### + +* Fixed an issue with the docker image not starting at all due to a configuration change of the web server. + + paperless-ng 0.9.10 ################### diff --git a/src-ui/src/environments/environment.prod.ts b/src-ui/src/environments/environment.prod.ts index 7b707f014..1ac69bc39 100644 --- a/src-ui/src/environments/environment.prod.ts +++ b/src-ui/src/environments/environment.prod.ts @@ -2,5 +2,5 @@ export const environment = { production: true, apiBaseUrl: "/api/", appTitle: "Paperless-ng", - version: "0.9.10" + version: "0.9.11" }; diff --git a/src/paperless/version.py b/src/paperless/version.py index facb097fc..e1ba14cb4 100644 --- a/src/paperless/version.py +++ b/src/paperless/version.py @@ -1 +1 @@ -__version__ = (0, 9, 10) +__version__ = (0, 9, 11) From aa88f25267e99c4d88943442cd58c97ce6f957b9 Mon Sep 17 00:00:00 2001 From: Jo Vandeginste Date: Thu, 31 Dec 2020 14:41:47 +0100 Subject: [PATCH 075/197] Refactor after feedback: - rename PAPERLESS_TIKA to PAPERLESS_TIKA_ENABLED - all other env params now start with PAPERLESS_TIKA - convert_to_pdf as class instance method - smaller details Signed-off-by: Jo Vandeginste --- docker/hub/docker-compose.tika.yml | 6 +-- docker/local/docker-compose.tika.yml | 6 +-- docs/configuration.rst | 6 +-- src/paperless/settings.py | 7 ++- src/paperless_tika/apps.py | 2 +- src/paperless_tika/parsers.py | 65 +++++++++++++--------------- src/paperless_tika/test.py | 3 -- 7 files changed, 46 insertions(+), 49 deletions(-) delete mode 100644 src/paperless_tika/test.py diff --git a/docker/hub/docker-compose.tika.yml b/docker/hub/docker-compose.tika.yml index 04dd3260e..af8f575a0 100644 --- a/docker/hub/docker-compose.tika.yml +++ b/docker/hub/docker-compose.tika.yml @@ -24,9 +24,9 @@ services: env_file: docker-compose.env environment: PAPERLESS_REDIS: redis://broker:6379 - PAPERLESS_TIKA: 1 - GOTENBERG_SERVER_ENDPOINT: http://gotenberg:3000 - TIKA_SERVER_ENDPOINT: http://tika:9998 + PAPERLESS_TIKA_ENABLED: 1 + PAPERLESS_TIKA_GOTENBERG_ENDPOINT: http://gotenberg:3000 + PAPERLESS_TIKA_ENDPOINT: http://tika:9998 gotenberg: image: thecodingmachine/gotenberg diff --git a/docker/local/docker-compose.tika.yml b/docker/local/docker-compose.tika.yml index ab901f306..889713908 100644 --- a/docker/local/docker-compose.tika.yml +++ b/docker/local/docker-compose.tika.yml @@ -24,9 +24,9 @@ services: env_file: docker-compose.env environment: PAPERLESS_REDIS: redis://broker:6379 - PAPERLESS_TIKA: 1 - GOTENBERG_SERVER_ENDPOINT: http://gotenberg:3000 - TIKA_SERVER_ENDPOINT: http://tika:9998 + PAPERLESS_TIKA_ENABLED: 1 + PAPERLESS_TIKA_GOTENBERG_ENDPOINT: http://gotenberg:3000 + PAPERLESS_TIKA_ENDPOINT: http://tika:9998 gotenberg: image: thecodingmachine/gotenberg diff --git a/docs/configuration.rst b/docs/configuration.rst index f53acb633..49c95bff1 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -291,17 +291,17 @@ configure their endpoints, and enable the feature. If you run paperless on docker, you can add those services to the docker-compose file (see the examples provided). -PAPERLESS_TIKA= +PAPERLESS_TIKA_ENABLED= Enable (or disable) the Tika parser. Defaults to false. -TIKA_SERVER_ENDPOINT= +PAPERLESS_TIKA_ENDPOINT= Set the endpoint URL were Paperless can reach your Tika server. Defaults to "http://localhost:9998". -GOTENBERG_SERVER_ENDPOINT= +PAPERLESS_TIKA_GOTENBERG_ENDPOINT= Set the endpoint URL were Paperless can reach your Gotenberg server. Defaults to "http://localhost:3000". diff --git a/src/paperless/settings.py b/src/paperless/settings.py index 219166cf5..caa1b9b18 100644 --- a/src/paperless/settings.py +++ b/src/paperless/settings.py @@ -427,5 +427,8 @@ PAPERLESS_FILENAME_FORMAT = os.getenv("PAPERLESS_FILENAME_FORMAT") THUMBNAIL_FONT_NAME = os.getenv("PAPERLESS_THUMBNAIL_FONT_NAME", "/usr/share/fonts/liberation/LiberationSerif-Regular.ttf") # Tika settings -PAPERLESS_TIKA = __get_boolean("PAPERLESS_TIKA", "NO") -GOTENBERG_SERVER_ENDPOINT = os.getenv("GOTENBERG_SERVER_ENDPOINT", "http://localhost:3000") +PAPERLESS_TIKA_ENABLED = __get_boolean("PAPERLESS_TIKA_ENABLED", "NO") +PAPERLESS_TIKA_ENDPOINT = os.getenv("PAPERLESS_TIKA_ENDPOINT", "http://localhost:9998") +PAPERLESS_TIKA_GOTENBERG_ENDPOINT = os.getenv( + "PAPERLESS_TIKA_GOTENBERG_ENDPOINT", "http://localhost:3000" +) diff --git a/src/paperless_tika/apps.py b/src/paperless_tika/apps.py index c29586d6a..5cab21427 100644 --- a/src/paperless_tika/apps.py +++ b/src/paperless_tika/apps.py @@ -9,6 +9,6 @@ class PaperlessTikaConfig(AppConfig): def ready(self): from documents.signals import document_consumer_declaration - if settings.PAPERLESS_TIKA: + if settings.PAPERLESS_TIKA_ENABLED: document_consumer_declaration.connect(tika_consumer_declaration) AppConfig.ready(self) diff --git a/src/paperless_tika/parsers.py b/src/paperless_tika/parsers.py index 5a77681f2..81f213a6b 100644 --- a/src/paperless_tika/parsers.py +++ b/src/paperless_tika/parsers.py @@ -70,49 +70,46 @@ class TikaDocumentParser(DocumentParser): def parse(self, document_path, mime_type): self.log("info", f"[TIKA_PARSE] Sending {document_path} to Tika server") + tika_server = settings.PAPERLESS_TIKA_ENDPOINT try: - parsed = parser.from_file(document_path) + parsed = parser.from_file(document_path, tika_server) except requests.exceptions.HTTPError as err: - raise ParseError(f"Could not parse {document_path} with tika server: {err}") - - try: - content = parsed["content"].strip() - except: - content = "" - - try: - creation_date = dateutil.parser.isoparse( - parsed["metadata"]["Creation-Date"] + raise ParseError( + f"Could not parse {document_path} with tika server at {tika_server}: {err}" ) + + try: + self.text = parsed["content"].strip() except: - creation_date = None + pass + + try: + self.date = dateutil.parser.isoparse(parsed["metadata"]["Creation-Date"]) + except: + pass archive_path = os.path.join(self.tempdir, "convert.pdf") - convert_to_pdf(self, document_path, archive_path) - + convert_to_pdf(document_path, archive_path) self.archive_path = archive_path - self.date = creation_date - self.text = content + def convert_to_pdf(document_path, pdf_path): + pdf_path = os.path.join(self.tempdir, "convert.pdf") + gotenberg_server = settings.PAPERLESS_TIKA_GOTENBERG_ENDPOINT + url = gotenberg_server + "/convert/office" -def convert_to_pdf(self, document_path, pdf_path): - pdf_path = os.path.join(self.tempdir, "convert.pdf") - gotenberg_server = settings.GOTENBERG_SERVER_ENDPOINT - url = gotenberg_server + "/convert/office" + self.log("info", f"[TIKA] Converting {document_path} to PDF as {pdf_path}") + files = {"files": open(document_path, "rb")} + headers = {} - self.log("info", f"[TIKA] Converting {document_path} to PDF as {pdf_path}") - files = {"files": open(document_path, "rb")} - headers = {} + try: + response = requests.post(url, files=files, headers=headers) + response.raise_for_status() # ensure we notice bad responses + except requests.exceptions.HTTPError as err: + raise ParseError( + f"Could not contact gotenberg server at {gotenberg_server}: {err}" + ) - try: - response = requests.post(url, files=files, headers=headers) - response.raise_for_status() # ensure we notice bad responses - except requests.exceptions.HTTPError as err: - raise ParseError( - f"Could not contact gotenberg server at {gotenberg_server}: {err}" - ) - - file = open(pdf_path, "wb") - file.write(response.content) - file.close() + file = open(pdf_path, "wb") + file.write(response.content) + file.close() diff --git a/src/paperless_tika/test.py b/src/paperless_tika/test.py deleted file mode 100644 index 0a2885226..000000000 --- a/src/paperless_tika/test.py +++ /dev/null @@ -1,3 +0,0 @@ -import magic -m = magic.from_file("/nfsstorage/jo/syncthing/Documenten/20R-309.153.052.pdf") -print(m) From d95dcf1ad4b0eb2e4a38168123c3f42787082028 Mon Sep 17 00:00:00 2001 From: Stefan Date: Thu, 31 Dec 2020 15:07:35 +0100 Subject: [PATCH 076/197] self serve pdf.worker.min.js --- src-ui/angular.json | 6 +++++- src-ui/src/app/app.component.ts | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src-ui/angular.json b/src-ui/angular.json index ce2dd82f7..db8c66b19 100644 --- a/src-ui/angular.json +++ b/src-ui/angular.json @@ -27,7 +27,11 @@ "assets": [ "src/favicon.ico", "src/assets", - "src/manifest.webmanifest" + "src/manifest.webmanifest", { + "glob": "pdf.worker.min.js", + "input": "node_modules/pdfjs-dist/build/", + "output": "/assets/js/" + } ], "styles": [ "src/styles.scss" diff --git a/src-ui/src/app/app.component.ts b/src-ui/src/app/app.component.ts index 84c173a18..330f8f157 100644 --- a/src-ui/src/app/app.component.ts +++ b/src-ui/src/app/app.component.ts @@ -6,8 +6,9 @@ import { Component } from '@angular/core'; styleUrls: ['./app.component.scss'] }) export class AppComponent { - + constructor () { + (window as any).pdfWorkerSrc = '/assets/js/pdf.worker.min.js'; } From 669163b8214152f0d5b677faa18aa9138653aca6 Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Thu, 31 Dec 2020 15:59:12 +0100 Subject: [PATCH 077/197] more translation --- src/documents/models.py | 5 +- src/paperless_mail/admin.py | 26 +++++----- src/paperless_mail/models.py | 96 ++++++++++++++++++++++++------------ 3 files changed, 81 insertions(+), 46 deletions(-) diff --git a/src/documents/models.py b/src/documents/models.py index 6395d66aa..2349dacd1 100755 --- a/src/documents/models.py +++ b/src/documents/models.py @@ -122,7 +122,6 @@ class DocumentType(MatchingModel): verbose_name_plural = _("document types") - class Document(models.Model): STORAGE_TYPE_UNENCRYPTED = "unencrypted" @@ -230,8 +229,8 @@ class Document(models.Model): class Meta: ordering = ("-created",) - verbose_name = _("Document") - verbose_name_plural = _("Documents") + verbose_name = _("document") + verbose_name_plural = _("documents") def __str__(self): created = datetime.date.isoformat(self.created) diff --git a/src/paperless_mail/admin.py b/src/paperless_mail/admin.py index 0440234b7..4c63c2b29 100644 --- a/src/paperless_mail/admin.py +++ b/src/paperless_mail/admin.py @@ -1,6 +1,8 @@ from django.contrib import admin from paperless_mail.models import MailAccount, MailRule +from django.utils.translation import gettext_lazy as _ + class MailAccountAdmin(admin.ModelAdmin): @@ -19,31 +21,31 @@ class MailRuleAdmin(admin.ModelAdmin): (None, { 'fields': ('name', 'order', 'account', 'folder') }), - ("Filter", { + (_("Filter"), { 'description': - "Paperless will only process mails that match ALL of the " - "filters given below.", + _("Paperless will only process mails that match ALL of the " + "filters given below."), 'fields': ('filter_from', 'filter_subject', 'filter_body', 'maximum_age') }), - ("Actions", { + (_("Actions"), { 'description': - "The action applied to the mail. This action is only " - "performed when documents were consumed from the mail. Mails " - "without attachments will remain entirely untouched.", + _("The action applied to the mail. This action is only " + "performed when documents were consumed from the mail. " + "Mails without attachments will remain entirely untouched."), 'fields': ( 'action', 'action_parameter') }), - ("Metadata", { + (_("Metadata"), { 'description': - "Assign metadata to documents consumed from this rule " - "automatically. If you do not assign tags, types or " - "correspondents here, paperless will still process all " - "matching rules that you have defined.", + _("Assign metadata to documents consumed from this rule " + "automatically. If you do not assign tags, types or " + "correspondents here, paperless will still process all " + "matching rules that you have defined."), "fields": ( 'assign_title_from', 'assign_tag', diff --git a/src/paperless_mail/models.py b/src/paperless_mail/models.py index aa1ac5684..d585d7c1c 100644 --- a/src/paperless_mail/models.py +++ b/src/paperless_mail/models.py @@ -2,6 +2,8 @@ from django.db import models import documents.models as document_models +from django.utils.translation import gettext_lazy as _ + class MailAccount(models.Model): @@ -10,29 +12,39 @@ class MailAccount(models.Model): IMAP_SECURITY_STARTTLS = 3 IMAP_SECURITY_OPTIONS = ( - (IMAP_SECURITY_NONE, "No encryption"), - (IMAP_SECURITY_SSL, "Use SSL"), - (IMAP_SECURITY_STARTTLS, "Use STARTTLS"), + (IMAP_SECURITY_NONE, _("No encryption")), + (IMAP_SECURITY_SSL, _("Use SSL")), + (IMAP_SECURITY_STARTTLS, _("Use STARTTLS")), ) - name = models.CharField(max_length=256, unique=True) + name = models.CharField( + _("name"), + max_length=256, unique=True) - imap_server = models.CharField(max_length=256) + imap_server = models.CharField( + _("imap server"), + max_length=256) imap_port = models.IntegerField( + _("imap port"), blank=True, null=True, - help_text="This is usually 143 for unencrypted and STARTTLS " - "connections, and 993 for SSL connections.") + help_text=_("This is usually 143 for unencrypted and STARTTLS " + "connections, and 993 for SSL connections.")) imap_security = models.PositiveIntegerField( + _("imap security"), choices=IMAP_SECURITY_OPTIONS, default=IMAP_SECURITY_SSL ) - username = models.CharField(max_length=256) + username = models.CharField( + _("username"), + max_length=256) - password = models.CharField(max_length=256) + password = models.CharField( + _("password"), + max_length=256) def __str__(self): return self.name @@ -46,18 +58,18 @@ class MailRule(models.Model): ACTION_FLAG = 4 ACTIONS = ( - (ACTION_MARK_READ, "Mark as read, don't process read mails"), - (ACTION_FLAG, "Flag the mail, don't process flagged mails"), - (ACTION_MOVE, "Move to specified folder"), - (ACTION_DELETE, "Delete"), + (ACTION_MARK_READ, _("Mark as read, don't process read mails")), + (ACTION_FLAG, _("Flag the mail, don't process flagged mails")), + (ACTION_MOVE, _("Move to specified folder")), + (ACTION_DELETE, _("Delete")), ) TITLE_FROM_SUBJECT = 1 TITLE_FROM_FILENAME = 2 TITLE_SELECTOR = ( - (TITLE_FROM_SUBJECT, "Use subject as title"), - (TITLE_FROM_FILENAME, "Use attachment filename as title") + (TITLE_FROM_SUBJECT, _("Use subject as title")), + (TITLE_FROM_FILENAME, _("Use attachment filename as title")) ) CORRESPONDENT_FROM_NOTHING = 1 @@ -67,47 +79,65 @@ class MailRule(models.Model): CORRESPONDENT_SELECTOR = ( (CORRESPONDENT_FROM_NOTHING, - "Do not assign a correspondent"), + _("Do not assign a correspondent")), (CORRESPONDENT_FROM_EMAIL, "Use mail address"), (CORRESPONDENT_FROM_NAME, - "Use name (or mail address if not available)"), + _("Use name (or mail address if not available)")), (CORRESPONDENT_FROM_CUSTOM, - "Use correspondent selected below") + _("Use correspondent selected below")) ) - name = models.CharField(max_length=256, unique=True) + name = models.CharField( + _("name"), + max_length=256, unique=True) - order = models.IntegerField(default=0) + order = models.IntegerField( + _("order"), + default=0) account = models.ForeignKey( MailAccount, related_name="rules", - on_delete=models.CASCADE + on_delete=models.CASCADE, + verbose_name=_("account") ) - folder = models.CharField(default='INBOX', max_length=256) + folder = models.CharField( + _("folder"), + default='INBOX', max_length=256) - filter_from = models.CharField(max_length=256, null=True, blank=True) - filter_subject = models.CharField(max_length=256, null=True, blank=True) - filter_body = models.CharField(max_length=256, null=True, blank=True) + filter_from = models.CharField( + _("filter from"), + max_length=256, null=True, blank=True) + filter_subject = models.CharField( + _("filter subject"), + max_length=256, null=True, blank=True) + filter_body = models.CharField( + _("filter body"), + max_length=256, null=True, blank=True) maximum_age = models.PositiveIntegerField( + _("maximum age"), default=30, - help_text="Specified in days.") + help_text=_("Specified in days.")) action = models.PositiveIntegerField( + _("action"), choices=ACTIONS, default=ACTION_MARK_READ, ) action_parameter = models.CharField( + _("action parameter"), max_length=256, blank=True, null=True, - help_text="Additional parameter for the action selected above, i.e., " - "the target folder of the move to folder action." + help_text=_("Additional parameter for the action selected above, " + "i.e., " + "the target folder of the move to folder action.") ) assign_title_from = models.PositiveIntegerField( + _("assign title from"), choices=TITLE_SELECTOR, default=TITLE_FROM_SUBJECT ) @@ -116,17 +146,20 @@ class MailRule(models.Model): document_models.Tag, null=True, blank=True, - on_delete=models.SET_NULL + on_delete=models.SET_NULL, + verbose_name=_("assign this tag"), ) assign_document_type = models.ForeignKey( document_models.DocumentType, null=True, blank=True, - on_delete=models.SET_NULL + on_delete=models.SET_NULL, + verbose_name=_("assign this document type"), ) assign_correspondent_from = models.PositiveIntegerField( + _("assign correspondent from"), choices=CORRESPONDENT_SELECTOR, default=CORRESPONDENT_FROM_NOTHING ) @@ -135,7 +168,8 @@ class MailRule(models.Model): document_models.Correspondent, null=True, blank=True, - on_delete=models.SET_NULL + on_delete=models.SET_NULL, + verbose_name=_("assign this correspondent") ) def __str__(self): From 2e706ec76253c9352a2a4cd349bb1b1db2d9c7bf Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Thu, 31 Dec 2020 16:00:24 +0100 Subject: [PATCH 078/197] update message file --- src/locale/en-us/LC_MESSAGES/django.po | 296 +++++++++++++++++++------ 1 file changed, 234 insertions(+), 62 deletions(-) diff --git a/src/locale/en-us/LC_MESSAGES/django.po b/src/locale/en-us/LC_MESSAGES/django.po index c3c76c5a4..0af8b7217 100644 --- a/src/locale/en-us/LC_MESSAGES/django.po +++ b/src/locale/en-us/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-12-30 19:20+0000\n" +"POT-Creation-Date: 2020-12-31 14:39+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -41,7 +41,8 @@ msgstr "" msgid "Automatic Classification" msgstr "" -#: documents/models.py:41 documents/models.py:355 +#: documents/models.py:41 documents/models.py:354 paperless_mail/models.py:21 +#: paperless_mail/models.py:92 msgid "name" msgstr "" @@ -57,7 +58,7 @@ msgstr "" msgid "is insensitive" msgstr "" -#: documents/models.py:80 documents/models.py:141 +#: documents/models.py:80 documents/models.py:140 msgid "correspondent" msgstr "" @@ -83,11 +84,11 @@ msgstr "" msgid "tag" msgstr "" -#: documents/models.py:115 documents/models.py:172 +#: documents/models.py:115 documents/models.py:171 msgid "tags" msgstr "" -#: documents/models.py:121 documents/models.py:154 +#: documents/models.py:121 documents/models.py:153 msgid "document type" msgstr "" @@ -95,221 +96,221 @@ msgstr "" msgid "document types" msgstr "" -#: documents/models.py:131 +#: documents/models.py:130 msgid "Unencrypted" msgstr "" -#: documents/models.py:132 +#: documents/models.py:131 msgid "Encrypted with GNU Privacy Guard" msgstr "" -#: documents/models.py:145 +#: documents/models.py:144 msgid "title" msgstr "" -#: documents/models.py:158 +#: documents/models.py:157 msgid "content" msgstr "" -#: documents/models.py:160 +#: documents/models.py:159 msgid "" "The raw, text-only data of the document. This field is primarily used for " "searching." msgstr "" -#: documents/models.py:165 +#: documents/models.py:164 msgid "mime type" msgstr "" -#: documents/models.py:176 +#: documents/models.py:175 msgid "checksum" msgstr "" -#: documents/models.py:180 +#: documents/models.py:179 msgid "The checksum of the original document." msgstr "" -#: documents/models.py:184 +#: documents/models.py:183 msgid "archive checksum" msgstr "" -#: documents/models.py:189 +#: documents/models.py:188 msgid "The checksum of the archived document." msgstr "" -#: documents/models.py:193 documents/models.py:333 +#: documents/models.py:192 documents/models.py:332 msgid "created" msgstr "" -#: documents/models.py:197 +#: documents/models.py:196 msgid "modified" msgstr "" -#: documents/models.py:201 +#: documents/models.py:200 msgid "storage type" msgstr "" -#: documents/models.py:209 +#: documents/models.py:208 msgid "added" msgstr "" -#: documents/models.py:213 +#: documents/models.py:212 msgid "filename" msgstr "" -#: documents/models.py:218 +#: documents/models.py:217 msgid "Current filename in storage" msgstr "" -#: documents/models.py:222 +#: documents/models.py:221 msgid "archive serial number" msgstr "" -#: documents/models.py:227 +#: documents/models.py:226 msgid "The position of this document in your physical document archive." msgstr "" +#: documents/models.py:232 +msgid "document" +msgstr "" + #: documents/models.py:233 -msgid "Document" +msgid "documents" msgstr "" -#: documents/models.py:234 -msgid "Documents" -msgstr "" - -#: documents/models.py:324 +#: documents/models.py:323 msgid "group" msgstr "" -#: documents/models.py:327 +#: documents/models.py:326 msgid "message" msgstr "" -#: documents/models.py:330 +#: documents/models.py:329 msgid "level" msgstr "" -#: documents/models.py:337 +#: documents/models.py:336 msgid "log" msgstr "" -#: documents/models.py:338 +#: documents/models.py:337 msgid "logs" msgstr "" -#: documents/models.py:349 documents/models.py:399 +#: documents/models.py:348 documents/models.py:398 msgid "saved view" msgstr "" -#: documents/models.py:350 +#: documents/models.py:349 msgid "saved views" msgstr "" -#: documents/models.py:353 +#: documents/models.py:352 msgid "user" msgstr "" -#: documents/models.py:359 +#: documents/models.py:358 msgid "show on dashboard" msgstr "" -#: documents/models.py:362 +#: documents/models.py:361 msgid "show in sidebar" msgstr "" -#: documents/models.py:366 +#: documents/models.py:365 msgid "sort field" msgstr "" -#: documents/models.py:369 +#: documents/models.py:368 msgid "sort reverse" msgstr "" -#: documents/models.py:375 +#: documents/models.py:374 msgid "title contains" msgstr "" -#: documents/models.py:376 +#: documents/models.py:375 msgid "content contains" msgstr "" -#: documents/models.py:377 +#: documents/models.py:376 msgid "ASN is" msgstr "" -#: documents/models.py:378 +#: documents/models.py:377 msgid "correspondent is" msgstr "" -#: documents/models.py:379 +#: documents/models.py:378 msgid "document type is" msgstr "" -#: documents/models.py:380 +#: documents/models.py:379 msgid "is in inbox" msgstr "" -#: documents/models.py:381 +#: documents/models.py:380 msgid "has tag" msgstr "" -#: documents/models.py:382 +#: documents/models.py:381 msgid "has any tag" msgstr "" -#: documents/models.py:383 +#: documents/models.py:382 msgid "created before" msgstr "" -#: documents/models.py:384 +#: documents/models.py:383 msgid "created after" msgstr "" -#: documents/models.py:385 +#: documents/models.py:384 msgid "created year is" msgstr "" -#: documents/models.py:386 +#: documents/models.py:385 msgid "created month is" msgstr "" -#: documents/models.py:387 +#: documents/models.py:386 msgid "created day is" msgstr "" -#: documents/models.py:388 +#: documents/models.py:387 msgid "added before" msgstr "" -#: documents/models.py:389 +#: documents/models.py:388 msgid "added after" msgstr "" -#: documents/models.py:390 +#: documents/models.py:389 msgid "modified before" msgstr "" -#: documents/models.py:391 +#: documents/models.py:390 msgid "modified after" msgstr "" -#: documents/models.py:392 +#: documents/models.py:391 msgid "does not have tag" msgstr "" -#: documents/models.py:403 +#: documents/models.py:402 msgid "rule type" msgstr "" -#: documents/models.py:407 +#: documents/models.py:406 msgid "value" msgstr "" -#: documents/models.py:411 +#: documents/models.py:410 msgid "filter rule" msgstr "" -#: documents/models.py:412 +#: documents/models.py:411 msgid "filter rules" msgstr "" @@ -320,3 +321,174 @@ msgstr "" #: paperless/settings.py:254 msgid "German" msgstr "" + +#: paperless_mail/admin.py:24 +msgid "Filter" +msgstr "" + +#: paperless_mail/admin.py:26 +msgid "" +"Paperless will only process mails that match ALL of the filters given below." +msgstr "" + +#: paperless_mail/admin.py:34 +msgid "Actions" +msgstr "" + +#: paperless_mail/admin.py:36 +msgid "" +"The action applied to the mail. This action is only performed when documents " +"were consumed from the mail. Mails without attachments will remain entirely " +"untouched." +msgstr "" + +#: paperless_mail/admin.py:43 +msgid "Metadata" +msgstr "" + +#: paperless_mail/admin.py:45 +msgid "" +"Assign metadata to documents consumed from this rule automatically. If you " +"do not assign tags, types or correspondents here, paperless will still " +"process all matching rules that you have defined." +msgstr "" + +#: paperless_mail/models.py:15 +msgid "No encryption" +msgstr "" + +#: paperless_mail/models.py:16 +msgid "Use SSL" +msgstr "" + +#: paperless_mail/models.py:17 +msgid "Use STARTTLS" +msgstr "" + +#: paperless_mail/models.py:25 +msgid "imap server" +msgstr "" + +#: paperless_mail/models.py:29 +msgid "imap port" +msgstr "" + +#: paperless_mail/models.py:32 +msgid "" +"This is usually 143 for unencrypted and STARTTLS connections, and 993 for " +"SSL connections." +msgstr "" + +#: paperless_mail/models.py:36 +msgid "imap security" +msgstr "" + +#: paperless_mail/models.py:42 +msgid "username" +msgstr "" + +#: paperless_mail/models.py:46 +msgid "password" +msgstr "" + +#: paperless_mail/models.py:61 +msgid "Mark as read, don't process read mails" +msgstr "" + +#: paperless_mail/models.py:62 +msgid "Flag the mail, don't process flagged mails" +msgstr "" + +#: paperless_mail/models.py:63 +msgid "Move to specified folder" +msgstr "" + +#: paperless_mail/models.py:64 +msgid "Delete" +msgstr "" + +#: paperless_mail/models.py:71 +msgid "Use subject as title" +msgstr "" + +#: paperless_mail/models.py:72 +msgid "Use attachment filename as title" +msgstr "" + +#: paperless_mail/models.py:82 +msgid "Do not assign a correspondent" +msgstr "" + +#: paperless_mail/models.py:86 +msgid "Use name (or mail address if not available)" +msgstr "" + +#: paperless_mail/models.py:88 +msgid "Use correspondent selected below" +msgstr "" + +#: paperless_mail/models.py:96 +msgid "order" +msgstr "" + +#: paperless_mail/models.py:103 +msgid "account" +msgstr "" + +#: paperless_mail/models.py:107 +msgid "folder" +msgstr "" + +#: paperless_mail/models.py:111 +msgid "filter from" +msgstr "" + +#: paperless_mail/models.py:114 +msgid "filter subject" +msgstr "" + +#: paperless_mail/models.py:117 +msgid "filter body" +msgstr "" + +#: paperless_mail/models.py:121 +msgid "maximum age" +msgstr "" + +#: paperless_mail/models.py:123 +msgid "Specified in days." +msgstr "" + +#: paperless_mail/models.py:126 +msgid "action" +msgstr "" + +#: paperless_mail/models.py:132 +msgid "action parameter" +msgstr "" + +#: paperless_mail/models.py:134 +msgid "" +"Additional parameter for the action selected above, i.e., the target folder " +"of the move to folder action." +msgstr "" + +#: paperless_mail/models.py:140 +msgid "assign title from" +msgstr "" + +#: paperless_mail/models.py:150 +msgid "assign this tag" +msgstr "" + +#: paperless_mail/models.py:158 +msgid "assign this document type" +msgstr "" + +#: paperless_mail/models.py:162 +msgid "assign correspondent from" +msgstr "" + +#: paperless_mail/models.py:172 +msgid "assign this correspondent" +msgstr "" From 0e33a55aa33006163ccb83587fa734711da0df0d Mon Sep 17 00:00:00 2001 From: Michael Shamoon <4887959+nikonratm@users.noreply.github.com> Date: Thu, 31 Dec 2020 07:52:14 -0800 Subject: [PATCH 079/197] Fix alignment --- src-ui/src/app/components/app-frame/app-frame.component.html | 2 +- src-ui/src/app/components/app-frame/app-frame.component.scss | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src-ui/src/app/components/app-frame/app-frame.component.html b/src-ui/src/app/components/app-frame/app-frame.component.html index 9d6c4924f..8029edc98 100644 --- a/src-ui/src/app/components/app-frame/app-frame.component.html +++ b/src-ui/src/app/components/app-frame/app-frame.component.html @@ -8,7 +8,7 @@ Paperless-ng -
+
diff --git a/src-ui/src/app/components/app-frame/app-frame.component.scss b/src-ui/src/app/components/app-frame/app-frame.component.scss index 44b1531b1..f62eccf96 100644 --- a/src-ui/src/app/components/app-frame/app-frame.component.scss +++ b/src-ui/src/app/components/app-frame/app-frame.component.scss @@ -82,7 +82,7 @@ svg { position: absolute; - left: 1.8em; + left: 2rem; color: rgba(255, 255, 255, 0.6); } From 0a5c82a908ed738bf235c4f4deac37692632119d Mon Sep 17 00:00:00 2001 From: Michael Shamoon <4887959+nikonratm@users.noreply.github.com> Date: Thu, 31 Dec 2020 16:23:08 -0800 Subject: [PATCH 080/197] tweak username display, dropdown size + spacing --- .../app-frame/app-frame.component.html | 27 ++++++++++++------- .../app-frame/app-frame.component.scss | 13 ++++++++- .../app-frame/app-frame.component.ts | 23 +++++++++++++--- 3 files changed, 49 insertions(+), 14 deletions(-) diff --git a/src-ui/src/app/components/app-frame/app-frame.component.html b/src-ui/src/app/components/app-frame/app-frame.component.html index 8029edc98..a05b691af 100644 --- a/src-ui/src/app/components/app-frame/app-frame.component.html +++ b/src-ui/src/app/components/app-frame/app-frame.component.html @@ -20,21 +20,28 @@ diff --git a/src-ui/src/app/components/app-frame/app-frame.component.scss b/src-ui/src/app/components/app-frame/app-frame.component.scss index f62eccf96..f2abb80f9 100644 --- a/src-ui/src/app/components/app-frame/app-frame.component.scss +++ b/src-ui/src/app/components/app-frame/app-frame.component.scss @@ -62,13 +62,16 @@ /* * Navbar */ + .navbar-brand { padding-top: 0.75rem; padding-bottom: 0.75rem; font-size: 1rem; } -.navbar-toggler { +.dropdown.show .dropdown-toggle, +.dropdown-toggle:hover { + opacity: 0.7; } .dropdown-toggle::after { @@ -76,6 +79,14 @@ vertical-align: 0.155em; } +.navbar .dropdown-menu { + font-size: 0.875rem; // body size + + a svg { + opacity: 0.6; + } +} + .navbar .search-form-container { max-width: 550px; position: relative; diff --git a/src-ui/src/app/components/app-frame/app-frame.component.ts b/src-ui/src/app/components/app-frame/app-frame.component.ts index c4c00843d..dca0d9106 100644 --- a/src-ui/src/app/components/app-frame/app-frame.component.ts +++ b/src-ui/src/app/components/app-frame/app-frame.component.ts @@ -9,7 +9,8 @@ import { SavedViewService } from 'src/app/services/rest/saved-view.service'; import { SearchService } from 'src/app/services/rest/search.service'; import { environment } from 'src/environments/environment'; import { DocumentDetailComponent } from '../document-detail/document-detail.component'; - +import { Meta } from '@angular/platform-browser'; + @Component({ selector: 'app-app-frame', templateUrl: './app-frame.component.html', @@ -22,8 +23,11 @@ export class AppFrameComponent implements OnInit, OnDestroy { private activatedRoute: ActivatedRoute, private openDocumentsService: OpenDocumentsService, private searchService: SearchService, - public savedViewService: SavedViewService + public savedViewService: SavedViewService, + private meta: Meta ) { + console.log(meta); + } versionString = `${environment.appTitle} ${environment.version}` @@ -55,7 +59,7 @@ export class AppFrameComponent implements OnInit, OnDestroy { term.length < 2 ? from([[]]) : this.searchService.autocomplete(term) ) ) - + itemSelected(event) { event.preventDefault() let currentSearch: string = this.searchField.value @@ -98,4 +102,17 @@ export class AppFrameComponent implements OnInit, OnDestroy { } } + get displayName() { + // TODO: taken from dashboard component, is this the best way to pass around username? + let tagFullName = this.meta.getTag('name=full_name') + let tagUsername = this.meta.getTag('name=username') + if (tagFullName && tagFullName.content) { + return tagFullName.content + } else if (tagUsername && tagUsername.content) { + return tagUsername.content + } else { + return null + } + } + } From 59be51ffd8003495669dd0c7f2407f38349b0d3c Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Fri, 1 Jan 2021 20:23:32 +0100 Subject: [PATCH 081/197] fix some messages --- src/locale/en-us/LC_MESSAGES/django.po | 12 ++++++++---- src/paperless_mail/models.py | 8 ++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/locale/en-us/LC_MESSAGES/django.po b/src/locale/en-us/LC_MESSAGES/django.po index 0af8b7217..7b9435883 100644 --- a/src/locale/en-us/LC_MESSAGES/django.po +++ b/src/locale/en-us/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-12-31 14:39+0000\n" +"POT-Creation-Date: 2021-01-01 19:09+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -366,11 +366,11 @@ msgid "Use STARTTLS" msgstr "" #: paperless_mail/models.py:25 -msgid "imap server" +msgid "IMAP server" msgstr "" #: paperless_mail/models.py:29 -msgid "imap port" +msgid "IMAP port" msgstr "" #: paperless_mail/models.py:32 @@ -380,7 +380,7 @@ msgid "" msgstr "" #: paperless_mail/models.py:36 -msgid "imap security" +msgid "IMAP security" msgstr "" #: paperless_mail/models.py:42 @@ -419,6 +419,10 @@ msgstr "" msgid "Do not assign a correspondent" msgstr "" +#: paperless_mail/models.py:84 +msgid "Use mail address" +msgstr "" + #: paperless_mail/models.py:86 msgid "Use name (or mail address if not available)" msgstr "" diff --git a/src/paperless_mail/models.py b/src/paperless_mail/models.py index d585d7c1c..44682cfbf 100644 --- a/src/paperless_mail/models.py +++ b/src/paperless_mail/models.py @@ -22,18 +22,18 @@ class MailAccount(models.Model): max_length=256, unique=True) imap_server = models.CharField( - _("imap server"), + _("IMAP server"), max_length=256) imap_port = models.IntegerField( - _("imap port"), + _("IMAP port"), blank=True, null=True, help_text=_("This is usually 143 for unencrypted and STARTTLS " "connections, and 993 for SSL connections.")) imap_security = models.PositiveIntegerField( - _("imap security"), + _("IMAP security"), choices=IMAP_SECURITY_OPTIONS, default=IMAP_SECURITY_SSL ) @@ -81,7 +81,7 @@ class MailRule(models.Model): (CORRESPONDENT_FROM_NOTHING, _("Do not assign a correspondent")), (CORRESPONDENT_FROM_EMAIL, - "Use mail address"), + _("Use mail address")), (CORRESPONDENT_FROM_NAME, _("Use name (or mail address if not available)")), (CORRESPONDENT_FROM_CUSTOM, From 343ac390410f016b971272daf366f23e8a0a7343 Mon Sep 17 00:00:00 2001 From: Michael Shamoon <4887959+nikonratm@users.noreply.github.com> Date: Fri, 1 Jan 2021 12:25:16 -0800 Subject: [PATCH 082/197] search icon position --- .../src/app/components/app-frame/app-frame.component.scss | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src-ui/src/app/components/app-frame/app-frame.component.scss b/src-ui/src/app/components/app-frame/app-frame.component.scss index f2abb80f9..473e6f85b 100644 --- a/src-ui/src/app/components/app-frame/app-frame.component.scss +++ b/src-ui/src/app/components/app-frame/app-frame.component.scss @@ -89,11 +89,14 @@ .navbar .search-form-container { max-width: 550px; - position: relative; + + form { + position: relative; + } svg { position: absolute; - left: 2rem; + left: 0.6rem; color: rgba(255, 255, 255, 0.6); } From 9391526088737fc762c2c04819d904165682be9b Mon Sep 17 00:00:00 2001 From: Michael Shamoon <4887959+nikonratm@users.noreply.github.com> Date: Fri, 1 Jan 2021 12:29:52 -0800 Subject: [PATCH 083/197] Dark mode compatability --- .../src/app/components/app-frame/app-frame.component.scss | 6 +++++- src-ui/src/theme_dark.scss | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src-ui/src/app/components/app-frame/app-frame.component.scss b/src-ui/src/app/components/app-frame/app-frame.component.scss index 473e6f85b..2d3cc5f04 100644 --- a/src-ui/src/app/components/app-frame/app-frame.component.scss +++ b/src-ui/src/app/components/app-frame/app-frame.component.scss @@ -104,6 +104,10 @@ svg { display: none; } + + .form-control::placeholder { + color: rgba(255, 255, 255, 0); + } } .form-control { @@ -121,7 +125,7 @@ &:focus { background-color: #fff; - color: initial; + color: #212529; flex-grow: 1; padding-left: 0.5rem; } diff --git a/src-ui/src/theme_dark.scss b/src-ui/src/theme_dark.scss index a122f1d86..5f08583e8 100644 --- a/src-ui/src/theme_dark.scss +++ b/src-ui/src/theme_dark.scss @@ -36,6 +36,10 @@ $border-color-dark-mode: #47494f; } } + .text-light { + color: $text-color-dark-mode !important; + } + .border { border-color: $border-color-dark-mode !important; } From a9ced7e1cf0a0b3fe2402a4324d493b69be47fab Mon Sep 17 00:00:00 2001 From: Michael Shamoon <4887959+nikonratm@users.noreply.github.com> Date: Fri, 1 Jan 2021 12:36:19 -0800 Subject: [PATCH 084/197] Linting --- .../src/app/components/app-frame/app-frame.component.scss | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src-ui/src/app/components/app-frame/app-frame.component.scss b/src-ui/src/app/components/app-frame/app-frame.component.scss index 2d3cc5f04..26c4db273 100644 --- a/src-ui/src/app/components/app-frame/app-frame.component.scss +++ b/src-ui/src/app/components/app-frame/app-frame.component.scss @@ -19,13 +19,11 @@ .sidebar-sticky { position: relative; - top: 0; - /* height: calc(100vh - 48px); */ + top: 0; /* height: calc(100vh - 48px); */ height: 100%; padding-top: 0.5rem; overflow-x: hidden; - overflow-y: auto; - /* Scrollable contents if viewport is shorter than content. */ + overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */ } @supports ((position: -webkit-sticky) or (position: sticky)) { .sidebar-sticky { From 88f79a6671b3ac219cbdc7c8852c5916d6be14b3 Mon Sep 17 00:00:00 2001 From: Michael Shamoon <4887959+nikonratm@users.noreply.github.com> Date: Fri, 1 Jan 2021 12:41:05 -0800 Subject: [PATCH 085/197] Mistakenly overwritten files from merge of dev branch --- src-ui/angular.json | 275 +++++++++++++------------ src-ui/src/environments/environment.ts | 2 +- 2 files changed, 139 insertions(+), 138 deletions(-) diff --git a/src-ui/angular.json b/src-ui/angular.json index f081430c7..db8c66b19 100644 --- a/src-ui/angular.json +++ b/src-ui/angular.json @@ -1,138 +1,139 @@ { - "$schema": "./node_modules/@angular/cli/lib/config/schema.json", - "version": 1, - "newProjectRoot": "projects", - "projects": { - "paperless-ui": { - "projectType": "application", - "schematics": { - "@schematics/angular:component": { - "style": "scss" - } - }, - "root": "", - "sourceRoot": "src", - "prefix": "app", - "architect": { - "build": { - "builder": "@angular-devkit/build-angular:browser", - "options": { - "outputPath": "dist/paperless-ui", - "outputHashing": "none", - "index": "src/index.html", - "main": "src/main.ts", - "polyfills": "src/polyfills.ts", - "tsConfig": "tsconfig.app.json", - "aot": true, - "assets": [ - "src/favicon.ico", - "src/assets", - "src/manifest.webmanifest" - ], - "styles": [ - "src/styles.scss" - ], - "scripts": [], - "allowedCommonJsDependencies": [ - "ng2-pdf-viewer" - ] - }, - "configurations": { - "production": { - "fileReplacements": [ - { - "replace": "src/environments/environment.ts", - "with": "src/environments/environment.prod.ts" - } - ], - "optimization": true, - "outputHashing": "none", - "sourceMap": false, - "extractCss": true, - "namedChunks": false, - "extractLicenses": true, - "vendorChunk": false, - "buildOptimizer": true, - "budgets": [ - { - "type": "initial", - "maximumWarning": "2mb", - "maximumError": "5mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "6kb", - "maximumError": "10kb" - } - ] - } - } - }, - "serve": { - "builder": "@angular-devkit/build-angular:dev-server", - "options": { - "browserTarget": "paperless-ui:build" - }, - "configurations": { - "production": { - "browserTarget": "paperless-ui:build:production" - } - } - }, - "extract-i18n": { - "builder": "@angular-devkit/build-angular:extract-i18n", - "options": { - "browserTarget": "paperless-ui:build" - } - }, - "test": { - "builder": "@angular-devkit/build-angular:karma", - "options": { - "main": "src/test.ts", - "polyfills": "src/polyfills.ts", - "tsConfig": "tsconfig.spec.json", - "karmaConfig": "karma.conf.js", - "assets": [ - "src/favicon.ico", - "src/assets", - "src/manifest.webmanifest" - ], - "styles": [ - "src/styles.scss" - ], - "scripts": [] - } - }, - "lint": { - "builder": "@angular-devkit/build-angular:tslint", - "options": { - "tsConfig": [ - "tsconfig.app.json", - "tsconfig.spec.json", - "e2e/tsconfig.json" - ], - "exclude": [ - "**/node_modules/**" - ] - } - }, - "e2e": { - "builder": "@angular-devkit/build-angular:protractor", - "options": { - "protractorConfig": "e2e/protractor.conf.js", - "devServerTarget": "paperless-ui:serve" - }, - "configurations": { - "production": { - "devServerTarget": "paperless-ui:serve:production" - } - } - } - } - } - }, - "defaultProject": "paperless-ui", - "cli": { - "analytics": "7c47c2bc-b97e-4014-85ae-b0c99b5750b4" - } -} \ No newline at end of file + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "paperless-ui": { + "projectType": "application", + "schematics": { + "@schematics/angular:component": { + "style": "scss" + } + }, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:browser", + "options": { + "outputPath": "dist/paperless-ui", + "outputHashing": "none", + "index": "src/index.html", + "main": "src/main.ts", + "polyfills": "src/polyfills.ts", + "tsConfig": "tsconfig.app.json", + "aot": true, + "assets": [ + "src/favicon.ico", + "src/assets", + "src/manifest.webmanifest", { + "glob": "pdf.worker.min.js", + "input": "node_modules/pdfjs-dist/build/", + "output": "/assets/js/" + } + ], + "styles": [ + "src/styles.scss" + ], + "scripts": [], + "allowedCommonJsDependencies": [ + "ng2-pdf-viewer" + ] + }, + "configurations": { + "production": { + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.prod.ts" + } + ], + "optimization": true, + "outputHashing": "none", + "sourceMap": false, + "extractCss": true, + "namedChunks": false, + "extractLicenses": true, + "vendorChunk": false, + "buildOptimizer": true, + "budgets": [ + { + "type": "initial", + "maximumWarning": "2mb", + "maximumError": "5mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "6kb", + "maximumError": "10kb" + } + ] + } + } + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "options": { + "browserTarget": "paperless-ui:build" + }, + "configurations": { + "production": { + "browserTarget": "paperless-ui:build:production" + } + } + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n", + "options": { + "browserTarget": "paperless-ui:build" + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "main": "src/test.ts", + "polyfills": "src/polyfills.ts", + "tsConfig": "tsconfig.spec.json", + "karmaConfig": "karma.conf.js", + "assets": [ + "src/favicon.ico", + "src/assets", + "src/manifest.webmanifest" + ], + "styles": [ + "src/styles.scss" + ], + "scripts": [] + } + }, + "lint": { + "builder": "@angular-devkit/build-angular:tslint", + "options": { + "tsConfig": [ + "tsconfig.app.json", + "tsconfig.spec.json", + "e2e/tsconfig.json" + ], + "exclude": [ + "**/node_modules/**" + ] + } + }, + "e2e": { + "builder": "@angular-devkit/build-angular:protractor", + "options": { + "protractorConfig": "e2e/protractor.conf.js", + "devServerTarget": "paperless-ui:serve" + }, + "configurations": { + "production": { + "devServerTarget": "paperless-ui:serve:production" + } + } + } + } + } + }, + "defaultProject": "paperless-ui" +} diff --git a/src-ui/src/environments/environment.ts b/src-ui/src/environments/environment.ts index 7c5b29e82..29a8f3af6 100644 --- a/src-ui/src/environments/environment.ts +++ b/src-ui/src/environments/environment.ts @@ -4,7 +4,7 @@ export const environment = { production: false, - apiBaseUrl: "http://10.0.1.26:8000/api/", + apiBaseUrl: "http://localhost:8000/api/", appTitle: "Paperless-ng", version: "DEVELOPMENT" }; From 3b3f8e30ac1cb3e86c26d3299515a0193dc0e87e Mon Sep 17 00:00:00 2001 From: Michael Shamoon <4887959+nikonratm@users.noreply.github.com> Date: Fri, 1 Jan 2021 12:42:58 -0800 Subject: [PATCH 086/197] Spaces --- src-ui/src/app/components/app-frame/app-frame.component.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src-ui/src/app/components/app-frame/app-frame.component.scss b/src-ui/src/app/components/app-frame/app-frame.component.scss index 26c4db273..d23ee8141 100644 --- a/src-ui/src/app/components/app-frame/app-frame.component.scss +++ b/src-ui/src/app/components/app-frame/app-frame.component.scss @@ -19,11 +19,11 @@ .sidebar-sticky { position: relative; - top: 0; /* height: calc(100vh - 48px); */ + top: 0; /* height: calc(100vh - 48px); */ height: 100%; padding-top: 0.5rem; overflow-x: hidden; - overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */ + overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */ } @supports ((position: -webkit-sticky) or (position: sticky)) { .sidebar-sticky { From 410c70c9a5013e8a6154c675324a32e7ea127423 Mon Sep 17 00:00:00 2001 From: Michael Shamoon <4887959+nikonratm@users.noreply.github.com> Date: Fri, 1 Jan 2021 12:43:19 -0800 Subject: [PATCH 087/197] Remove unused line --- src-ui/src/app/components/app-frame/app-frame.component.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src-ui/src/app/components/app-frame/app-frame.component.scss b/src-ui/src/app/components/app-frame/app-frame.component.scss index d23ee8141..6809875eb 100644 --- a/src-ui/src/app/components/app-frame/app-frame.component.scss +++ b/src-ui/src/app/components/app-frame/app-frame.component.scss @@ -19,7 +19,7 @@ .sidebar-sticky { position: relative; - top: 0; /* height: calc(100vh - 48px); */ + top: 0; height: 100%; padding-top: 0.5rem; overflow-x: hidden; From 4a425d06839ba42d24126b860676cf22c798e2c3 Mon Sep 17 00:00:00 2001 From: Michael Shamoon <4887959+nikonratm@users.noreply.github.com> Date: Fri, 1 Jan 2021 12:49:48 -0800 Subject: [PATCH 088/197] Not sure why Typescript complained about this --- src-ui/src/app/app.component.ts | 2 +- src-ui/src/app/services/app-view.service.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src-ui/src/app/app.component.ts b/src-ui/src/app/app.component.ts index 1c2001043..30ecb40d0 100644 --- a/src-ui/src/app/app.component.ts +++ b/src-ui/src/app/app.component.ts @@ -9,8 +9,8 @@ import { AppViewService } from './services/app-view.service'; export class AppComponent { constructor (appViewService: AppViewService) { - appViewService.updateDarkModeSettings() (window as any).pdfWorkerSrc = '/assets/js/pdf.worker.min.js'; + appViewService.updateDarkModeSettings() } diff --git a/src-ui/src/app/services/app-view.service.ts b/src-ui/src/app/services/app-view.service.ts index 6af2e43af..67a429ffe 100644 --- a/src-ui/src/app/services/app-view.service.ts +++ b/src-ui/src/app/services/app-view.service.ts @@ -18,7 +18,7 @@ export class AppViewService { this.updateDarkModeSettings() } - updateDarkModeSettings() { + updateDarkModeSettings(): void { let darkModeUseSystem = this.settings.get(SETTINGS_KEYS.DARK_MODE_USE_SYSTEM) let darkModeEnabled = this.settings.get(SETTINGS_KEYS.DARK_MODE_ENABLED) From 3dcb52c6b557a26f3dd27d6f428f42d474b520aa Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Fri, 1 Jan 2021 21:50:23 +0100 Subject: [PATCH 089/197] update lockfile --- Pipfile.lock | 57 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index 1cfccb8ff..c6621b543 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "3d576f289958226a7583e4c471c7f8c11bff6933bf093185f623cfb381a92412" + "sha256": "993e362c31af6b8094693075f614270a820cf0b557369d66d674e1a107b7bd31" }, "pipfile-spec": 6, "requires": { @@ -44,6 +44,13 @@ ], "version": "==1.17.12" }, + "certifi": { + "hashes": [ + "sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c", + "sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830" + ], + "version": "==2020.12.5" + }, "cffi": { "hashes": [ "sha256:00a1ba5e2e95684448de9b89888ccd02c98d512064b4cb987d48f4b40aa0421e", @@ -229,6 +236,15 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==9.0" }, + "idna": { + "hashes": [ + "sha256:4a57a6379512ade94fa99e2fa46d3cd0f2f553040548d0e2958c6ed90ee48226", + "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6", + "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==2.10" + }, "imap-tools": { "hashes": [ "sha256:72bf46dc135b039a5d5b59f4e079242ac15eac02a30038e8cb2dec7b153cab65", @@ -683,6 +699,14 @@ ], "version": "==3.5.56" }, + "requests": { + "hashes": [ + "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804", + "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==2.25.1" + }, "scikit-learn": { "hashes": [ "sha256:090bbf144fd5823c1f2efa3e1a9bf180295b24294ca8f478e75b40ed54f8036e", @@ -769,6 +793,14 @@ "markers": "python_version >= '3.5'", "version": "==2.1.0" }, + "tika": { + "hashes": [ + "sha256:c2c50f405622f74531841104f9e85c17511aede11de8e5385eab1a29a31f191b", + "sha256:d1f2eddb93caa9a2857569486aa2bc0320d0bf1796cdbe03066954cbc4b4bf62" + ], + "index": "pypi", + "version": "==1.24" + }, "tqdm": { "hashes": [ "sha256:38b658a3e4ecf9b4f6f8ff75ca16221ae3378b2e175d846b6b33ea3a20852cf5", @@ -777,6 +809,15 @@ "index": "pypi", "version": "==4.54.1" }, + "typing-extensions": { + "hashes": [ + "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918", + "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c", + "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f" + ], + "markers": "python_version < '3.8'", + "version": "==3.7.4.3" + }, "tzlocal": { "hashes": [ "sha256:643c97c5294aedc737780a49d9df30889321cbe1204eac2c2ec6134035a92e44", @@ -784,6 +825,14 @@ ], "version": "==2.1" }, + "urllib3": { + "hashes": [ + "sha256:19188f96923873c92ccb987120ec4acaa12f0461fa9ce5d3d0772bc965a39e08", + "sha256:d8ff90d979214d7b4f8ce956e80f4028fc6860e4431f731ea4a8c08f23f99473" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'", + "version": "==1.26.2" + }, "watchdog": { "hashes": [ "sha256:3caefdcc8f06a57fdc5ef2d22aa7c0bfda4f55e71a0bee74cbf3176d97536ef3", @@ -1197,11 +1246,11 @@ }, "requests": { "hashes": [ - "sha256:7f1a0b932f4a60a1a65caa4263921bb7d9ee911957e0ae4a23a6dd08185ad5f8", - "sha256:e786fa28d8c9154e6a4de5d46a1d921b8749f8b74e28bde23768e5e16eece998" + "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804", + "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==2.25.0" + "version": "==2.25.1" }, "six": { "hashes": [ From 1b6a9a6bdf87176b4dd2ce3302f3c4fc2a410f69 Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Fri, 1 Jan 2021 21:50:32 +0100 Subject: [PATCH 090/197] update start_services.sh script --- scripts/start_services.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/start_services.sh b/scripts/start_services.sh index e566f59b3..cbab7ac9e 100755 --- a/scripts/start_services.sh +++ b/scripts/start_services.sh @@ -1,2 +1,4 @@ docker run -p 5432:5432 -v paperless_pgdata:/var/lib/postgresql/data -d postgres:13 docker run -d -p 6379:6379 redis:latest +docker run -p 3000:3000 -d thecodingmachine/gotenberg +docker run -p 9998:9998 -d apache/tika From f1e9b414f989775ce560987ec20227920fed18f0 Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Fri, 1 Jan 2021 21:50:45 +0100 Subject: [PATCH 091/197] remove duplicate code --- src/documents/parsers.py | 46 ++++++++++++++++++++ src/paperless_tesseract/parsers.py | 50 ++-------------------- src/paperless_tika/parsers.py | 67 +++++------------------------- 3 files changed, 60 insertions(+), 103 deletions(-) diff --git a/src/documents/parsers.py b/src/documents/parsers.py index 725e605a2..65d321ce5 100644 --- a/src/documents/parsers.py +++ b/src/documents/parsers.py @@ -144,6 +144,52 @@ def run_convert(input_file, raise ParseError("Convert failed at {}".format(args)) +def make_thumbnail_from_pdf(in_path, temp_dir, logging_group=None): + """ + The thumbnail of a PDF is just a 500px wide image of the first page. + """ + out_path = os.path.join(temp_dir, "convert.png") + + # Run convert to get a decent thumbnail + try: + run_convert(density=300, + scale="500x5000>", + alpha="remove", + strip=True, + trim=False, + auto_orient=True, + input_file="{}[0]".format(in_path), + output_file=out_path, + logging_group=logging_group) + except ParseError: + # if convert fails, fall back to extracting + # the first PDF page as a PNG using Ghostscript + logger.warning( + "Thumbnail generation with ImageMagick failed, falling back " + "to ghostscript. Check your /etc/ImageMagick-x/policy.xml!", + extra={'group': logging_group} + ) + gs_out_path = os.path.join(temp_dir, "gs_out.png") + cmd = [settings.GS_BINARY, + "-q", + "-sDEVICE=pngalpha", + "-o", gs_out_path, + in_path] + if not subprocess.Popen(cmd).wait() == 0: + raise ParseError("Thumbnail (gs) failed at {}".format(cmd)) + # then run convert on the output from gs + run_convert(density=300, + scale="500x5000>", + alpha="remove", + strip=True, + trim=False, + auto_orient=True, + input_file=gs_out_path, + output_file=out_path, + logging_group=logging_group) + + return out_path + def parse_date(filename, text): """ Returns the date of the document. diff --git a/src/paperless_tesseract/parsers.py b/src/paperless_tesseract/parsers.py index 4da5af2c0..fc8702eac 100644 --- a/src/paperless_tesseract/parsers.py +++ b/src/paperless_tesseract/parsers.py @@ -1,7 +1,6 @@ import json import os import re -import subprocess import ocrmypdf import pdftotext @@ -10,7 +9,8 @@ from PIL import Image from django.conf import settings from ocrmypdf import InputFileError, EncryptedPdfError -from documents.parsers import DocumentParser, ParseError, run_convert +from documents.parsers import DocumentParser, ParseError, \ + make_thumbnail_from_pdf class RasterisedDocumentParser(DocumentParser): @@ -47,50 +47,8 @@ class RasterisedDocumentParser(DocumentParser): return result def get_thumbnail(self, document_path, mime_type): - """ - The thumbnail of a PDF is just a 500px wide image of the first page. - """ - - out_path = os.path.join(self.tempdir, "convert.png") - - # Run convert to get a decent thumbnail - try: - run_convert(density=300, - scale="500x5000>", - alpha="remove", - strip=True, - trim=False, - auto_orient=True, - input_file="{}[0]".format(document_path), - output_file=out_path, - logging_group=self.logging_group) - except ParseError: - # if convert fails, fall back to extracting - # the first PDF page as a PNG using Ghostscript - self.log( - 'warning', - "Thumbnail generation with ImageMagick failed, falling back " - "to ghostscript. Check your /etc/ImageMagick-x/policy.xml!") - gs_out_path = os.path.join(self.tempdir, "gs_out.png") - cmd = [settings.GS_BINARY, - "-q", - "-sDEVICE=pngalpha", - "-o", gs_out_path, - document_path] - if not subprocess.Popen(cmd).wait() == 0: - raise ParseError("Thumbnail (gs) failed at {}".format(cmd)) - # then run convert on the output from gs - run_convert(density=300, - scale="500x5000>", - alpha="remove", - strip=True, - trim=False, - auto_orient=True, - input_file=gs_out_path, - output_file=out_path, - logging_group=self.logging_group) - - return out_path + return make_thumbnail_from_pdf( + document_path, self.tempdir, self.logging_group) def is_image(self, mime_type): return mime_type in [ diff --git a/src/paperless_tika/parsers.py b/src/paperless_tika/parsers.py index 81f213a6b..8ee10632f 100644 --- a/src/paperless_tika/parsers.py +++ b/src/paperless_tika/parsers.py @@ -1,14 +1,11 @@ import os -import subprocess -import tika import requests import dateutil.parser -from PIL import ImageDraw, ImageFont, Image from django.conf import settings -from documents.parsers import DocumentParser, ParseError, run_convert -from paperless_tesseract.parsers import RasterisedDocumentParser +from documents.parsers import DocumentParser, ParseError, \ + make_thumbnail_from_pdf from tika import parser @@ -18,55 +15,11 @@ class TikaDocumentParser(DocumentParser): """ def get_thumbnail(self, document_path, mime_type): - self.log("info", f"[TIKA_THUMB] Generating thumbnail for{document_path}") - archive_path = self.archive_path + if not self.archive_path: + self.archive_path = self.convert_to_pdf(document_path) - out_path = os.path.join(self.tempdir, "convert.png") - - # Run convert to get a decent thumbnail - try: - run_convert( - density=300, - scale="500x5000>", - alpha="remove", - strip=True, - trim=False, - input_file="{}[0]".format(archive_path), - output_file=out_path, - logging_group=self.logging_group, - ) - except ParseError: - # if convert fails, fall back to extracting - # the first PDF page as a PNG using Ghostscript - self.log( - "warning", - "Thumbnail generation with ImageMagick failed, falling back " - "to ghostscript. Check your /etc/ImageMagick-x/policy.xml!", - ) - gs_out_path = os.path.join(self.tempdir, "gs_out.png") - cmd = [ - settings.GS_BINARY, - "-q", - "-sDEVICE=pngalpha", - "-o", - gs_out_path, - archive_path, - ] - if not subprocess.Popen(cmd).wait() == 0: - raise ParseError("Thumbnail (gs) failed at {}".format(cmd)) - # then run convert on the output from gs - run_convert( - density=300, - scale="500x5000>", - alpha="remove", - strip=True, - trim=False, - input_file=gs_out_path, - output_file=out_path, - logging_group=self.logging_group, - ) - - return out_path + return make_thumbnail_from_pdf( + self.archive_path, self.tempdir, self.logging_group) def parse(self, document_path, mime_type): self.log("info", f"[TIKA_PARSE] Sending {document_path} to Tika server") @@ -89,11 +42,9 @@ class TikaDocumentParser(DocumentParser): except: pass - archive_path = os.path.join(self.tempdir, "convert.pdf") - convert_to_pdf(document_path, archive_path) - self.archive_path = archive_path + self.archive_path = self.convert_to_pdf(document_path) - def convert_to_pdf(document_path, pdf_path): + def convert_to_pdf(self, document_path): pdf_path = os.path.join(self.tempdir, "convert.pdf") gotenberg_server = settings.PAPERLESS_TIKA_GOTENBERG_ENDPOINT url = gotenberg_server + "/convert/office" @@ -113,3 +64,5 @@ class TikaDocumentParser(DocumentParser): file = open(pdf_path, "wb") file.write(response.content) file.close() + + return pdf_path From bcde6e470264d224200f9f2fc35af47dddced92c Mon Sep 17 00:00:00 2001 From: Michael Shamoon <4887959+nikonratm@users.noreply.github.com> Date: Fri, 1 Jan 2021 12:52:35 -0800 Subject: [PATCH 092/197] brand width rem --- src-ui/src/app/components/app-frame/app-frame.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src-ui/src/app/components/app-frame/app-frame.component.html b/src-ui/src/app/components/app-frame/app-frame.component.html index 36408dce5..46065a102 100644 --- a/src-ui/src/app/components/app-frame/app-frame.component.html +++ b/src-ui/src/app/components/app-frame/app-frame.component.html @@ -5,7 +5,7 @@ - + Paperless-ng From f800fdf66ac316e7c1e2148738f179f3a001d59c Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Fri, 1 Jan 2021 21:59:21 +0100 Subject: [PATCH 093/197] fix up the tika parser --- src/paperless_tika/parsers.py | 44 ++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/src/paperless_tika/parsers.py b/src/paperless_tika/parsers.py index 8ee10632f..56792fb51 100644 --- a/src/paperless_tika/parsers.py +++ b/src/paperless_tika/parsers.py @@ -21,26 +21,44 @@ class TikaDocumentParser(DocumentParser): return make_thumbnail_from_pdf( self.archive_path, self.tempdir, self.logging_group) + def extract_metadata(self, document_path, mime_type): + tika_server = settings.PAPERLESS_TIKA_ENDPOINT + try: + parsed = parser.from_file(document_path, tika_server) + except Exception as e: + self.log("warning", f"Error while fetching document metadata for " + f"{document_path}: {e}") + return [] + + return [ + { + "namespace": "", + "prefix": "", + "key": key, + "value": parsed['metadata'][key] + } for key in parsed['metadata'] + ] + def parse(self, document_path, mime_type): - self.log("info", f"[TIKA_PARSE] Sending {document_path} to Tika server") + self.log("info", f"Sending {document_path} to Tika server") tika_server = settings.PAPERLESS_TIKA_ENDPOINT try: parsed = parser.from_file(document_path, tika_server) - except requests.exceptions.HTTPError as err: + except Exception as err: raise ParseError( - f"Could not parse {document_path} with tika server at {tika_server}: {err}" + f"Could not parse {document_path} with tika server at " + f"{tika_server}: {err}" ) - try: - self.text = parsed["content"].strip() - except: - pass + self.text = parsed["content"].strip() try: - self.date = dateutil.parser.isoparse(parsed["metadata"]["Creation-Date"]) - except: - pass + self.date = dateutil.parser.isoparse( + parsed["metadata"]["Creation-Date"]) + except Exception as e: + self.log("warning", f"Unable to extract date for document " + f"{document_path}: {e}") self.archive_path = self.convert_to_pdf(document_path) @@ -49,16 +67,16 @@ class TikaDocumentParser(DocumentParser): gotenberg_server = settings.PAPERLESS_TIKA_GOTENBERG_ENDPOINT url = gotenberg_server + "/convert/office" - self.log("info", f"[TIKA] Converting {document_path} to PDF as {pdf_path}") + self.log("info", f"Converting {document_path} to PDF as {pdf_path}") files = {"files": open(document_path, "rb")} headers = {} try: response = requests.post(url, files=files, headers=headers) response.raise_for_status() # ensure we notice bad responses - except requests.exceptions.HTTPError as err: + except Exception as err: raise ParseError( - f"Could not contact gotenberg server at {gotenberg_server}: {err}" + f"Error while converting document to PDF: {err}" ) file = open(pdf_path, "wb") From 755f950cd20627e3a106484bf89a3f72987a133a Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Fri, 1 Jan 2021 22:19:43 +0100 Subject: [PATCH 094/197] supply file_name for tika parser --- src/documents/consumer.py | 3 +-- src/documents/parsers.py | 2 +- src/documents/tests/test_consumer.py | 4 ++-- src/paperless_tesseract/parsers.py | 2 +- src/paperless_text/parsers.py | 2 +- src/paperless_tika/parsers.py | 8 ++++---- 6 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/documents/consumer.py b/src/documents/consumer.py index 5a06194b7..abd12d802 100755 --- a/src/documents/consumer.py +++ b/src/documents/consumer.py @@ -1,6 +1,5 @@ import datetime import hashlib -import logging import os import magic @@ -130,7 +129,7 @@ class Consumer(LoggingMixin): try: self.log("debug", "Parsing {}...".format(self.filename)) - document_parser.parse(self.path, mime_type) + document_parser.parse(self.path, mime_type, self.filename) self.log("debug", f"Generating thumbnail for {self.filename}...") thumbnail = document_parser.get_optimised_thumbnail( diff --git a/src/documents/parsers.py b/src/documents/parsers.py index 65d321ce5..e14607bd0 100644 --- a/src/documents/parsers.py +++ b/src/documents/parsers.py @@ -267,7 +267,7 @@ class DocumentParser(LoggingMixin): def extract_metadata(self, document_path, mime_type): return [] - def parse(self, document_path, mime_type): + def parse(self, document_path, mime_type, file_name=None): raise NotImplementedError() def get_archive_path(self): diff --git a/src/documents/tests/test_consumer.py b/src/documents/tests/test_consumer.py index 795ca7f95..90c034f9e 100644 --- a/src/documents/tests/test_consumer.py +++ b/src/documents/tests/test_consumer.py @@ -177,7 +177,7 @@ class DummyParser(DocumentParser): def get_optimised_thumbnail(self, document_path, mime_type): return self.fake_thumb - def parse(self, document_path, mime_type): + def parse(self, document_path, mime_type, file_name=None): self.text = "The Text" @@ -194,7 +194,7 @@ class FaultyParser(DocumentParser): def get_optimised_thumbnail(self, document_path, mime_type): return self.fake_thumb - def parse(self, document_path, mime_type): + def parse(self, document_path, mime_type, file_name=None): raise ParseError("Does not compute.") diff --git a/src/paperless_tesseract/parsers.py b/src/paperless_tesseract/parsers.py index fc8702eac..31e956284 100644 --- a/src/paperless_tesseract/parsers.py +++ b/src/paperless_tesseract/parsers.py @@ -88,7 +88,7 @@ class RasterisedDocumentParser(DocumentParser): f"Error while calculating DPI for image {image}: {e}") return None - def parse(self, document_path, mime_type): + def parse(self, document_path, mime_type, file_name=None): mode = settings.OCR_MODE text_original = get_text_from_pdf(document_path) diff --git a/src/paperless_text/parsers.py b/src/paperless_text/parsers.py index a38bd7a91..c1afe07fc 100644 --- a/src/paperless_text/parsers.py +++ b/src/paperless_text/parsers.py @@ -32,6 +32,6 @@ class TextDocumentParser(DocumentParser): return out_path - def parse(self, document_path, mime_type): + def parse(self, document_path, mime_type, file_name=None): with open(document_path, 'r') as f: self.text = f.read() diff --git a/src/paperless_tika/parsers.py b/src/paperless_tika/parsers.py index 56792fb51..13e937daa 100644 --- a/src/paperless_tika/parsers.py +++ b/src/paperless_tika/parsers.py @@ -39,7 +39,7 @@ class TikaDocumentParser(DocumentParser): } for key in parsed['metadata'] ] - def parse(self, document_path, mime_type): + def parse(self, document_path, mime_type, file_name=None): self.log("info", f"Sending {document_path} to Tika server") tika_server = settings.PAPERLESS_TIKA_ENDPOINT @@ -60,15 +60,15 @@ class TikaDocumentParser(DocumentParser): self.log("warning", f"Unable to extract date for document " f"{document_path}: {e}") - self.archive_path = self.convert_to_pdf(document_path) + self.archive_path = self.convert_to_pdf(document_path, file_name) - def convert_to_pdf(self, document_path): + def convert_to_pdf(self, document_path, file_name): pdf_path = os.path.join(self.tempdir, "convert.pdf") gotenberg_server = settings.PAPERLESS_TIKA_GOTENBERG_ENDPOINT url = gotenberg_server + "/convert/office" self.log("info", f"Converting {document_path} to PDF as {pdf_path}") - files = {"files": open(document_path, "rb")} + files = {"files": (file_name, open(document_path, "rb"))} headers = {} try: From dac7b11c91d408f66a85f14a745635c9bad82bb6 Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Fri, 1 Jan 2021 22:29:25 +0100 Subject: [PATCH 095/197] remove active class from user menu --- src-ui/src/app/components/app-frame/app-frame.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src-ui/src/app/components/app-frame/app-frame.component.html b/src-ui/src/app/components/app-frame/app-frame.component.html index 46065a102..42273ca3a 100644 --- a/src-ui/src/app/components/app-frame/app-frame.component.html +++ b/src-ui/src/app/components/app-frame/app-frame.component.html @@ -34,7 +34,7 @@

Logged in as {{displayName}}

- + Settings From 4906b12bcf80fa589a27d67ec3dd518805f23d09 Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Fri, 1 Jan 2021 22:38:26 +0100 Subject: [PATCH 096/197] refactored app-view service --- src-ui/src/app/app.component.ts | 10 +++--- .../app-frame/app-frame.component.ts | 3 +- .../manage/settings/settings.component.ts | 6 ++-- .../src/app/services/app-view.service.spec.ts | 16 --------- src-ui/src/app/services/app-view.service.ts | 35 ------------------- src-ui/src/app/services/settings.service.ts | 28 +++++++++++++-- 6 files changed, 34 insertions(+), 64 deletions(-) delete mode 100644 src-ui/src/app/services/app-view.service.spec.ts delete mode 100644 src-ui/src/app/services/app-view.service.ts diff --git a/src-ui/src/app/app.component.ts b/src-ui/src/app/app.component.ts index 30ecb40d0..73c5fc861 100644 --- a/src-ui/src/app/app.component.ts +++ b/src-ui/src/app/app.component.ts @@ -1,5 +1,5 @@ import { Component } from '@angular/core'; -import { AppViewService } from './services/app-view.service'; +import { SettingsService } from './services/settings.service'; @Component({ selector: 'app-root', @@ -8,10 +8,10 @@ import { AppViewService } from './services/app-view.service'; }) export class AppComponent { - constructor (appViewService: AppViewService) { - (window as any).pdfWorkerSrc = '/assets/js/pdf.worker.min.js'; - appViewService.updateDarkModeSettings() + constructor (private settings: SettingsService) { + let anyWindow = (window as any) + anyWindow.pdfWorkerSrc = '/assets/js/pdf.worker.min.js'; + this.settings.updateDarkModeSettings() } - } diff --git a/src-ui/src/app/components/app-frame/app-frame.component.ts b/src-ui/src/app/components/app-frame/app-frame.component.ts index dca0d9106..ad4460f16 100644 --- a/src-ui/src/app/components/app-frame/app-frame.component.ts +++ b/src-ui/src/app/components/app-frame/app-frame.component.ts @@ -26,8 +26,7 @@ export class AppFrameComponent implements OnInit, OnDestroy { public savedViewService: SavedViewService, private meta: Meta ) { - console.log(meta); - + } versionString = `${environment.appTitle} ${environment.version}` diff --git a/src-ui/src/app/components/manage/settings/settings.component.ts b/src-ui/src/app/components/manage/settings/settings.component.ts index df3015e21..0b0646157 100644 --- a/src-ui/src/app/components/manage/settings/settings.component.ts +++ b/src-ui/src/app/components/manage/settings/settings.component.ts @@ -5,7 +5,6 @@ import { DocumentListViewService } from 'src/app/services/document-list-view.ser import { SavedViewService } from 'src/app/services/rest/saved-view.service'; import { SettingsService, SETTINGS_KEYS } from 'src/app/services/settings.service'; import { ToastService } from 'src/app/services/toast.service'; -import { AppViewService } from 'src/app/services/app-view.service'; @Component({ selector: 'app-settings', @@ -31,8 +30,7 @@ export class SettingsComponent implements OnInit { public savedViewService: SavedViewService, private documentListViewService: DocumentListViewService, private toastService: ToastService, - private settings: SettingsService, - private appViewService: AppViewService + private settings: SettingsService ) { } ngOnInit() { @@ -72,7 +70,7 @@ export class SettingsComponent implements OnInit { this.settings.set(SETTINGS_KEYS.DARK_MODE_USE_SYSTEM, this.settingsForm.value.darkModeUseSystem) this.settings.set(SETTINGS_KEYS.DARK_MODE_ENABLED, (this.settingsForm.value.darkModeEnabled == true).toString()) this.documentListViewService.updatePageSize() - this.appViewService.updateDarkModeSettings() + this.settings.updateDarkModeSettings() this.toastService.showInfo($localize`Settings saved successfully.`) } diff --git a/src-ui/src/app/services/app-view.service.spec.ts b/src-ui/src/app/services/app-view.service.spec.ts deleted file mode 100644 index fc44ed3a4..000000000 --- a/src-ui/src/app/services/app-view.service.spec.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { TestBed } from '@angular/core/testing'; - -import { AppViewService } from './app-view.service'; - -describe('AppViewService', () => { - let service: AppViewService; - - beforeEach(() => { - TestBed.configureTestingModule({}); - service = TestBed.inject(AppViewService); - }); - - it('should be created', () => { - expect(service).toBeTruthy(); - }); -}); diff --git a/src-ui/src/app/services/app-view.service.ts b/src-ui/src/app/services/app-view.service.ts deleted file mode 100644 index 67a429ffe..000000000 --- a/src-ui/src/app/services/app-view.service.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Inject, Injectable, Renderer2, RendererFactory2 } from '@angular/core'; -import { DOCUMENT } from '@angular/common'; -import { SettingsService, SETTINGS_KEYS } from './settings.service'; - -@Injectable({ - providedIn: 'root' -}) -export class AppViewService { - private renderer: Renderer2; - - constructor( - private settings: SettingsService, - private rendererFactory: RendererFactory2, - @Inject(DOCUMENT) private document - ) { - this.renderer = rendererFactory.createRenderer(null, null); - - this.updateDarkModeSettings() - } - - updateDarkModeSettings(): void { - let darkModeUseSystem = this.settings.get(SETTINGS_KEYS.DARK_MODE_USE_SYSTEM) - let darkModeEnabled = this.settings.get(SETTINGS_KEYS.DARK_MODE_ENABLED) - - if (darkModeUseSystem) { - this.renderer.addClass(this.document.body, 'color-scheme-system') - this.renderer.removeClass(this.document.body, 'color-scheme-dark') - } else { - this.renderer.removeClass(this.document.body, 'color-scheme-system') - darkModeEnabled ? this.renderer.addClass(this.document.body, 'color-scheme-dark') : this.renderer.removeClass(this.document.body, 'color-scheme-dark') - } - - } - -} diff --git a/src-ui/src/app/services/settings.service.ts b/src-ui/src/app/services/settings.service.ts index 7b1cfe9e3..a8f85972d 100644 --- a/src-ui/src/app/services/settings.service.ts +++ b/src-ui/src/app/services/settings.service.ts @@ -1,4 +1,5 @@ -import { Injectable } from '@angular/core'; +import { DOCUMENT } from '@angular/common'; +import { Inject, Injectable, Renderer2, RendererFactory2 } from '@angular/core'; export interface PaperlessSettings { key: string @@ -27,7 +28,30 @@ const SETTINGS: PaperlessSettings[] = [ }) export class SettingsService { - constructor() { } + private renderer: Renderer2; + + constructor( + private rendererFactory: RendererFactory2, + @Inject(DOCUMENT) private document + ) { + this.renderer = rendererFactory.createRenderer(null, null); + + this.updateDarkModeSettings() + } + + updateDarkModeSettings(): void { + let darkModeUseSystem = this.get(SETTINGS_KEYS.DARK_MODE_USE_SYSTEM) + let darkModeEnabled = this.get(SETTINGS_KEYS.DARK_MODE_ENABLED) + + if (darkModeUseSystem) { + this.renderer.addClass(this.document.body, 'color-scheme-system') + this.renderer.removeClass(this.document.body, 'color-scheme-dark') + } else { + this.renderer.removeClass(this.document.body, 'color-scheme-system') + darkModeEnabled ? this.renderer.addClass(this.document.body, 'color-scheme-dark') : this.renderer.removeClass(this.document.body, 'color-scheme-dark') + } + + } get(key: string): any { let setting = SETTINGS.find(s => s.key == key) From baa393d4672723ad452a6d5df8f7e7382bb193a6 Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Fri, 1 Jan 2021 22:38:33 +0100 Subject: [PATCH 097/197] messages --- src-ui/messages.xlf | 97 +++++++++++++++++++++++++++------------------ 1 file changed, 59 insertions(+), 38 deletions(-) diff --git a/src-ui/messages.xlf b/src-ui/messages.xlf index 5f12c504c..133d1ae96 100644 --- a/src-ui/messages.xlf +++ b/src-ui/messages.xlf @@ -377,7 +377,7 @@ Do you really want to delete the tag ""? src/app/components/manage/tag-list/tag-list.component.ts - 31 + 28 @@ -440,7 +440,7 @@ Do you really want to delete the document type ""? src/app/components/manage/document-type-list/document-type-list.component.ts - 26 + 24 @@ -468,21 +468,21 @@ Saved view " deleted. src/app/components/manage/settings/settings.component.ts - 52 + 54 Settings saved successfully. src/app/components/manage/settings/settings.component.ts - 61 + 74 Error while storing settings on server: src/app/components/manage/settings/settings.component.ts - 73 + 86 @@ -496,11 +496,11 @@ Saved views src/app/components/manage/settings/settings.component.html - 41 + 56 - - Document list + + Appearance src/app/components/manage/settings/settings.component.html 13 @@ -513,60 +513,74 @@ 17 + + Dark mode + + src/app/components/manage/settings/settings.component.html + 33 + + + + Use system settings + + src/app/components/manage/settings/settings.component.html + 36 + + Bulk editing src/app/components/manage/settings/settings.component.html - 33 + 44 Show confirmation dialogs src/app/components/manage/settings/settings.component.html - 35 + 48 Deleting documents will always ask for confirmation. src/app/components/manage/settings/settings.component.html - 35 + 48 Apply on close src/app/components/manage/settings/settings.component.html - 36 + 49 Appears on src/app/components/manage/settings/settings.component.html - 53 + 68 Show on dashboard src/app/components/manage/settings/settings.component.html - 56 + 71 Show in sidebar src/app/components/manage/settings/settings.component.html - 60 + 75 No saved views defined. src/app/components/manage/settings/settings.component.html - 70 + 85 @@ -580,7 +594,7 @@ Do you really want to delete the correspondent ""? src/app/components/manage/correspondent-list/correspondent-list.component.ts - 26 + 24 @@ -776,26 +790,33 @@ Paperless-ng src/app/components/app-frame/app-frame.component.html - 4 + 11 app title - - Search for documents + + Search documents src/app/components/app-frame/app-frame.component.html - 12 - - - - Manage - - src/app/components/app-frame/app-frame.component.html - 77 + 15 Settings + + src/app/components/app-frame/app-frame.component.html + 40 + + + + Logout + + src/app/components/app-frame/app-frame.component.html + 45 + + + + Manage src/app/components/app-frame/app-frame.component.html 112 @@ -805,49 +826,49 @@ Admin src/app/components/app-frame/app-frame.component.html - 119 + 147 Misc src/app/components/app-frame/app-frame.component.html - 125 + 153 Documentation src/app/components/app-frame/app-frame.component.html - 132 + 160 GitHub src/app/components/app-frame/app-frame.component.html - 139 + 167 - - Logout + + Logged in as src/app/components/app-frame/app-frame.component.html - 146 + 34 Open documents src/app/components/app-frame/app-frame.component.html - 57 + 92 Close all src/app/components/app-frame/app-frame.component.html - 71 + 106 @@ -910,7 +931,7 @@ Not assigned src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts - 145 + 161 Filter drop down element to filter for documents with no correspondent/type/tag assigned From c4b643b812975df2e9f6756a4ca0f6e34fb858b0 Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Fri, 1 Jan 2021 22:44:10 +0100 Subject: [PATCH 098/197] fix metadata column --- .../metadata-collapse/metadata-collapse.component.html | 2 +- .../metadata-collapse/metadata-collapse.component.scss | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src-ui/src/app/components/document-detail/metadata-collapse/metadata-collapse.component.html b/src-ui/src/app/components/document-detail/metadata-collapse/metadata-collapse.component.html index e8fda1d0b..ac42860c9 100644 --- a/src-ui/src/app/components/document-detail/metadata-collapse/metadata-collapse.component.html +++ b/src-ui/src/app/components/document-detail/metadata-collapse/metadata-collapse.component.html @@ -16,7 +16,7 @@
- +
NameColourMatchingDocument countActionsNameColorMatchingDocument countActions
{{m.prefix}}:{{m.key}}{{m.value}}
diff --git a/src-ui/src/app/components/document-detail/metadata-collapse/metadata-collapse.component.scss b/src-ui/src/app/components/document-detail/metadata-collapse/metadata-collapse.component.scss index e69de29bb..b946da146 100644 --- a/src-ui/src/app/components/document-detail/metadata-collapse/metadata-collapse.component.scss +++ b/src-ui/src/app/components/document-detail/metadata-collapse/metadata-collapse.component.scss @@ -0,0 +1,3 @@ +.metadata-column { + overflow-wrap: anywhere; +} \ No newline at end of file From fac8ceb2a757bec95f14c29203b61dc482d3d031 Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Fri, 1 Jan 2021 23:08:02 +0100 Subject: [PATCH 099/197] better matching algorithm descriptions --- .../correspondent-edit-dialog.component.html | 2 +- .../document-type-edit-dialog.component.html | 2 +- .../manage/generic-list/generic-list.component.ts | 2 +- .../tag-edit-dialog/tag-edit-dialog.component.html | 2 +- src-ui/src/app/data/matching-model.ts | 12 ++++++------ 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src-ui/src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.html b/src-ui/src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.html index e35c57e26..fd6b01de9 100644 --- a/src-ui/src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.html +++ b/src-ui/src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.html @@ -9,7 +9,7 @@ - + diff --git a/src-ui/src/app/components/manage/generic-list/generic-list.component.ts b/src-ui/src/app/components/manage/generic-list/generic-list.component.ts index 1f9cc65f9..b31231bc8 100644 --- a/src-ui/src/app/components/manage/generic-list/generic-list.component.ts +++ b/src-ui/src/app/components/manage/generic-list/generic-list.component.ts @@ -30,7 +30,7 @@ export abstract class GenericListComponent implements On if (o.matching_algorithm == MATCH_AUTO) { return $localize`Automatic` } else if (o.match && o.match.length > 0) { - return `${o.match} (${MATCHING_ALGORITHMS.find(a => a.id == o.matching_algorithm).name})` + return `${MATCHING_ALGORITHMS.find(a => a.id == o.matching_algorithm).shortName}: ${o.match}` } else { return "-" } diff --git a/src-ui/src/app/components/manage/tag-list/tag-edit-dialog/tag-edit-dialog.component.html b/src-ui/src/app/components/manage/tag-list/tag-edit-dialog/tag-edit-dialog.component.html index bbb96fb6b..7efaac4b9 100644 --- a/src-ui/src/app/components/manage/tag-list/tag-edit-dialog/tag-edit-dialog.component.html +++ b/src-ui/src/app/components/manage/tag-list/tag-edit-dialog/tag-edit-dialog.component.html @@ -20,7 +20,7 @@ - +