data-sourcerer 0.2.3__py3-none-any.whl → 0.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. {data_sourcerer-0.2.3.dist-info → data_sourcerer-0.3.0.dist-info}/METADATA +1 -1
  2. {data_sourcerer-0.2.3.dist-info → data_sourcerer-0.3.0.dist-info}/RECORD +42 -28
  3. sourcerer/__init__.py +1 -1
  4. sourcerer/domain/access_credentials/entities.py +3 -1
  5. sourcerer/domain/access_credentials/repositories.py +1 -1
  6. sourcerer/domain/storage/__init__.py +0 -0
  7. sourcerer/domain/storage/entities.py +27 -0
  8. sourcerer/domain/storage/repositories.py +31 -0
  9. sourcerer/infrastructure/access_credentials/repositories.py +3 -2
  10. sourcerer/infrastructure/access_credentials/services.py +9 -25
  11. sourcerer/infrastructure/db/models.py +33 -2
  12. sourcerer/infrastructure/storage/__init__.py +0 -0
  13. sourcerer/infrastructure/storage/repositories.py +72 -0
  14. sourcerer/infrastructure/storage/services.py +37 -0
  15. sourcerer/infrastructure/storage_provider/services/gcp.py +1 -1
  16. sourcerer/infrastructure/utils.py +2 -1
  17. sourcerer/presentation/di_container.py +15 -0
  18. sourcerer/presentation/screens/file_system_finder/main.py +5 -4
  19. sourcerer/presentation/screens/file_system_finder/widgets/file_system_navigator.py +16 -13
  20. sourcerer/presentation/screens/main/main.py +63 -8
  21. sourcerer/presentation/screens/main/messages/select_storage_item.py +1 -0
  22. sourcerer/presentation/screens/main/mixins/resize_containers_watcher_mixin.py +2 -1
  23. sourcerer/presentation/screens/main/widgets/storage_content.py +187 -77
  24. sourcerer/presentation/screens/main/widgets/storage_list_sidebar.py +99 -31
  25. sourcerer/presentation/screens/preview_content/main.py +15 -3
  26. sourcerer/presentation/screens/provider_creds_list/main.py +29 -8
  27. sourcerer/presentation/screens/provider_creds_registration/main.py +7 -4
  28. sourcerer/presentation/screens/shared/widgets/spinner.py +57 -0
  29. sourcerer/presentation/screens/storage_action_progress/main.py +3 -5
  30. sourcerer/presentation/screens/storages_list/__init__.py +0 -0
  31. sourcerer/presentation/screens/storages_list/main.py +180 -0
  32. sourcerer/presentation/screens/storages_list/messages/__init__.py +0 -0
  33. sourcerer/presentation/screens/storages_list/messages/reload_storages_request.py +8 -0
  34. sourcerer/presentation/screens/storages_list/styles.tcss +55 -0
  35. sourcerer/presentation/screens/storages_registration/__init__.py +0 -0
  36. sourcerer/presentation/screens/storages_registration/main.py +100 -0
  37. sourcerer/presentation/screens/storages_registration/styles.tcss +41 -0
  38. sourcerer/presentation/settings.py +29 -16
  39. sourcerer/presentation/utils.py +9 -1
  40. sourcerer/presentation/screens/shared/widgets/loader.py +0 -31
  41. {data_sourcerer-0.2.3.dist-info → data_sourcerer-0.3.0.dist-info}/WHEEL +0 -0
  42. {data_sourcerer-0.2.3.dist-info → data_sourcerer-0.3.0.dist-info}/entry_points.txt +0 -0
  43. {data_sourcerer-0.2.3.dist-info → data_sourcerer-0.3.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: data-sourcerer
3
- Version: 0.2.3
3
+ Version: 0.3.0
4
4
  Summary: Sourcerer is a terminal cloud storage navigator.
5
5
  Author-email: Bohdana Kuzmenko <bohdana.kuzmenko.dev@gmail.com>
6
6
  License: MIT
@@ -1,11 +1,11 @@
1
- sourcerer/__init__.py,sha256=LdB6MZT6D2_yXGq1KBBQRC47gZXfwv61ZvJi4I6cBGk,585
1
+ sourcerer/__init__.py,sha256=3SFTxE-wK6g4MigwpFa7z88woGrTeoJTPs8F1qg8bII,585
2
2
  sourcerer/settings.py,sha256=dwY2GoaWD1CsAoVtWzaAhP7_e3KUugmBr2E624JSedc,1388
3
3
  sourcerer/utils.py,sha256=4jAlcofepAQMcD1cYDsC1ryGwBLxE9m7ckPS6CzDsCI,879
4
4
  sourcerer/domain/__init__.py,sha256=rV21d-dD-e0q4EQ2LfWDSDLlrUOjnHnWBtWPujoue0o,556
5
5
  sourcerer/domain/access_credentials/__init__.py,sha256=pFAwnr74uy09e7kubYsuaqzkVPkTA66dwjKzpIGQkAY,217
6
- sourcerer/domain/access_credentials/entities.py,sha256=u_pZMTncYorVYFNZOnJHn8qnsTWpbFyl7rEOaVrFjxQ,2020
6
+ sourcerer/domain/access_credentials/entities.py,sha256=m5hktJPmcwgG7vG-HKasA-gAd8US6jrZxGso4sCLZc8,2123
7
7
  sourcerer/domain/access_credentials/exceptions.py,sha256=jo3vhGpIaEsDl68uV8JLDqPvfVZMi7H6MA0qsRL0QXQ,546
8
- sourcerer/domain/access_credentials/repositories.py,sha256=fTSCBUqSwgZnY0NVxCIwDLjyvylOBk3xSUBJ5Sr8FKA,2720
8
+ sourcerer/domain/access_credentials/repositories.py,sha256=hPlFnUDbR_W4WfiRRdsXvMQNfJ_3_Om1Wh7fvImepLo,2741
9
9
  sourcerer/domain/access_credentials/services.py,sha256=HtTOBrDyh8Wz-dxYtcohPYu0qWxgnvzafGiXOXRu6Ww,2821
10
10
  sourcerer/domain/file_system/__init__.py,sha256=5diScp5Q8Hw8e_4vqacVocQBw0KA7fPs_YERoNwSEzM,184
11
11
  sourcerer/domain/file_system/entities.py,sha256=IeTu5VYxmBQMH7AcKfW1Muk4wUmgZ769eWwNyqeWRpw,2060
@@ -13,45 +13,51 @@ sourcerer/domain/file_system/exceptions.py,sha256=TairaMaLkSHgbiq3pImkmVZAACoVHy
13
13
  sourcerer/domain/file_system/services.py,sha256=kQeEM1Lt28UBVT9uG4M2iFDSxSvQdaJw4QzM9giUdjY,2208
14
14
  sourcerer/domain/shared/__init__.py,sha256=pkCn6PfBLIlYT5q4xWq3cNtOfbUrrePiH06TduLq6_o,148
15
15
  sourcerer/domain/shared/entities.py,sha256=jJR1PhJBWrSeJyEFvauEYJ1UXG7BcT6pi2oFpmglu4I,497
16
+ sourcerer/domain/storage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
+ sourcerer/domain/storage/entities.py,sha256=bSWVFx4Hh7_RLCHVLN_U2Wg6XxeYUyzDGLUpbFuWTLo,687
18
+ sourcerer/domain/storage/repositories.py,sha256=v7RU8_X_HgFT3wn7Yc5m07aN7DEbsBMh8sRZSRSCTxU,1003
16
19
  sourcerer/domain/storage_provider/__init__.py,sha256=P3RUH9LFkWez3ehCczgVbnbp0tZZepPeOQf9spsC8FQ,192
17
20
  sourcerer/domain/storage_provider/entities.py,sha256=EgHkVFizMzzpzN161DlmWKPV9QhoRo8X7iiLtcN3_Wk,1931
18
21
  sourcerer/domain/storage_provider/exceptions.py,sha256=6xK5r62Bhedx3vV0_i7Eu5ZG5IExxeiuaGHG5sX17i4,508
19
22
  sourcerer/domain/storage_provider/services.py,sha256=Zm6nrKqQJW-9ZaqTp9wQaQuwMeH6hkLJZCkhQ_sTRF0,3997
20
23
  sourcerer/infrastructure/__init__.py,sha256=HQoqA8S9Vx2dr1Eua86wu_YxwXyY6jqa4IfEoZJcXcQ,616
21
- sourcerer/infrastructure/utils.py,sha256=5ITzUIsraIVGRJOt9C5znDSu9TUYPBS9YTx9OsiOVzM,5135
24
+ sourcerer/infrastructure/utils.py,sha256=_8dtobWxgrfHK7CUCFHq2AXS54KBwQQgDWWFxR21pFA,5198
22
25
  sourcerer/infrastructure/access_credentials/__init__.py,sha256=7BSXnI9n59_PuGxHjOra6PG82R_6JlrU4S1tsJx4WGM,249
23
26
  sourcerer/infrastructure/access_credentials/exceptions.py,sha256=usad48RTA7ub8AfnUs2EzbD-fiUwpmnRGjJluBjd3m4,1101
24
27
  sourcerer/infrastructure/access_credentials/registry.py,sha256=YEjkbh5639j8LkAocozC8O_7t1pPcrJwbL1LCJhiGkY,3416
25
- sourcerer/infrastructure/access_credentials/repositories.py,sha256=1Yf2ByKed8Z6WXcjbnHjC9dyw-PV0KE62JVO5SDaOMU,4393
26
- sourcerer/infrastructure/access_credentials/services.py,sha256=YUbltxfreMMJRr-ERnbsRqdABrx8zb5bSRUEI8vdk60,16086
28
+ sourcerer/infrastructure/access_credentials/repositories.py,sha256=_GLT-d3yarQD9Rx4Y2EPYtFoWDeBIidixQW4MxXSZ2U,4472
29
+ sourcerer/infrastructure/access_credentials/services.py,sha256=QFU-eRKsl7P4Eg44i-A8BT6llVlT4vc6juvlJE39dq4,15720
27
30
  sourcerer/infrastructure/db/__init__.py,sha256=sjx2F0aDnxej7-FAjhFJYIQQ5d2apmItkquKbvGYIBc,175
28
31
  sourcerer/infrastructure/db/config.py,sha256=c3ubAxBWt-zDUwTe3pAgJ86-rw-LZZAZppuBRo93Xn8,1792
29
- sourcerer/infrastructure/db/models.py,sha256=U7Ocdup4KHyCRGvTTxHY2kF1FES3oaU2-hT7vU8pFIw,1743
32
+ sourcerer/infrastructure/db/models.py,sha256=XLkV7wpKZTPKCur32hpapT690O5UiILhYhTTr3dMw_U,2780
30
33
  sourcerer/infrastructure/file_system/__init__.py,sha256=Swx8arwXeZ4E40ViDSpQglmUrIlpuEvZY6crcWpGC2g,219
31
34
  sourcerer/infrastructure/file_system/exceptions.py,sha256=obx0NxVuhVzLgL5K2MA5d4rNImlRHJ4Gr-2RrIuKJqk,2944
32
35
  sourcerer/infrastructure/file_system/services.py,sha256=J0XHv-zF8WblE6bzzEpKkqU_k3gefMj_OArWBRFtGHA,5649
36
+ sourcerer/infrastructure/storage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
+ sourcerer/infrastructure/storage/repositories.py,sha256=GTMxxdeRmnxqpLUq_FCX9i28tkUL6xYRSsv9rVYFTzM,2334
38
+ sourcerer/infrastructure/storage/services.py,sha256=wP37li_ts-By0Z_q5pizl__v-nRjFlkM7LlAJghujnc,1024
33
39
  sourcerer/infrastructure/storage_provider/__init__.py,sha256=GONjDCsTmd6f_fF3lzxDAfLlyuSQDhO4bz0eF9a35tI,229
34
40
  sourcerer/infrastructure/storage_provider/exceptions.py,sha256=acx3IIXD2yWlzLvD2asJBEpKEa6eJW31uKkzzr8MrR4,3336
35
41
  sourcerer/infrastructure/storage_provider/registry.py,sha256=8dbRLOx1jLK_i18uuh_JnKvId9NJBECKg4nG9F_dFH4,2249
36
42
  sourcerer/infrastructure/storage_provider/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
43
  sourcerer/infrastructure/storage_provider/services/azure.py,sha256=A7k8Zs6rK5nBsUr5ZNBzkDQWRxpU0qnfWAcrz3eZzAk,9796
38
- sourcerer/infrastructure/storage_provider/services/gcp.py,sha256=_iVNf8OESVynGHKt68ZmudQtS6qU-UWZMhFa3v0Sm7Y,9102
44
+ sourcerer/infrastructure/storage_provider/services/gcp.py,sha256=nohx-WE5STYRkeZd4nk8blBZxmWSWSEz5bdFOXN1QYc,9097
39
45
  sourcerer/infrastructure/storage_provider/services/s3.py,sha256=lSpf5SPyTZGl19ChgYBtf3IR6uUWULuAvLBEdD-oarM,9277
40
46
  sourcerer/presentation/__init__.py,sha256=kzOeaTpy9hm61MLl_nybdooRrawFUd1uEX4f3Y-84ZU,472
41
47
  sourcerer/presentation/app.py,sha256=ROu3vSWzo6d8W30A9Zqi5zdLcVeHJsGLDJMLTKrthHE,1018
42
- sourcerer/presentation/di_container.py,sha256=mbK8tDY0LgVRfQfXVZ5tGXPHSfr_8JraCMIQlZn0hBc,1641
43
- sourcerer/presentation/settings.py,sha256=OcNrvwqHwAq3ZqWOfEmZ0PqyvQpAY1fmBpMc9lBNfgI,1062
44
- sourcerer/presentation/utils.py,sha256=aM5eCNEmIzCyfg8Egb2rFfOlXQ5pFTXzbRVwQGSOdjY,2638
48
+ sourcerer/presentation/di_container.py,sha256=KTDSWEtR_YTqJTOsyhwBBHqB9gqIkX-nu5a8Ks9UlDc,2215
49
+ sourcerer/presentation/settings.py,sha256=iR8oK62c3kzgN5w3h0sEQlXhE5AEwufk_pv3hjMODMo,1255
50
+ sourcerer/presentation/utils.py,sha256=9sDvwnXsycxHXvH0V_we5F6BzGyncGvWQ-vogaUqMBM,2979
45
51
  sourcerer/presentation/screens/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
52
  sourcerer/presentation/screens/critical_error/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
47
53
  sourcerer/presentation/screens/critical_error/main.py,sha256=10Ip1InBzktwwM2ijKXBOkhvBXGorw1X8EGxdh75WZE,2208
48
54
  sourcerer/presentation/screens/critical_error/styles.tcss,sha256=mURvbf0_npkRtzVBs2bVBybbyNK9cO_6Ar2Muk1Mpv8,604
49
- sourcerer/presentation/screens/file_system_finder/main.py,sha256=PSOxD_UfAMxSIdDFVJZeh0tcYGh2qZP2RY9rBUMU12A,10241
55
+ sourcerer/presentation/screens/file_system_finder/main.py,sha256=AC_G6VYMTO0NOYmGmOZ3be5isTGFjebR0IHFHU-yw3o,10343
50
56
  sourcerer/presentation/screens/file_system_finder/styles.tcss,sha256=fZkdwXFsDkjXkaIskLxoQ_YHsLWKjgrn6hYseugg_68,718
51
57
  sourcerer/presentation/screens/file_system_finder/widgets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
52
- sourcerer/presentation/screens/file_system_finder/widgets/file_system_navigator.py,sha256=EHPsVWyq0Lmkv1Jt3m4OgpJvI1nsye2Os1XA0XAZz8M,30884
58
+ sourcerer/presentation/screens/file_system_finder/widgets/file_system_navigator.py,sha256=giQXiNEsSAmBV-YWc1eXcJDFUWxpCppv0oNxgvrLZxg,31070
53
59
  sourcerer/presentation/screens/main/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
54
- sourcerer/presentation/screens/main/main.py,sha256=FhG0_uev8W5bfrP-F5pBVst_ZnSyim6aM7G4nL9yYfQ,21354
60
+ sourcerer/presentation/screens/main/main.py,sha256=vIsrhj0rb1OR0ITASDvIl-yf1_7n8oNi494s7QRRBz8,23127
55
61
  sourcerer/presentation/screens/main/styles.tcss,sha256=Ruv2vBKzM8njH7OS2TCpZqCmRVEp7XQLeBN4XhVB5AU,381
56
62
  sourcerer/presentation/screens/main/messages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
57
63
  sourcerer/presentation/screens/main/messages/delete_request.py,sha256=puaU1UtbDErfYi8ViPEawhSbycnUpwdE81zZfzlslNE,203
@@ -59,26 +65,26 @@ sourcerer/presentation/screens/main/messages/download_request.py,sha256=3urSTrvN
59
65
  sourcerer/presentation/screens/main/messages/preview_request.py,sha256=px8N3E2VEexKmpZESb9nYDQvhXUThPxM0dU41B533tM,184
60
66
  sourcerer/presentation/screens/main/messages/refresh_storages_list_request.py,sha256=NxOBcUf5oKF1cMCcHZny8qG2Jv6zTdPmYeFV9qORHh8,136
61
67
  sourcerer/presentation/screens/main/messages/resizing_rule.py,sha256=ws7lzS08h6qqeihF66XV5FsX26YkjQOje_4vgCw2mqI,332
62
- sourcerer/presentation/screens/main/messages/select_storage_item.py,sha256=xBu0UH5A6iyZPJECt_f_vfWVaCmE0bJo5hq2FJXMHQo,237
68
+ sourcerer/presentation/screens/main/messages/select_storage_item.py,sha256=iZOwzOwFLhsr58WV01-NtTFr4LXKykz1i76nayLkCLw,269
63
69
  sourcerer/presentation/screens/main/messages/uncheck_files_request.py,sha256=CMpYVwos1JHknqDcqru1hG8RJy5f1Lwjsxtrse1ZDGw,140
64
70
  sourcerer/presentation/screens/main/messages/upload_request.py,sha256=KXPTliqdvRvtMwob5bQUuBDxCjWmFcSjt-eUgQoRv7g,185
65
71
  sourcerer/presentation/screens/main/mixins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
66
- sourcerer/presentation/screens/main/mixins/resize_containers_watcher_mixin.py,sha256=wZnTbJHjHDJbKFkfbyT0CR3GWlVupyiSotgnumBiEoI,5647
72
+ sourcerer/presentation/screens/main/mixins/resize_containers_watcher_mixin.py,sha256=LmB7ZQh6ngl-x3QsDBlcKqJFFm8bYW9FSBYMYRAEi_0,5696
67
73
  sourcerer/presentation/screens/main/widgets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
68
74
  sourcerer/presentation/screens/main/widgets/gradient.py,sha256=Ow6oaX0tsFNbUKRh_e9ITph20_tKoQgqzM7rujwKmxs,1263
69
75
  sourcerer/presentation/screens/main/widgets/resizing_rule.py,sha256=W4tAbSZlmAIytP1BNlSvBeiMGA7cD6l13IpxG2JYzxk,2088
70
- sourcerer/presentation/screens/main/widgets/storage_content.py,sha256=9Gkd-MWtV_sK1hCLA3pa4yc1P53xKfF4KdJFqhI-BDU,22488
71
- sourcerer/presentation/screens/main/widgets/storage_list_sidebar.py,sha256=dz1Qdznc2hNt_MBB4j6kszx7cCpiaM9kM9_7LDwyPDc,5619
76
+ sourcerer/presentation/screens/main/widgets/storage_content.py,sha256=TnPG4uN9-7oZj4JbZC_Xj60BGj6jbm3IxygK-TsVpQg,26097
77
+ sourcerer/presentation/screens/main/widgets/storage_list_sidebar.py,sha256=83R7HximPBPIj-3J9oWnISv10RcCabTo5EVWmhO5lSk,7748
72
78
  sourcerer/presentation/screens/preview_content/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
73
- sourcerer/presentation/screens/preview_content/main.py,sha256=c7WEM3dCRHh0gnB2AXgl_upi8lfNwRfH1425736mya8,2498
79
+ sourcerer/presentation/screens/preview_content/main.py,sha256=QX3eyoLkgMhRLneUz3rIHkzFGmxHqD1vvok9LcxU8cE,2785
74
80
  sourcerer/presentation/screens/preview_content/styles.tcss,sha256=Qk0nZtUfp-mCFaUXtkjwimAnshXnhEgh719aT4_lDPQ,374
75
81
  sourcerer/presentation/screens/provider_creds_list/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
76
- sourcerer/presentation/screens/provider_creds_list/main.py,sha256=s3t9UaaOVHBiSQ5L-tduzxaJWdDgWqbJtIol1IlAv5s,7870
82
+ sourcerer/presentation/screens/provider_creds_list/main.py,sha256=ybnaT6GROnNfIcwhfa5zrtEL4JaP80qRiL4YjqMocyk,8595
77
83
  sourcerer/presentation/screens/provider_creds_list/styles.tcss,sha256=_BXTWQw_LjPjbAG-V4YxxOeHn4GFShVjc4K1by-uVR0,956
78
84
  sourcerer/presentation/screens/provider_creds_list/messages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
79
85
  sourcerer/presentation/screens/provider_creds_list/messages/reload_credentials_request.py,sha256=zkyLFkXZHQMj5OsDU_IiInUnezHNWyvYn8yZLoJmJn0,134
80
86
  sourcerer/presentation/screens/provider_creds_registration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
81
- sourcerer/presentation/screens/provider_creds_registration/main.py,sha256=fBAi3xnH-QoRwq6dttuS_lqBMCe66RZND2M228IhngI,11182
87
+ sourcerer/presentation/screens/provider_creds_registration/main.py,sha256=sIkdS1cvjzT4-0Y-z1R2bLiNx8chinGQvr5v9VWcoBg,11354
82
88
  sourcerer/presentation/screens/provider_creds_registration/styles.tcss,sha256=gd1SNeRoHTYwNzdGxK-2aDqNPeY5b2wFWajtoNn5--Y,612
83
89
  sourcerer/presentation/screens/question/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
84
90
  sourcerer/presentation/screens/question/main.py,sha256=7ogFbKrqP9deBYfgq7Bs6NkiSdy3whEu51mW_--TCIY,980
@@ -88,14 +94,22 @@ sourcerer/presentation/screens/shared/containers.py,sha256=9Tkl5SbPNgycZlfp5Pq50
88
94
  sourcerer/presentation/screens/shared/widgets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
89
95
  sourcerer/presentation/screens/shared/widgets/button.py,sha256=aGsJTwK04nTXarafkl8TgdeB9EGfRwn4gffoPvFFwiU,1580
90
96
  sourcerer/presentation/screens/shared/widgets/labeled_input.py,sha256=OmaZjRJSg8LABvBvbN3LQ0s9M3-jp9X2i3yCVNbRhEk,2798
91
- sourcerer/presentation/screens/shared/widgets/loader.py,sha256=_sRFM9I_KhiqPyUCN_hX7IP1AlxtrUNn5QBXi5hmdtU,737
97
+ sourcerer/presentation/screens/shared/widgets/spinner.py,sha256=Do_Gc32GKA9ibFhORjfiK0RM3a7bvhnJ1SvnCXQJsHY,1713
92
98
  sourcerer/presentation/screens/storage_action_progress/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
93
- sourcerer/presentation/screens/storage_action_progress/main.py,sha256=4SnbTYFRSKAoBVqFzVD24GJgdeddjWGi1XXSbF5u-7Y,17944
99
+ sourcerer/presentation/screens/storage_action_progress/main.py,sha256=0nNSxKwZv-ly5uA1cpdZf6x-UO8xoF0poHwc9VcGMj4,17899
94
100
  sourcerer/presentation/screens/storage_action_progress/styles.tcss,sha256=ffvDxRWhckE5tjEG4jwlhQNqeQsYpdF71104StWCGWU,818
101
+ sourcerer/presentation/screens/storages_list/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
102
+ sourcerer/presentation/screens/storages_list/main.py,sha256=trlNfWIe3VE318ksy803TC1AH9duYN3ZEfzOAv1a9eM,6254
103
+ sourcerer/presentation/screens/storages_list/styles.tcss,sha256=BlvlL5M-WGtMZuyqxT37gGlAIi1AFfILMaLiL-ZwvIc,766
104
+ sourcerer/presentation/screens/storages_list/messages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
105
+ sourcerer/presentation/screens/storages_list/messages/reload_storages_request.py,sha256=PtwlWgPUP_ZcAid535fd4Py6AvKUVhaXbc0WMka4QD0,131
106
+ sourcerer/presentation/screens/storages_registration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
107
+ sourcerer/presentation/screens/storages_registration/main.py,sha256=_MlyeTbI-zoNWegGY6jnZPR9aoeTeeXDpjXQL8hEFIM,3734
108
+ sourcerer/presentation/screens/storages_registration/styles.tcss,sha256=Yd78pkiaaShb30r5s6qlYlLxyB62DJNeAQqs_gMcP6k,601
95
109
  sourcerer/presentation/themes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
96
110
  sourcerer/presentation/themes/github_dark.py,sha256=9E1mEOr701nU-ZDSKBccMl3GYchroCEsxEVelm5oI-E,497
97
- data_sourcerer-0.2.3.dist-info/METADATA,sha256=OjcWwOqLnN3WL-1CJULg-QldS5Ax1t_MwOaWbJBxu6U,2535
98
- data_sourcerer-0.2.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
99
- data_sourcerer-0.2.3.dist-info/entry_points.txt,sha256=CyD02GehPW6QuhR5oDY5tLLRHQ9qbPXe0v3aT1pK3N8,62
100
- data_sourcerer-0.2.3.dist-info/licenses/LICENSE,sha256=HjZ7RAG3i6izxvitGfY4feHfvW5F8DPj5eF0YBSf2rI,1073
101
- data_sourcerer-0.2.3.dist-info/RECORD,,
111
+ data_sourcerer-0.3.0.dist-info/METADATA,sha256=JWKRdTOJMClCyOZR6alR2Ew2aFZtvN0fxAYxAnM52Ew,2535
112
+ data_sourcerer-0.3.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
113
+ data_sourcerer-0.3.0.dist-info/entry_points.txt,sha256=CyD02GehPW6QuhR5oDY5tLLRHQ9qbPXe0v3aT1pK3N8,62
114
+ data_sourcerer-0.3.0.dist-info/licenses/LICENSE,sha256=HjZ7RAG3i6izxvitGfY4feHfvW5F8DPj5eF0YBSf2rI,1073
115
+ data_sourcerer-0.3.0.dist-info/RECORD,,
sourcerer/__init__.py CHANGED
@@ -12,4 +12,4 @@ The application is structured using a clean architecture approach with:
12
12
  - Presentation layer: User interface components
13
13
  """
14
14
 
15
- __version__ = "0.2.3"
15
+ __version__ = "0.3.0"
@@ -4,13 +4,14 @@ Access credentials entity classes.
4
4
  This module defines data classes representing access credentials
5
5
  used for authentication with various cloud providers.
6
6
  """
7
-
8
7
  from datetime import datetime
9
8
 
10
9
  import boto3
11
10
  from azure.identity import ClientSecretCredential
12
11
  from msgspec._core import Struct
13
12
 
13
+ from sourcerer.domain.storage.entities import Storage
14
+
14
15
 
15
16
  class Credentials(Struct):
16
17
  """
@@ -35,6 +36,7 @@ class Credentials(Struct):
35
36
  active: bool
36
37
  created_at: datetime | None = None
37
38
  updated_at: datetime | None = None
39
+ storages: list[Storage] = [] # noqa: RUF012
38
40
 
39
41
 
40
42
  class Boto3Credentials(Struct):
@@ -56,7 +56,7 @@ class BaseCredentialsRepository(metaclass=ABCMeta):
56
56
  raise NotImplementedError
57
57
 
58
58
  @abstractmethod
59
- def list(self, active_only: bool | None = None):
59
+ def list(self, active_only: bool | None = None) -> list[Credentials]:
60
60
  """List all credentials in the repository.
61
61
 
62
62
  Args:
File without changes
@@ -0,0 +1,27 @@
1
+ """
2
+ Storage provider entity classes.
3
+
4
+ This module defines data classes representing cloud storage entities
5
+ such as storage containers, files, folders, and permissions.
6
+ """
7
+
8
+ from datetime import datetime
9
+
10
+ from msgspec._core import Struct
11
+
12
+
13
+ class Storage(Struct):
14
+ """
15
+ Represents a cloud storage container (bucket/container).
16
+
17
+ Attributes:
18
+ credentials_id (int): The ID of the associated credentials
19
+ name (str): The storage name/identifier (e.g., bucket name)
20
+ date_created (datetime): When the storage was created
21
+ """
22
+
23
+ name: str
24
+ uuid: str
25
+ date_created: datetime
26
+ credentials_id: int | None = None
27
+ credentials_name: str | None = None
@@ -0,0 +1,31 @@
1
+ from abc import ABCMeta, abstractmethod
2
+
3
+ from sourcerer.domain.storage.entities import Storage
4
+
5
+
6
+ class BaseStoragesRepository(metaclass=ABCMeta):
7
+ @abstractmethod
8
+ def create(self, storage: Storage) -> None:
9
+ """Create a new storage entry in the repository.
10
+ Args:
11
+ storage (Storage): The storage object to store
12
+ """
13
+ raise NotImplementedError()
14
+
15
+ @abstractmethod
16
+ def list(self, provider_id: int | None = None) -> list[Storage]:
17
+ """List all storage entries in the repository.
18
+ Args:
19
+ provider_id (int | None): The provider ID to filter by. If None, all entries are returned.
20
+ Returns:
21
+ List[Storage]: A list of storage entries
22
+ """
23
+ raise NotImplementedError()
24
+
25
+ @abstractmethod
26
+ def delete(self, uuid: str) -> None:
27
+ """Delete a storage entry by UUID.
28
+ Args:
29
+ uuid (str): The UUID of the storage entry to delete
30
+ """
31
+ raise NotImplementedError()
@@ -46,7 +46,7 @@ class SQLAlchemyCredentialsRepository(BaseCredentialsRepository):
46
46
  session.add(credentials)
47
47
  session.commit()
48
48
 
49
- def delete(self, uuid: str):
49
+ def delete(self, uuid: str) -> None:
50
50
  """
51
51
  Delete credentials from the database by UUID.
52
52
 
@@ -78,7 +78,7 @@ class SQLAlchemyCredentialsRepository(BaseCredentialsRepository):
78
78
  session.query(DBCredentials).filter(DBCredentials.uuid == uuid).first()
79
79
  )
80
80
 
81
- def list(self, active_only: bool | None = None):
81
+ def list(self, active_only: bool | None = None) -> list[Credentials]:
82
82
  """
83
83
  List all credentials in the repository.
84
84
 
@@ -103,6 +103,7 @@ class SQLAlchemyCredentialsRepository(BaseCredentialsRepository):
103
103
  credentials_type=credential.credentials_type,
104
104
  credentials=credential.credentials,
105
105
  active=credential.active,
106
+ storages=credential.storages,
106
107
  )
107
108
  for credential in credentials_query.all()
108
109
  ]
@@ -10,7 +10,6 @@ from abc import ABC
10
10
 
11
11
  import boto3
12
12
  from azure.identity import ClientSecretCredential
13
- from dependency_injector.wiring import Provide
14
13
  from google.cloud import storage
15
14
 
16
15
  from sourcerer.domain.access_credentials.entities import (
@@ -33,7 +32,6 @@ from sourcerer.infrastructure.access_credentials.registry import (
33
32
  access_credentials_method,
34
33
  )
35
34
  from sourcerer.infrastructure.utils import generate_uuid
36
- from sourcerer.presentation.di_container import DiContainer
37
35
 
38
36
 
39
37
  class CredentialsService:
@@ -44,21 +42,16 @@ class CredentialsService:
44
42
  and deactivating credentials.
45
43
  """
46
44
 
47
- def __init__(
48
- self,
49
- credentials_repo: BaseCredentialsRepository = Provide[
50
- DiContainer.credentials_repository
51
- ],
52
- ):
45
+ def __init__(self, repository: BaseCredentialsRepository):
53
46
  """
54
47
  Initialize the service with a credentials repository.
55
48
 
56
49
  Args:
57
- credentials_repo (BaseCredentialsRepository): Repository for storing credentials
50
+ repository (BaseCredentialsRepository): Repository for storing credentials
58
51
  """
59
- self.credentials_repo = credentials_repo
52
+ self.credentials_repo = repository
60
53
 
61
- def list(self, active_only=False):
54
+ def list(self, active_only=False) -> list[Credentials]:
62
55
  """
63
56
  List credentials.
64
57
 
@@ -119,12 +112,7 @@ class AccessCredentialsService(BaseAccessCredentialsService, ABC):
119
112
  access credential service implementations.
120
113
  """
121
114
 
122
- def __init__(
123
- self,
124
- credentials_repo: BaseCredentialsRepository = Provide[
125
- DiContainer.credentials_repository
126
- ],
127
- ):
115
+ def __init__(self, credentials_repo: BaseCredentialsRepository):
128
116
  """
129
117
  Initialize the service with a credentials repository.
130
118
 
@@ -408,11 +396,9 @@ class GCPCredentialsService(AccessCredentialsService):
408
396
  return storage.Client.from_service_account_info(service_acc_info)
409
397
 
410
398
  except json.JSONDecodeError as e:
411
- raise CredentialsAuthError(f"Invalid credentials format: {str(e)}") from e
399
+ raise CredentialsAuthError(f"Invalid credentials format: {e}") from e
412
400
  except Exception as e:
413
- raise CredentialsAuthError(
414
- f"Failed to authenticate with GCP: {str(e)}"
415
- ) from e
401
+ raise CredentialsAuthError(f"Failed to authenticate with GCP: {e}") from e
416
402
 
417
403
  @classmethod
418
404
  def auth_fields(cls) -> list[AuthField]:
@@ -484,11 +470,9 @@ class AzureClientSecretCredentialsService(AccessCredentialsService):
484
470
  )
485
471
 
486
472
  except json.JSONDecodeError as e:
487
- raise CredentialsAuthError(f"Invalid credentials format: {str(e)}") from e
473
+ raise CredentialsAuthError(f"Invalid credentials format: {e}") from e
488
474
  except Exception as e:
489
- raise CredentialsAuthError(
490
- f"Failed to authenticate with Azure: {str(e)}"
491
- ) from e
475
+ raise CredentialsAuthError(f"Failed to authenticate with Azure: {e}") from e
492
476
 
493
477
  @classmethod
494
478
  def auth_fields(cls) -> list[AuthField]:
@@ -7,8 +7,8 @@ and their relationships.
7
7
 
8
8
  from datetime import datetime
9
9
 
10
- from sqlalchemy import Boolean, Column, DateTime, Integer, String
11
- from sqlalchemy.orm import declarative_base
10
+ from sqlalchemy import Boolean, Column, DateTime, ForeignKey, Integer, String
11
+ from sqlalchemy.orm import backref, declarative_base, relationship
12
12
  from sqlalchemy_utils.types.encrypted.encrypted_type import EncryptedType
13
13
 
14
14
  from sourcerer.settings import ENCRYPTION_KEY
@@ -45,3 +45,34 @@ class Credentials(Base):
45
45
  active = Column(Boolean, default=True)
46
46
  created_at = Column(DateTime, default=datetime.utcnow)
47
47
  updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
48
+
49
+
50
+ class Storage(Base):
51
+ """
52
+ SQLAlchemy model for storing storage information.
53
+
54
+ This model represents the storage table in the database,
55
+ storing information about different storage containers.
56
+
57
+ Attributes:
58
+ id (int): Primary key
59
+ uuid (str): Unique identifier for the storage
60
+ name (str): Name of the storage
61
+ credentials_id (int): Foreign key referencing the credentials table
62
+ created_at (datetime): Timestamp when the storage was created
63
+ """
64
+
65
+ __tablename__ = "storages"
66
+ id = Column(Integer, primary_key=True)
67
+ uuid = Column(String, unique=True, nullable=False)
68
+ name = Column(String, nullable=False)
69
+ credentials_id = Column(
70
+ Integer, ForeignKey("credentials.id", ondelete="CASCADE"), nullable=False
71
+ )
72
+ created_at = Column(DateTime, default=datetime.utcnow)
73
+
74
+ credentials = relationship(
75
+ "Credentials",
76
+ cascade="save-update",
77
+ backref=backref("storages", passive_deletes=True),
78
+ )
File without changes
@@ -0,0 +1,72 @@
1
+ from sourcerer.domain.storage.entities import Storage
2
+ from sourcerer.domain.storage.repositories import BaseStoragesRepository
3
+ from sourcerer.infrastructure.db.models import Storage as DBStorage
4
+
5
+
6
+ class SQLAlchemyStoragesRepository(BaseStoragesRepository):
7
+ def __init__(self, db):
8
+ """
9
+ Initialize the repository with a database session factory.
10
+
11
+ Args:
12
+ db: Database session factory
13
+ """
14
+ self.db = db
15
+
16
+ def create(self, storage: Storage) -> None:
17
+ """
18
+ Create a new storage entity in the database.
19
+
20
+ Args:
21
+ storage (Storage): The storage entity to be created
22
+ """
23
+ entry = DBStorage(
24
+ uuid=storage.uuid,
25
+ name=storage.name,
26
+ credentials_id=storage.credentials_id,
27
+ created_at=storage.date_created,
28
+ )
29
+ with self.db() as session:
30
+ session.add(entry)
31
+ session.commit()
32
+
33
+ def list(self, provider_id: int | None = None) -> list[Storage]:
34
+ """
35
+ List all storages, optionally filtered by provider ID.
36
+
37
+ Args:
38
+ provider_id (int | None): The ID of the provider to filter by
39
+
40
+ Returns:
41
+ list[Storage]: List of storage entities
42
+ """
43
+ with self.db() as session:
44
+ query = session.query(DBStorage)
45
+ if provider_id is not None:
46
+ query = query.filter(DBStorage.credentials_id == provider_id)
47
+ return [
48
+ Storage(
49
+ name=storage.name,
50
+ uuid=storage.uuid,
51
+ credentials_id=storage.credentials_id,
52
+ date_created=storage.created_at,
53
+ credentials_name=storage.credentials and storage.credentials.name,
54
+ )
55
+ for storage in query.all()
56
+ ]
57
+
58
+ def delete(self, uuid: str) -> None:
59
+ """
60
+ Delete a storage entity by its UUID.
61
+
62
+ Args:
63
+ uuid (str): The UUID of the storage entity to be deleted
64
+ """
65
+ with self.db() as session:
66
+ storage = (
67
+ session.query(DBStorage).filter(DBStorage.uuid == uuid).one_or_none()
68
+ )
69
+ if storage is None:
70
+ return
71
+ session.delete(storage)
72
+ session.commit()
@@ -0,0 +1,37 @@
1
+ from sourcerer.domain.storage.entities import Storage
2
+ from sourcerer.domain.storage.repositories import BaseStoragesRepository
3
+
4
+
5
+ class StoragesService:
6
+ def __init__(
7
+ self,
8
+ repository: BaseStoragesRepository,
9
+ ):
10
+ self.repository = repository
11
+
12
+ def create(self, storage: Storage) -> None:
13
+ """
14
+ Create a new storage entity.
15
+
16
+ Args:
17
+ storage (Storage): The storage object to be created
18
+ """
19
+ self.repository.create(storage)
20
+
21
+ def list(self, provider_id: int | None = None) -> list[Storage]:
22
+ """
23
+ List all storage entities.
24
+
25
+ Args:
26
+ provider_id (int|None, optional): If provided, filter storage entities by provider ID
27
+ """
28
+ return self.repository.list(provider_id)
29
+
30
+ def delete(self, uuid: str) -> None:
31
+ """
32
+ Delete a storage entity by its UUID.
33
+
34
+ Args:
35
+ uuid (str): The UUID of the storage entity to be deleted
36
+ """
37
+ self.repository.delete(uuid)
@@ -150,7 +150,7 @@ class GCPStorageProviderService(BaseStorageProviderService):
150
150
 
151
151
  except Exception as ex:
152
152
  raise ListStorageItemsError(
153
- f"Failed to list items in {storage}: {str(ex)}"
153
+ f"Failed to list items in {storage}: {ex}"
154
154
  ) from ex
155
155
 
156
156
  def read_storage_item(self, storage: str, key: str) -> str:
@@ -8,6 +8,7 @@ import mimetypes
8
8
  import secrets
9
9
  import uuid
10
10
  from pathlib import Path
11
+ from typing import ClassVar
11
12
 
12
13
  from sourcerer.settings import TEXT_EXTENSIONS
13
14
 
@@ -83,7 +84,7 @@ class Singleton(type):
83
84
  Metaclass that implements the singleton pattern, ensuring only one instance of a class exists.
84
85
  """
85
86
 
86
- _instances = {}
87
+ _instances: ClassVar[dict["Singleton", type]] = {}
87
88
 
88
89
  def __call__(cls, *args, **kwargs):
89
90
  """
@@ -13,8 +13,11 @@ from dependency_injector import containers, providers
13
13
  from sourcerer.infrastructure.access_credentials.repositories import (
14
14
  SQLAlchemyCredentialsRepository,
15
15
  )
16
+ from sourcerer.infrastructure.access_credentials.services import CredentialsService
16
17
  from sourcerer.infrastructure.db.config import Database
17
18
  from sourcerer.infrastructure.file_system.services import FileSystemService
19
+ from sourcerer.infrastructure.storage.repositories import SQLAlchemyStoragesRepository
20
+ from sourcerer.infrastructure.storage.services import StoragesService
18
21
  from sourcerer.settings import APP_DIR, DB_NAME
19
22
 
20
23
  DB_URL = f"sqlite:////{APP_DIR}/{DB_NAME}"
@@ -43,4 +46,16 @@ class DiContainer(containers.DeclarativeContainer):
43
46
  SQLAlchemyCredentialsRepository, session_factory
44
47
  )
45
48
 
49
+ storages_repository = providers.Factory(
50
+ SQLAlchemyStoragesRepository, session_factory
51
+ )
52
+
53
+ credentials_service = providers.Factory(
54
+ CredentialsService, repository=credentials_repository
55
+ )
56
+ storages_service = providers.Factory(
57
+ StoragesService,
58
+ repository=storages_repository,
59
+ )
60
+
46
61
  file_system_service = providers.Factory(FileSystemService, Path.home())
@@ -1,11 +1,12 @@
1
1
  from collections.abc import Callable
2
2
  from dataclasses import dataclass
3
3
  from pathlib import Path
4
+ from typing import ClassVar
4
5
 
5
6
  from dependency_injector.wiring import Provide
6
7
  from textual import on
7
8
  from textual.app import ComposeResult
8
- from textual.binding import Binding
9
+ from textual.binding import Binding, BindingType
9
10
  from textual.containers import Container, Horizontal
10
11
  from textual.css.query import NoMatches
11
12
  from textual.reactive import reactive
@@ -30,7 +31,7 @@ class FileSystemNavigationModal(ModalScreen):
30
31
  CONTAINER_ID = "file_system_view_container"
31
32
  CSS_PATH = "styles.tcss"
32
33
 
33
- BINDINGS = [
34
+ BINDINGS: ClassVar[list[BindingType]] = [
34
35
  Binding("escape", "app.pop_screen", "Pop screen"),
35
36
  ]
36
37
 
@@ -39,8 +40,8 @@ class FileSystemNavigationModal(ModalScreen):
39
40
  def __init__(
40
41
  self,
41
42
  *args,
42
- file_system_service: FileSystemService = Provide[
43
- DiContainer.file_system_service
43
+ file_system_service: FileSystemService = Provide[ # type: ignore
44
+ DiContainer.file_system_service # type: ignore
44
45
  ],
45
46
  validation_rules: list[FileSystemSelectionValidationRule] | None = None,
46
47
  **kwargs,