mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-10-30 03:56:23 -05:00 
			
		
		
		
	Compare commits
	
		
			4 Commits
		
	
	
		
			4210addb46
			...
			07c298523a
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 07c298523a | ||
|   | 0ea159683d | ||
|   | f0b6e79d14 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 302cb22ec6 | 
| @@ -159,6 +159,23 @@ Available options are `postgresql` and `mariadb`. | ||||
|  | ||||
|     Defaults to unset, which uses Django’s built-in defaults. | ||||
|  | ||||
| #### [`PAPERLESS_DB_POOLSIZE=<int>`](#PAPERLESS_DB_POOLSIZE) {#PAPERLESS_DB_POOLSIZE} | ||||
|  | ||||
| : Defines the maximum number of database connections to keep in the pool. | ||||
|  | ||||
|     Only applies to PostgreSQL. This setting is ignored for other database engines. | ||||
|  | ||||
|     The value must be greater than or equal to 1 to be used. | ||||
|     Defaults to unset, which disables connection pooling. | ||||
|  | ||||
|     !!! note | ||||
|  | ||||
|     A small pool is typically sufficient — for example, a size of 4. | ||||
|     Make sure your PostgreSQL server's max_connections setting is large enough to handle: | ||||
|     ```(Paperless workers + Celery workers) × pool size + safety margin``` | ||||
|     For example, with 4 Paperless workers and 2 Celery workers, and a pool size of 4: | ||||
|     (4 + 2) × 4 + 10 = 34 connections required. | ||||
|  | ||||
| #### [`PAPERLESS_DB_READ_CACHE_ENABLED=<bool>`](#PAPERLESS_DB_READ_CACHE_ENABLED) {#PAPERLESS_DB_READ_CACHE_ENABLED} | ||||
|  | ||||
| : Caches the database read query results into Redis. This can significantly improve application response times by caching database queries, at the cost of slightly increased memory usage. | ||||
|   | ||||
| @@ -52,6 +52,7 @@ dependencies = [ | ||||
|   "ocrmypdf~=16.10.0", | ||||
|   "pathvalidate~=3.3.1", | ||||
|   "pdf2image~=1.17.0", | ||||
|   "psycopg-pool", | ||||
|   "python-dateutil~=2.9.0", | ||||
|   "python-dotenv~=1.1.0", | ||||
|   "python-gnupg~=0.5.4", | ||||
| @@ -74,9 +75,10 @@ optional-dependencies.mariadb = [ | ||||
|   "mysqlclient~=2.2.7", | ||||
| ] | ||||
| optional-dependencies.postgres = [ | ||||
|   "psycopg[c]==3.2.9", | ||||
|   "psycopg[c,pool]==3.2.9", | ||||
|   # Direct dependency for proper resolution of the pre-built wheels | ||||
|   "psycopg-c==3.2.9", | ||||
|   "psycopg-pool==3.2.6", | ||||
| ] | ||||
| optional-dependencies.webserver = [ | ||||
|   "granian[uvloop]~=2.4.1", | ||||
|   | ||||
| @@ -1507,64 +1507,64 @@ | ||||
|         <source>Use system language</source> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/admin/settings/settings.component.ts</context> | ||||
|           <context context-type="linenumber">77</context> | ||||
|           <context context-type="linenumber">78</context> | ||||
|         </context-group> | ||||
|       </trans-unit> | ||||
|       <trans-unit id="7729897675462249787" datatype="html"> | ||||
|         <source>Use date format of display language</source> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/admin/settings/settings.component.ts</context> | ||||
|           <context context-type="linenumber">80</context> | ||||
|           <context context-type="linenumber">81</context> | ||||
|         </context-group> | ||||
|       </trans-unit> | ||||
|       <trans-unit id="1235706724900303689" datatype="html"> | ||||
|         <source>Error retrieving users</source> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/admin/settings/settings.component.ts</context> | ||||
|           <context context-type="linenumber">224</context> | ||||
|           <context context-type="linenumber">225</context> | ||||
|         </context-group> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/admin/users-groups/users-groups.component.ts</context> | ||||
|           <context context-type="linenumber">55</context> | ||||
|           <context context-type="linenumber">56</context> | ||||
|         </context-group> | ||||
|       </trans-unit> | ||||
|       <trans-unit id="3066660568529853846" datatype="html"> | ||||
|         <source>Error retrieving groups</source> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/admin/settings/settings.component.ts</context> | ||||
|           <context context-type="linenumber">243</context> | ||||
|           <context context-type="linenumber">244</context> | ||||
|         </context-group> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/admin/users-groups/users-groups.component.ts</context> | ||||
|           <context context-type="linenumber">67</context> | ||||
|           <context context-type="linenumber">68</context> | ||||
|         </context-group> | ||||
|       </trans-unit> | ||||
|       <trans-unit id="7217000812750597833" datatype="html"> | ||||
|         <source>Settings were saved successfully.</source> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/admin/settings/settings.component.ts</context> | ||||
|           <context context-type="linenumber">546</context> | ||||
|           <context context-type="linenumber">547</context> | ||||
|         </context-group> | ||||
|       </trans-unit> | ||||
|       <trans-unit id="525012668859298131" datatype="html"> | ||||
|         <source>Settings were saved successfully. Reload is required to apply some changes.</source> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/admin/settings/settings.component.ts</context> | ||||
|           <context context-type="linenumber">550</context> | ||||
|           <context context-type="linenumber">551</context> | ||||
|         </context-group> | ||||
|       </trans-unit> | ||||
|       <trans-unit id="8491974984518503778" datatype="html"> | ||||
|         <source>Reload now</source> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/admin/settings/settings.component.ts</context> | ||||
|           <context context-type="linenumber">551</context> | ||||
|           <context context-type="linenumber">552</context> | ||||
|         </context-group> | ||||
|       </trans-unit> | ||||
|       <trans-unit id="3011185103048412841" datatype="html"> | ||||
|         <source>An error occurred while saving settings.</source> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/admin/settings/settings.component.ts</context> | ||||
|           <context context-type="linenumber">561</context> | ||||
|           <context context-type="linenumber">562</context> | ||||
|         </context-group> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/app-frame/app-frame.component.ts</context> | ||||
| @@ -2229,11 +2229,11 @@ | ||||
|         </context-group> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/admin/users-groups/users-groups.component.ts</context> | ||||
|           <context context-type="linenumber">120</context> | ||||
|           <context context-type="linenumber">123</context> | ||||
|         </context-group> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/admin/users-groups/users-groups.component.ts</context> | ||||
|           <context context-type="linenumber">173</context> | ||||
|           <context context-type="linenumber">176</context> | ||||
|         </context-group> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/manage/custom-fields/custom-fields.component.ts</context> | ||||
| @@ -2497,50 +2497,50 @@ | ||||
|         <source>Password has been changed, you will be logged out momentarily.</source> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/admin/users-groups/users-groups.component.ts</context> | ||||
|           <context context-type="linenumber">93</context> | ||||
|           <context context-type="linenumber">94</context> | ||||
|         </context-group> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.ts</context> | ||||
|           <context context-type="linenumber">194</context> | ||||
|           <context context-type="linenumber">195</context> | ||||
|         </context-group> | ||||
|       </trans-unit> | ||||
|       <trans-unit id="2753185112875184719" datatype="html"> | ||||
|         <source>Saved user "<x id="PH" equiv-text="newUser.username"/>".</source> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/admin/users-groups/users-groups.component.ts</context> | ||||
|           <context context-type="linenumber">100</context> | ||||
|           <context context-type="linenumber">103</context> | ||||
|         </context-group> | ||||
|       </trans-unit> | ||||
|       <trans-unit id="3471101514724661554" datatype="html"> | ||||
|         <source>Error saving user.</source> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/admin/users-groups/users-groups.component.ts</context> | ||||
|           <context context-type="linenumber">110</context> | ||||
|           <context context-type="linenumber">113</context> | ||||
|         </context-group> | ||||
|       </trans-unit> | ||||
|       <trans-unit id="5565868288871970148" datatype="html"> | ||||
|         <source>Confirm delete user account</source> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/admin/users-groups/users-groups.component.ts</context> | ||||
|           <context context-type="linenumber">118</context> | ||||
|           <context context-type="linenumber">121</context> | ||||
|         </context-group> | ||||
|       </trans-unit> | ||||
|       <trans-unit id="8133663925694885325" datatype="html"> | ||||
|         <source>This operation will permanently delete this user account.</source> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/admin/users-groups/users-groups.component.ts</context> | ||||
|           <context context-type="linenumber">119</context> | ||||
|           <context context-type="linenumber">122</context> | ||||
|         </context-group> | ||||
|       </trans-unit> | ||||
|       <trans-unit id="1181910457994920507" datatype="html"> | ||||
|         <source>Proceed</source> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/admin/users-groups/users-groups.component.ts</context> | ||||
|           <context context-type="linenumber">122</context> | ||||
|           <context context-type="linenumber">125</context> | ||||
|         </context-group> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/admin/users-groups/users-groups.component.ts</context> | ||||
|           <context context-type="linenumber">175</context> | ||||
|           <context context-type="linenumber">178</context> | ||||
|         </context-group> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> | ||||
| @@ -2595,56 +2595,56 @@ | ||||
|         <source>Deleted user "<x id="PH" equiv-text="user.username"/>"</source> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/admin/users-groups/users-groups.component.ts</context> | ||||
|           <context context-type="linenumber">128</context> | ||||
|           <context context-type="linenumber">131</context> | ||||
|         </context-group> | ||||
|       </trans-unit> | ||||
|       <trans-unit id="286457042048584728" datatype="html"> | ||||
|         <source>Error deleting user "<x id="PH" equiv-text="user.username"/>".</source> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/admin/users-groups/users-groups.component.ts</context> | ||||
|           <context context-type="linenumber">135</context> | ||||
|           <context context-type="linenumber">138</context> | ||||
|         </context-group> | ||||
|       </trans-unit> | ||||
|       <trans-unit id="5766640174051730159" datatype="html"> | ||||
|         <source>Saved group "<x id="PH" equiv-text="newGroup.name"/>".</source> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/admin/users-groups/users-groups.component.ts</context> | ||||
|           <context context-type="linenumber">155</context> | ||||
|           <context context-type="linenumber">158</context> | ||||
|         </context-group> | ||||
|       </trans-unit> | ||||
|       <trans-unit id="8382042988405122578" datatype="html"> | ||||
|         <source>Error saving group.</source> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/admin/users-groups/users-groups.component.ts</context> | ||||
|           <context context-type="linenumber">163</context> | ||||
|           <context context-type="linenumber">166</context> | ||||
|         </context-group> | ||||
|       </trans-unit> | ||||
|       <trans-unit id="6538873300613683004" datatype="html"> | ||||
|         <source>Confirm delete user group</source> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/admin/users-groups/users-groups.component.ts</context> | ||||
|           <context context-type="linenumber">171</context> | ||||
|           <context context-type="linenumber">174</context> | ||||
|         </context-group> | ||||
|       </trans-unit> | ||||
|       <trans-unit id="7710984639498518244" datatype="html"> | ||||
|         <source>This operation will permanently delete this user group.</source> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/admin/users-groups/users-groups.component.ts</context> | ||||
|           <context context-type="linenumber">172</context> | ||||
|           <context context-type="linenumber">175</context> | ||||
|         </context-group> | ||||
|       </trans-unit> | ||||
|       <trans-unit id="3756187211130340490" datatype="html"> | ||||
|         <source>Deleted group "<x id="PH" equiv-text="group.name"/>"</source> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/admin/users-groups/users-groups.component.ts</context> | ||||
|           <context context-type="linenumber">181</context> | ||||
|           <context context-type="linenumber">184</context> | ||||
|         </context-group> | ||||
|       </trans-unit> | ||||
|       <trans-unit id="1697803415975901060" datatype="html"> | ||||
|         <source>Error deleting group "<x id="PH" equiv-text="group.name"/>".</source> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/admin/users-groups/users-groups.component.ts</context> | ||||
|           <context context-type="linenumber">188</context> | ||||
|           <context context-type="linenumber">191</context> | ||||
|         </context-group> | ||||
|       </trans-unit> | ||||
|       <trans-unit id="7931334600001636863" datatype="html"> | ||||
| @@ -5828,85 +5828,85 @@ | ||||
|         <source>Emails must match</source> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.ts</context> | ||||
|           <context context-type="linenumber">142</context> | ||||
|           <context context-type="linenumber">143</context> | ||||
|         </context-group> | ||||
|       </trans-unit> | ||||
|       <trans-unit id="5281933990298241826" datatype="html"> | ||||
|         <source>Passwords must match</source> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.ts</context> | ||||
|           <context context-type="linenumber">170</context> | ||||
|           <context context-type="linenumber">171</context> | ||||
|         </context-group> | ||||
|       </trans-unit> | ||||
|       <trans-unit id="4219429959475101385" datatype="html"> | ||||
|         <source>Profile updated successfully</source> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.ts</context> | ||||
|           <context context-type="linenumber">191</context> | ||||
|           <context context-type="linenumber">192</context> | ||||
|         </context-group> | ||||
|       </trans-unit> | ||||
|       <trans-unit id="3417726855410304962" datatype="html"> | ||||
|         <source>Error saving profile</source> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.ts</context> | ||||
|           <context context-type="linenumber">203</context> | ||||
|           <context context-type="linenumber">206</context> | ||||
|         </context-group> | ||||
|       </trans-unit> | ||||
|       <trans-unit id="154249228726292516" datatype="html"> | ||||
|         <source>Error generating auth token</source> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.ts</context> | ||||
|           <context context-type="linenumber">220</context> | ||||
|           <context context-type="linenumber">223</context> | ||||
|         </context-group> | ||||
|       </trans-unit> | ||||
|       <trans-unit id="4153637646944982460" datatype="html"> | ||||
|         <source>Error disconnecting social account</source> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.ts</context> | ||||
|           <context context-type="linenumber">245</context> | ||||
|           <context context-type="linenumber">248</context> | ||||
|         </context-group> | ||||
|       </trans-unit> | ||||
|       <trans-unit id="5939111172212776886" datatype="html"> | ||||
|         <source>Error fetching TOTP settings</source> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.ts</context> | ||||
|           <context context-type="linenumber">264</context> | ||||
|           <context context-type="linenumber">267</context> | ||||
|         </context-group> | ||||
|       </trans-unit> | ||||
|       <trans-unit id="1030314492414713260" datatype="html"> | ||||
|         <source>TOTP activated successfully</source> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.ts</context> | ||||
|           <context context-type="linenumber">285</context> | ||||
|           <context context-type="linenumber">288</context> | ||||
|         </context-group> | ||||
|       </trans-unit> | ||||
|       <trans-unit id="3755006064892435830" datatype="html"> | ||||
|         <source>Error activating TOTP</source> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.ts</context> | ||||
|           <context context-type="linenumber">287</context> | ||||
|           <context context-type="linenumber">290</context> | ||||
|         </context-group> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.ts</context> | ||||
|           <context context-type="linenumber">293</context> | ||||
|           <context context-type="linenumber">296</context> | ||||
|         </context-group> | ||||
|       </trans-unit> | ||||
|       <trans-unit id="5919827473541889422" datatype="html"> | ||||
|         <source>TOTP deactivated successfully</source> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.ts</context> | ||||
|           <context context-type="linenumber">309</context> | ||||
|           <context context-type="linenumber">312</context> | ||||
|         </context-group> | ||||
|       </trans-unit> | ||||
|       <trans-unit id="6214722303383624015" datatype="html"> | ||||
|         <source>Error deactivating TOTP</source> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.ts</context> | ||||
|           <context context-type="linenumber">311</context> | ||||
|           <context context-type="linenumber">314</context> | ||||
|         </context-group> | ||||
|         <context-group purpose="location"> | ||||
|           <context context-type="sourcefile">src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.ts</context> | ||||
|           <context context-type="linenumber">316</context> | ||||
|           <context context-type="linenumber">319</context> | ||||
|         </context-group> | ||||
|       </trans-unit> | ||||
|       <trans-unit id="6617773613987957957" datatype="html"> | ||||
|   | ||||
| @@ -54,16 +54,16 @@ | ||||
|     "@angular/compiler-cli": "~20.1.4", | ||||
|     "@codecov/webpack-plugin": "^1.9.1", | ||||
|     "@playwright/test": "^1.54.2", | ||||
|     "@types/jest": "^29.5.14", | ||||
|     "@types/jest": "^30.0.0", | ||||
|     "@types/node": "^24.1.0", | ||||
|     "@typescript-eslint/eslint-plugin": "^8.38.0", | ||||
|     "@typescript-eslint/parser": "^8.38.0", | ||||
|     "@typescript-eslint/utils": "^8.38.0", | ||||
|     "eslint": "^9.32.0", | ||||
|     "jest": "29.7.0", | ||||
|     "jest-environment-jsdom": "^29.7.0", | ||||
|     "jest": "30.0.5", | ||||
|     "jest-environment-jsdom": "^30.0.5", | ||||
|     "jest-junit": "^16.0.0", | ||||
|     "jest-preset-angular": "^14.5.5", | ||||
|     "jest-preset-angular": "^15.0.0", | ||||
|     "jest-websocket-mock": "^2.5.0", | ||||
|     "prettier-plugin-organize-imports": "^4.2.0", | ||||
|     "ts-node": "~10.9.1", | ||||
|   | ||||
							
								
								
									
										2068
									
								
								src-ui/pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2068
									
								
								src-ui/pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,12 +1,16 @@ | ||||
| import '@angular/localize/init' | ||||
| import { jest } from '@jest/globals' | ||||
| import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone' | ||||
| import { TextDecoder, TextEncoder } from 'util' | ||||
| import { TextDecoder, TextEncoder } from 'node:util' | ||||
| if (process.env.NODE_ENV === 'test') { | ||||
|   setupZoneTestEnv() | ||||
| } | ||||
| global.TextEncoder = TextEncoder | ||||
| global.TextDecoder = TextDecoder | ||||
| ;(globalThis as any).TextEncoder = TextEncoder as unknown as { | ||||
|   new (): TextEncoder | ||||
| } | ||||
| ;(globalThis as any).TextDecoder = TextDecoder as unknown as { | ||||
|   new (): TextDecoder | ||||
| } | ||||
|  | ||||
| import { registerLocaleData } from '@angular/common' | ||||
| import localeAf from '@angular/common/locales/af' | ||||
| @@ -116,10 +120,6 @@ if (!URL.revokeObjectURL) { | ||||
|   Object.defineProperty(window.URL, 'revokeObjectURL', { value: jest.fn() }) | ||||
| } | ||||
| Object.defineProperty(window, 'ResizeObserver', { value: mock() }) | ||||
| Object.defineProperty(window, 'location', { | ||||
|   configurable: true, | ||||
|   value: { reload: jest.fn() }, | ||||
| }) | ||||
|  | ||||
| HTMLCanvasElement.prototype.getContext = < | ||||
|   typeof HTMLCanvasElement.prototype.getContext | ||||
|   | ||||
| @@ -36,6 +36,7 @@ import { UserService } from 'src/app/services/rest/user.service' | ||||
| import { SettingsService } from 'src/app/services/settings.service' | ||||
| import { SystemStatusService } from 'src/app/services/system-status.service' | ||||
| import { Toast, ToastService } from 'src/app/services/toast.service' | ||||
| import * as navUtils from 'src/app/utils/navigation' | ||||
| import { ConfirmButtonComponent } from '../../common/confirm-button/confirm-button.component' | ||||
| import { ConfirmDialogComponent } from '../../common/confirm-dialog/confirm-dialog.component' | ||||
| import { CheckComponent } from '../../common/input/check/check.component' | ||||
| @@ -225,6 +226,9 @@ describe('SettingsComponent', () => { | ||||
|   }) | ||||
|  | ||||
|   it('should offer reload if settings changes require', () => { | ||||
|     const reloadSpy = jest | ||||
|       .spyOn(navUtils, 'locationReload') | ||||
|       .mockImplementation(() => {}) | ||||
|     completeSetup() | ||||
|     let toast: Toast | ||||
|     toastService.getToasts().subscribe((t) => (toast = t[0])) | ||||
| @@ -241,6 +245,7 @@ describe('SettingsComponent', () => { | ||||
|  | ||||
|     expect(toast.actionName).toEqual('Reload now') | ||||
|     toast.action() | ||||
|     expect(reloadSpy).toHaveBeenCalled() | ||||
|   }) | ||||
|  | ||||
|   it('should allow setting theme color, visually apply change immediately but not save', () => { | ||||
| @@ -269,7 +274,7 @@ describe('SettingsComponent', () => { | ||||
|       ) | ||||
|     completeSetup(userService) | ||||
|     fixture.detectChanges() | ||||
|     expect(toastErrorSpy).toBeCalled() | ||||
|     expect(toastErrorSpy).toHaveBeenCalled() | ||||
|   }) | ||||
|  | ||||
|   it('should show errors on load if load groups failure', () => { | ||||
| @@ -281,7 +286,7 @@ describe('SettingsComponent', () => { | ||||
|       ) | ||||
|     completeSetup(groupService) | ||||
|     fixture.detectChanges() | ||||
|     expect(toastErrorSpy).toBeCalled() | ||||
|     expect(toastErrorSpy).toHaveBeenCalled() | ||||
|   }) | ||||
|  | ||||
|   it('should load system status on initialize, show errors if needed', () => { | ||||
|   | ||||
| @@ -57,6 +57,7 @@ import { | ||||
| } from 'src/app/services/settings.service' | ||||
| import { SystemStatusService } from 'src/app/services/system-status.service' | ||||
| import { Toast, ToastService } from 'src/app/services/toast.service' | ||||
| import { locationReload } from 'src/app/utils/navigation' | ||||
| import { CheckComponent } from '../../common/input/check/check.component' | ||||
| import { ColorComponent } from '../../common/input/color/color.component' | ||||
| import { PermissionsGroupComponent } from '../../common/input/permissions/permissions-group/permissions-group.component' | ||||
| @@ -550,7 +551,7 @@ export class SettingsComponent | ||||
|             savedToast.content = $localize`Settings were saved successfully. Reload is required to apply some changes.` | ||||
|             savedToast.actionName = $localize`Reload now` | ||||
|             savedToast.action = () => { | ||||
|               location.reload() | ||||
|               locationReload() | ||||
|             } | ||||
|           } | ||||
|  | ||||
|   | ||||
| @@ -19,6 +19,7 @@ import { GroupService } from 'src/app/services/rest/group.service' | ||||
| import { UserService } from 'src/app/services/rest/user.service' | ||||
| import { SettingsService } from 'src/app/services/settings.service' | ||||
| import { ToastService } from 'src/app/services/toast.service' | ||||
| import * as navUtils from 'src/app/utils/navigation' | ||||
| import { ConfirmDialogComponent } from '../../common/confirm-dialog/confirm-dialog.component' | ||||
| import { GroupEditDialogComponent } from '../../common/edit-dialog/group-edit-dialog/group-edit-dialog.component' | ||||
| import { UserEditDialogComponent } from '../../common/edit-dialog/user-edit-dialog/user-edit-dialog.component' | ||||
| @@ -107,7 +108,7 @@ describe('UsersAndGroupsComponent', () => { | ||||
|     const toastErrorSpy = jest.spyOn(toastService, 'showError') | ||||
|     const toastInfoSpy = jest.spyOn(toastService, 'showInfo') | ||||
|     editDialog.failed.emit() | ||||
|     expect(toastErrorSpy).toBeCalled() | ||||
|     expect(toastErrorSpy).toHaveBeenCalled() | ||||
|     settingsService.currentUser = users[1] // simulate logged in as different user | ||||
|     editDialog.succeeded.emit(users[0]) | ||||
|     expect(toastInfoSpy).toHaveBeenCalledWith( | ||||
| @@ -130,7 +131,7 @@ describe('UsersAndGroupsComponent', () => { | ||||
|       throwError(() => new Error('error deleting user')) | ||||
|     ) | ||||
|     deleteDialog.confirm() | ||||
|     expect(toastErrorSpy).toBeCalled() | ||||
|     expect(toastErrorSpy).toHaveBeenCalled() | ||||
|     deleteSpy.mockReturnValueOnce(of(true)) | ||||
|     deleteDialog.confirm() | ||||
|     expect(listAllSpy).toHaveBeenCalled() | ||||
| @@ -142,19 +143,18 @@ describe('UsersAndGroupsComponent', () => { | ||||
|     let modal: NgbModalRef | ||||
|     modalService.activeInstances.subscribe((refs) => (modal = refs[0])) | ||||
|     component.editUser(users[0]) | ||||
|     const navSpy = jest | ||||
|       .spyOn(navUtils, 'setLocationHref') | ||||
|       .mockImplementation(() => {}) | ||||
|     const editDialog = modal.componentInstance as UserEditDialogComponent | ||||
|     editDialog.passwordIsSet = true | ||||
|     settingsService.currentUser = users[0] // simulate logged in as same user | ||||
|     editDialog.succeeded.emit(users[0]) | ||||
|     fixture.detectChanges() | ||||
|     Object.defineProperty(window, 'location', { | ||||
|       value: { | ||||
|         href: 'http://localhost/', | ||||
|       }, | ||||
|       writable: true, // possibility to override | ||||
|     }) | ||||
|     tick(2600) | ||||
|     expect(window.location.href).toContain('logout') | ||||
|     expect(navSpy).toHaveBeenCalledWith( | ||||
|       `${window.location.origin}/accounts/logout/?next=/accounts/login/?next=/` | ||||
|     ) | ||||
|   })) | ||||
|  | ||||
|   it('should support edit / create group, show error if needed', () => { | ||||
| @@ -166,7 +166,7 @@ describe('UsersAndGroupsComponent', () => { | ||||
|     const toastErrorSpy = jest.spyOn(toastService, 'showError') | ||||
|     const toastInfoSpy = jest.spyOn(toastService, 'showInfo') | ||||
|     editDialog.failed.emit() | ||||
|     expect(toastErrorSpy).toBeCalled() | ||||
|     expect(toastErrorSpy).toHaveBeenCalled() | ||||
|     editDialog.succeeded.emit(groups[0]) | ||||
|     expect(toastInfoSpy).toHaveBeenCalledWith( | ||||
|       `Saved group "${groups[0].name}".` | ||||
| @@ -188,7 +188,7 @@ describe('UsersAndGroupsComponent', () => { | ||||
|       throwError(() => new Error('error deleting group')) | ||||
|     ) | ||||
|     deleteDialog.confirm() | ||||
|     expect(toastErrorSpy).toBeCalled() | ||||
|     expect(toastErrorSpy).toHaveBeenCalled() | ||||
|     deleteSpy.mockReturnValueOnce(of(true)) | ||||
|     deleteDialog.confirm() | ||||
|     expect(listAllSpy).toHaveBeenCalled() | ||||
| @@ -210,7 +210,7 @@ describe('UsersAndGroupsComponent', () => { | ||||
|       ) | ||||
|     completeSetup(userService) | ||||
|     fixture.detectChanges() | ||||
|     expect(toastErrorSpy).toBeCalled() | ||||
|     expect(toastErrorSpy).toHaveBeenCalled() | ||||
|   }) | ||||
|  | ||||
|   it('should show errors on load if load groups failure', () => { | ||||
| @@ -222,6 +222,6 @@ describe('UsersAndGroupsComponent', () => { | ||||
|       ) | ||||
|     completeSetup(groupService) | ||||
|     fixture.detectChanges() | ||||
|     expect(toastErrorSpy).toBeCalled() | ||||
|     expect(toastErrorSpy).toHaveBeenCalled() | ||||
|   }) | ||||
| }) | ||||
|   | ||||
| @@ -10,6 +10,7 @@ import { GroupService } from 'src/app/services/rest/group.service' | ||||
| import { UserService } from 'src/app/services/rest/user.service' | ||||
| import { SettingsService } from 'src/app/services/settings.service' | ||||
| import { ToastService } from 'src/app/services/toast.service' | ||||
| import { setLocationHref } from 'src/app/utils/navigation' | ||||
| import { ConfirmDialogComponent } from '../../common/confirm-dialog/confirm-dialog.component' | ||||
| import { EditDialogMode } from '../../common/edit-dialog/edit-dialog.component' | ||||
| import { GroupEditDialogComponent } from '../../common/edit-dialog/group-edit-dialog/group-edit-dialog.component' | ||||
| @@ -93,7 +94,9 @@ export class UsersAndGroupsComponent | ||||
|             $localize`Password has been changed, you will be logged out momentarily.` | ||||
|           ) | ||||
|           setTimeout(() => { | ||||
|             window.location.href = `${window.location.origin}/accounts/logout/?next=/accounts/login/?next=/` | ||||
|             setLocationHref( | ||||
|               `${window.location.origin}/accounts/logout/?next=/accounts/login/?next=/` | ||||
|             ) | ||||
|           }, 2500) | ||||
|         } else { | ||||
|           this.toastService.showInfo( | ||||
|   | ||||
| @@ -18,6 +18,7 @@ import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons' | ||||
| import { of, throwError } from 'rxjs' | ||||
| import { ProfileService } from 'src/app/services/profile.service' | ||||
| import { ToastService } from 'src/app/services/toast.service' | ||||
| import * as navUtils from 'src/app/utils/navigation' | ||||
| import { ConfirmButtonComponent } from '../confirm-button/confirm-button.component' | ||||
| import { PasswordComponent } from '../input/password/password.component' | ||||
| import { TextComponent } from '../input/text/text.component' | ||||
| @@ -205,16 +206,15 @@ describe('ProfileEditDialogComponent', () => { | ||||
|  | ||||
|     const updateSpy = jest.spyOn(profileService, 'update') | ||||
|     updateSpy.mockReturnValue(of(null)) | ||||
|     Object.defineProperty(window, 'location', { | ||||
|       value: { | ||||
|         href: 'http://localhost/', | ||||
|       }, | ||||
|       writable: true, // possibility to override | ||||
|     }) | ||||
|     const navSpy = jest | ||||
|       .spyOn(navUtils, 'setLocationHref') | ||||
|       .mockImplementation(() => {}) | ||||
|     component.save() | ||||
|     expect(updateSpy).toHaveBeenCalled() | ||||
|     tick(2600) | ||||
|     expect(window.location.href).toContain('logout') | ||||
|     expect(navSpy).toHaveBeenCalledWith( | ||||
|       `${window.location.origin}/accounts/logout/?next=/accounts/login/?next=/` | ||||
|     ) | ||||
|   })) | ||||
|  | ||||
|   it('should support auth token copy', fakeAsync(() => { | ||||
|   | ||||
| @@ -21,6 +21,7 @@ import { | ||||
| import { SafeHtmlPipe } from 'src/app/pipes/safehtml.pipe' | ||||
| import { ProfileService } from 'src/app/services/profile.service' | ||||
| import { ToastService } from 'src/app/services/toast.service' | ||||
| import { setLocationHref } from 'src/app/utils/navigation' | ||||
| import { LoadingComponentWithPermissions } from '../../loading-component/loading.component' | ||||
| import { ConfirmButtonComponent } from '../confirm-button/confirm-button.component' | ||||
| import { PasswordComponent } from '../input/password/password.component' | ||||
| @@ -194,7 +195,9 @@ export class ProfileEditDialogComponent | ||||
|               $localize`Password has been changed, you will be logged out momentarily.` | ||||
|             ) | ||||
|             setTimeout(() => { | ||||
|               window.location.href = `${window.location.origin}/accounts/logout/?next=/accounts/login/?next=/` | ||||
|               setLocationHref( | ||||
|                 `${window.location.origin}/accounts/logout/?next=/accounts/login/?next=/` | ||||
|               ) | ||||
|             }, 2500) | ||||
|           } | ||||
|           this.activeModal.close() | ||||
|   | ||||
| @@ -188,7 +188,7 @@ describe('MailComponent', () => { | ||||
|     const toastErrorSpy = jest.spyOn(toastService, 'showError') | ||||
|     const toastInfoSpy = jest.spyOn(toastService, 'showInfo') | ||||
|     editDialog.failed.emit() | ||||
|     expect(toastErrorSpy).toBeCalled() | ||||
|     expect(toastErrorSpy).toHaveBeenCalled() | ||||
|     editDialog.succeeded.emit(mailAccounts[0] as any) | ||||
|     expect(toastInfoSpy).toHaveBeenCalledWith( | ||||
|       `Saved account "${mailAccounts[0].name}".` | ||||
| @@ -211,7 +211,7 @@ describe('MailComponent', () => { | ||||
|       throwError(() => new Error('error deleting mail account')) | ||||
|     ) | ||||
|     deleteDialog.confirm() | ||||
|     expect(toastErrorSpy).toBeCalled() | ||||
|     expect(toastErrorSpy).toHaveBeenCalled() | ||||
|     deleteSpy.mockReturnValueOnce(of(true)) | ||||
|     deleteDialog.confirm() | ||||
|     expect(listAllSpy).toHaveBeenCalled() | ||||
| @@ -246,7 +246,7 @@ describe('MailComponent', () => { | ||||
|     const toastErrorSpy = jest.spyOn(toastService, 'showError') | ||||
|     const toastInfoSpy = jest.spyOn(toastService, 'showInfo') | ||||
|     editDialog.failed.emit() | ||||
|     expect(toastErrorSpy).toBeCalled() | ||||
|     expect(toastErrorSpy).toHaveBeenCalled() | ||||
|     editDialog.succeeded.emit(mailRules[0] as any) | ||||
|     expect(toastInfoSpy).toHaveBeenCalledWith( | ||||
|       `Saved rule "${mailRules[0].name}".` | ||||
| @@ -280,7 +280,7 @@ describe('MailComponent', () => { | ||||
|       throwError(() => new Error('error deleting mail rule "rule1"')) | ||||
|     ) | ||||
|     deleteDialog.confirm() | ||||
|     expect(toastErrorSpy).toBeCalled() | ||||
|     expect(toastErrorSpy).toHaveBeenCalled() | ||||
|     deleteSpy.mockReturnValueOnce(of(true)) | ||||
|     deleteDialog.confirm() | ||||
|     expect(listAllSpy).toHaveBeenCalled() | ||||
|   | ||||
							
								
								
									
										8
									
								
								src-ui/src/app/utils/navigation.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src-ui/src/app/utils/navigation.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| /* istanbul ignore file */ | ||||
| export function setLocationHref(url: string) { | ||||
|   window.location.href = url | ||||
| } | ||||
|  | ||||
| export function locationReload() { | ||||
|   window.location.reload() | ||||
| } | ||||
| @@ -3,7 +3,8 @@ | ||||
|   "compilerOptions": { | ||||
|     "outDir": "./out-tsc/spec", | ||||
|     "types": [ | ||||
|       "jest" | ||||
|       "jest", | ||||
|       "node", | ||||
|     ], | ||||
|     "module": "commonjs", | ||||
|     "emitDecoratorMetadata": true, | ||||
|   | ||||
| @@ -12,11 +12,13 @@ from celery.signals import before_task_publish | ||||
| from celery.signals import task_failure | ||||
| from celery.signals import task_postrun | ||||
| from celery.signals import task_prerun | ||||
| from celery.signals import worker_process_init | ||||
| from django.conf import settings | ||||
| from django.contrib.auth.models import Group | ||||
| from django.contrib.auth.models import User | ||||
| from django.db import DatabaseError | ||||
| from django.db import close_old_connections | ||||
| from django.db import connections | ||||
| from django.db import models | ||||
| from django.db.models import Q | ||||
| from django.dispatch import receiver | ||||
| @@ -1439,3 +1441,18 @@ def task_failure_handler( | ||||
|             task_instance.save() | ||||
|     except Exception:  # pragma: no cover | ||||
|         logger.exception("Updating PaperlessTask failed") | ||||
|  | ||||
|  | ||||
| @worker_process_init.connect | ||||
| def close_connection_pool_on_worker_init(**kwargs): | ||||
|     """ | ||||
|     Close the DB connection pool for each Celery child process after it starts. | ||||
|  | ||||
|     This is necessary because the parent process parse the Django configuration, | ||||
|     initializes connection pools then forks. | ||||
|  | ||||
|     Closing these pools after forking ensures child processes have a valid connection. | ||||
|     """ | ||||
|     for conn in connections.all(initialized_only=True): | ||||
|         if conn.alias == "default" and hasattr(conn, "pool") and conn.pool: | ||||
|             conn.close_pool() | ||||
|   | ||||
| @@ -2,7 +2,7 @@ msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: paperless-ngx\n" | ||||
| "Report-Msgid-Bugs-To: \n" | ||||
| "POT-Creation-Date: 2025-07-08 21:14+0000\n" | ||||
| "POT-Creation-Date: 2025-08-02 12:55+0000\n" | ||||
| "PO-Revision-Date: 2022-02-17 04:17\n" | ||||
| "Last-Translator: \n" | ||||
| "Language-Team: English\n" | ||||
| @@ -1645,147 +1645,147 @@ msgstr "" | ||||
| msgid "paperless application settings" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:762 | ||||
| #: paperless/settings.py:774 | ||||
| msgid "English (US)" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:763 | ||||
| #: paperless/settings.py:775 | ||||
| msgid "Arabic" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:764 | ||||
| #: paperless/settings.py:776 | ||||
| msgid "Afrikaans" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:765 | ||||
| #: paperless/settings.py:777 | ||||
| msgid "Belarusian" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:766 | ||||
| #: paperless/settings.py:778 | ||||
| msgid "Bulgarian" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:767 | ||||
| #: paperless/settings.py:779 | ||||
| msgid "Catalan" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:768 | ||||
| #: paperless/settings.py:780 | ||||
| msgid "Czech" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:769 | ||||
| #: paperless/settings.py:781 | ||||
| msgid "Danish" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:770 | ||||
| #: paperless/settings.py:782 | ||||
| msgid "German" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:771 | ||||
| #: paperless/settings.py:783 | ||||
| msgid "Greek" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:772 | ||||
| #: paperless/settings.py:784 | ||||
| msgid "English (GB)" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:773 | ||||
| #: paperless/settings.py:785 | ||||
| msgid "Spanish" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:774 | ||||
| #: paperless/settings.py:786 | ||||
| msgid "Persian" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:775 | ||||
| #: paperless/settings.py:787 | ||||
| msgid "Finnish" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:776 | ||||
| #: paperless/settings.py:788 | ||||
| msgid "French" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:777 | ||||
| #: paperless/settings.py:789 | ||||
| msgid "Hungarian" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:778 | ||||
| #: paperless/settings.py:790 | ||||
| msgid "Italian" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:779 | ||||
| #: paperless/settings.py:791 | ||||
| msgid "Japanese" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:780 | ||||
| #: paperless/settings.py:792 | ||||
| msgid "Korean" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:781 | ||||
| #: paperless/settings.py:793 | ||||
| msgid "Luxembourgish" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:782 | ||||
| #: paperless/settings.py:794 | ||||
| msgid "Norwegian" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:783 | ||||
| #: paperless/settings.py:795 | ||||
| msgid "Dutch" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:784 | ||||
| #: paperless/settings.py:796 | ||||
| msgid "Polish" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:785 | ||||
| #: paperless/settings.py:797 | ||||
| msgid "Portuguese (Brazil)" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:786 | ||||
| #: paperless/settings.py:798 | ||||
| msgid "Portuguese" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:787 | ||||
| #: paperless/settings.py:799 | ||||
| msgid "Romanian" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:788 | ||||
| #: paperless/settings.py:800 | ||||
| msgid "Russian" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:789 | ||||
| #: paperless/settings.py:801 | ||||
| msgid "Slovak" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:790 | ||||
| #: paperless/settings.py:802 | ||||
| msgid "Slovenian" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:791 | ||||
| #: paperless/settings.py:803 | ||||
| msgid "Serbian" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:792 | ||||
| #: paperless/settings.py:804 | ||||
| msgid "Swedish" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:793 | ||||
| #: paperless/settings.py:805 | ||||
| msgid "Turkish" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:794 | ||||
| #: paperless/settings.py:806 | ||||
| msgid "Ukrainian" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:795 | ||||
| #: paperless/settings.py:807 | ||||
| msgid "Vietnamese" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:796 | ||||
| #: paperless/settings.py:808 | ||||
| msgid "Chinese Simplified" | ||||
| msgstr "" | ||||
|  | ||||
| #: paperless/settings.py:797 | ||||
| #: paperless/settings.py:809 | ||||
| msgid "Chinese Traditional" | ||||
| msgstr "" | ||||
|  | ||||
|   | ||||
| @@ -703,6 +703,9 @@ def _parse_db_settings() -> dict: | ||||
|         # Leave room for future extensibility | ||||
|         if os.getenv("PAPERLESS_DBENGINE") == "mariadb": | ||||
|             engine = "django.db.backends.mysql" | ||||
|             # Contrary to Postgres, Django does not natively support connection pooling for MariaDB. | ||||
|             # However, since MariaDB uses threads instead of forks, establishing connections is significantly faster | ||||
|             # compared to PostgreSQL, so the lack of pooling is not an issue | ||||
|             options = { | ||||
|                 "read_default_file": "/etc/mysql/my.cnf", | ||||
|                 "charset": "utf8mb4", | ||||
| @@ -722,6 +725,15 @@ def _parse_db_settings() -> dict: | ||||
|                 "sslcert": os.getenv("PAPERLESS_DBSSLCERT", None), | ||||
|                 "sslkey": os.getenv("PAPERLESS_DBSSLKEY", None), | ||||
|             } | ||||
|             if int(os.getenv("PAPERLESS_DB_POOLSIZE", 0)) > 0: | ||||
|                 options.update( | ||||
|                     { | ||||
|                         "pool": { | ||||
|                             "min_size": 1, | ||||
|                             "max_size": int(os.getenv("PAPERLESS_DB_POOLSIZE")), | ||||
|                         }, | ||||
|                     }, | ||||
|                 ) | ||||
|  | ||||
|         databases["default"]["ENGINE"] = engine | ||||
|         databases["default"]["OPTIONS"].update(options) | ||||
|   | ||||
							
								
								
									
										19
									
								
								uv.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										19
									
								
								uv.lock
									
									
									
										generated
									
									
									
								
							| @@ -1971,10 +1971,11 @@ mariadb = [ | ||||
|     { name = "mysqlclient", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, | ||||
| ] | ||||
| postgres = [ | ||||
|     { name = "psycopg", extra = ["c"], marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, | ||||
|     { name = "psycopg", extra = ["c", "pool"], marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, | ||||
|     { name = "psycopg-c", version = "3.2.9", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version != '3.12.*' and platform_machine == 'aarch64' and sys_platform == 'linux') or (python_full_version != '3.12.*' and platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine != 'aarch64' and platform_machine != 'x86_64' and sys_platform == 'linux') or sys_platform == 'darwin'" }, | ||||
|     { name = "psycopg-c", version = "3.2.9", source = { url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.9/psycopg_c-3.2.9-cp312-cp312-linux_aarch64.whl" }, marker = "python_full_version == '3.12.*' and platform_machine == 'aarch64' and sys_platform == 'linux'" }, | ||||
|     { name = "psycopg-c", version = "3.2.9", source = { url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.9/psycopg_c-3.2.9-cp312-cp312-linux_x86_64.whl" }, marker = "python_full_version == '3.12.*' and platform_machine == 'x86_64' and sys_platform == 'linux'" }, | ||||
|     { name = "psycopg-pool", version = "3.2.6", source = { registry = "https://pypi.org/simple" }, marker = "sys_platform == 'linux' or sys_platform == 'darwin'" }, | ||||
| ] | ||||
| webserver = [ | ||||
|     { name = "granian", extra = ["uvloop"], marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, | ||||
| @@ -2079,10 +2080,11 @@ requires-dist = [ | ||||
|     { name = "ocrmypdf", specifier = "~=16.10.0" }, | ||||
|     { name = "pathvalidate", specifier = "~=3.3.1" }, | ||||
|     { name = "pdf2image", specifier = "~=1.17.0" }, | ||||
|     { name = "psycopg", extras = ["c"], marker = "extra == 'postgres'", specifier = "==3.2.9" }, | ||||
|     { name = "psycopg", extras = ["c", "pool"], marker = "extra == 'postgres'", specifier = "==3.2.9" }, | ||||
|     { name = "psycopg-c", marker = "python_full_version == '3.12.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'postgres'", url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.9/psycopg_c-3.2.9-cp312-cp312-linux_aarch64.whl" }, | ||||
|     { name = "psycopg-c", marker = "python_full_version == '3.12.*' and platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'postgres'", url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.9/psycopg_c-3.2.9-cp312-cp312-linux_x86_64.whl" }, | ||||
|     { name = "psycopg-c", marker = "(python_full_version != '3.12.*' and platform_machine == 'aarch64' and extra == 'postgres') or (python_full_version != '3.12.*' and platform_machine == 'x86_64' and extra == 'postgres') or (platform_machine != 'aarch64' and platform_machine != 'x86_64' and extra == 'postgres') or (sys_platform != 'linux' and extra == 'postgres')", specifier = "==3.2.9" }, | ||||
|     { name = "psycopg-pool", marker = "extra == 'postgres'" }, | ||||
|     { name = "python-dateutil", specifier = "~=2.9.0" }, | ||||
|     { name = "python-dotenv", specifier = "~=1.1.0" }, | ||||
|     { name = "python-gnupg", specifier = "~=0.5.4" }, | ||||
| @@ -2433,6 +2435,9 @@ c = [ | ||||
|     { name = "psycopg-c", version = "3.2.9", source = { url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.9/psycopg_c-3.2.9-cp312-cp312-linux_aarch64.whl" }, marker = "python_full_version == '3.12.*' and implementation_name != 'pypy' and platform_machine == 'aarch64' and sys_platform == 'linux'" }, | ||||
|     { name = "psycopg-c", version = "3.2.9", source = { url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.9/psycopg_c-3.2.9-cp312-cp312-linux_x86_64.whl" }, marker = "python_full_version == '3.12.*' and implementation_name != 'pypy' and platform_machine == 'x86_64' and sys_platform == 'linux'" }, | ||||
| ] | ||||
| pool = [ | ||||
|     { name = "psycopg-pool", version = "3.2.6", source = { registry = "https://pypi.org/simple" }, marker = "sys_platform == 'linux' or sys_platform == 'darwin'" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "psycopg-c" | ||||
| @@ -2466,6 +2471,16 @@ wheels = [ | ||||
|     { url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.9/psycopg_c-3.2.9-cp312-cp312-linux_x86_64.whl", hash = "sha256:250c357319242da102047b04c5cc78af872dbf85c2cb05abf114e1fb5f207917" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "psycopg-pool" | ||||
| version = "3.2.6" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/cf/13/1e7850bb2c69a63267c3dbf37387d3f71a00fd0e2fa55c5db14d64ba1af4/psycopg_pool-3.2.6.tar.gz", hash = "sha256:0f92a7817719517212fbfe2fd58b8c35c1850cdd2a80d36b581ba2085d9148e5", size = 29770, upload-time = "2025-02-26T12:03:47.129Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/47/fd/4feb52a55c1a4bd748f2acaed1903ab54a723c47f6d0242780f4d97104d4/psycopg_pool-3.2.6-py3-none-any.whl", hash = "sha256:5887318a9f6af906d041a0b1dc1c60f8f0dda8340c2572b74e10907b51ed5da7", size = 38252, upload-time = "2025-02-26T12:03:45.073Z" }, | ||||
| ] | ||||
|  | ||||
|  | ||||
| [[package]] | ||||
| name = "pyasn1" | ||||
| version = "0.6.1" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user