Merge remote-tracking branch 'origin/dev'

This commit is contained in:
Trenton H 2023-04-27 07:10:04 -07:00
commit 8f18baea8f
203 changed files with 955 additions and 809 deletions

View File

@ -200,7 +200,6 @@ class RegistryTagsCleaner:
tag,
)
for manifest in image_index.image_pointers:
if manifest.digest in untagged_versions:
logger.info(
f"Skipping deletion of {manifest.digest},"
@ -287,7 +286,6 @@ class RegistryTagsCleaner:
logger.info("Beginning confirmation step")
a_tag_failed = False
for tag in sorted(self.tags_to_keep):
try:
image_index = ImageIndex(
f"ghcr.io/{self.repo_owner}/{self.package_name}",
@ -301,7 +299,6 @@ class RegistryTagsCleaner:
digest_name = f"ghcr.io/{self.repo_owner}/{self.package_name}@{manifest.digest}"
try:
subprocess.run(
[
shutil.which("docker"),

View File

@ -37,16 +37,16 @@ repos:
exclude: "(^Pipfile\\.lock$)"
# Python hooks
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: 'v0.0.259'
rev: 'v0.0.263'
hooks:
- id: ruff
- repo: https://github.com/psf/black
rev: 22.12.0
rev: 23.3.0
hooks:
- id: black
# Dockerfile hooks
- repo: https://github.com/AleksaC/hadolint-py
rev: v2.10.0
rev: v2.12.0.2
hooks:
- id: hadolint
# Shell script hooks

View File

@ -1,6 +1,6 @@
# https://beta.ruff.rs/docs/settings/
# https://beta.ruff.rs/docs/rules/
select = ["F", "E", "W", "UP", "COM", "DJ", "EXE", "ISC", "ICN", "G201", "INP", "PIE", "RSE", "SIM", "TID", "PLC", "PLE", "RUF"]
extend-select = ["I", "W", "UP", "COM", "DJ", "EXE", "ISC", "ICN", "G201", "INP", "PIE", "RSE", "SIM", "TID", "PLC", "PLE", "RUF"]
# TODO PTH
ignore = ["DJ001", "SIM105"]
fix = true

112
Pipfile.lock generated
View File

@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "8395f25f876a71a7307a55dd542e69a4cdcb3be3be38c4e89ed06ce3d52a5345"
"sha256": "77248fee6dad10b9e5189e9ba80f7c506c9f49c875bac8b259e90dadecba03f1"
},
"pipfile-spec": 6,
"requires": {},
@ -1508,11 +1508,11 @@
"hiredis"
],
"hashes": [
"sha256:56732e156fe31801c4f43396bd3ca0c2a7f6f83d7936798531b9848d103381aa",
"sha256:7df17a0a2b72a4c8895b462dd07616c51b1dcb48fdd7ecb7b6f4bf39ecb2e94e"
"sha256:2c19e6767c474f2e85167909061d525ed65bea9301c0770bb151e041b7ac89a2",
"sha256:73ec35da4da267d6847e47f68730fdd5f62e2ca69e3ef5885c6a78a9374c3893"
],
"index": "pypi",
"version": "==4.5.3"
"version": "==4.5.4"
},
"regex": {
"hashes": [
@ -2256,34 +2256,35 @@
},
"black": {
"hashes": [
"sha256:0052dba51dec07ed029ed61b18183942043e00008ec65d5028814afaab9a22fd",
"sha256:0680d4380db3719ebcfb2613f34e86c8e6d15ffeabcf8ec59355c5e7b85bb555",
"sha256:121ca7f10b4a01fd99951234abdbd97728e1240be89fde18480ffac16503d481",
"sha256:162e37d49e93bd6eb6f1afc3e17a3d23a823042530c37c3c42eeeaf026f38468",
"sha256:2a951cc83ab535d248c89f300eccbd625e80ab880fbcfb5ac8afb5f01a258ac9",
"sha256:2bf649fda611c8550ca9d7592b69f0637218c2369b7744694c5e4902873b2f3a",
"sha256:382998821f58e5c8238d3166c492139573325287820963d2f7de4d518bd76958",
"sha256:49f7b39e30f326a34b5c9a4213213a6b221d7ae9d58ec70df1c4a307cf2a1580",
"sha256:57c18c5165c1dbe291d5306e53fb3988122890e57bd9b3dcb75f967f13411a26",
"sha256:7a0f701d314cfa0896b9001df70a530eb2472babb76086344e688829efd97d32",
"sha256:8178318cb74f98bc571eef19068f6ab5613b3e59d4f47771582f04e175570ed8",
"sha256:8b70eb40a78dfac24842458476135f9b99ab952dd3f2dab738c1881a9b38b753",
"sha256:9880d7d419bb7e709b37e28deb5e68a49227713b623c72b2b931028ea65f619b",
"sha256:9afd3f493666a0cd8f8df9a0200c6359ac53940cbde049dcb1a7eb6ee2dd7074",
"sha256:a29650759a6a0944e7cca036674655c2f0f63806ddecc45ed40b7b8aa314b651",
"sha256:a436e7881d33acaf2536c46a454bb964a50eff59b21b51c6ccf5a40601fbef24",
"sha256:a59db0a2094d2259c554676403fa2fac3473ccf1354c1c63eccf7ae65aac8ab6",
"sha256:a8471939da5e824b891b25751955be52ee7f8a30a916d570a5ba8e0f2eb2ecad",
"sha256:b0bd97bea8903f5a2ba7219257a44e3f1f9d00073d6cc1add68f0beec69692ac",
"sha256:b6a92a41ee34b883b359998f0c8e6eb8e99803aa8bf3123bf2b2e6fec505a221",
"sha256:bb460c8561c8c1bec7824ecbc3ce085eb50005883a6203dcfb0122e95797ee06",
"sha256:bfffba28dc52a58f04492181392ee380e95262af14ee01d4bc7bb1b1c6ca8d27",
"sha256:c1c476bc7b7d021321e7d93dc2cbd78ce103b84d5a4cf97ed535fbc0d6660648",
"sha256:c91dfc2c2a4e50df0026f88d2215e166616e0c80e86004d0003ece0488db2739",
"sha256:e6663f91b6feca5d06f2ccd49a10f254f9298cc1f7f49c46e498a0771b507104"
"sha256:064101748afa12ad2291c2b91c960be28b817c0c7eaa35bec09cc63aa56493c5",
"sha256:0945e13506be58bf7db93ee5853243eb368ace1c08a24c65ce108986eac65915",
"sha256:11c410f71b876f961d1de77b9699ad19f939094c3a677323f43d7a29855fe326",
"sha256:1c7b8d606e728a41ea1ccbd7264677e494e87cf630e399262ced92d4a8dac940",
"sha256:1d06691f1eb8de91cd1b322f21e3bfc9efe0c7ca1f0e1eb1db44ea367dff656b",
"sha256:3238f2aacf827d18d26db07524e44741233ae09a584273aa059066d644ca7b30",
"sha256:32daa9783106c28815d05b724238e30718f34155653d4d6e125dc7daec8e260c",
"sha256:35d1381d7a22cc5b2be2f72c7dfdae4072a3336060635718cc7e1ede24221d6c",
"sha256:3a150542a204124ed00683f0db1f5cf1c2aaaa9cc3495b7a3b5976fb136090ab",
"sha256:48f9d345675bb7fbc3dd85821b12487e1b9a75242028adad0333ce36ed2a6d27",
"sha256:50cb33cac881766a5cd9913e10ff75b1e8eb71babf4c7104f2e9c52da1fb7de2",
"sha256:562bd3a70495facf56814293149e51aa1be9931567474993c7942ff7d3533961",
"sha256:67de8d0c209eb5b330cce2469503de11bca4085880d62f1628bd9972cc3366b9",
"sha256:6b39abdfb402002b8a7d030ccc85cf5afff64ee90fa4c5aebc531e3ad0175ddb",
"sha256:6f3c333ea1dd6771b2d3777482429864f8e258899f6ff05826c3a4fcc5ce3f70",
"sha256:714290490c18fb0126baa0fca0a54ee795f7502b44177e1ce7624ba1c00f2331",
"sha256:7c3eb7cea23904399866c55826b31c1f55bbcd3890ce22ff70466b907b6775c2",
"sha256:92c543f6854c28a3c7f39f4d9b7694f9a6eb9d3c5e2ece488c327b6e7ea9b266",
"sha256:a6f6886c9869d4daae2d1715ce34a19bbc4b95006d20ed785ca00fa03cba312d",
"sha256:a8a968125d0a6a404842fa1bf0b349a568634f856aa08ffaff40ae0dfa52e7c6",
"sha256:c7ab5790333c448903c4b721b59c0d80b11fe5e9803d8703e84dcb8da56fec1b",
"sha256:e114420bf26b90d4b9daa597351337762b63039752bdf72bf361364c1aa05925",
"sha256:e198cf27888ad6f4ff331ca1c48ffc038848ea9f031a3b40ba36aced7e22f2c8",
"sha256:ec751418022185b0c1bb7d7736e6933d40bbb14c14a0abcf9123d1b159f98dd4",
"sha256:f0bd2f4a58d6666500542b26354978218a9babcdc972722f4bf90779524515f3"
],
"index": "pypi",
"version": "==23.1.0"
"markers": "python_version >= '3.7'",
"version": "==23.3.0"
},
"certifi": {
"hashes": [
@ -2718,11 +2719,11 @@
},
"packaging": {
"hashes": [
"sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2",
"sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97"
"sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61",
"sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"
],
"markers": "python_version >= '3.7'",
"version": "==23.0"
"version": "==23.1"
},
"pathspec": {
"hashes": [
@ -2817,11 +2818,11 @@
},
"platformdirs": {
"hashes": [
"sha256:024996549ee88ec1a9aa99ff7f8fc819bb59e2c3477b410d90a16d32d6e707aa",
"sha256:e5986afb596e4bb5bde29a79ac9061aa955b94fca2399b7aaac4090860920dd8"
"sha256:64370d47dc3fca65b4879f89bdead8197e93e05d696d6d1816243ebae8595da5",
"sha256:ea61fd7b85554beecbbd3e9b37fb26689b227ffae38f73353cbcc1cf8bd01878"
],
"markers": "python_version >= '3.7'",
"version": "==3.1.1"
"version": "==3.3.0"
},
"pluggy": {
"hashes": [
@ -3071,26 +3072,27 @@
},
"ruff": {
"hashes": [
"sha256:22e1e35bf5f12072cd644d22afd9203641ccf258bc14ff91aa1c43dc14f6047d",
"sha256:29e2b77b7d5da6a7dd5cf9b738b511355c5734ece56f78e500d4b5bffd58c1a0",
"sha256:38704f151323aa5858370a2f792e122cc25e5d1aabe7d42ceeab83da18f0b456",
"sha256:40ae87f2638484b7e8a7567b04a7af719f1c484c5bf132038b702bb32e1f6577",
"sha256:428507fb321b386dda70d66cd1a8aa0abf51d7c197983d83bb9e4fa5ee60300b",
"sha256:49e903bcda19f6bb0725a962c058eb5d61f40d84ef52ed53b61939b69402ab4e",
"sha256:5b3c1beacf6037e7f0781d4699d9a2dd4ba2462f475be5b1f45cf84c4ba3c69d",
"sha256:71f0ef1985e9a6696fa97da8459917fa34bdaa2c16bd33bd5edead585b7d44f7",
"sha256:79b02fa17ec1fd8d306ae302cb47fb614b71e1f539997858243769bcbe78c6d9",
"sha256:7cfef26619cba184d59aa7fa17b48af5891d51fc0b755a9bc533478a10d4d066",
"sha256:8b56496063ab3bfdf72339a5fbebb8bd46e5c5fee25ef11a9f03b208fa0562ec",
"sha256:aa9449b898287e621942cc71b9327eceb8f0c357e4065fecefb707ef2d978df8",
"sha256:c5fbaea9167f1852757f02133e5daacdb8c75b3431343205395da5b10499927a",
"sha256:d2fb20e89e85d147c85caa807707a1488bccc1f3854dc3d53533e89b52a0c5ff",
"sha256:daaea322e7e85f4c13d82be9536309e1c4b8b9851bb0cbc7eeb15d490fd46bf9",
"sha256:e4f39e18702de69faaaee3969934b92d7467285627f99a5b6ecd55a7d9f5d086",
"sha256:f3938dc45e2a3f818e9cbd53007265c22246fbfded8837b2c563bf0ebde1a226"
"sha256:04e0b280dd246448564c892bce5607d820ad1f14944f3d535db98692e2a7ac07",
"sha256:1008f211ad8aa1d998517ac5bf3d68fbc68ec516d1da89b6081f25ff2f30b687",
"sha256:15386933dd8e03aafa3186f9e996d6823105492817311338fbcb64d0ecbcd95f",
"sha256:3e9fcee3f81129eabc75da005d839235e32d7d374f2d4c0db0c708dad4703d6e",
"sha256:4010b156f2e9fa6e74b5581098467f6ff68beac48945599b3a9239481e578ab4",
"sha256:4f75fa1632ea065b8f10678e7b6ae9873f84d5046bdf146990112751e98af42a",
"sha256:7890499c2c3dcb1e60de2a8b4c5f5775b2bfcdff7d3e68e38db5cb2d65b12006",
"sha256:82c41f276106017b6f075dd2f2cc68e1a0b434cc75488f816fc98bd41982628d",
"sha256:981e3c4d773f7ff52479c4fd74a65e408f1e13fa5f889b72214d400cd1299ce4",
"sha256:9af932f665e177de62e172901704257fd6e5bfabb95893867ff7382a851459d3",
"sha256:bed1d3fba306e3f7e13ce226927b84200350e25abd1e754e06ee361c6d41de15",
"sha256:c2b79919ebd93674b93dfc2c843e264bf8e52fbe737467e9b58521775c85f4ad",
"sha256:c3b7d4b365207f3e4c40d235127091478e595b31e35b6cd57d940920cdfae68b",
"sha256:ddcee0d91629a4fa4bc9faebf5b94d4615d50d1cd76d1098fa71fbe1c54f4104",
"sha256:ddf4503595b560bfa5fae92fa2e4cb09ec465ee4cf88cc248f10ad2e956deec3",
"sha256:ebc778d95f29c9917e6e7608b2b67815707e6ab8eb5af9341617beda479c3edf",
"sha256:ee6c7a77f142c427fa73e1f5f603fc1a39413a36fe6966ed0fc55e97f6921d9c"
],
"index": "pypi",
"version": "==0.0.259"
"markers": "python_version >= '3.7'",
"version": "==0.0.263"
},
"scipy": {
"hashes": [
@ -3158,7 +3160,7 @@
"sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb",
"sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4"
],
"markers": "python_version >= '3.7'",
"markers": "python_version < '3.10'",
"version": "==4.5.0"
},
"urllib3": {

View File

@ -12,7 +12,6 @@ from typing import Final
from redis import Redis
if __name__ == "__main__":
MAX_RETRY_COUNT: Final[int] = 5
RETRY_SLEEP_SECONDS: Final[int] = 5

View File

@ -204,7 +204,7 @@ for details.
## Permissions
As of version 1.13.0 Paperless-ngx added core support for user / group permissions. Permissions is
As of version 1.14.0 Paperless-ngx added core support for user / group permissions. Permissions is
based around an object 'owner' and 'view' and 'edit' permissions can be granted to other users
or groups.
@ -212,13 +212,13 @@ Permissions uses the built-in user model of the backend framework, Django.
!!! note
After migration to version 1.13.0 all existing documents, tags etc. will have no explicit owner
After migration to version 1.14.0 all existing documents, tags etc. will have no explicit owner
set which means they will be visible / editable by all users. Once an object has an owner set,
only the owner can explicitly grant / revoke permissions.
!!! note
When first migrating to permissions it is recommended to user a 'superuser' account (which
When first migrating to permissions it is recommended to use a 'superuser' account (which
would usually have been setup during installation) to ensure you have full permissions.
Note that superusers have access to all objects.
@ -230,7 +230,7 @@ do not have an owner set.
### Users and Groups
Paperless-ngx versions after 1.13.0 allow creating and editing users and groups via the 'frontend' UI.
Paperless-ngx versions after 1.14.0 allow creating and editing users and groups via the 'frontend' UI.
These can be found under Settings > Users & Groups, assuming the user has access. If a user is designated
as a member of a group those permissions will be inherited and this is reflected in the UI. Explicit
permissions can be granted to limit access to certain parts of the UI (and corresponding API endpoints).

View File

@ -5,11 +5,15 @@ describe('document-detail', () => {
this.modifiedDocuments = []
cy.fixture('documents/documents.json').then((documentsJson) => {
cy.intercept('GET', 'http://localhost:8000/api/documents/1/', (req) => {
let response = { ...documentsJson }
response = response.results.find((d) => d.id == 1)
req.reply(response)
})
cy.intercept(
'GET',
'http://localhost:8000/api/documents/1/?full_perms=true',
(req) => {
let response = { ...documentsJson }
response = response.results.find((d) => d.id == 1)
req.reply(response)
}
)
})
cy.intercept('PUT', 'http://localhost:8000/api/documents/1/', (req) => {

View File

@ -21,6 +21,7 @@
"original_file_name": "2022-03-22 no latin title.pdf",
"archived_file_name": "2022-03-22 no latin title.pdf",
"owner": null,
"user_can_change": true,
"permissions": {
"view": {
"users": [],
@ -68,6 +69,7 @@
"original_file_name": "2022-03-23 lorem ipsum dolor sit amet.pdf",
"archived_file_name": "2022-03-23 llorem ipsum dolor sit amet.pdf",
"owner": null,
"user_can_change": true,
"permissions": {
"view": {
"users": [],
@ -98,6 +100,7 @@
"original_file_name": "2022-03-24 dolor.pdf",
"archived_file_name": "2022-03-24 dolor.pdf",
"owner": null,
"user_can_change": true,
"permissions": {
"view": {
"users": [],
@ -128,6 +131,7 @@
"original_file_name": "2022-06-01 sit amet.pdf",
"archived_file_name": "2022-06-01 sit amet.pdf",
"owner": null,
"user_can_change": true,
"permissions": {
"view": {
"users": [],

View File

@ -43,8 +43,8 @@ export class SelectComponent extends AbstractInputComponent<number> {
}
checkForPrivateItems(value: any) {
if (Array.isArray(value) && value.length > 0) {
value.forEach((id) => this.checkForPrivateItem(id))
if (Array.isArray(value)) {
if (value.length > 0) value.forEach((id) => this.checkForPrivateItem(id))
} else {
this.checkForPrivateItem(value)
}

View File

@ -122,7 +122,8 @@ export abstract class ManagementListComponent<T extends ObjectWithId>
null,
this.sortField,
this.sortReverse,
this._nameFilter
this._nameFilter,
true
)
.subscribe((c) => {
this.data = c.results

View File

@ -16,4 +16,6 @@ export interface ObjectWithPermissions extends ObjectWithId {
owner?: number
permissions?: PermissionsObject
user_can_change?: boolean
}

View File

@ -58,17 +58,24 @@ export class PermissionsService {
action: string,
object: ObjectWithPermissions
): boolean {
let actionObject = null
if (action === PermissionAction.View) actionObject = object.permissions.view
else if (action === PermissionAction.Change)
actionObject = object.permissions.change
if (!actionObject) return false
return (
this.currentUserOwnsObject(object) ||
actionObject.users.includes(this.currentUser.id) ||
actionObject.groups.filter((g) => this.currentUser.groups.includes(g))
.length > 0
)
if (action === PermissionAction.View) {
return (
this.currentUserOwnsObject(object) ||
object.permissions?.view.users.includes(this.currentUser.id) ||
object.permissions?.view.groups.filter((g) =>
this.currentUser.groups.includes(g)
).length > 0
)
} else if (action === PermissionAction.Change) {
return (
this.currentUserOwnsObject(object) ||
object.user_can_change ||
object.permissions?.change.users.includes(this.currentUser.id) ||
object.permissions?.change.groups.filter((g) =>
this.currentUser.groups.includes(g)
).length > 0
)
}
}
public getPermissionCode(

View File

@ -9,11 +9,15 @@ export abstract class AbstractNameFilterService<
pageSize?: number,
sortField?: string,
sortReverse?: boolean,
nameFilter?: string
nameFilter?: string,
fullPerms?: boolean
) {
let params = {}
if (nameFilter) {
params = { name__icontains: nameFilter }
params['name__icontains'] = nameFilter
}
if (fullPerms) {
params['full_perms'] = true
}
return this.list(page, pageSize, sortField, sortReverse, params)
}

View File

@ -113,6 +113,14 @@ export class DocumentService extends AbstractPaperlessService<PaperlessDocument>
}).pipe(map((response) => response.results.map((doc) => doc.id)))
}
get(id: number): Observable<PaperlessDocument> {
return this.http.get<PaperlessDocument>(this.getResourceUrl(id), {
params: {
full_perms: true,
},
})
}
getPreviewUrl(id: number, original: boolean = false): string {
let url = this.getResourceUrl(id, 'preview')
if (this._searchQuery) url += `#search="${this._searchQuery}"`

View File

@ -5,7 +5,7 @@ export const environment = {
apiBaseUrl: document.baseURI + 'api/',
apiVersion: '2',
appTitle: 'Paperless-ngx',
version: '1.14.0',
version: '1.14.0-dev',
webSocketHost: window.location.host,
webSocketProtocol: window.location.protocol == 'https:' ? 'wss:' : 'ws:',
webSocketBaseUrl: base_url.pathname + 'ws/',

View File

@ -625,7 +625,7 @@
<context context-type="sourcefile">src/app/components/app-frame/app-frame.component.html</context>
<context context-type="linenumber">134</context>
</context-group>
<target state="translated">Corresponsal és</target>
<target state="translated">Corresponsals</target>
</trans-unit>
<trans-unit id="7886570921510760899" datatype="html">
<source>Tags</source>
@ -4186,7 +4186,7 @@
<context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.html</context>
<context context-type="linenumber">2</context>
</context-group>
<target state="translated">Creat</target>
<target state="translated">Crear</target>
</trans-unit>
<trans-unit id="4010735610815226758" datatype="html">
<source>Filter by:</source>

View File

@ -797,7 +797,7 @@
<context context-type="sourcefile">src/app/components/app-frame/app-frame.component.html</context>
<context context-type="linenumber">235</context>
</context-group>
<target state="translated">Aktualisierung verfügbar</target>
<target state="translated">Update verfügbar</target>
</trans-unit>
<trans-unit id="3011185103048412841" datatype="html">
<source>An error occurred while saving settings.</source>
@ -3076,7 +3076,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">595,597</context>
</context-group>
<target state="needs-translation">Error deleting document: <x id="PH" equiv-text="error.error?.detail ?? error.message ?? JSON.stringify(error)"/></target>
<target state="translated">Fehler beim Löschen des Dokuments <x id="PH" equiv-text="error.error?.detail ?? error.message ?? JSON.stringify(error)"/></target>
</trans-unit>
<trans-unit id="7362691899087997122" datatype="html">
<source>Redo OCR confirm</source>
@ -4578,7 +4578,7 @@
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context>
<context context-type="linenumber">140,142</context>
</context-group>
<target state="needs-translation"> Update checking works by pinging the public <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://api.github.com/repos/paperless-ngx/paperless-ngx/releases/latest&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;"/>Github API<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> for the latest release to determine whether a new version is available.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> Actual updating of the app must still be performed manually. </target>
<target state="translated"> Die Überprüfung auf Updates erfolgt über Anfragen an die öffentliche <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://api.github.com/repos/paperless-ngx/paperless-ngx/releases/latest&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;"/>Github API<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>, um zu ermitteln, ob eine neue Version verfügbar ist.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> Das eigentliche Update der Anwendung muss weiterhin manuell durchgeführt werden. </target>
</trans-unit>
<trans-unit id="5489945693955857309" datatype="html">
<source><x id="START_EMPHASISED_TEXT" ctype="x-em" equiv-text="No track"/>No tracking data is collected by the app in any way.<x id="CLOSE_EMPHASISED_TEXT" ctype="x-em" equiv-text="&lt;/em&gt;"/></source>
@ -5671,7 +5671,7 @@
<context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">177</context>
</context-group>
<target state="needs-translation">Catalan</target>
<target state="translated">Katalanisch</target>
</trans-unit>
<trans-unit id="2719780722934172508" datatype="html">
<source>Czech</source>

View File

@ -3076,7 +3076,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">595,597</context>
</context-group>
<target state="needs-translation">Error deleting document: <x id="PH" equiv-text="error.error?.detail ?? error.message ?? JSON.stringify(error)"/></target>
<target state="translated">Virhe poistettaessa asiakirjaa: <x id="PH" equiv-text="error.error?.detail ?? error.message ?? JSON.stringify(error)"/></target>
</trans-unit>
<trans-unit id="7362691899087997122" datatype="html">
<source>Redo OCR confirm</source>
@ -4578,7 +4578,7 @@
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context>
<context context-type="linenumber">140,142</context>
</context-group>
<target state="needs-translation"> Update checking works by pinging the public <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://api.github.com/repos/paperless-ngx/paperless-ngx/releases/latest&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;"/>Github API<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> for the latest release to determine whether a new version is available.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> Actual updating of the app must still be performed manually. </target>
<target state="translated"> Päivityksen tarkistaminen tapahtuu yhteydellä <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://api.github.com/repos/paperless-ngx/paperless-ngx/releases/latest&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;"/>Github API-palveluun<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> viimeisimmän version tarkistamiseksi.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> Sovelluksen varsinainen päivitys on silti suoritettava manuaalisesti. </target>
</trans-unit>
<trans-unit id="5489945693955857309" datatype="html">
<source><x id="START_EMPHASISED_TEXT" ctype="x-em" equiv-text="No track"/>No tracking data is collected by the app in any way.<x id="CLOSE_EMPHASISED_TEXT" ctype="x-em" equiv-text="&lt;/em&gt;"/></source>
@ -5671,7 +5671,7 @@
<context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">177</context>
</context-group>
<target state="needs-translation">Catalan</target>
<target state="translated">Katalaani</target>
</trans-unit>
<trans-unit id="2719780722934172508" datatype="html">
<source>Czech</source>

View File

@ -1327,21 +1327,21 @@
</context-group>
<target state="final">Mot de passe</target>
</trans-unit>
<trans-unit id="4249303448466017578" datatype="html">
<trans-unit id="4249303448466017578" datatype="html" approved="yes">
<source>Password is token</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html</context>
<context context-type="linenumber">18</context>
</context-group>
<target state="translated">Le mot de passe est le jeton d'authentification</target>
<target state="final">Le mot de passe est un jeton d'authentification</target>
</trans-unit>
<trans-unit id="8313198211675984619" datatype="html">
<trans-unit id="8313198211675984619" datatype="html" approved="yes">
<source>Check if the password above is a token used for authentication</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html</context>
<context context-type="linenumber">18</context>
</context-group>
<target state="translated">Vérifier si le mot de passe ci-dessus est un jeton utilisé pour l'authentification</target>
<target state="final">Cocher si le mot de passe ci-dessus est un jeton utilisé pour l'authentification</target>
</trans-unit>
<trans-unit id="6124167940736826613" datatype="html" approved="yes">
<source>Character Set</source>
@ -1395,13 +1395,13 @@
</context-group>
<target state="final">Chargement ...</target>
</trans-unit>
<trans-unit id="6563391987554512024" datatype="html">
<trans-unit id="6563391987554512024" datatype="html" approved="yes">
<source>Test</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html</context>
<context context-type="linenumber">32</context>
</context-group>
<target state="translated">Test</target>
<target state="final">Tester</target>
</trans-unit>
<trans-unit id="451418349275958054" datatype="html" approved="yes">
<source>No encryption</source>
@ -1443,21 +1443,21 @@
</context-group>
<target state="final">Éditer un compte de messagerie</target>
</trans-unit>
<trans-unit id="7726734777863565313" datatype="html">
<trans-unit id="7726734777863565313" datatype="html" approved="yes">
<source>Successfully connected to the mail server</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts</context>
<context context-type="linenumber">88</context>
</context-group>
<target state="translated">Connexion réussie au serveur de courrier</target>
<target state="final">Connexion réussie au serveur de messagerie électronique</target>
</trans-unit>
<trans-unit id="6533084895896956145" datatype="html">
<trans-unit id="6533084895896956145" datatype="html" approved="yes">
<source>Unable to connect to the mail server</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts</context>
<context context-type="linenumber">89</context>
</context-group>
<target state="translated">Impossible de se connecter au serveur d'impression</target>
<target state="final">Impossible de se connecter au serveur de messagerie électronique</target>
</trans-unit>
<trans-unit id="4086606389696938932" datatype="html" approved="yes">
<source>Account</source>
@ -2063,21 +2063,21 @@
</context-group>
<target state="translated">Tous</target>
</trans-unit>
<trans-unit id="6381578200008167206" datatype="html">
<trans-unit id="6381578200008167206" datatype="html" approved="yes">
<source>Include</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/filterable-dropdown/filterable-dropdown.component.html</context>
<context context-type="linenumber">24</context>
</context-group>
<target state="translated">Inclure</target>
<target state="final">Inclure</target>
</trans-unit>
<trans-unit id="5668077948386857930" datatype="html">
<trans-unit id="5668077948386857930" datatype="html" approved="yes">
<source>Exclude</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/filterable-dropdown/filterable-dropdown.component.html</context>
<context context-type="linenumber">26</context>
</context-group>
<target state="translated">Exclure</target>
<target state="final">Exclure</target>
</trans-unit>
<trans-unit id="4391289919356861627" datatype="html" approved="yes">
<source>Apply</source>
@ -2273,7 +2273,7 @@
<note priority="1" from="description">Used for both types, correspondents, storage paths</note>
<target state="final">Ajouter un élément</target>
</trans-unit>
<trans-unit id="3686284950598311784" datatype="html">
<trans-unit id="3686284950598311784" datatype="html" approved="yes">
<source>Private</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/input/select/select.component.ts</context>
@ -2287,7 +2287,7 @@
<context context-type="sourcefile">src/app/components/common/tag/tag.component.html</context>
<context context-type="linenumber">8</context>
</context-group>
<target state="translated">Privé</target>
<target state="final">Privé</target>
</trans-unit>
<trans-unit id="6560126119609945418" datatype="html" approved="yes">
<source>Add tag</source>
@ -2351,13 +2351,13 @@
</context-group>
<target state="final"><x id="INTERPOLATION" equiv-text="{{action.key}}"/></target>
</trans-unit>
<trans-unit id="6895273602775249942" datatype="html">
<trans-unit id="6895273602775249942" datatype="html" approved="yes">
<source>Inherited from group</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/permissions-select/permissions-select.component.ts</context>
<context context-type="linenumber">62</context>
</context-group>
<target state="translated">Hérité du groupe</target>
<target state="final">Hérité du groupe</target>
</trans-unit>
<trans-unit id="3797570084942068182" datatype="html" approved="yes">
<source>Select</source>
@ -2467,53 +2467,53 @@
</context-group>
<target state="final">Statistiques</target>
</trans-unit>
<trans-unit id="2028517964701399614" datatype="html">
<trans-unit id="2028517964701399614" datatype="html" approved="yes">
<source>Go to inbox</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html</context>
<context context-type="linenumber">4</context>
</context-group>
<target state="translated">Accéder à la boîte de réception</target>
<target state="final">Accéder à la boîte de réception</target>
</trans-unit>
<trans-unit id="3497361602348932709" datatype="html">
<trans-unit id="3497361602348932709" datatype="html" approved="yes">
<source>Documents in inbox</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html</context>
<context context-type="linenumber">5</context>
</context-group>
<target state="translated">Documents dans la boîte de réception</target>
<target state="final">Documents dans la boîte de réception</target>
</trans-unit>
<trans-unit id="8809281703097241399" datatype="html">
<trans-unit id="8809281703097241399" datatype="html" approved="yes">
<source>Go to documents</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html</context>
<context context-type="linenumber">8</context>
</context-group>
<target state="translated">Aller aux documents</target>
<target state="final">Aller aux documents</target>
</trans-unit>
<trans-unit id="3823413855067727192" datatype="html">
<trans-unit id="3823413855067727192" datatype="html" approved="yes">
<source>Total documents</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html</context>
<context context-type="linenumber">9</context>
</context-group>
<target state="translated">Nombre total de documents</target>
<target state="final">Nombre total de documents </target>
</trans-unit>
<trans-unit id="6503529145162789855" datatype="html">
<trans-unit id="6503529145162789855" datatype="html" approved="yes">
<source>Total characters</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html</context>
<context context-type="linenumber">13</context>
</context-group>
<target state="translated">Nombre total de caractères</target>
<target state="final">Nombre total de caractères </target>
</trans-unit>
<trans-unit id="8693603235657020323" datatype="html">
<trans-unit id="8693603235657020323" datatype="html" approved="yes">
<source>Other</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.ts</context>
<context context-type="linenumber">55</context>
</context-group>
<target state="translated">Autres</target>
<target state="final">Autres</target>
</trans-unit>
<trans-unit id="8187573012244728580" datatype="html" approved="yes">
<source>Upload new documents</source>
@ -2962,13 +2962,13 @@
</context-group>
<target state="translated">Saisir le mot de passe</target>
</trans-unit>
<trans-unit id="8460995830263484763" datatype="html">
<trans-unit id="8460995830263484763" datatype="html" approved="yes">
<source>Notes <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span *ngIf=&quot;document?.notes.length&quot; class=&quot;badge text-bg-secondary ms-1&quot;&gt;"/><x id="INTERPOLATION" equiv-text="ngth}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/a&gt;"/></source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
<context context-type="linenumber">175,176</context>
</context-group>
<target state="translated">Notes <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span *ngIf=&quot;document?.notes.length&quot; class=&quot;badge text-bg-secondary ms-1&quot;&gt;"/><x id="INTERPOLATION" equiv-text="ngth}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/a&gt;"/></target>
<target state="final">Notes <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span *ngIf=&quot;document?.notes.length&quot; class=&quot;badge text-bg-secondary ms-1&quot;&gt;"/><x id="INTERPOLATION" equiv-text="ngth}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/a&gt;"/></target>
</trans-unit>
<trans-unit id="3823219296477075982" datatype="html" approved="yes">
<source>Discard</source>
@ -2986,13 +2986,13 @@
</context-group>
<target state="final">Enregistrer &amp; suivant</target>
</trans-unit>
<trans-unit id="2218903673684131427" datatype="html">
<trans-unit id="2218903673684131427" datatype="html" approved="yes">
<source>An error occurred loading content: <x id="PH" equiv-text="err.message ?? err.toString()"/></source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">226,228</context>
</context-group>
<target state="translated">Une erreur s'est produite lors du chargement du contenu : <x id="PH" equiv-text="err.message ?? err.toString()"/></target>
<target state="final">Une erreur s'est produite lors du chargement du contenu : <x id="PH" equiv-text="err.message ?? err.toString()"/></target>
</trans-unit>
<trans-unit id="5758784066858623886" datatype="html" approved="yes">
<source>Error retrieving metadata</source>
@ -3010,7 +3010,7 @@
</context-group>
<target state="final">Erreur lors de la récupération des suggestions</target>
</trans-unit>
<trans-unit id="8348337312757497317" datatype="html">
<trans-unit id="8348337312757497317" datatype="html" approved="yes">
<source>Document saved successfully.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
@ -3020,7 +3020,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">492</context>
</context-group>
<target state="translated">Document enregistré avec succès.</target>
<target state="final">Document enregistré avec succès.</target>
</trans-unit>
<trans-unit id="448882439049417053" datatype="html" approved="yes">
<source>Error saving document</source>
@ -3070,13 +3070,13 @@
</context-group>
<target state="final">Supprimer le document</target>
</trans-unit>
<trans-unit id="1844801255494293730" datatype="html">
<trans-unit id="1844801255494293730" datatype="html" approved="yes">
<source>Error deleting document: <x id="PH" equiv-text="error.error?.detail ?? error.message ?? JSON.stringify(error)"/></source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">595,597</context>
</context-group>
<target state="needs-translation">Error deleting document: <x id="PH" equiv-text="error.error?.detail ?? error.message ?? JSON.stringify(error)"/></target>
<target state="final">Erreur lors de la suppression du document : <x id="PH" equiv-text="error.error?.detail ?? error.message ?? JSON.stringify(error)"/></target>
</trans-unit>
<trans-unit id="7362691899087997122" datatype="html" approved="yes">
<source>Redo OCR confirm</source>
@ -3532,21 +3532,21 @@
</context-group>
<target state="final">Filtrer par étiquette</target>
</trans-unit>
<trans-unit id="106713086593101376" datatype="html">
<trans-unit id="106713086593101376" datatype="html" approved="yes">
<source>View notes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-card-large/document-card-large.component.html</context>
<context context-type="linenumber">70</context>
</context-group>
<target state="translated">Afficher les Notes</target>
<target state="final">Afficher les notes</target>
</trans-unit>
<trans-unit id="8778002102373462277" datatype="html">
<trans-unit id="8778002102373462277" datatype="html" approved="yes">
<source><x id="INTERPOLATION" equiv-text="otes.length}}"/> Notes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-card-large/document-card-large.component.html</context>
<context context-type="linenumber">74</context>
</context-group>
<target state="translated"><x id="INTERPOLATION" equiv-text="otes.length}}"/> Notes</target>
<target state="final"><x id="INTERPOLATION" equiv-text="otes.length}}"/> Notes</target>
</trans-unit>
<trans-unit id="78870852467682010" datatype="html" approved="yes">
<source>Filter by document type</source>
@ -3740,13 +3740,13 @@
</context-group>
<target state="final">Erreur lors du téléchargement du document</target>
</trans-unit>
<trans-unit id="494022736054110363" datatype="html">
<trans-unit id="494022736054110363" datatype="html" approved="yes">
<source>Sort by ASN</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">126</context>
</context-group>
<target state="translated">Trier par ASN</target>
<target state="final">Trier par ASN</target>
</trans-unit>
<trans-unit id="7517688192215738656" datatype="html" approved="yes">
<source>ASN</source>
@ -3764,31 +3764,31 @@
</context-group>
<target state="final">NSA</target>
</trans-unit>
<trans-unit id="6954625430271090777" datatype="html">
<trans-unit id="6954625430271090777" datatype="html" approved="yes">
<source>Sort by correspondent</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">133</context>
</context-group>
<target state="translated">Trier par correspondant</target>
<target state="final">Trier par correspondant</target>
</trans-unit>
<trans-unit id="2066713941761361709" datatype="html">
<trans-unit id="2066713941761361709" datatype="html" approved="yes">
<source>Sort by title</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">140</context>
</context-group>
<target state="translated">Trier par titre</target>
<target state="final">Trier par titre</target>
</trans-unit>
<trans-unit id="3557446856808034218" datatype="html">
<trans-unit id="3557446856808034218" datatype="html" approved="yes">
<source>Sort by notes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">147</context>
</context-group>
<target state="translated">Trier par notes</target>
<target state="final">Trier par notes</target>
</trans-unit>
<trans-unit id="8104421162933956065" datatype="html">
<trans-unit id="8104421162933956065" datatype="html" approved="yes">
<source>Notes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
@ -3802,39 +3802,39 @@
<context context-type="sourcefile">src/app/services/rest/document.service.ts</context>
<context context-type="linenumber">25</context>
</context-group>
<target state="translated">Notes</target>
<target state="final">Notes</target>
</trans-unit>
<trans-unit id="5499001829734502606" datatype="html">
<trans-unit id="5499001829734502606" datatype="html" approved="yes">
<source>Sort by document type</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">154</context>
</context-group>
<target state="translated">Trier par type de documents</target>
<target state="final">Trier par type de documents</target>
</trans-unit>
<trans-unit id="6213829731736042759" datatype="html">
<trans-unit id="6213829731736042759" datatype="html" approved="yes">
<source>Sort by storage path</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">161</context>
</context-group>
<target state="translated">Trier par chemin de stockage</target>
<target state="final">Trier par chemin de stockage</target>
</trans-unit>
<trans-unit id="3406167410329973166" datatype="html">
<trans-unit id="3406167410329973166" datatype="html" approved="yes">
<source>Sort by created date</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">168</context>
</context-group>
<target state="translated">Trier par la date de création</target>
<target state="final">Trier par date de création</target>
</trans-unit>
<trans-unit id="3769035778779263084" datatype="html">
<trans-unit id="3769035778779263084" datatype="html" approved="yes">
<source>Sort by added date</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">175</context>
</context-group>
<target state="translated">Trier par date d'ajout</target>
<target state="final">Trier par date d'ajout</target>
</trans-unit>
<trans-unit id="231679111972850796" datatype="html" approved="yes">
<source>Added</source>
@ -4060,31 +4060,31 @@
</context-group>
<target state="final">L'erreur renvoyée était</target>
</trans-unit>
<trans-unit id="1044349881182559852" datatype="html">
<trans-unit id="1044349881182559852" datatype="html" approved="yes">
<source>Enter note</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-notes/document-notes.component.html</context>
<context context-type="linenumber">4</context>
</context-group>
<target state="translated">Saisir des notes</target>
<target state="final">Saisir une note</target>
</trans-unit>
<trans-unit id="7770536883443596194" datatype="html">
<trans-unit id="7770536883443596194" datatype="html" approved="yes">
<source> Please enter a note. </source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-notes/document-notes.component.html</context>
<context context-type="linenumber">5,7</context>
</context-group>
<target state="translated"> Veuillez saisir une note. </target>
<target state="final"> Veuillez saisir une note. </target>
</trans-unit>
<trans-unit id="8433732438274024544" datatype="html">
<trans-unit id="8433732438274024544" datatype="html" approved="yes">
<source>Add note</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-notes/document-notes.component.html</context>
<context context-type="linenumber">11</context>
</context-group>
<target state="translated">Ajouter une note</target>
<target state="final">Ajouter une note</target>
</trans-unit>
<trans-unit id="8428006099054244235" datatype="html">
<trans-unit id="8428006099054244235" datatype="html" approved="yes">
<source>Delete note</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-notes/document-notes.component.html</context>
@ -4094,23 +4094,23 @@
<context context-type="sourcefile">src/app/components/document-notes/document-notes.component.html</context>
<context context-type="linenumber">25</context>
</context-group>
<target state="translated">Supprimer une note</target>
<target state="final">Supprimer une note</target>
</trans-unit>
<trans-unit id="207390237682956115" datatype="html">
<trans-unit id="207390237682956115" datatype="html" approved="yes">
<source>Error saving note: <x id="PH" equiv-text="e.toString()"/></source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-notes/document-notes.component.ts</context>
<context context-type="linenumber">65</context>
</context-group>
<target state="translated">Erreur lors de l'enregistrement de la note: <x id="PH" equiv-text="e.toString()"/></target>
<target state="final">Erreur lors de l'enregistrement de la note : <x id="PH" equiv-text="e.toString()"/></target>
</trans-unit>
<trans-unit id="5682285129543775369" datatype="html">
<trans-unit id="5682285129543775369" datatype="html" approved="yes">
<source>Error deleting note: <x id="PH" equiv-text="e.toString()"/></source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-notes/document-notes.component.ts</context>
<context context-type="linenumber">81</context>
</context-group>
<target state="translated">Erreur lors de l'enregistrement de la note: <x id="PH" equiv-text="e.toString()"/></target>
<target state="final">Une erreur s'est produite lors de la suppression de la note : <x id="PH" equiv-text="e.toString()"/></target>
</trans-unit>
<trans-unit id="6316128875819022658" datatype="html" approved="yes">
<source>correspondent</source>
@ -4312,7 +4312,7 @@
</context-group>
<target state="final">Aucun</target>
</trans-unit>
<trans-unit id="6328828522970676938" datatype="html">
<trans-unit id="6328828522970676938" datatype="html" approved="yes">
<source>Error occurred while creating <x id="PH" equiv-text="this.typeName"/> : <x id="PH_1" equiv-text="activeModal.componentInstance.error"/>.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.ts</context>
@ -4322,7 +4322,7 @@
<context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.ts</context>
<context context-type="linenumber">153,155</context>
</context-group>
<target state="translated">Une erreur s'est produite lors de la création de <x id="PH" equiv-text="this.typeName"/> : <x id="PH_1" equiv-text="activeModal.componentInstance.error"/>.</target>
<target state="final">Une erreur s'est produite lors de la création de <x id="PH" equiv-text="this.typeName"/> : <x id="PH_1" equiv-text="activeModal.componentInstance.error"/>.</target>
</trans-unit>
<trans-unit id="211408744872436427" datatype="html">
<source>Successfully created <x id="PH" equiv-text="this.typeName"/>.</source>
@ -4332,13 +4332,13 @@
</context-group>
<target state="translated">Création de <x id="PH" equiv-text="this.typeName"/> réussie.</target>
</trans-unit>
<trans-unit id="1370653329436185913" datatype="html">
<trans-unit id="1370653329436185913" datatype="html" approved="yes">
<source>Error occurred while saving <x id="PH" equiv-text="this.typeName"/><x id="PH_1" equiv-text="errorDetail ? &apos;: &apos; + errorDetail : &apos;&apos;"/>.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.ts</context>
<context context-type="linenumber">174,176</context>
</context-group>
<target state="translated">Une erreur s'est produite lors de la sauvegarde de <x id="PH" equiv-text="this.typeName"/> : <x id="PH_1" equiv-text="errorDetail ? ': ' + errorDetail : ''"/>.</target>
<target state="final">Une erreur s'est produite lors de la sauvegarde de <x id="PH" equiv-text="this.typeName"/> : <x id="PH_1" equiv-text="errorDetail ? ': ' + errorDetail : ''"/>.</target>
</trans-unit>
<trans-unit id="2541368547549828690" datatype="html" approved="yes">
<source>Successfully updated <x id="PH" equiv-text="this.typeName"/>.</source>
@ -4348,13 +4348,13 @@
</context-group>
<target state="final">Mise à jour de <x id="PH" equiv-text="this.typeName"/> réussie.</target>
</trans-unit>
<trans-unit id="6151710751857751783" datatype="html">
<trans-unit id="6151710751857751783" datatype="html" approved="yes">
<source>Error occurred while saving <x id="PH" equiv-text="this.typeName"/> : <x id="PH_1" equiv-text="e.toString()"/>.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.ts</context>
<context context-type="linenumber">187,189</context>
</context-group>
<target state="translated">Une erreur s'est produite lors de la sauvegarde de <x id="PH" equiv-text="this.typeName"/> : <x id="PH_1" equiv-text="e.toString()"/>.</target>
<target state="final">Une erreur s'est produite lors de la sauvegarde de <x id="PH" equiv-text="this.typeName"/> : <x id="PH_1" equiv-text="e.toString()"/>.</target>
</trans-unit>
<trans-unit id="4012132330507560812" datatype="html">
<source>Do you really want to delete the <x id="PH" equiv-text="this.typeName"/>?</source>
@ -4572,13 +4572,13 @@
</context-group>
<target state="final">Vérification des mises à jour</target>
</trans-unit>
<trans-unit id="7578076359386888824" datatype="html">
<trans-unit id="7578076359386888824" datatype="html" approved="yes">
<source> Update checking works by pinging the public <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://api.github.com/repos/paperless-ngx/paperless-ngx/releases/latest&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;"/>Github API<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> for the latest release to determine whether a new version is available.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> Actual updating of the app must still be performed manually. </source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context>
<context context-type="linenumber">140,142</context>
</context-group>
<target state="needs-translation"> Update checking works by pinging the public <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://api.github.com/repos/paperless-ngx/paperless-ngx/releases/latest&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;"/>Github API<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> for the latest release to determine whether a new version is available.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> Actual updating of the app must still be performed manually. </target>
<target state="final"> La vérification des mises à jour fonctionne en faisant un ping sur l'API publique <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://api.github.com/repos/paperless-ngx/paperless-ngx/releases/latest&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;"/>Github<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> pour la dernière version afin de déterminer si une nouvelle version est disponible.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> La mise à jour réelle de l'application doit toujours être effectuée manuellement. </target>
</trans-unit>
<trans-unit id="5489945693955857309" datatype="html">
<source><x id="START_EMPHASISED_TEXT" ctype="x-em" equiv-text="No track"/>No tracking data is collected by the app in any way.<x id="CLOSE_EMPHASISED_TEXT" ctype="x-em" equiv-text="&lt;/em&gt;"/></source>
@ -4636,13 +4636,13 @@
</context-group>
<target state="final">Appliquer lors de la fermeture</target>
</trans-unit>
<trans-unit id="293524471897878391" datatype="html">
<trans-unit id="293524471897878391" datatype="html" approved="yes">
<source>Enable notes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context>
<context context-type="linenumber">163</context>
</context-group>
<target state="translated">Activez les notes</target>
<target state="final">Activer les notes</target>
</trans-unit>
<trans-unit id="5851560788527570644" datatype="html" approved="yes">
<source>Notifications</source>
@ -4884,13 +4884,13 @@
</context-group>
<target state="translated">Une erreur s'est produite lors de l'enregistrement des paramètres sur le serveur : <x id="PH" equiv-text="JSON.stringify( error.error )"/></target>
</trans-unit>
<trans-unit id="4510369340305901516" datatype="html">
<trans-unit id="4510369340305901516" datatype="html" approved="yes">
<source>Password has been changed, you will be logged out momentarily.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.ts</context>
<context context-type="linenumber">659</context>
</context-group>
<target state="translated">Le mot de passe a été modifié, vous serez déconnecté momentanément.</target>
<target state="final">Le mot de passe a été modifié, vous serez déconnecté momentanément.</target>
</trans-unit>
<trans-unit id="2753185112875184719" datatype="html" approved="yes">
<source>Saved user &quot;<x id="PH" equiv-text="newUser.username"/>&quot;.</source>
@ -5665,13 +5665,13 @@
</context-group>
<target state="final">Biélorusse</target>
</trans-unit>
<trans-unit id="1001043467371963032" datatype="html">
<trans-unit id="1001043467371963032" datatype="html" approved="yes">
<source>Catalan</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">177</context>
</context-group>
<target state="needs-translation">Catalan</target>
<target state="final">Catalan</target>
</trans-unit>
<trans-unit id="2719780722934172508" datatype="html" approved="yes">
<source>Czech</source>

View File

@ -3076,7 +3076,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">595,597</context>
</context-group>
<target state="needs-translation">Error deleting document: <x id="PH" equiv-text="error.error?.detail ?? error.message ?? JSON.stringify(error)"/></target>
<target state="translated">Greška prilikom brisanja dokumenta: <x id="PH" equiv-text="error.error?.detail ?? error.message ?? JSON.stringify(error)"/></target>
</trans-unit>
<trans-unit id="7362691899087997122" datatype="html">
<source>Redo OCR confirm</source>
@ -4578,7 +4578,7 @@
<context context-type="sourcefile">src/app/components/manage/settings/settings.component.html</context>
<context context-type="linenumber">140,142</context>
</context-group>
<target state="needs-translation"> Update checking works by pinging the public <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://api.github.com/repos/paperless-ngx/paperless-ngx/releases/latest&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;"/>Github API<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> for the latest release to determine whether a new version is available.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> Actual updating of the app must still be performed manually. </target>
<target state="translated"> Provera ažuriranja funkcioniše pingovanjem javnog <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://api.github.com/repos/paperless-ngx/paperless-ngx/releases/latest&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;"/>Github API<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> za najnovije izdanje da bi se utvrdilo da li je nova verzija dostupna.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> Stvarno ažuriranje aplikacije i dalje mora da se obavlja ručno. </target>
</trans-unit>
<trans-unit id="5489945693955857309" datatype="html">
<source><x id="START_EMPHASISED_TEXT" ctype="x-em" equiv-text="No track"/>No tracking data is collected by the app in any way.<x id="CLOSE_EMPHASISED_TEXT" ctype="x-em" equiv-text="&lt;/em&gt;"/></source>
@ -5671,7 +5671,7 @@
<context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">177</context>
</context-group>
<target state="needs-translation">Catalan</target>
<target state="translated">Katalonski</target>
</trans-unit>
<trans-unit id="2719780722934172508" datatype="html">
<source>Czech</source>

View File

@ -13,28 +13,24 @@ from .models import Tag
class CorrespondentAdmin(GuardedModelAdmin):
list_display = ("name", "match", "matching_algorithm")
list_filter = ("matching_algorithm",)
list_editable = ("match", "matching_algorithm")
class TagAdmin(GuardedModelAdmin):
list_display = ("name", "color", "match", "matching_algorithm")
list_filter = ("color", "matching_algorithm")
list_editable = ("color", "match", "matching_algorithm")
class DocumentTypeAdmin(GuardedModelAdmin):
list_display = ("name", "match", "matching_algorithm")
list_filter = ("matching_algorithm",)
list_editable = ("match", "matching_algorithm")
class DocumentAdmin(GuardedModelAdmin):
search_fields = ("correspondent__name", "title", "content", "tags__name")
readonly_fields = (
"added",
@ -99,7 +95,6 @@ class RuleInline(admin.TabularInline):
class SavedViewAdmin(GuardedModelAdmin):
list_display = ("name", "owner")
inlines = [RuleInline]
@ -116,7 +111,6 @@ class StoragePathAdmin(GuardedModelAdmin):
class TaskAdmin(admin.ModelAdmin):
list_display = ("task_id", "task_file_name", "task_name", "date_done", "status")
list_filter = ("status", "date_done", "task_file_name", "task_name")
search_fields = ("task_name", "task_id", "status")
@ -133,7 +127,6 @@ class TaskAdmin(admin.ModelAdmin):
class NotesAdmin(GuardedModelAdmin):
list_display = ("user", "created", "note", "document")
list_filter = ("created", "user")
list_display_links = ("created",)

View File

@ -3,22 +3,19 @@ from django.utils.translation import gettext_lazy as _
class DocumentsConfig(AppConfig):
name = "documents"
verbose_name = _("Documents")
def ready(self):
from .signals import document_consumption_finished
from .signals.handlers import (
add_inbox_tags,
set_log_entry,
set_correspondent,
set_document_type,
set_tags,
set_storage_path,
add_to_index,
)
from .signals.handlers import add_inbox_tags
from .signals.handlers import add_to_index
from .signals.handlers import set_correspondent
from .signals.handlers import set_document_type
from .signals.handlers import set_log_entry
from .signals.handlers import set_storage_path
from .signals.handlers import set_tags
document_consumption_finished.connect(add_inbox_tags)
document_consumption_finished.connect(set_correspondent)

View File

@ -1,6 +1,7 @@
import itertools
from django.db.models import Q
from documents.models import Correspondent
from documents.models import Document
from documents.models import DocumentType
@ -54,7 +55,6 @@ def set_document_type(doc_ids, document_type):
def add_tag(doc_ids, tag):
qs = Document.objects.filter(Q(id__in=doc_ids) & ~Q(tags__id=tag))
affected_docs = [doc.id for doc in qs]
@ -70,7 +70,6 @@ def add_tag(doc_ids, tag):
def remove_tag(doc_ids, tag):
qs = Document.objects.filter(Q(id__in=doc_ids) & Q(tags__id=tag))
affected_docs = [doc.id for doc in qs]
@ -122,7 +121,6 @@ def delete(doc_ids):
def redo_ocr(doc_ids):
for document_id in doc_ids:
update_document_archive_file.delay(
document_id=document_id,
@ -132,7 +130,6 @@ def redo_ocr(doc_ids):
def set_permissions(doc_ids, set_permissions, owner=None):
qs = Document.objects.filter(id__in=doc_ids)
qs.update(owner=owner)

View File

@ -6,6 +6,7 @@ from django.core.checks import register
from django.core.exceptions import FieldError
from django.db.utils import OperationalError
from django.db.utils import ProgrammingError
from documents.signals import document_consumer_declaration
@ -22,7 +23,6 @@ def changed_password_check(app_configs, **kwargs):
return [] # No documents table yet
if encrypted_doc:
if not settings.PASSPHRASE:
return [
Error(
@ -52,7 +52,6 @@ def changed_password_check(app_configs, **kwargs):
@register()
def parser_check(app_configs, **kwargs):
parsers = []
for response in document_consumer_declaration.send(None):
parsers.append(response[1])

View File

@ -10,6 +10,7 @@ from typing import List
from typing import Optional
from django.conf import settings
from documents.models import Document
from documents.models import MatchingModel
@ -59,7 +60,6 @@ def load_classifier() -> Optional["DocumentClassifier"]:
class DocumentClassifier:
# v7 - Updated scikit-learn package version
# v8 - Added storage path classifier
# v9 - Changed from hashing to time/ids for re-train check
@ -140,7 +140,6 @@ class DocumentClassifier:
target_file_temp.rename(target_file)
def train(self):
# Get non-inbox documents
docs_queryset = Document.objects.exclude(
tags__is_inbox_tag=True,
@ -159,7 +158,6 @@ class DocumentClassifier:
logger.debug("Gathering data from database...")
hasher = sha256()
for doc in docs_queryset:
y = -1
dt = doc.document_type
if dt and dt.matching_algorithm == MatchingModel.MATCH_AUTO:
@ -334,12 +332,10 @@ class DocumentClassifier:
# If the NLTK language is supported, do further processing
if settings.NLTK_LANGUAGE is not None and settings.NLTK_ENABLED:
import nltk
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
from nltk.stem import SnowballStemmer
from nltk.tokenize import word_tokenize
# Not really hacky, since it isn't private and is documented, but
# set the search path for NLTK data to the single location it should be in

View File

@ -31,9 +31,9 @@ from .models import DocumentType
from .models import FileInfo
from .models import Tag
from .parsers import DocumentParser
from .parsers import ParseError
from .parsers import get_parser_class_for_mime_type
from .parsers import parse_date
from .parsers import ParseError
from .signals import document_consumption_finished
from .signals import document_consumption_started
@ -60,7 +60,6 @@ MESSAGE_FINISHED = "finished"
class Consumer(LoggingMixin):
logging_name = "paperless.consumer"
def _send_progress(
@ -426,7 +425,6 @@ class Consumer(LoggingMixin):
# in the system. This will be a transaction and reasonably fast.
try:
with transaction.atomic():
# store the document.
document = self._store(text=text, date=date, mime_type=mime_type)
@ -520,7 +518,6 @@ class Consumer(LoggingMixin):
date: Optional[datetime.datetime],
mime_type: str,
) -> Document:
# If someone gave us the original filename, use it instead of doc.
file_info = FileInfo.from_filename(self.filename)

View File

@ -7,6 +7,7 @@ import pathvalidate
from django.conf import settings
from django.template.defaultfilters import slugify
from django.utils import timezone
from documents.models import Document
logger = logging.getLogger("paperless.filehandling")

View File

@ -11,7 +11,6 @@ from .models import Log
from .models import StoragePath
from .models import Tag
CHAR_KWARGS = ["istartswith", "iendswith", "icontains", "iexact"]
ID_KWARGS = ["in", "exact"]
INT_KWARGS = ["exact", "gt", "gte", "lt", "lte", "isnull"]
@ -83,7 +82,6 @@ class TitleContentFilter(Filter):
class DocumentFilterSet(FilterSet):
is_tagged = BooleanFilter(
label="Is tagged",
field_name="tags",

View File

@ -6,8 +6,6 @@ from contextlib import contextmanager
from dateutil.parser import isoparse
from django.conf import settings
from django.utils import timezone
from documents.models import Document
from documents.models import Note
from guardian.shortcuts import get_users_with_perms
from whoosh import classify
from whoosh import highlight
@ -16,8 +14,8 @@ from whoosh.fields import BOOLEAN
from whoosh.fields import DATETIME
from whoosh.fields import KEYWORD
from whoosh.fields import NUMERIC
from whoosh.fields import Schema
from whoosh.fields import TEXT
from whoosh.fields import Schema
from whoosh.highlight import HtmlFormatter
from whoosh.index import create_in
from whoosh.index import exists_in
@ -28,6 +26,9 @@ from whoosh.searching import ResultsPage
from whoosh.searching import Searcher
from whoosh.writing import AsyncWriter
from documents.models import Document
from documents.models import Note
logger = logging.getLogger("paperless.index")
@ -330,7 +331,7 @@ class DelayedMoreLikeThisQuery(DelayedQuery):
def autocomplete(ix, term, limit=10):
with ix.reader() as reader:
terms = []
for (score, t) in reader.most_distinctive_terms(
for score, t in reader.most_distinctive_terms(
"content",
number=limit,
prefix=term.lower(),

View File

@ -3,7 +3,6 @@ import uuid
class LoggingMixin:
logging_group = None
logging_name = None

View File

@ -3,19 +3,18 @@ import os
from django.conf import settings
from django.core.management.base import BaseCommand
from django.core.management.base import CommandError
from documents.models import Document
from paperless.db import GnuPG
class Command(BaseCommand):
help = (
"This is how you migrate your stored documents from an encrypted "
"state to an unencrypted one (or vice-versa)"
)
def add_arguments(self, parser):
parser.add_argument(
"--passphrase",
help="If PAPERLESS_PASSPHRASE isn't set already, you need to "
@ -23,7 +22,6 @@ class Command(BaseCommand):
)
def handle(self, *args, **options):
try:
print(
"\n\nWARNING: This script is going to work directly on your "
@ -48,13 +46,11 @@ class Command(BaseCommand):
@staticmethod
def __gpg_to_unencrypted(passphrase):
encrypted_files = Document.objects.filter(
storage_type=Document.STORAGE_TYPE_GPG,
)
for document in encrypted_files:
print(f"Decrypting {document}".encode())
old_paths = [document.source_path, document.thumbnail_path]

View File

@ -6,15 +6,14 @@ import tqdm
from django import db
from django.conf import settings
from django.core.management.base import BaseCommand
from documents.models import Document
from documents.tasks import update_document_archive_file
logger = logging.getLogger("paperless.management.archiver")
class Command(BaseCommand):
help = """
Using the current classification model, assigns correspondents, tags
and document types to all documents, effectively allowing you to
@ -51,7 +50,6 @@ class Command(BaseCommand):
)
def handle(self, *args, **options):
os.makedirs(settings.SCRATCH_DIR, exist_ok=True)
overwrite = options["overwrite"]
@ -74,7 +72,6 @@ class Command(BaseCommand):
db.connections.close_all()
try:
logging.getLogger().handlers[0].level = logging.ERROR
with multiprocessing.Pool(processes=settings.TASK_WORKERS) as pool:
list(

View File

@ -13,17 +13,19 @@ from typing import Set
from django.conf import settings
from django.core.management.base import BaseCommand
from django.core.management.base import CommandError
from watchdog.events import FileSystemEventHandler
from watchdog.observers.polling import PollingObserver
from documents.data_models import ConsumableDocument
from documents.data_models import DocumentMetadataOverrides
from documents.data_models import DocumentSource
from documents.models import Tag
from documents.parsers import is_file_ext_supported
from documents.tasks import consume_file
from watchdog.events import FileSystemEventHandler
from watchdog.observers.polling import PollingObserver
try:
from inotifyrecursive import INotify, flags
from inotifyrecursive import INotify
from inotifyrecursive import flags
except ImportError: # pragma: nocover
INotify = flags = None

View File

@ -4,7 +4,6 @@ from documents.tasks import train_classifier
class Command(BaseCommand):
help = """
Trains the classifier on your data and saves the resulting models to a
file. The document consumer will then automatically use this new model.

View File

@ -17,6 +17,10 @@ from django.core.management.base import BaseCommand
from django.core.management.base import CommandError
from django.db import transaction
from django.utils import timezone
from filelock import FileLock
from documents.file_handling import delete_empty_directories
from documents.file_handling import generate_filename
from documents.models import Correspondent
from documents.models import Document
from documents.models import DocumentType
@ -29,18 +33,13 @@ from documents.models import UiSettings
from documents.settings import EXPORTER_ARCHIVE_NAME
from documents.settings import EXPORTER_FILE_NAME
from documents.settings import EXPORTER_THUMBNAIL_NAME
from filelock import FileLock
from paperless import version
from paperless.db import GnuPG
from paperless_mail.models import MailAccount
from paperless_mail.models import MailRule
from documents.file_handling import delete_empty_directories
from documents.file_handling import generate_filename
class Command(BaseCommand):
help = """
Decrypt and rename all files in our collection into a given target
directory. And include a manifest file containing document data for
@ -144,7 +143,6 @@ class Command(BaseCommand):
self.no_thumbnail = False
def handle(self, *args, **options):
self.target = Path(options["target"]).resolve()
self.split_manifest = options["split_manifest"]
self.compare_checksums = options["compare_checksums"]

View File

@ -14,16 +14,16 @@ from django.core.management.base import CommandError
from django.core.serializers.base import DeserializationError
from django.db.models.signals import m2m_changed
from django.db.models.signals import post_save
from filelock import FileLock
from documents.file_handling import create_source_path_directory
from documents.models import Document
from documents.parsers import run_convert
from documents.settings import EXPORTER_ARCHIVE_NAME
from documents.settings import EXPORTER_FILE_NAME
from documents.settings import EXPORTER_THUMBNAIL_NAME
from filelock import FileLock
from paperless import version
from documents.file_handling import create_source_path_directory
from documents.signals.handlers import update_filename_and_move_files
from paperless import version
@contextmanager
@ -36,7 +36,6 @@ def disable_signal(sig, receiver, sender):
class Command(BaseCommand):
help = """
Using a manifest.json file, load the data from there, and import the
documents it refers to.
@ -61,12 +60,11 @@ class Command(BaseCommand):
self.version = None
def handle(self, *args, **options):
logging.getLogger().handlers[0].level = logging.ERROR
self.source = options["source"]
self.source = Path(options["source"]).resolve()
if not os.path.exists(self.source):
if not self.source.exists():
raise CommandError("That path doesn't exist")
if not os.access(self.source, os.R_OK):
@ -74,39 +72,39 @@ class Command(BaseCommand):
manifest_paths = []
main_manifest_path = os.path.normpath(
os.path.join(self.source, "manifest.json"),
)
main_manifest_path = self.source / "manifest.json"
self._check_manifest_exists(main_manifest_path)
with open(main_manifest_path) as f:
self.manifest = json.load(f)
with main_manifest_path.open() as infile:
self.manifest = json.load(infile)
manifest_paths.append(main_manifest_path)
for file in Path(self.source).glob("**/*-manifest.json"):
with open(file) as f:
self.manifest += json.load(f)
with file.open() as infile:
self.manifest += json.load(infile)
manifest_paths.append(file)
version_path = os.path.normpath(os.path.join(self.source, "version.json"))
if os.path.exists(version_path):
with open(version_path) as f:
self.version = json.load(f)["version"]
# Provide an initial warning if needed to the user
if self.version != version.__full_version_str__:
self.stdout.write(
self.style.WARNING(
"Version mismatch: "
f"Currently {version.__full_version_str__},"
f" importing {self.version}."
" Continuing, but import may fail.",
),
)
version_path = self.source / "version.json"
if version_path.exists():
with version_path.open() as infile:
self.version = json.load(infile)["version"]
# Provide an initial warning if needed to the user
if self.version != version.__full_version_str__:
self.stdout.write(
self.style.WARNING(
"Version mismatch: "
f"Currently {version.__full_version_str__},"
f" importing {self.version}."
" Continuing, but import may fail.",
),
)
else:
self.stdout.write(self.style.NOTICE("No version.json file located"))
self._check_manifest()
self._check_manifest_valid()
with disable_signal(
post_save,
receiver=update_filename_and_move_files,
@ -150,16 +148,19 @@ class Command(BaseCommand):
)
@staticmethod
def _check_manifest_exists(path):
if not os.path.exists(path):
def _check_manifest_exists(path: Path):
if not path.exists():
raise CommandError(
"That directory doesn't appear to contain a manifest.json file.",
)
def _check_manifest(self):
def _check_manifest_valid(self):
"""
Attempts to verify the manifest is valid. Namely checking the files
referred to exist and the files can be read from
"""
self.stdout.write("Checking the manifest")
for record in self.manifest:
if record["model"] != "documents.document":
continue
@ -170,22 +171,37 @@ class Command(BaseCommand):
)
doc_file = record[EXPORTER_FILE_NAME]
if not os.path.exists(os.path.join(self.source, doc_file)):
doc_path = self.source / doc_file
if not doc_path.exists():
raise CommandError(
'The manifest file refers to "{}" which does not '
"appear to be in the source directory.".format(doc_file),
)
try:
with doc_path.open(mode="rb") as infile:
infile.read(1)
except Exception as e:
raise CommandError(
f"Failed to read from original file {doc_path}",
) from e
if EXPORTER_ARCHIVE_NAME in record:
archive_file = record[EXPORTER_ARCHIVE_NAME]
if not os.path.exists(os.path.join(self.source, archive_file)):
doc_archive_path = self.source / archive_file
if not doc_archive_path.exists():
raise CommandError(
f"The manifest file refers to {archive_file} which "
f"does not appear to be in the source directory.",
)
try:
with doc_archive_path.open(mode="rb") as infile:
infile.read(1)
except Exception as e:
raise CommandError(
f"Failed to read from archive file {doc_archive_path}",
) from e
def _import_files_from_manifest(self, progress_bar_disable):
os.makedirs(settings.ORIGINALS_DIR, exist_ok=True)
os.makedirs(settings.THUMBNAIL_DIR, exist_ok=True)
os.makedirs(settings.ARCHIVE_DIR, exist_ok=True)
@ -197,7 +213,6 @@ class Command(BaseCommand):
)
for record in tqdm.tqdm(manifest_documents, disable=progress_bar_disable):
document = Document.objects.get(pk=record["pk"])
doc_file = record[EXPORTER_FILE_NAME]

View File

@ -1,11 +1,11 @@
from django.core.management import BaseCommand
from django.db import transaction
from documents.tasks import index_optimize
from documents.tasks import index_reindex
class Command(BaseCommand):
help = "Manages the document index."
def add_arguments(self, parser):

View File

@ -3,11 +3,11 @@ import logging
import tqdm
from django.core.management.base import BaseCommand
from django.db.models.signals import post_save
from documents.models import Document
class Command(BaseCommand):
help = """
This will rename all documents to match the latest filename format.
""".replace(
@ -24,7 +24,6 @@ class Command(BaseCommand):
)
def handle(self, *args, **options):
logging.getLogger().handlers[0].level = logging.ERROR
for document in tqdm.tqdm(

View File

@ -2,20 +2,18 @@ import logging
import tqdm
from django.core.management.base import BaseCommand
from documents.classifier import load_classifier
from documents.models import Document
from documents.signals.handlers import set_correspondent
from documents.signals.handlers import set_document_type
from documents.signals.handlers import set_storage_path
from documents.signals.handlers import set_tags
logger = logging.getLogger("paperless.management.retagger")
class Command(BaseCommand):
help = """
Using the current classification model, assigns correspondents, tags
and document types to all documents, effectively allowing you to
@ -79,7 +77,6 @@ class Command(BaseCommand):
classifier = load_classifier()
for document in tqdm.tqdm(documents, disable=options["no_progress_bar"]):
if options["correspondent"]:
set_correspondent(
sender=None,

View File

@ -1,9 +1,9 @@
from django.core.management.base import BaseCommand
from documents.sanity_checker import check_sanity
class Command(BaseCommand):
help = """
This command checks your document archive for issues.
""".replace(
@ -20,7 +20,6 @@ class Command(BaseCommand):
)
def handle(self, *args, **options):
messages = check_sanity(progress=not options["no_progress_bar"])
messages.log_messages()

View File

@ -5,8 +5,8 @@ import shutil
import tqdm
from django import db
from django.core.management.base import BaseCommand
from documents.models import Document
from documents.models import Document
from documents.parsers import get_parser_class_for_mime_type
@ -21,7 +21,6 @@ def _process_document(doc_in):
return
try:
thumb = parser.get_thumbnail(
document.source_path,
document.mime_type,
@ -34,7 +33,6 @@ def _process_document(doc_in):
class Command(BaseCommand):
help = """
This will regenerate the thumbnails for all documents.
""".replace(

View File

@ -4,12 +4,10 @@ import os
from django.contrib.auth.models import User
from django.core.management.base import BaseCommand
logger = logging.getLogger("paperless.management.superuser")
class Command(BaseCommand):
help = """
Creates a Django superuser:
User named: admin
@ -25,7 +23,6 @@ class Command(BaseCommand):
)
def handle(self, *args, **options):
username = os.getenv("PAPERLESS_ADMIN_USER", "admin")
mail = os.getenv("PAPERLESS_ADMIN_MAIL", "root@localhost")
password = os.getenv("PAPERLESS_ADMIN_PASSWORD")

View File

@ -8,7 +8,6 @@ from documents.models import StoragePath
from documents.models import Tag
from documents.permissions import get_objects_for_user_owner_aware
logger = logging.getLogger("paperless.matching")
@ -23,6 +22,9 @@ def log_reason(matching_model, document, reason):
def match_correspondents(document, classifier, user=None):
pred_id = classifier.predict_correspondent(document.content) if classifier else None
if user is None and document.owner is not None:
user = document.owner
if user is not None:
correspondents = get_objects_for_user_owner_aware(
user,
@ -40,6 +42,9 @@ def match_correspondents(document, classifier, user=None):
def match_document_types(document, classifier, user=None):
pred_id = classifier.predict_document_type(document.content) if classifier else None
if user is None and document.owner is not None:
user = document.owner
if user is not None:
document_types = get_objects_for_user_owner_aware(
user,
@ -57,6 +62,9 @@ def match_document_types(document, classifier, user=None):
def match_tags(document, classifier, user=None):
predicted_tag_ids = classifier.predict_tags(document.content) if classifier else []
if user is None and document.owner is not None:
user = document.owner
if user is not None:
tags = get_objects_for_user_owner_aware(user, "documents.view_tag", Tag)
else:
@ -70,6 +78,9 @@ def match_tags(document, classifier, user=None):
def match_storage_paths(document, classifier, user=None):
pred_id = classifier.predict_storage_path(document.content) if classifier else None
if user is None and document.owner is not None:
user = document.owner
if user is not None:
storage_paths = get_objects_for_user_owner_aware(
user,

View File

@ -1,11 +1,11 @@
# Generated by Django 1.9 on 2015-12-20 19:10
from django.db import migrations, models
from django.conf import settings
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
initial = True
dependencies = []

View File

@ -1,11 +1,11 @@
# Generated by Django 1.9 on 2015-12-26 13:16
from django.db import migrations, models
import django.utils.timezone
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("documents", "0001_initial"),
]

View File

@ -1,16 +1,14 @@
# Generated by Django 1.9 on 2016-01-11 12:21
from django.db import migrations, models
from django.template.defaultfilters import slugify
import django.db.models.deletion
from django.db import migrations
from django.db import models
from django.template.defaultfilters import slugify
DOCUMENT_SENDER_MAP = {}
def move_sender_strings_to_sender_model(apps, schema_editor):
sender_model = apps.get_model("documents", "Sender")
document_model = apps.get_model("documents", "Document")

View File

@ -1,11 +1,11 @@
# Generated by Django 1.9 on 2016-01-14 18:44
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("documents", "0003_sender"),
]

View File

@ -4,7 +4,6 @@ from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("documents", "0004_auto_20160114_1844"),
]

View File

@ -1,10 +1,10 @@
# Generated by Django 1.9 on 2016-01-23 04:30
from django.db import migrations, models
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("documents", "0005_auto_20160123_0313"),
]

View File

@ -1,10 +1,10 @@
# Generated by Django 1.9 on 2016-01-26 21:14
from django.db import migrations, models
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("documents", "0006_auto_20160123_0430"),
]

View File

@ -1,10 +1,10 @@
# Generated by Django 1.9 on 2016-01-29 22:58
from django.db import migrations, models
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("documents", "0007_auto_20160126_2114"),
]

View File

@ -1,10 +1,10 @@
# Generated by Django 1.9 on 2016-02-14 00:40
from django.db import migrations, models
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("documents", "0008_document_file_type"),
]

View File

@ -1,10 +1,10 @@
# Generated by Django 1.9 on 2016-02-27 17:54
from django.db import migrations, models
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("documents", "0009_auto_20160214_0040"),
]

View File

@ -1,12 +1,12 @@
# Generated by Django 1.9.2 on 2016-03-05 00:40
import gnupg
import os
import re
import shutil
import subprocess
import tempfile
import gnupg
from django.conf import settings
from django.db import migrations
from django.utils.termcolors import colorize as colourise # Spelling hurts me
@ -34,7 +34,6 @@ class GnuPG:
def move_documents_and_create_thumbnails(apps, schema_editor):
os.makedirs(
os.path.join(settings.MEDIA_ROOT, "documents", "originals"),
exist_ok=True,
@ -67,7 +66,6 @@ def move_documents_and_create_thumbnails(apps, schema_editor):
pass
for f in sorted(documents):
if not f.endswith("gpg"):
continue

View File

@ -1,11 +1,11 @@
# Generated by Django 1.9.4 on 2016-03-25 21:11
from django.db import migrations, models
import django.utils.timezone
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("documents", "0012_auto_20160305_0040"),
]

View File

@ -1,12 +1,13 @@
# Generated by Django 1.9.4 on 2016-03-28 19:09
import gnupg
import hashlib
import os
import django.utils.timezone
import gnupg
from django.conf import settings
from django.db import migrations, models
from django.db import migrations
from django.db import models
from django.template.defaultfilters import slugify
from django.utils.termcolors import colorize as colourise # Spelling hurts me
@ -74,7 +75,6 @@ class Document:
def set_checksums(apps, schema_editor):
document_model = apps.get_model("documents", "Document")
if not document_model.objects.all().exists():
@ -94,7 +94,6 @@ def set_checksums(apps, schema_editor):
sums = {}
for d in document_model.objects.all():
document = Document(d)
print(

View File

@ -1,10 +1,10 @@
# Generated by Django 1.10.2 on 2016-10-05 21:38
from django.db import migrations, models
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("documents", "0014_document_checksum"),
]

View File

@ -1,11 +1,11 @@
# Generated by Django 1.10.5 on 2017-03-25 15:58
from django.db import migrations, models
from django.conf import settings
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("documents", "0015_add_insensitive_to_match"),
]

View File

@ -1,10 +1,10 @@
# Generated by Django 1.10.5 on 2017-05-12 05:07
from django.db import migrations, models
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("documents", "0016_auto_20170325_1558"),
]

View File

@ -1,11 +1,11 @@
# Generated by Django 1.10.5 on 2017-07-15 17:12
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("documents", "0017_auto_20170512_0507"),
]

View File

@ -1,5 +1,6 @@
from django.db import migrations, models
import django.utils.timezone
from django.db import migrations
from django.db import models
def set_added_time_to_created_time(apps, schema_editor):

View File

@ -1,10 +1,10 @@
# Generated by Django 1.11.10 on 2018-02-04 13:07
from django.db import migrations, models
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("documents", "0020_document_added"),
]

View File

@ -1,6 +1,7 @@
# Generated by Django 2.0.8 on 2018-10-07 14:20
from django.db import migrations, models
from django.db import migrations
from django.db import models
from django.utils.text import slugify
@ -19,7 +20,6 @@ def re_slug_all_the_things(apps, schema_editor):
class Migration(migrations.Migration):
dependencies = [
("documents", "0021_document_storage_type"),
]

View File

@ -1,6 +1,7 @@
# Generated by Django 2.0.10 on 2019-04-26 18:57
from django.db import migrations, models
from django.db import migrations
from django.db import models
def set_filename(apps, schema_editor):
@ -18,7 +19,6 @@ def set_filename(apps, schema_editor):
class Migration(migrations.Migration):
dependencies = [
("documents", "0022_auto_20181007_1420"),
]

View File

@ -1,8 +1,9 @@
# Generated by Django 3.1.3 on 2020-11-07 12:35
import uuid
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations
from django.db import models
def logs_set_default_group(apps, schema_editor):
@ -14,7 +15,6 @@ def logs_set_default_group(apps, schema_editor):
class Migration(migrations.Migration):
dependencies = [
("documents", "0023_document_current_filename"),
]

View File

@ -4,7 +4,6 @@ from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("documents", "1000_update_paperless_all"),
]

View File

@ -1,10 +1,10 @@
# Generated by Django 3.1.3 on 2020-11-11 11:05
from django.db import migrations, models
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("documents", "1001_auto_20201109_1636"),
]

View File

@ -3,7 +3,8 @@ import os
import magic
from django.conf import settings
from django.db import migrations, models
from django.db import migrations
from django.db import models
from paperless.db import GnuPG
@ -29,7 +30,6 @@ def add_mime_types(apps, schema_editor):
for d in documents:
f = open(source_path(d), "rb")
if d.storage_type == STORAGE_TYPE_GPG:
data = GnuPG.decrypted(f)
else:
data = f.read(1024)
@ -50,7 +50,6 @@ def add_file_extensions(apps, schema_editor):
class Migration(migrations.Migration):
dependencies = [
("documents", "1002_auto_20201111_1105"),
]

View File

@ -5,7 +5,6 @@ from django.db.migrations import RunPython
class Migration(migrations.Migration):
dependencies = [
("documents", "1003_mime_types"),
]

View File

@ -1,10 +1,10 @@
# Generated by Django 3.1.3 on 2020-11-29 00:48
from django.db import migrations, models
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("documents", "1004_sanity_check_schedule"),
]

View File

@ -4,7 +4,6 @@ from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("documents", "1005_checksums"),
]

View File

@ -1,12 +1,12 @@
# Generated by Django 3.1.4 on 2020-12-12 14:41
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
from django.conf import settings
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
("documents", "1006_auto_20201208_2209"),

View File

@ -1,11 +1,10 @@
# Generated by Django 3.1.4 on 2020-12-16 17:36
from django.db import migrations
import django.db.models.functions.text
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("documents", "1007_savedview_savedviewfilterrule"),
]

View File

@ -4,7 +4,6 @@ from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("documents", "1008_auto_20201216_1736"),
]

View File

@ -1,10 +1,10 @@
# Generated by Django 3.1.4 on 2021-01-01 21:59
from django.db import migrations, models
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("documents", "1009_auto_20201216_2005"),
]

View File

@ -1,13 +1,13 @@
# Generated by Django 3.1.4 on 2021-01-01 23:40
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
from django.conf import settings
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
("documents", "1010_auto_20210101_2159"),

View File

@ -8,11 +8,12 @@ from time import sleep
import pathvalidate
from django.conf import settings
from django.db import migrations, models
from django.db import migrations
from django.db import models
from django.template.defaultfilters import slugify
from documents.file_handling import defaultdictNoStr, many_to_dictionary
from documents.file_handling import defaultdictNoStr
from documents.file_handling import many_to_dictionary
logger = logging.getLogger("paperless.migrations")
@ -160,11 +161,9 @@ def parse_wrapper(parser, path, mime_type, file_name):
def create_archive_version(doc, retry_count=3):
from documents.parsers import (
get_parser_class_for_mime_type,
DocumentParser,
ParseError,
)
from documents.parsers import DocumentParser
from documents.parsers import ParseError
from documents.parsers import get_parser_class_for_mime_type
logger.info(f"Regenerating archive document for document ID:{doc.id}")
parser_class = get_parser_class_for_mime_type(doc.mime_type)
@ -255,7 +254,6 @@ def move_old_to_new_locations(apps, schema_editor):
)
for doc in Document.objects.filter(archive_checksum__isnull=False):
if doc.id in affected_document_ids:
old_path = archive_path_old(doc)
# remove affected archive versions
@ -305,7 +303,6 @@ def move_new_to_old_locations(apps, schema_editor):
class Migration(migrations.Migration):
dependencies = [
("documents", "1011_auto_20210101_2340"),
]

View File

@ -1,6 +1,7 @@
# Generated by Django 3.1.4 on 2020-12-02 21:43
from django.db import migrations, models
from django.db import migrations
from django.db import models
COLOURS_OLD = {
1: "#a6cee3",
@ -46,7 +47,6 @@ def reverse(apps, schema_editor):
class Migration(migrations.Migration):
dependencies = [
("documents", "1012_fix_archive_files"),
]

View File

@ -1,10 +1,10 @@
# Generated by Django 3.1.7 on 2021-02-28 15:14
from django.db import migrations, models
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("documents", "1013_migrate_tag_colour"),
]

View File

@ -3,7 +3,6 @@ import logging
from django.db import migrations
logger = logging.getLogger("paperless.migrations")
@ -19,7 +18,6 @@ def remove_null_characters(apps, schema_editor):
class Migration(migrations.Migration):
dependencies = [
("documents", "1014_auto_20210228_1614"),
]

View File

@ -1,10 +1,10 @@
# Generated by Django 3.1.7 on 2021-03-17 12:51
from django.db import migrations, models
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("documents", "1015_remove_null_characters"),
]

View File

@ -1,10 +1,10 @@
# Generated by Django 3.2.12 on 2022-03-17 11:59
from django.db import migrations, models
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("documents", "1016_auto_20210317_1351"),
]

View File

@ -1,10 +1,10 @@
# Generated by Django 4.0.3 on 2022-04-01 22:50
from django.db import migrations, models
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("documents", "1017_alter_savedviewfilterrule_rule_type"),
]

View File

@ -1,11 +1,11 @@
# Generated by Django 4.0.4 on 2022-05-02 15:56
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("documents", "1018_alter_savedviewfilterrule_value"),
]

View File

@ -1,12 +1,12 @@
# Generated by Django 4.0.4 on 2022-05-07 05:10
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
from django.conf import settings
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
("documents", "1018_alter_savedviewfilterrule_value"),

View File

@ -4,7 +4,6 @@ from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("documents", "1019_storagepath_document_storage_path"),
("documents", "1019_uisettings"),

View File

@ -8,6 +8,7 @@ from pathlib import Path
from django.conf import settings
from django.db import migrations
from documents.parsers import run_convert
logger = logging.getLogger("paperless.migrations")
@ -16,7 +17,6 @@ logger = logging.getLogger("paperless.migrations")
def _do_convert(work_package):
existing_thumbnail, converted_thumbnail = work_package
try:
logger.info(f"Converting thumbnail: {existing_thumbnail}")
# Run actual conversion
@ -50,7 +50,6 @@ def _convert_thumbnails_to_webp(apps, schema_editor):
start = time.time()
with tempfile.TemporaryDirectory() as tempdir:
work_packages = []
for file in Path(settings.THUMBNAIL_DIR).glob("*.png"):
@ -72,7 +71,6 @@ def _convert_thumbnails_to_webp(apps, schema_editor):
)
if len(work_packages):
logger.info(
"\n\n"
" This is a one-time only migration to convert thumbnails for all of your\n"
@ -94,7 +92,6 @@ def _convert_thumbnails_to_webp(apps, schema_editor):
class Migration(migrations.Migration):
dependencies = [
("documents", "1020_merge_20220518_1839"),
]

View File

@ -1,11 +1,11 @@
# Generated by Django 4.0.4 on 2022-05-23 07:14
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("documents", "1021_webp_thumbnail_conversion"),
]

View File

@ -1,6 +1,7 @@
from django.db import migrations, models
import django.utils.timezone
from django.conf import settings
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):

View File

@ -1,10 +1,10 @@
# Generated by Django 4.0.6 on 2022-07-25 06:34
from django.db import migrations, models
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("documents", "1023_add_comments"),
]

View File

@ -1,10 +1,10 @@
# Generated by Django 4.0.5 on 2022-08-26 16:49
from django.db import migrations, models
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("documents", "1024_document_original_filename"),
]

View File

@ -1,11 +1,11 @@
# Generated by Django 4.1.1 on 2022-09-27 19:31
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("django_celery_results", "0011_taskresult_periodic_task_name"),
("documents", "1025_alter_savedviewfilterrule_rule_type"),

View File

@ -1,11 +1,11 @@
# Generated by Django 4.1.2 on 2022-10-17 16:31
from django.db import migrations, models
import django.utils.timezone
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("documents", "1026_transition_to_celery"),
]

View File

@ -4,7 +4,6 @@ from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("documents", "1027_remove_paperlesstask_attempted_task_and_more"),
]

View File

@ -1,11 +1,11 @@
# Generated by Django 4.1.4 on 2023-01-24 17:56
import django.core.validators
from django.db import migrations, models
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("documents", "1028_remove_paperlesstask_task_args_and_more"),
]

View File

@ -1,10 +1,10 @@
# Generated by Django 4.1.5 on 2023-02-03 21:53
from django.db import migrations, models
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("documents", "1029_alter_document_archive_serial_number"),
]

View File

@ -1,12 +1,12 @@
# Generated by Django 4.1.4 on 2022-02-03 04:24
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
from django.conf import settings
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
("documents", "1030_alter_paperlesstask_task_file_name"),

View File

@ -1,10 +1,10 @@
# Generated by Django 4.1.7 on 2023-02-22 00:45
from django.db import migrations, models
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("documents", "1031_remove_savedview_user_correspondent_owner_and_more"),
]

View File

@ -1,10 +1,10 @@
# Generated by Django 4.1.5 on 2023-03-04 22:33
from django.db import migrations, models
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("documents", "1032_alter_correspondent_matching_algorithm_and_more"),
]

View File

@ -1,10 +1,10 @@
# Generated by Django 4.1.5 on 2023-03-15 07:10
from django.db import migrations, models
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("documents", "1033_alter_documenttype_options_alter_tag_options_and_more"),
]

Some files were not shown because too many files have changed in this diff Show More