refactor: remove GlobalLogger and migrate to standard Python logging
- Remove src/infrastructure/logging/GlobalLogger.py - Update SerieScanner.py to use standard logging.getLogger() - Update aniworld_provider.py to remove custom noKeyFound_logger setup - Fix test_dependencies.py to properly mock config_service - Fix code style issues (line length, formatting) - All 846 tests passing
This commit is contained in:
parent
a3651e0e47
commit
a41c86f1da
@ -18,7 +18,7 @@
|
||||
},
|
||||
"other": {
|
||||
"anime_directory": "/home/lukas/Volume/serien/",
|
||||
"master_password_hash": "$pbkdf2-sha256$29000$ZWwtJaQ0ZkxpLUWolRJijA$QcfgTBqgM3ABu9N93/w8naBLdfCKmKFc65Cn/f4fP84"
|
||||
"master_password_hash": "$pbkdf2-sha256$29000$gdCa897bm/Oec07J2RvDOA$L60V4C1PUEGWC3WtX.32koXvTA12P6J2rYPXTIPFg5g"
|
||||
},
|
||||
"version": "1.0.0"
|
||||
}
|
||||
24
data/config_backups/config_backup_20251025_171511.json
Normal file
24
data/config_backups/config_backup_20251025_171511.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "Aniworld",
|
||||
"data_dir": "data",
|
||||
"scheduler": {
|
||||
"enabled": true,
|
||||
"interval_minutes": 60
|
||||
},
|
||||
"logging": {
|
||||
"level": "INFO",
|
||||
"file": null,
|
||||
"max_bytes": null,
|
||||
"backup_count": 3
|
||||
},
|
||||
"backup": {
|
||||
"enabled": false,
|
||||
"path": "data/backups",
|
||||
"keep_days": 30
|
||||
},
|
||||
"other": {
|
||||
"anime_directory": "/home/lukas/Volume/serien/",
|
||||
"master_password_hash": "$pbkdf2-sha256$29000$w3jPmfM.B8DY2xsjJCQkZA$BT52/04WG0hpMP/4uRnJUgBjYyrLxEwQodBoa6mKVOQ"
|
||||
},
|
||||
"version": "1.0.0"
|
||||
}
|
||||
24
data/config_backups/config_backup_20251025_171530.json
Normal file
24
data/config_backups/config_backup_20251025_171530.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "Aniworld",
|
||||
"data_dir": "data",
|
||||
"scheduler": {
|
||||
"enabled": true,
|
||||
"interval_minutes": 60
|
||||
},
|
||||
"logging": {
|
||||
"level": "INFO",
|
||||
"file": null,
|
||||
"max_bytes": null,
|
||||
"backup_count": 3
|
||||
},
|
||||
"backup": {
|
||||
"enabled": false,
|
||||
"path": "data/backups",
|
||||
"keep_days": 30
|
||||
},
|
||||
"other": {
|
||||
"anime_directory": "/home/lukas/Volume/serien/",
|
||||
"master_password_hash": "$pbkdf2-sha256$29000$fw.hFMI4JyRkrHXufU/J2Q$Lu.CArOq.fQ32HPX8IeiH/dNX1NOjOqVQl1uXuoTP4k"
|
||||
},
|
||||
"version": "1.0.0"
|
||||
}
|
||||
24
data/config_backups/config_backup_20251025_171647.json
Normal file
24
data/config_backups/config_backup_20251025_171647.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "Aniworld",
|
||||
"data_dir": "data",
|
||||
"scheduler": {
|
||||
"enabled": true,
|
||||
"interval_minutes": 60
|
||||
},
|
||||
"logging": {
|
||||
"level": "INFO",
|
||||
"file": null,
|
||||
"max_bytes": null,
|
||||
"backup_count": 3
|
||||
},
|
||||
"backup": {
|
||||
"enabled": false,
|
||||
"path": "data/backups",
|
||||
"keep_days": 30
|
||||
},
|
||||
"other": {
|
||||
"anime_directory": "/home/lukas/Volume/serien/",
|
||||
"master_password_hash": "$pbkdf2-sha256$29000$d.7dG8N4r/V.zzknxHiv9Q$pL5O6lAj4YhG1VNJYQKyojEti1yhvfxkjmP.O3OMXMk"
|
||||
},
|
||||
"version": "1.0.0"
|
||||
}
|
||||
24
data/config_backups/config_backup_20251025_171912.json
Normal file
24
data/config_backups/config_backup_20251025_171912.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "Aniworld",
|
||||
"data_dir": "data",
|
||||
"scheduler": {
|
||||
"enabled": true,
|
||||
"interval_minutes": 60
|
||||
},
|
||||
"logging": {
|
||||
"level": "INFO",
|
||||
"file": null,
|
||||
"max_bytes": null,
|
||||
"backup_count": 3
|
||||
},
|
||||
"backup": {
|
||||
"enabled": false,
|
||||
"path": "data/backups",
|
||||
"keep_days": 30
|
||||
},
|
||||
"other": {
|
||||
"anime_directory": "/home/lukas/Volume/serien/",
|
||||
"master_password_hash": "$pbkdf2-sha256$29000$aS1l7H3vnbM2JqT03jun1A$ZDIgiVSD5j6Gj/WrOJObZzhB/UBTDzjg3KebQj62ae0"
|
||||
},
|
||||
"version": "1.0.0"
|
||||
}
|
||||
24
data/config_backups/config_backup_20251025_171937.json
Normal file
24
data/config_backups/config_backup_20251025_171937.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "Aniworld",
|
||||
"data_dir": "data",
|
||||
"scheduler": {
|
||||
"enabled": true,
|
||||
"interval_minutes": 60
|
||||
},
|
||||
"logging": {
|
||||
"level": "INFO",
|
||||
"file": null,
|
||||
"max_bytes": null,
|
||||
"backup_count": 3
|
||||
},
|
||||
"backup": {
|
||||
"enabled": false,
|
||||
"path": "data/backups",
|
||||
"keep_days": 30
|
||||
},
|
||||
"other": {
|
||||
"anime_directory": "/home/lukas/Volume/serien/",
|
||||
"master_password_hash": "$pbkdf2-sha256$29000$s3YOYUyplRJiDOGcs3autQ$/Uxgp3nQSzYwKYB1tt7H230PL.zR7DQrB4Dp/8Y0xBI"
|
||||
},
|
||||
"version": "1.0.0"
|
||||
}
|
||||
24
data/config_backups/config_backup_20251025_172020.json
Normal file
24
data/config_backups/config_backup_20251025_172020.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "Aniworld",
|
||||
"data_dir": "data",
|
||||
"scheduler": {
|
||||
"enabled": true,
|
||||
"interval_minutes": 60
|
||||
},
|
||||
"logging": {
|
||||
"level": "INFO",
|
||||
"file": null,
|
||||
"max_bytes": null,
|
||||
"backup_count": 3
|
||||
},
|
||||
"backup": {
|
||||
"enabled": false,
|
||||
"path": "data/backups",
|
||||
"keep_days": 30
|
||||
},
|
||||
"other": {
|
||||
"anime_directory": "/home/lukas/Volume/serien/",
|
||||
"master_password_hash": "$pbkdf2-sha256$29000$RigFgPD.n9O69/5fq9Xauw$Vy2ak.30Y89iiSq9NOWKNxTp49ZyuZcIUCyzmyMgiCc"
|
||||
},
|
||||
"version": "1.0.0"
|
||||
}
|
||||
24
data/config_backups/config_backup_20251025_172138.json
Normal file
24
data/config_backups/config_backup_20251025_172138.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "Aniworld",
|
||||
"data_dir": "data",
|
||||
"scheduler": {
|
||||
"enabled": true,
|
||||
"interval_minutes": 60
|
||||
},
|
||||
"logging": {
|
||||
"level": "INFO",
|
||||
"file": null,
|
||||
"max_bytes": null,
|
||||
"backup_count": 3
|
||||
},
|
||||
"backup": {
|
||||
"enabled": false,
|
||||
"path": "data/backups",
|
||||
"keep_days": 30
|
||||
},
|
||||
"other": {
|
||||
"anime_directory": "/home/lukas/Volume/serien/",
|
||||
"master_password_hash": "$pbkdf2-sha256$29000$VQohxNhb6x0j5Lz3XqsVIg$yNJHqC7RxzhwScZVDmOY60CrCQG5RQbzCBGVz8FZrf0"
|
||||
},
|
||||
"version": "1.0.0"
|
||||
}
|
||||
24
data/config_backups/config_backup_20251025_172359.json
Normal file
24
data/config_backups/config_backup_20251025_172359.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "Aniworld",
|
||||
"data_dir": "data",
|
||||
"scheduler": {
|
||||
"enabled": true,
|
||||
"interval_minutes": 60
|
||||
},
|
||||
"logging": {
|
||||
"level": "INFO",
|
||||
"file": null,
|
||||
"max_bytes": null,
|
||||
"backup_count": 3
|
||||
},
|
||||
"backup": {
|
||||
"enabled": false,
|
||||
"path": "data/backups",
|
||||
"keep_days": 30
|
||||
},
|
||||
"other": {
|
||||
"anime_directory": "/home/lukas/Volume/serien/",
|
||||
"master_password_hash": "$pbkdf2-sha256$29000$I8S41/p/D2HsXYsxhvCeUw$0MEEWNZA3RJlxKtqZ8TDqahhDlueTvHWE100uo115R4"
|
||||
},
|
||||
"version": "1.0.0"
|
||||
}
|
||||
24
data/config_backups/config_backup_20251025_172550.json
Normal file
24
data/config_backups/config_backup_20251025_172550.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "Aniworld",
|
||||
"data_dir": "data",
|
||||
"scheduler": {
|
||||
"enabled": true,
|
||||
"interval_minutes": 60
|
||||
},
|
||||
"logging": {
|
||||
"level": "INFO",
|
||||
"file": null,
|
||||
"max_bytes": null,
|
||||
"backup_count": 3
|
||||
},
|
||||
"backup": {
|
||||
"enabled": false,
|
||||
"path": "data/backups",
|
||||
"keep_days": 30
|
||||
},
|
||||
"other": {
|
||||
"anime_directory": "/home/lukas/Volume/serien/",
|
||||
"master_password_hash": "$pbkdf2-sha256$29000$YoyRkvIeg/D.H8NYKwWgdA$AWAYrJO3h7vDZJ3IZCc1men8OrroAzRXlJWvXcBpBDA"
|
||||
},
|
||||
"version": "1.0.0"
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"pending": [
|
||||
{
|
||||
"id": "7cc643ca-0b4e-4769-8d25-c99ce539b434",
|
||||
"id": "fb90e232-52cc-4315-a994-725d132df69a",
|
||||
"serie_id": "workflow-series",
|
||||
"serie_name": "Workflow Test Series",
|
||||
"episode": {
|
||||
@ -11,7 +11,7 @@
|
||||
},
|
||||
"status": "pending",
|
||||
"priority": "high",
|
||||
"added_at": "2025-10-24T17:23:26.098284Z",
|
||||
"added_at": "2025-10-25T15:25:53.734312Z",
|
||||
"started_at": null,
|
||||
"completed_at": null,
|
||||
"progress": null,
|
||||
@ -20,7 +20,7 @@
|
||||
"source_url": null
|
||||
},
|
||||
{
|
||||
"id": "6a017a0d-78e2-4123-9715-80b540e03c41",
|
||||
"id": "37ab9885-cf61-4417-96b7-383490ce2fca",
|
||||
"serie_id": "series-2",
|
||||
"serie_name": "Series 2",
|
||||
"episode": {
|
||||
@ -30,7 +30,7 @@
|
||||
},
|
||||
"status": "pending",
|
||||
"priority": "normal",
|
||||
"added_at": "2025-10-24T17:23:25.819219Z",
|
||||
"added_at": "2025-10-25T15:25:53.327912Z",
|
||||
"started_at": null,
|
||||
"completed_at": null,
|
||||
"progress": null,
|
||||
@ -39,7 +39,7 @@
|
||||
"source_url": null
|
||||
},
|
||||
{
|
||||
"id": "e31ecefa-470a-4ea6-aaa0-c16d38d5ab8b",
|
||||
"id": "ede47aa4-4533-4a86-90e6-81126ff1189a",
|
||||
"serie_id": "series-1",
|
||||
"serie_name": "Series 1",
|
||||
"episode": {
|
||||
@ -49,7 +49,7 @@
|
||||
},
|
||||
"status": "pending",
|
||||
"priority": "normal",
|
||||
"added_at": "2025-10-24T17:23:25.816100Z",
|
||||
"added_at": "2025-10-25T15:25:53.324487Z",
|
||||
"started_at": null,
|
||||
"completed_at": null,
|
||||
"progress": null,
|
||||
@ -58,7 +58,7 @@
|
||||
"source_url": null
|
||||
},
|
||||
{
|
||||
"id": "e3b9418c-7b1e-47dc-928c-3746059a0fa8",
|
||||
"id": "33af9d7b-4787-4d54-af2a-6b9af4f2b061",
|
||||
"serie_id": "series-0",
|
||||
"serie_name": "Series 0",
|
||||
"episode": {
|
||||
@ -68,7 +68,7 @@
|
||||
},
|
||||
"status": "pending",
|
||||
"priority": "normal",
|
||||
"added_at": "2025-10-24T17:23:25.812680Z",
|
||||
"added_at": "2025-10-25T15:25:53.322230Z",
|
||||
"started_at": null,
|
||||
"completed_at": null,
|
||||
"progress": null,
|
||||
@ -77,7 +77,7 @@
|
||||
"source_url": null
|
||||
},
|
||||
{
|
||||
"id": "77083b3b-8b7b-4e02-a4c9-0e95652b1865",
|
||||
"id": "c04610c9-fa71-43fc-9cbf-2f8934b097bd",
|
||||
"serie_id": "series-high",
|
||||
"serie_name": "Series High",
|
||||
"episode": {
|
||||
@ -87,7 +87,7 @@
|
||||
},
|
||||
"status": "pending",
|
||||
"priority": "high",
|
||||
"added_at": "2025-10-24T17:23:25.591277Z",
|
||||
"added_at": "2025-10-25T15:25:53.022054Z",
|
||||
"started_at": null,
|
||||
"completed_at": null,
|
||||
"progress": null,
|
||||
@ -96,7 +96,7 @@
|
||||
"source_url": null
|
||||
},
|
||||
{
|
||||
"id": "03fa75a1-0641-41e8-be69-c274383d6198",
|
||||
"id": "1da55781-81dd-43bc-89a7-b4f9149c0cfe",
|
||||
"serie_id": "test-series-2",
|
||||
"serie_name": "Another Series",
|
||||
"episode": {
|
||||
@ -106,7 +106,7 @@
|
||||
},
|
||||
"status": "pending",
|
||||
"priority": "high",
|
||||
"added_at": "2025-10-24T17:23:25.567577Z",
|
||||
"added_at": "2025-10-25T15:25:52.986476Z",
|
||||
"started_at": null,
|
||||
"completed_at": null,
|
||||
"progress": null,
|
||||
@ -115,7 +115,7 @@
|
||||
"source_url": null
|
||||
},
|
||||
{
|
||||
"id": "bbfa8dd3-0f28-43f3-9f42-03595684e873",
|
||||
"id": "155cef74-9b1d-4582-b836-d13c48290c80",
|
||||
"serie_id": "test-series-1",
|
||||
"serie_name": "Test Anime Series",
|
||||
"episode": {
|
||||
@ -125,7 +125,7 @@
|
||||
},
|
||||
"status": "pending",
|
||||
"priority": "normal",
|
||||
"added_at": "2025-10-24T17:23:25.543811Z",
|
||||
"added_at": "2025-10-25T15:25:52.952839Z",
|
||||
"started_at": null,
|
||||
"completed_at": null,
|
||||
"progress": null,
|
||||
@ -134,7 +134,7 @@
|
||||
"source_url": null
|
||||
},
|
||||
{
|
||||
"id": "4d462a39-e705-4dd4-a968-e6d995471615",
|
||||
"id": "682399d3-6b56-4bc2-b3a6-8aa0f30d91ba",
|
||||
"serie_id": "test-series-1",
|
||||
"serie_name": "Test Anime Series",
|
||||
"episode": {
|
||||
@ -144,7 +144,7 @@
|
||||
},
|
||||
"status": "pending",
|
||||
"priority": "normal",
|
||||
"added_at": "2025-10-24T17:23:25.543911Z",
|
||||
"added_at": "2025-10-25T15:25:52.952940Z",
|
||||
"started_at": null,
|
||||
"completed_at": null,
|
||||
"progress": null,
|
||||
@ -153,7 +153,7 @@
|
||||
"source_url": null
|
||||
},
|
||||
{
|
||||
"id": "04e5ce5d-ce4c-4776-a1be-b0c78c17d651",
|
||||
"id": "b12de848-efcd-4e4d-838e-992f48dca631",
|
||||
"serie_id": "series-normal",
|
||||
"serie_name": "Series Normal",
|
||||
"episode": {
|
||||
@ -163,7 +163,7 @@
|
||||
},
|
||||
"status": "pending",
|
||||
"priority": "normal",
|
||||
"added_at": "2025-10-24T17:23:25.593205Z",
|
||||
"added_at": "2025-10-25T15:25:53.024208Z",
|
||||
"started_at": null,
|
||||
"completed_at": null,
|
||||
"progress": null,
|
||||
@ -172,7 +172,7 @@
|
||||
"source_url": null
|
||||
},
|
||||
{
|
||||
"id": "8a8da509-9bec-4979-aa01-22f726e298ef",
|
||||
"id": "901ea5d2-1491-492f-8f7b-62db605d6bb4",
|
||||
"serie_id": "series-low",
|
||||
"serie_name": "Series Low",
|
||||
"episode": {
|
||||
@ -182,7 +182,7 @@
|
||||
},
|
||||
"status": "pending",
|
||||
"priority": "low",
|
||||
"added_at": "2025-10-24T17:23:25.595371Z",
|
||||
"added_at": "2025-10-25T15:25:53.026631Z",
|
||||
"started_at": null,
|
||||
"completed_at": null,
|
||||
"progress": null,
|
||||
@ -191,7 +191,7 @@
|
||||
"source_url": null
|
||||
},
|
||||
{
|
||||
"id": "b07b9e02-3517-4066-aba0-2ee6b2349580",
|
||||
"id": "6cddccb4-14cd-43e7-9425-5c4b20dd34f2",
|
||||
"serie_id": "test-series",
|
||||
"serie_name": "Test Series",
|
||||
"episode": {
|
||||
@ -201,7 +201,7 @@
|
||||
},
|
||||
"status": "pending",
|
||||
"priority": "normal",
|
||||
"added_at": "2025-10-24T17:23:25.760199Z",
|
||||
"added_at": "2025-10-25T15:25:53.257343Z",
|
||||
"started_at": null,
|
||||
"completed_at": null,
|
||||
"progress": null,
|
||||
@ -210,7 +210,7 @@
|
||||
"source_url": null
|
||||
},
|
||||
{
|
||||
"id": "9577295e-7ac6-4786-8601-ac13267aba9f",
|
||||
"id": "2b6e4d96-70e9-4d71-806f-ffd6348ef205",
|
||||
"serie_id": "test-series",
|
||||
"serie_name": "Test Series",
|
||||
"episode": {
|
||||
@ -220,7 +220,7 @@
|
||||
},
|
||||
"status": "pending",
|
||||
"priority": "normal",
|
||||
"added_at": "2025-10-24T17:23:25.850731Z",
|
||||
"added_at": "2025-10-25T15:25:53.364247Z",
|
||||
"started_at": null,
|
||||
"completed_at": null,
|
||||
"progress": null,
|
||||
@ -229,7 +229,7 @@
|
||||
"source_url": null
|
||||
},
|
||||
{
|
||||
"id": "562ce52c-2979-4107-b630-999ff6c095e9",
|
||||
"id": "1ac25804-5be3-420a-93df-1ca7b70a40e2",
|
||||
"serie_id": "invalid-series",
|
||||
"serie_name": "Invalid Series",
|
||||
"episode": {
|
||||
@ -239,7 +239,7 @@
|
||||
},
|
||||
"status": "pending",
|
||||
"priority": "normal",
|
||||
"added_at": "2025-10-24T17:23:25.902493Z",
|
||||
"added_at": "2025-10-25T15:25:53.430806Z",
|
||||
"started_at": null,
|
||||
"completed_at": null,
|
||||
"progress": null,
|
||||
@ -248,7 +248,7 @@
|
||||
"source_url": null
|
||||
},
|
||||
{
|
||||
"id": "1684fe7f-5755-4064-86ed-a78831e8dc0f",
|
||||
"id": "4e568aec-ac73-444a-aeb3-d8c6c27cf630",
|
||||
"serie_id": "test-series",
|
||||
"serie_name": "Test Series",
|
||||
"episode": {
|
||||
@ -258,7 +258,7 @@
|
||||
},
|
||||
"status": "pending",
|
||||
"priority": "normal",
|
||||
"added_at": "2025-10-24T17:23:25.926933Z",
|
||||
"added_at": "2025-10-25T15:25:53.464054Z",
|
||||
"started_at": null,
|
||||
"completed_at": null,
|
||||
"progress": null,
|
||||
@ -267,7 +267,7 @@
|
||||
"source_url": null
|
||||
},
|
||||
{
|
||||
"id": "c4fe86cb-e6f7-4303-a8b6-2e76c51d7c40",
|
||||
"id": "1e387ffb-c029-4fa6-9e48-93244c9b91fc",
|
||||
"serie_id": "series-4",
|
||||
"serie_name": "Series 4",
|
||||
"episode": {
|
||||
@ -277,7 +277,7 @@
|
||||
},
|
||||
"status": "pending",
|
||||
"priority": "normal",
|
||||
"added_at": "2025-10-24T17:23:25.965540Z",
|
||||
"added_at": "2025-10-25T15:25:53.550292Z",
|
||||
"started_at": null,
|
||||
"completed_at": null,
|
||||
"progress": null,
|
||||
@ -286,45 +286,7 @@
|
||||
"source_url": null
|
||||
},
|
||||
{
|
||||
"id": "94d7d85c-911e-495b-9203-065324594c74",
|
||||
"serie_id": "series-0",
|
||||
"serie_name": "Series 0",
|
||||
"episode": {
|
||||
"season": 1,
|
||||
"episode": 1,
|
||||
"title": null
|
||||
},
|
||||
"status": "pending",
|
||||
"priority": "normal",
|
||||
"added_at": "2025-10-24T17:23:25.966417Z",
|
||||
"started_at": null,
|
||||
"completed_at": null,
|
||||
"progress": null,
|
||||
"error": null,
|
||||
"retry_count": 0,
|
||||
"source_url": null
|
||||
},
|
||||
{
|
||||
"id": "1d8e1cda-ff78-4ab8-a040-2f325d53666a",
|
||||
"serie_id": "series-3",
|
||||
"serie_name": "Series 3",
|
||||
"episode": {
|
||||
"season": 1,
|
||||
"episode": 1,
|
||||
"title": null
|
||||
},
|
||||
"status": "pending",
|
||||
"priority": "normal",
|
||||
"added_at": "2025-10-24T17:23:25.967083Z",
|
||||
"started_at": null,
|
||||
"completed_at": null,
|
||||
"progress": null,
|
||||
"error": null,
|
||||
"retry_count": 0,
|
||||
"source_url": null
|
||||
},
|
||||
{
|
||||
"id": "f9b4174e-f809-4272-bcd8-f9bd44238d3c",
|
||||
"id": "73c2af3f-784c-4351-9bac-ddefa11e5e18",
|
||||
"serie_id": "series-2",
|
||||
"serie_name": "Series 2",
|
||||
"episode": {
|
||||
@ -334,7 +296,7 @@
|
||||
},
|
||||
"status": "pending",
|
||||
"priority": "normal",
|
||||
"added_at": "2025-10-24T17:23:25.967759Z",
|
||||
"added_at": "2025-10-25T15:25:53.552089Z",
|
||||
"started_at": null,
|
||||
"completed_at": null,
|
||||
"progress": null,
|
||||
@ -343,7 +305,45 @@
|
||||
"source_url": null
|
||||
},
|
||||
{
|
||||
"id": "b41f4c2a-40d6-4205-b769-c3a77df8df5e",
|
||||
"id": "d6a798ce-be87-42d9-847a-39e3ae1bc704",
|
||||
"serie_id": "series-3",
|
||||
"serie_name": "Series 3",
|
||||
"episode": {
|
||||
"season": 1,
|
||||
"episode": 1,
|
||||
"title": null
|
||||
},
|
||||
"status": "pending",
|
||||
"priority": "normal",
|
||||
"added_at": "2025-10-25T15:25:53.552805Z",
|
||||
"started_at": null,
|
||||
"completed_at": null,
|
||||
"progress": null,
|
||||
"error": null,
|
||||
"retry_count": 0,
|
||||
"source_url": null
|
||||
},
|
||||
{
|
||||
"id": "1c34959e-bcdb-4dce-812b-32fe278f5a42",
|
||||
"serie_id": "series-0",
|
||||
"serie_name": "Series 0",
|
||||
"episode": {
|
||||
"season": 1,
|
||||
"episode": 1,
|
||||
"title": null
|
||||
},
|
||||
"status": "pending",
|
||||
"priority": "normal",
|
||||
"added_at": "2025-10-25T15:25:53.553458Z",
|
||||
"started_at": null,
|
||||
"completed_at": null,
|
||||
"progress": null,
|
||||
"error": null,
|
||||
"retry_count": 0,
|
||||
"source_url": null
|
||||
},
|
||||
{
|
||||
"id": "9a02ae1f-c264-4a72-98e0-a2120dc625ea",
|
||||
"serie_id": "series-1",
|
||||
"serie_name": "Series 1",
|
||||
"episode": {
|
||||
@ -353,7 +353,7 @@
|
||||
},
|
||||
"status": "pending",
|
||||
"priority": "normal",
|
||||
"added_at": "2025-10-24T17:23:25.968503Z",
|
||||
"added_at": "2025-10-25T15:25:53.554161Z",
|
||||
"started_at": null,
|
||||
"completed_at": null,
|
||||
"progress": null,
|
||||
@ -362,7 +362,7 @@
|
||||
"source_url": null
|
||||
},
|
||||
{
|
||||
"id": "ae4e67dd-b77f-4fbe-8d4c-19fe979f6783",
|
||||
"id": "3080213e-4a0f-4b62-8dd5-871640e4379d",
|
||||
"serie_id": "persistent-series",
|
||||
"serie_name": "Persistent Series",
|
||||
"episode": {
|
||||
@ -372,7 +372,7 @@
|
||||
},
|
||||
"status": "pending",
|
||||
"priority": "normal",
|
||||
"added_at": "2025-10-24T17:23:26.027365Z",
|
||||
"added_at": "2025-10-25T15:25:53.636324Z",
|
||||
"started_at": null,
|
||||
"completed_at": null,
|
||||
"progress": null,
|
||||
@ -381,7 +381,7 @@
|
||||
"source_url": null
|
||||
},
|
||||
{
|
||||
"id": "5dc0b529-627c-47ed-8f2a-55112d78de93",
|
||||
"id": "6bd8762b-9800-4306-9143-8277b7d23611",
|
||||
"serie_id": "ws-series",
|
||||
"serie_name": "WebSocket Series",
|
||||
"episode": {
|
||||
@ -391,7 +391,7 @@
|
||||
},
|
||||
"status": "pending",
|
||||
"priority": "normal",
|
||||
"added_at": "2025-10-24T17:23:26.073822Z",
|
||||
"added_at": "2025-10-25T15:25:53.700590Z",
|
||||
"started_at": null,
|
||||
"completed_at": null,
|
||||
"progress": null,
|
||||
@ -400,7 +400,7 @@
|
||||
"source_url": null
|
||||
},
|
||||
{
|
||||
"id": "44f479fd-61f7-4279-ace1-5fbf31dad243",
|
||||
"id": "b0f208df-9fa1-4952-a65b-97d39696ee72",
|
||||
"serie_id": "pause-test",
|
||||
"serie_name": "Pause Test Series",
|
||||
"episode": {
|
||||
@ -410,7 +410,7 @@
|
||||
},
|
||||
"status": "pending",
|
||||
"priority": "normal",
|
||||
"added_at": "2025-10-24T17:23:26.227077Z",
|
||||
"added_at": "2025-10-25T15:25:53.876408Z",
|
||||
"started_at": null,
|
||||
"completed_at": null,
|
||||
"progress": null,
|
||||
@ -421,5 +421,5 @@
|
||||
],
|
||||
"active": [],
|
||||
"failed": [],
|
||||
"timestamp": "2025-10-24T17:23:26.227320+00:00"
|
||||
"timestamp": "2025-10-25T15:25:53.876987+00:00"
|
||||
}
|
||||
@ -23,9 +23,10 @@ from src.core.interfaces.callbacks import (
|
||||
ProgressPhase,
|
||||
)
|
||||
from src.core.providers.base_provider import Loader
|
||||
from src.infrastructure.logging.GlobalLogger import error_logger, noKeyFound_logger
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
error_logger = logging.getLogger("error")
|
||||
no_key_found_logger = logging.getLogger("series.nokey")
|
||||
|
||||
|
||||
class SerieScanner:
|
||||
@ -174,7 +175,7 @@ class SerieScanner:
|
||||
# remote metadata, yielding missing episodes per
|
||||
# season. Results are saved back to disk so that both
|
||||
# CLI and API consumers see consistent state.
|
||||
missing_episodes, site = (
|
||||
missing_episodes, _site = (
|
||||
self.__get_missing_episodes_and_season(
|
||||
serie.key, mp4_files
|
||||
)
|
||||
@ -192,14 +193,14 @@ class SerieScanner:
|
||||
)
|
||||
else:
|
||||
self.folderDict[serie.key] = serie
|
||||
noKeyFound_logger.info(
|
||||
no_key_found_logger.info(
|
||||
"Saved Serie: '%s'", str(serie)
|
||||
)
|
||||
|
||||
except NoKeyFoundException as nkfe:
|
||||
# Log error and notify via callback
|
||||
error_msg = f"Error processing folder '{folder}': {nkfe}"
|
||||
NoKeyFoundException.error(error_msg)
|
||||
logger.error(error_msg)
|
||||
|
||||
self._callback_manager.notify_error(
|
||||
ErrorContext(
|
||||
|
||||
@ -46,12 +46,7 @@ if not download_error_logger.handlers:
|
||||
download_error_handler.setLevel(logging.ERROR)
|
||||
download_error_logger.addHandler(download_error_handler)
|
||||
|
||||
noKeyFound_logger = logging.getLogger("NoKeyFound")
|
||||
if not noKeyFound_logger.handlers:
|
||||
log_path = _logs_dir / "no_key_found.log"
|
||||
noKeyFound_handler = logging.FileHandler(str(log_path))
|
||||
noKeyFound_handler.setLevel(logging.ERROR)
|
||||
noKeyFound_logger.addHandler(noKeyFound_handler)
|
||||
noKeyFound_logger = logging.getLogger()
|
||||
|
||||
|
||||
class AniworldLoader(Loader):
|
||||
|
||||
@ -1,40 +0,0 @@
|
||||
import logging
|
||||
|
||||
console_handler = None
|
||||
error_logger = None
|
||||
noKeyFound_logger = None
|
||||
noGerFound_logger = None
|
||||
def setupLogger():
|
||||
global console_handler, error_logger, noKeyFound_logger, noGerFound_logger
|
||||
# Configure logging
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(funcName)s - %(message)s')
|
||||
if (console_handler is None):
|
||||
console_handler = logging.StreamHandler()
|
||||
console_handler.setLevel(logging.INFO)
|
||||
console_handler.setFormatter(logging.Formatter(
|
||||
"%(asctime)s - %(levelname)s - %(funcName)s - %(message)s")
|
||||
)
|
||||
logging.getLogger().addHandler(console_handler)
|
||||
logging.getLogger("urllib3.connectionpool").setLevel(logging.INFO)
|
||||
logging.getLogger('charset_normalizer').setLevel(logging.INFO)
|
||||
logging.getLogger().setLevel(logging.INFO)
|
||||
|
||||
if (error_logger is None):
|
||||
error_logger = logging.getLogger("ErrorLog")
|
||||
error_handler = logging.FileHandler("../errors.log")
|
||||
error_handler.setLevel(logging.ERROR)
|
||||
error_logger.addHandler(error_handler)
|
||||
|
||||
if (noKeyFound_logger is None):
|
||||
noKeyFound_logger = logging.getLogger("NoKeyFound")
|
||||
noKeyFound_handler = logging.FileHandler("../NoKeyFound.log")
|
||||
noKeyFound_handler.setLevel(logging.ERROR)
|
||||
noKeyFound_logger.addHandler(noKeyFound_handler)
|
||||
|
||||
if (noGerFound_logger is None):
|
||||
noGerFound_logger = logging.getLogger("noGerFound")
|
||||
noGerFound_handler = logging.FileHandler("../noGerFound.log")
|
||||
noGerFound_handler.setLevel(logging.ERROR)
|
||||
noGerFound_logger.addHandler(noGerFound_handler)
|
||||
|
||||
setupLogger()
|
||||
122
src/server/config/logging_config.py
Normal file
122
src/server/config/logging_config.py
Normal file
@ -0,0 +1,122 @@
|
||||
"""
|
||||
Logging configuration for the FastAPI server.
|
||||
|
||||
This module provides comprehensive logging setup with both console and file
|
||||
handlers, ensuring all server activity is properly logged.
|
||||
"""
|
||||
import logging
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Dict
|
||||
|
||||
from src.config.settings import settings
|
||||
|
||||
|
||||
def setup_logging() -> Dict[str, logging.Logger]:
|
||||
"""
|
||||
Configure logging for the FastAPI application.
|
||||
|
||||
Creates:
|
||||
- Console handler for real-time output
|
||||
- File handler for server.log (general logs)
|
||||
- File handler for error.log (errors only)
|
||||
- File handler for access.log (request logs)
|
||||
|
||||
Returns:
|
||||
Dict containing configured loggers
|
||||
"""
|
||||
# Create logs directory if it doesn't exist
|
||||
log_dir = Path("logs")
|
||||
log_dir.mkdir(exist_ok=True)
|
||||
|
||||
# Define log file paths
|
||||
server_log_file = log_dir / "server.log"
|
||||
error_log_file = log_dir / "error.log"
|
||||
access_log_file = log_dir / "access.log"
|
||||
|
||||
# Define log format
|
||||
detailed_format = logging.Formatter(
|
||||
fmt="%(asctime)s - %(name)s - %(levelname)s - %(funcName)s:%(lineno)d - %(message)s",
|
||||
datefmt="%Y-%m-%d %H:%M:%S"
|
||||
)
|
||||
|
||||
simple_format = logging.Formatter(
|
||||
fmt="%(asctime)s - %(levelname)s - %(message)s",
|
||||
datefmt="%Y-%m-%d %H:%M:%S"
|
||||
)
|
||||
|
||||
# Configure root logger
|
||||
root_logger = logging.getLogger()
|
||||
root_logger.setLevel(getattr(logging, settings.log_level.upper(), logging.INFO))
|
||||
|
||||
# Remove existing handlers to avoid duplicates
|
||||
root_logger.handlers.clear()
|
||||
|
||||
# Console handler - visible in terminal
|
||||
console_handler = logging.StreamHandler(sys.stdout)
|
||||
console_handler.setLevel(logging.INFO)
|
||||
console_handler.setFormatter(simple_format)
|
||||
root_logger.addHandler(console_handler)
|
||||
|
||||
# File handler for general server logs
|
||||
server_file_handler = logging.FileHandler(server_log_file, mode='a', encoding='utf-8')
|
||||
server_file_handler.setLevel(logging.DEBUG)
|
||||
server_file_handler.setFormatter(detailed_format)
|
||||
root_logger.addHandler(server_file_handler)
|
||||
|
||||
# File handler for errors only
|
||||
error_file_handler = logging.FileHandler(error_log_file, mode='a', encoding='utf-8')
|
||||
error_file_handler.setLevel(logging.ERROR)
|
||||
error_file_handler.setFormatter(detailed_format)
|
||||
root_logger.addHandler(error_file_handler)
|
||||
|
||||
# Configure uvicorn loggers
|
||||
uvicorn_logger = logging.getLogger("uvicorn")
|
||||
uvicorn_logger.setLevel(logging.INFO)
|
||||
|
||||
uvicorn_access_logger = logging.getLogger("uvicorn.access")
|
||||
uvicorn_access_logger.setLevel(logging.INFO)
|
||||
|
||||
# Access log file handler
|
||||
access_file_handler = logging.FileHandler(access_log_file, mode='a', encoding='utf-8')
|
||||
access_file_handler.setLevel(logging.INFO)
|
||||
access_file_handler.setFormatter(simple_format)
|
||||
uvicorn_access_logger.addHandler(access_file_handler)
|
||||
|
||||
# Configure FastAPI logger
|
||||
fastapi_logger = logging.getLogger("fastapi")
|
||||
fastapi_logger.setLevel(logging.INFO)
|
||||
|
||||
# Reduce noise from third-party libraries
|
||||
logging.getLogger("urllib3").setLevel(logging.WARNING)
|
||||
logging.getLogger("charset_normalizer").setLevel(logging.WARNING)
|
||||
logging.getLogger("multipart").setLevel(logging.WARNING)
|
||||
|
||||
# Log initial setup
|
||||
root_logger.info("=" * 80)
|
||||
root_logger.info("FastAPI Server Logging Initialized")
|
||||
root_logger.info(f"Log Level: {settings.log_level.upper()}")
|
||||
root_logger.info(f"Server Log: {server_log_file.absolute()}")
|
||||
root_logger.info(f"Error Log: {error_log_file.absolute()}")
|
||||
root_logger.info(f"Access Log: {access_log_file.absolute()}")
|
||||
root_logger.info("=" * 80)
|
||||
|
||||
return {
|
||||
"root": root_logger,
|
||||
"uvicorn": uvicorn_logger,
|
||||
"uvicorn.access": uvicorn_access_logger,
|
||||
"fastapi": fastapi_logger,
|
||||
}
|
||||
|
||||
|
||||
def get_logger(name: str) -> logging.Logger:
|
||||
"""
|
||||
Get a logger instance for a specific module.
|
||||
|
||||
Args:
|
||||
name: Name of the module/logger
|
||||
|
||||
Returns:
|
||||
Configured logger instance
|
||||
"""
|
||||
return logging.getLogger(name)
|
||||
@ -50,11 +50,21 @@ class TestSeriesAppDependency:
|
||||
assert result == mock_series_app_instance
|
||||
mock_series_app_class.assert_called_once_with("/path/to/anime")
|
||||
|
||||
@patch('src.server.services.config_service.get_config_service')
|
||||
@patch('src.server.utils.dependencies.settings')
|
||||
def test_get_series_app_no_directory_configured(self, mock_settings):
|
||||
def test_get_series_app_no_directory_configured(
|
||||
self, mock_settings, mock_get_config_service
|
||||
):
|
||||
"""Test SeriesApp dependency when directory is not configured."""
|
||||
# Arrange
|
||||
mock_settings.anime_directory = ""
|
||||
|
||||
# Mock config service to return empty config
|
||||
mock_config_service = Mock()
|
||||
mock_config = Mock()
|
||||
mock_config.other = {}
|
||||
mock_config_service.load_config.return_value = mock_config
|
||||
mock_get_config_service.return_value = mock_config_service
|
||||
|
||||
# Act & Assert
|
||||
with pytest.raises(HTTPException) as exc_info:
|
||||
@ -178,8 +188,10 @@ class TestAuthenticationDependencies:
|
||||
mock_get_current_user.assert_called_once_with(credentials)
|
||||
|
||||
@patch('src.server.utils.dependencies.get_current_user')
|
||||
def test_optional_auth_with_invalid_credentials(self,
|
||||
mock_get_current_user):
|
||||
def test_optional_auth_with_invalid_credentials(
|
||||
self,
|
||||
mock_get_current_user
|
||||
):
|
||||
"""Test optional authentication with invalid credentials."""
|
||||
# Arrange
|
||||
credentials = HTTPAuthorizationCredentials(
|
||||
@ -277,6 +289,8 @@ class TestUtilityDependencies:
|
||||
await log_request_dependency(mock_request)
|
||||
|
||||
# Assert - no exception should be raised
|
||||
|
||||
|
||||
class TestIntegrationScenarios:
|
||||
"""Integration test scenarios for dependency injection."""
|
||||
|
||||
@ -284,14 +298,18 @@ class TestIntegrationScenarios:
|
||||
"""Test the complete SeriesApp dependency lifecycle."""
|
||||
# Use separate mock instances for each call
|
||||
with patch('src.server.utils.dependencies.settings') as mock_settings:
|
||||
with patch('src.server.utils.dependencies.SeriesApp') as mock_series_app_class:
|
||||
with patch(
|
||||
'src.server.utils.dependencies.SeriesApp'
|
||||
) as mock_series_app_class:
|
||||
# Arrange
|
||||
mock_settings.anime_directory = "/path/to/anime"
|
||||
|
||||
# Create separate mock instances for each instantiation
|
||||
mock_instance1 = MagicMock()
|
||||
mock_instance2 = MagicMock()
|
||||
mock_series_app_class.side_effect = [mock_instance1, mock_instance2]
|
||||
mock_series_app_class.side_effect = [
|
||||
mock_instance1, mock_instance2
|
||||
]
|
||||
|
||||
# Act - Get SeriesApp instance
|
||||
app1 = get_series_app()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user