data-sourcerer 0.2.1__py3-none-any.whl → 0.2.3__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 (39) hide show
  1. {data_sourcerer-0.2.1.dist-info → data_sourcerer-0.2.3.dist-info}/METADATA +4 -1
  2. {data_sourcerer-0.2.1.dist-info → data_sourcerer-0.2.3.dist-info}/RECORD +39 -35
  3. sourcerer/__init__.py +1 -1
  4. sourcerer/domain/access_credentials/entities.py +4 -7
  5. sourcerer/domain/access_credentials/repositories.py +12 -0
  6. sourcerer/domain/access_credentials/services.py +2 -1
  7. sourcerer/domain/file_system/entities.py +5 -7
  8. sourcerer/domain/storage_provider/entities.py +7 -11
  9. sourcerer/infrastructure/access_credentials/registry.py +1 -1
  10. sourcerer/infrastructure/access_credentials/repositories.py +17 -0
  11. sourcerer/infrastructure/access_credentials/services.py +30 -14
  12. sourcerer/infrastructure/db/config.py +1 -1
  13. sourcerer/infrastructure/storage_provider/services/azure.py +5 -3
  14. sourcerer/infrastructure/utils.py +115 -1
  15. sourcerer/presentation/screens/critical_error/main.py +4 -4
  16. sourcerer/presentation/screens/file_system_finder/main.py +7 -3
  17. sourcerer/presentation/screens/file_system_finder/widgets/file_system_navigator.py +1 -1
  18. sourcerer/presentation/screens/main/main.py +37 -6
  19. sourcerer/presentation/screens/main/messages/refresh_storages_list_request.py +8 -0
  20. sourcerer/presentation/screens/main/widgets/gradient.py +3 -3
  21. sourcerer/presentation/screens/main/widgets/resizing_rule.py +3 -1
  22. sourcerer/presentation/screens/main/widgets/storage_content.py +43 -18
  23. sourcerer/presentation/screens/main/widgets/storage_list_sidebar.py +38 -6
  24. sourcerer/presentation/screens/preview_content/main.py +5 -5
  25. sourcerer/presentation/screens/provider_creds_list/main.py +44 -0
  26. sourcerer/presentation/screens/provider_creds_list/messages/__init__.py +0 -0
  27. sourcerer/presentation/screens/provider_creds_list/messages/reload_credentials_request.py +8 -0
  28. sourcerer/presentation/screens/provider_creds_list/styles.tcss +5 -5
  29. sourcerer/presentation/screens/provider_creds_registration/main.py +6 -2
  30. sourcerer/presentation/screens/question/main.py +4 -3
  31. sourcerer/presentation/screens/question/styles.tcss +2 -8
  32. sourcerer/presentation/screens/shared/widgets/button.py +1 -1
  33. sourcerer/presentation/screens/shared/widgets/labeled_input.py +5 -1
  34. sourcerer/presentation/screens/shared/widgets/loader.py +31 -0
  35. sourcerer/presentation/screens/storage_action_progress/main.py +29 -29
  36. sourcerer/utils.py +1 -1
  37. {data_sourcerer-0.2.1.dist-info → data_sourcerer-0.2.3.dist-info}/WHEEL +0 -0
  38. {data_sourcerer-0.2.1.dist-info → data_sourcerer-0.2.3.dist-info}/entry_points.txt +0 -0
  39. {data_sourcerer-0.2.1.dist-info → data_sourcerer-0.2.3.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.1
3
+ Version: 0.2.3
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
@@ -15,6 +15,7 @@ Requires-Dist: cryptography<45.0.0,>=44.0.2
15
15
  Requires-Dist: dependency-injector<5.0.0,>=4.43.0
16
16
  Requires-Dist: google-cloud-storage<4.0.0,>=3.1.0
17
17
  Requires-Dist: humanize<5.0.0,>=4.12.1
18
+ Requires-Dist: msgspec>=0.19.0
18
19
  Requires-Dist: pyopenssl>=22.1.0; sys_platform == 'linux'
19
20
  Requires-Dist: sqlalchemy-utils<1.0.0,>=0.41.2
20
21
  Requires-Dist: sqlalchemy<3.0.0,>=2.0.38
@@ -23,12 +24,14 @@ Provides-Extra: dev
23
24
  Requires-Dist: bandit>=1.8.3; extra == 'dev'
24
25
  Requires-Dist: black>=25.1.0; extra == 'dev'
25
26
  Requires-Dist: coverage>=7.8.0; extra == 'dev'
27
+ Requires-Dist: hatch>=1.14.1; extra == 'dev'
26
28
  Requires-Dist: mkdocs-material>=9.6.12; extra == 'dev'
27
29
  Requires-Dist: pre-commit>=4.2.0; extra == 'dev'
28
30
  Requires-Dist: pylint>=3.3.6; extra == 'dev'
29
31
  Requires-Dist: pyright>=1.1.400; extra == 'dev'
30
32
  Requires-Dist: ruff>=0.11.7; extra == 'dev'
31
33
  Requires-Dist: textual-dev>=1.7.0; extra == 'dev'
34
+ Requires-Dist: ty>=0.0.1a6; extra == 'dev'
32
35
  Description-Content-Type: text/markdown
33
36
 
34
37
  # 🧙‍♂️ Sourcerer
@@ -1,31 +1,31 @@
1
- sourcerer/__init__.py,sha256=cZLeIuWVmh6AIGlima_d3udNCth5hJG-VZOj0AoCShE,585
1
+ sourcerer/__init__.py,sha256=LdB6MZT6D2_yXGq1KBBQRC47gZXfwv61ZvJi4I6cBGk,585
2
2
  sourcerer/settings.py,sha256=dwY2GoaWD1CsAoVtWzaAhP7_e3KUugmBr2E624JSedc,1388
3
- sourcerer/utils.py,sha256=1VzKResV28-BlNlvEQ694WcxOZCK-NBR9uTbopl_slE,872
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=UVjNbxTuXyaywG7RxxTADe67wRB8xlo3GO0bnij1Srs,2030
6
+ sourcerer/domain/access_credentials/entities.py,sha256=u_pZMTncYorVYFNZOnJHn8qnsTWpbFyl7rEOaVrFjxQ,2020
7
7
  sourcerer/domain/access_credentials/exceptions.py,sha256=jo3vhGpIaEsDl68uV8JLDqPvfVZMi7H6MA0qsRL0QXQ,546
8
- sourcerer/domain/access_credentials/repositories.py,sha256=KVD9P_-wYelt2_40Vyh-G6uyrNjtbDyKmD9gO8EiStY,2408
9
- sourcerer/domain/access_credentials/services.py,sha256=MHTcz2OajQbQypbL082gXA7kqs4klCBUdKlguhWpLgQ,2791
8
+ sourcerer/domain/access_credentials/repositories.py,sha256=fTSCBUqSwgZnY0NVxCIwDLjyvylOBk3xSUBJ5Sr8FKA,2720
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
- sourcerer/domain/file_system/entities.py,sha256=5W2_I1lng8J2foSJN-FqNZPR6n151VntiD_vkssAqgQ,2069
11
+ sourcerer/domain/file_system/entities.py,sha256=IeTu5VYxmBQMH7AcKfW1Muk4wUmgZ769eWwNyqeWRpw,2060
12
12
  sourcerer/domain/file_system/exceptions.py,sha256=TairaMaLkSHgbiq3pImkmVZAACoVHy-1vQMl7Ox24cQ,509
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
16
  sourcerer/domain/storage_provider/__init__.py,sha256=P3RUH9LFkWez3ehCczgVbnbp0tZZepPeOQf9spsC8FQ,192
17
- sourcerer/domain/storage_provider/entities.py,sha256=08ueb1KXHfU_nyeY6GnQJ0-JxJEEW-WxKlIMWYY0T4A,1946
17
+ sourcerer/domain/storage_provider/entities.py,sha256=EgHkVFizMzzpzN161DlmWKPV9QhoRo8X7iiLtcN3_Wk,1931
18
18
  sourcerer/domain/storage_provider/exceptions.py,sha256=6xK5r62Bhedx3vV0_i7Eu5ZG5IExxeiuaGHG5sX17i4,508
19
19
  sourcerer/domain/storage_provider/services.py,sha256=Zm6nrKqQJW-9ZaqTp9wQaQuwMeH6hkLJZCkhQ_sTRF0,3997
20
20
  sourcerer/infrastructure/__init__.py,sha256=HQoqA8S9Vx2dr1Eua86wu_YxwXyY6jqa4IfEoZJcXcQ,616
21
- sourcerer/infrastructure/utils.py,sha256=ZN8X2raaz_0mwYxz5gE9TgnuI8haSfYkuO_DadsAKgg,3000
21
+ sourcerer/infrastructure/utils.py,sha256=5ITzUIsraIVGRJOt9C5znDSu9TUYPBS9YTx9OsiOVzM,5135
22
22
  sourcerer/infrastructure/access_credentials/__init__.py,sha256=7BSXnI9n59_PuGxHjOra6PG82R_6JlrU4S1tsJx4WGM,249
23
23
  sourcerer/infrastructure/access_credentials/exceptions.py,sha256=usad48RTA7ub8AfnUs2EzbD-fiUwpmnRGjJluBjd3m4,1101
24
- sourcerer/infrastructure/access_credentials/registry.py,sha256=KNhjocRCb5yQ0BzETPGauBoqUx3xnpBdRfTHFW-QD4A,3432
25
- sourcerer/infrastructure/access_credentials/repositories.py,sha256=og5kAgUlNNGbCQYCMTJ7DE1GotmqLc7owpnXIfOSnng,3839
26
- sourcerer/infrastructure/access_credentials/services.py,sha256=Hbzubm1oN5-sVunzcRb11F31GpWGiiCyFNvMSy2fzEk,15628
24
+ 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
27
27
  sourcerer/infrastructure/db/__init__.py,sha256=sjx2F0aDnxej7-FAjhFJYIQQ5d2apmItkquKbvGYIBc,175
28
- sourcerer/infrastructure/db/config.py,sha256=VUh4S4bEh9GSx3ZDfQTI-ZGdkWNs_KdO9zDjRCGDjPQ,1808
28
+ sourcerer/infrastructure/db/config.py,sha256=c3ubAxBWt-zDUwTe3pAgJ86-rw-LZZAZppuBRo93Xn8,1792
29
29
  sourcerer/infrastructure/db/models.py,sha256=U7Ocdup4KHyCRGvTTxHY2kF1FES3oaU2-hT7vU8pFIw,1743
30
30
  sourcerer/infrastructure/file_system/__init__.py,sha256=Swx8arwXeZ4E40ViDSpQglmUrIlpuEvZY6crcWpGC2g,219
31
31
  sourcerer/infrastructure/file_system/exceptions.py,sha256=obx0NxVuhVzLgL5K2MA5d4rNImlRHJ4Gr-2RrIuKJqk,2944
@@ -34,7 +34,7 @@ sourcerer/infrastructure/storage_provider/__init__.py,sha256=GONjDCsTmd6f_fF3lzx
34
34
  sourcerer/infrastructure/storage_provider/exceptions.py,sha256=acx3IIXD2yWlzLvD2asJBEpKEa6eJW31uKkzzr8MrR4,3336
35
35
  sourcerer/infrastructure/storage_provider/registry.py,sha256=8dbRLOx1jLK_i18uuh_JnKvId9NJBECKg4nG9F_dFH4,2249
36
36
  sourcerer/infrastructure/storage_provider/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
- sourcerer/infrastructure/storage_provider/services/azure.py,sha256=u5yr1xFZwhqSCXcaQMygpOVhuNSabqLBZ_MpB8tmWV4,9785
37
+ sourcerer/infrastructure/storage_provider/services/azure.py,sha256=A7k8Zs6rK5nBsUr5ZNBzkDQWRxpU0qnfWAcrz3eZzAk,9796
38
38
  sourcerer/infrastructure/storage_provider/services/gcp.py,sha256=_iVNf8OESVynGHKt68ZmudQtS6qU-UWZMhFa3v0Sm7Y,9102
39
39
  sourcerer/infrastructure/storage_provider/services/s3.py,sha256=lSpf5SPyTZGl19ChgYBtf3IR6uUWULuAvLBEdD-oarM,9277
40
40
  sourcerer/presentation/__init__.py,sha256=kzOeaTpy9hm61MLl_nybdooRrawFUd1uEX4f3Y-84ZU,472
@@ -44,19 +44,20 @@ sourcerer/presentation/settings.py,sha256=OcNrvwqHwAq3ZqWOfEmZ0PqyvQpAY1fmBpMc9l
44
44
  sourcerer/presentation/utils.py,sha256=aM5eCNEmIzCyfg8Egb2rFfOlXQ5pFTXzbRVwQGSOdjY,2638
45
45
  sourcerer/presentation/screens/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
46
  sourcerer/presentation/screens/critical_error/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
47
- sourcerer/presentation/screens/critical_error/main.py,sha256=DEYFNBqm-KE-TB09aJHMGBA0SVeFaOy4Zd9q3rcBpb4,2224
47
+ sourcerer/presentation/screens/critical_error/main.py,sha256=10Ip1InBzktwwM2ijKXBOkhvBXGorw1X8EGxdh75WZE,2208
48
48
  sourcerer/presentation/screens/critical_error/styles.tcss,sha256=mURvbf0_npkRtzVBs2bVBybbyNK9cO_6Ar2Muk1Mpv8,604
49
- sourcerer/presentation/screens/file_system_finder/main.py,sha256=DnzAz--JcfRxeBzNLk0qA9EuTkSK26IbIkMErV2t1nE,10121
49
+ sourcerer/presentation/screens/file_system_finder/main.py,sha256=PSOxD_UfAMxSIdDFVJZeh0tcYGh2qZP2RY9rBUMU12A,10241
50
50
  sourcerer/presentation/screens/file_system_finder/styles.tcss,sha256=fZkdwXFsDkjXkaIskLxoQ_YHsLWKjgrn6hYseugg_68,718
51
51
  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=Le_76mA12dN8UhWddJexnb3Qqm-f4kqQdAaiyvIfxYQ,30878
52
+ sourcerer/presentation/screens/file_system_finder/widgets/file_system_navigator.py,sha256=EHPsVWyq0Lmkv1Jt3m4OgpJvI1nsye2Os1XA0XAZz8M,30884
53
53
  sourcerer/presentation/screens/main/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
54
- sourcerer/presentation/screens/main/main.py,sha256=OOczA6lem6JSdJCq-Nd2TtXmFA1R-xeVdqbM7I5QHTM,20440
54
+ sourcerer/presentation/screens/main/main.py,sha256=FhG0_uev8W5bfrP-F5pBVst_ZnSyim6aM7G4nL9yYfQ,21354
55
55
  sourcerer/presentation/screens/main/styles.tcss,sha256=Ruv2vBKzM8njH7OS2TCpZqCmRVEp7XQLeBN4XhVB5AU,381
56
56
  sourcerer/presentation/screens/main/messages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
57
57
  sourcerer/presentation/screens/main/messages/delete_request.py,sha256=puaU1UtbDErfYi8ViPEawhSbycnUpwdE81zZfzlslNE,203
58
58
  sourcerer/presentation/screens/main/messages/download_request.py,sha256=3urSTrvNbod1FrXfu-C1UDZqOu5D0OC-NJsKJhhprXE,205
59
59
  sourcerer/presentation/screens/main/messages/preview_request.py,sha256=px8N3E2VEexKmpZESb9nYDQvhXUThPxM0dU41B533tM,184
60
+ sourcerer/presentation/screens/main/messages/refresh_storages_list_request.py,sha256=NxOBcUf5oKF1cMCcHZny8qG2Jv6zTdPmYeFV9qORHh8,136
60
61
  sourcerer/presentation/screens/main/messages/resizing_rule.py,sha256=ws7lzS08h6qqeihF66XV5FsX26YkjQOje_4vgCw2mqI,332
61
62
  sourcerer/presentation/screens/main/messages/select_storage_item.py,sha256=xBu0UH5A6iyZPJECt_f_vfWVaCmE0bJo5hq2FJXMHQo,237
62
63
  sourcerer/presentation/screens/main/messages/uncheck_files_request.py,sha256=CMpYVwos1JHknqDcqru1hG8RJy5f1Lwjsxtrse1ZDGw,140
@@ -64,34 +65,37 @@ sourcerer/presentation/screens/main/messages/upload_request.py,sha256=KXPTliqdvR
64
65
  sourcerer/presentation/screens/main/mixins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
65
66
  sourcerer/presentation/screens/main/mixins/resize_containers_watcher_mixin.py,sha256=wZnTbJHjHDJbKFkfbyT0CR3GWlVupyiSotgnumBiEoI,5647
66
67
  sourcerer/presentation/screens/main/widgets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
67
- sourcerer/presentation/screens/main/widgets/gradient.py,sha256=LThG7XSIUhJeXnONgArWuabosv9UiGHoHd95jKrT6rk,1226
68
- sourcerer/presentation/screens/main/widgets/resizing_rule.py,sha256=-SIqnXtQNM80t73nsyUx02bz8I6dAHJiSxWL0Aki2Bo,2040
69
- sourcerer/presentation/screens/main/widgets/storage_content.py,sha256=fXHBfrZ5db7rzF4MfDwUDO8cQSeyVa73smJFw-qzaj0,21863
70
- sourcerer/presentation/screens/main/widgets/storage_list_sidebar.py,sha256=CFzNpnhEJ0TZHOVxaVGl2AsvYcRF3VvNhKAbD0KGuCg,4670
68
+ sourcerer/presentation/screens/main/widgets/gradient.py,sha256=Ow6oaX0tsFNbUKRh_e9ITph20_tKoQgqzM7rujwKmxs,1263
69
+ 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
71
72
  sourcerer/presentation/screens/preview_content/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
72
- sourcerer/presentation/screens/preview_content/main.py,sha256=hvJpiHZD3fuT6qPauSgPIMj7uaUUVSUKp1KnmaSQr5E,2546
73
+ sourcerer/presentation/screens/preview_content/main.py,sha256=c7WEM3dCRHh0gnB2AXgl_upi8lfNwRfH1425736mya8,2498
73
74
  sourcerer/presentation/screens/preview_content/styles.tcss,sha256=Qk0nZtUfp-mCFaUXtkjwimAnshXnhEgh719aT4_lDPQ,374
74
75
  sourcerer/presentation/screens/provider_creds_list/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
75
- sourcerer/presentation/screens/provider_creds_list/main.py,sha256=gs35uG4mC0vWD_-TcQB3Wr6XnLyDFvtkPItj-qq_B9E,6203
76
- sourcerer/presentation/screens/provider_creds_list/styles.tcss,sha256=PmO_JKNR7NhYhT9CXLSZqh_q3rxFJ1HkSzVxOjJs_P8,904
76
+ sourcerer/presentation/screens/provider_creds_list/main.py,sha256=s3t9UaaOVHBiSQ5L-tduzxaJWdDgWqbJtIol1IlAv5s,7870
77
+ sourcerer/presentation/screens/provider_creds_list/styles.tcss,sha256=_BXTWQw_LjPjbAG-V4YxxOeHn4GFShVjc4K1by-uVR0,956
78
+ sourcerer/presentation/screens/provider_creds_list/messages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
79
+ sourcerer/presentation/screens/provider_creds_list/messages/reload_credentials_request.py,sha256=zkyLFkXZHQMj5OsDU_IiInUnezHNWyvYn8yZLoJmJn0,134
77
80
  sourcerer/presentation/screens/provider_creds_registration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
78
- sourcerer/presentation/screens/provider_creds_registration/main.py,sha256=TUPw2E54-ALfEk2YSU7DpzuyJ24oDj3jHEfQQsH6n_g,11079
81
+ sourcerer/presentation/screens/provider_creds_registration/main.py,sha256=fBAi3xnH-QoRwq6dttuS_lqBMCe66RZND2M228IhngI,11182
79
82
  sourcerer/presentation/screens/provider_creds_registration/styles.tcss,sha256=gd1SNeRoHTYwNzdGxK-2aDqNPeY5b2wFWajtoNn5--Y,612
80
83
  sourcerer/presentation/screens/question/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
81
- sourcerer/presentation/screens/question/main.py,sha256=XftOcA6gDpK1Tc9WqE_jK5q0CLNvZuVuW88hp4X_kZM,901
82
- sourcerer/presentation/screens/question/styles.tcss,sha256=fJl0Votob2sfRQP4s8Oqd5P2OQ0WiGMdoLpTsMgISfw,418
84
+ sourcerer/presentation/screens/question/main.py,sha256=7ogFbKrqP9deBYfgq7Bs6NkiSdy3whEu51mW_--TCIY,980
85
+ sourcerer/presentation/screens/question/styles.tcss,sha256=NT8Ty4opqYLG1-sal3m1us4M4LNhtTcQywlU-Al-v7o,396
83
86
  sourcerer/presentation/screens/shared/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
84
87
  sourcerer/presentation/screens/shared/containers.py,sha256=9Tkl5SbPNgycZlfp5Pq50pHnJqbP0EckmxayXPPuhFs,378
85
88
  sourcerer/presentation/screens/shared/widgets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
86
- sourcerer/presentation/screens/shared/widgets/button.py,sha256=MpzxKZ7KGe5g4aNkNnFN6novnXv1au3WdgsVN-ITOns,1558
87
- sourcerer/presentation/screens/shared/widgets/labeled_input.py,sha256=H_v62jpcZD0iuaKlTtKvOy_0GKCugibR7n6weGK-Upk,2750
89
+ sourcerer/presentation/screens/shared/widgets/button.py,sha256=aGsJTwK04nTXarafkl8TgdeB9EGfRwn4gffoPvFFwiU,1580
90
+ 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
88
92
  sourcerer/presentation/screens/storage_action_progress/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
89
- sourcerer/presentation/screens/storage_action_progress/main.py,sha256=F33lL4NEqrw8B_xORSoQWVdUCldFTPPdqUsn2_YgEKM,17973
93
+ sourcerer/presentation/screens/storage_action_progress/main.py,sha256=4SnbTYFRSKAoBVqFzVD24GJgdeddjWGi1XXSbF5u-7Y,17944
90
94
  sourcerer/presentation/screens/storage_action_progress/styles.tcss,sha256=ffvDxRWhckE5tjEG4jwlhQNqeQsYpdF71104StWCGWU,818
91
95
  sourcerer/presentation/themes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
92
96
  sourcerer/presentation/themes/github_dark.py,sha256=9E1mEOr701nU-ZDSKBccMl3GYchroCEsxEVelm5oI-E,497
93
- data_sourcerer-0.2.1.dist-info/METADATA,sha256=1xiV9NxnzOG-ZWqB02EvzAos7nmfM21bJMuX8SYVAXQ,2416
94
- data_sourcerer-0.2.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
95
- data_sourcerer-0.2.1.dist-info/entry_points.txt,sha256=CyD02GehPW6QuhR5oDY5tLLRHQ9qbPXe0v3aT1pK3N8,62
96
- data_sourcerer-0.2.1.dist-info/licenses/LICENSE,sha256=HjZ7RAG3i6izxvitGfY4feHfvW5F8DPj5eF0YBSf2rI,1073
97
- data_sourcerer-0.2.1.dist-info/RECORD,,
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,,
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.1"
15
+ __version__ = "0.2.3"
@@ -5,15 +5,14 @@ This module defines data classes representing access credentials
5
5
  used for authentication with various cloud providers.
6
6
  """
7
7
 
8
- from dataclasses import dataclass
9
8
  from datetime import datetime
10
9
 
11
10
  import boto3
12
11
  from azure.identity import ClientSecretCredential
12
+ from msgspec._core import Struct
13
13
 
14
14
 
15
- @dataclass
16
- class Credentials:
15
+ class Credentials(Struct):
17
16
  """
18
17
  Represents access credentials for a provider.
19
18
 
@@ -38,8 +37,7 @@ class Credentials:
38
37
  updated_at: datetime | None = None
39
38
 
40
39
 
41
- @dataclass
42
- class Boto3Credentials:
40
+ class Boto3Credentials(Struct):
43
41
  """
44
42
  Represents AWS credentials using boto3 session.
45
43
 
@@ -54,8 +52,7 @@ class Boto3Credentials:
54
52
  signature_version: str | None = None
55
53
 
56
54
 
57
- @dataclass
58
- class AzureCredentials:
55
+ class AzureCredentials(Struct):
59
56
  """
60
57
  Represents Azure credentials.
61
58
 
@@ -28,6 +28,18 @@ class BaseCredentialsRepository(metaclass=ABCMeta):
28
28
  """
29
29
  raise NotImplementedError
30
30
 
31
+ @abstractmethod
32
+ def delete(self, uuid):
33
+ """Delete credentials by UUID.
34
+
35
+ Args:
36
+ uuid: Unique identifier for the credentials to delete
37
+
38
+ Raises:
39
+ NotImplementedError: Method must be implemented by concrete classes
40
+ """
41
+ raise NotImplementedError
42
+
31
43
  @abstractmethod
32
44
  def get(self, uuid):
33
45
  """Retrieve credentials by UUID.
@@ -8,6 +8,7 @@ authentication methods.
8
8
 
9
9
  from abc import abstractmethod
10
10
  from dataclasses import dataclass
11
+ from typing import Any
11
12
 
12
13
  from sourcerer.domain.access_credentials.repositories import BaseCredentialsRepository
13
14
 
@@ -71,7 +72,7 @@ class BaseAccessCredentialsService:
71
72
  """
72
73
 
73
74
  @abstractmethod
74
- def authenticate(self, credentials: str):
75
+ def authenticate(self, credentials: str) -> Any:
75
76
  """
76
77
  Authenticate using stored credentials.
77
78
 
@@ -5,12 +5,12 @@ This module defines data classes representing file system entities and
5
5
  operation results used throughout the application.
6
6
  """
7
7
 
8
- from dataclasses import dataclass
9
8
  from pathlib import Path
10
9
 
10
+ from msgspec._core import Struct
11
11
 
12
- @dataclass
13
- class SearchResult:
12
+
13
+ class SearchResult(Struct):
14
14
  """
15
15
  Represents the result of a search operation.
16
16
 
@@ -30,8 +30,7 @@ class SearchResult:
30
30
  line: int
31
31
 
32
32
 
33
- @dataclass
34
- class SearchResultOutput:
33
+ class SearchResultOutput(Struct):
35
34
  """
36
35
  Represents the output of a search operation.
37
36
 
@@ -51,8 +50,7 @@ class SearchResultOutput:
51
50
  total: int
52
51
 
53
52
 
54
- @dataclass
55
- class ListDirOutput:
53
+ class ListDirOutput(Struct):
56
54
  """
57
55
  Represents the output of a list directory operation.
58
56
 
@@ -5,12 +5,12 @@ This module defines data classes representing cloud storage entities
5
5
  such as storage containers, files, folders, and permissions.
6
6
  """
7
7
 
8
- from dataclasses import dataclass
9
8
  from datetime import datetime
10
9
 
10
+ from msgspec._core import Struct
11
11
 
12
- @dataclass
13
- class Storage:
12
+
13
+ class Storage(Struct):
14
14
  """
15
15
  Represents a cloud storage container (bucket/container).
16
16
 
@@ -25,8 +25,7 @@ class Storage:
25
25
  date_created: datetime
26
26
 
27
27
 
28
- @dataclass
29
- class StoragePermissions:
28
+ class StoragePermissions(Struct):
30
29
  """
31
30
  Represents permissions for a user on a storage resource.
32
31
 
@@ -39,8 +38,7 @@ class StoragePermissions:
39
38
  permissions: list[str]
40
39
 
41
40
 
42
- @dataclass
43
- class Folder:
41
+ class Folder(Struct):
44
42
  """
45
43
  Represents a folder/directory within a storage container.
46
44
 
@@ -51,8 +49,7 @@ class Folder:
51
49
  key: str
52
50
 
53
51
 
54
- @dataclass
55
- class File:
52
+ class File(Struct):
56
53
  """
57
54
  Represents a file within a storage container.
58
55
 
@@ -71,8 +68,7 @@ class File:
71
68
  date_modified: datetime | None = None
72
69
 
73
70
 
74
- @dataclass
75
- class StorageContent:
71
+ class StorageContent(Struct):
76
72
  """
77
73
  Represents the contents of a storage location, including files and folders.
78
74
 
@@ -37,7 +37,7 @@ class AccessCredentialsRegistry(metaclass=Singleton):
37
37
  def __init__(self, *args, **kwargs):
38
38
  """Initialize the registry with an empty dictionary."""
39
39
  super().__init__(*args, **kwargs)
40
- self._items_: dict[str, dict[str, type]] = {} # type: ignore
40
+ self._items_: dict[str, dict[str, type]] = {}
41
41
 
42
42
  def register(
43
43
  self,
@@ -46,6 +46,23 @@ class SQLAlchemyCredentialsRepository(BaseCredentialsRepository):
46
46
  session.add(credentials)
47
47
  session.commit()
48
48
 
49
+ def delete(self, uuid: str):
50
+ """
51
+ Delete credentials from the database by UUID.
52
+
53
+ Args:
54
+ uuid (str): Unique identifier for the credentials to delete
55
+ """
56
+ with self.db() as session:
57
+ credentials = (
58
+ session.query(DBCredentials).filter(DBCredentials.uuid == uuid).first()
59
+ )
60
+ if credentials is None:
61
+ # No matching credentials found; return early
62
+ return
63
+ session.delete(credentials)
64
+ session.commit()
65
+
49
66
  def get(self, uuid: str):
50
67
  """
51
68
  Retrieve credentials by UUID.
@@ -71,6 +71,15 @@ class CredentialsService:
71
71
  """
72
72
  return self.credentials_repo.list(active_only)
73
73
 
74
+ def delete(self, uuid):
75
+ """
76
+ Delete credentials by UUID.
77
+
78
+ Args:
79
+ uuid (str): Unique identifier for the credentials to delete
80
+ """
81
+ return self.credentials_repo.delete(uuid)
82
+
74
83
  def get(self, uuid):
75
84
  """
76
85
  Get credentials by UUID.
@@ -190,7 +199,7 @@ class S3AccessKeySecretKeyPair(S3AccessCredentialsService):
190
199
  """
191
200
  return self.credentials_repo.get(uuid)
192
201
 
193
- def authenticate(self, credentials: str): # type: ignore
202
+ def authenticate(self, credentials: str):
194
203
  """
195
204
  Authenticate using stored credentials.
196
205
 
@@ -201,22 +210,27 @@ class S3AccessKeySecretKeyPair(S3AccessCredentialsService):
201
210
  boto3.Session: Authenticated boto3 session
202
211
  """
203
212
  try:
204
- credentials: dict = json.loads(credentials)
213
+ credentials_dict: dict = json.loads(credentials)
214
+
215
+ access_key_id = credentials_dict.get("aws_access_key_id")
216
+ secret_access_key = credentials_dict.get("aws_secret_access_key")
217
+ endpoint_url = credentials_dict.get("endpoint_url")
218
+ signature_version = credentials_dict.get("signature_version")
205
219
 
206
220
  session_args = {
207
- "aws_access_key_id": credentials.get("aws_access_key_id"),
208
- "aws_secret_access_key": credentials.get("aws_secret_access_key"),
221
+ "aws_access_key_id": access_key_id,
222
+ "aws_secret_access_key": secret_access_key,
209
223
  }
210
224
 
211
- if region := credentials.get("region"):
225
+ if region := credentials_dict.get("region"):
212
226
  session_args["region_name"] = region
213
227
 
214
228
  session = boto3.Session(**session_args)
215
229
 
216
230
  return Boto3Credentials(
217
231
  session=session,
218
- endpoint_url=credentials.get("endpoint_url", None),
219
- signature_version=credentials.get("signature_version", None),
232
+ endpoint_url=endpoint_url,
233
+ signature_version=signature_version,
220
234
  )
221
235
  except Exception as e:
222
236
  raise CredentialsAuthError("Failed to authenticate") from e
@@ -277,7 +291,7 @@ class S3ProfileName(S3AccessCredentialsService):
277
291
  """
278
292
  return self.credentials_repo.get(uuid)
279
293
 
280
- def authenticate(self, credentials: str): # type: ignore
294
+ def authenticate(self, credentials: str):
281
295
  """
282
296
  Authenticate using stored profile name.
283
297
 
@@ -288,11 +302,14 @@ class S3ProfileName(S3AccessCredentialsService):
288
302
  boto3.Session: Authenticated boto3 session
289
303
  """
290
304
  try:
291
- credentials: dict = json.loads(credentials)
292
- session = boto3.Session(profile_name=credentials.get("profile_name"))
305
+ credentials_dict: dict = json.loads(credentials)
306
+ profile_name = credentials_dict.get("profile_name")
307
+ endpoint_url = credentials_dict.get("endpoint_url")
308
+
309
+ session = boto3.Session(profile_name=profile_name)
293
310
  return Boto3Credentials(
294
311
  session=session,
295
- endpoint_url=credentials.get("endpoint_url"),
312
+ endpoint_url=endpoint_url,
296
313
  )
297
314
  except Exception as e:
298
315
  raise CredentialsAuthError("Failed to authenticate") from e
@@ -353,7 +370,7 @@ class GCPCredentialsService(AccessCredentialsService):
353
370
  """
354
371
  return self.credentials_repo.get(uuid)
355
372
 
356
- def authenticate(self, credentials: str): # type: ignore
373
+ def authenticate(self, credentials: str):
357
374
  """
358
375
  Authenticate with Google Cloud Platform using service account credentials.
359
376
 
@@ -414,7 +431,6 @@ class GCPCredentialsService(AccessCredentialsService):
414
431
  AccessCredentialsMethod(StorageProvider.AzureStorage, "Client Secret Credentials")
415
432
  )
416
433
  class AzureClientSecretCredentialsService(AccessCredentialsService):
417
-
418
434
  def store(self, name, credentials: dict):
419
435
  """
420
436
  Store Azure client_id and secret_key_pair credentials.
@@ -446,7 +462,7 @@ class AzureClientSecretCredentialsService(AccessCredentialsService):
446
462
  """
447
463
  return self.credentials_repo.get(uuid)
448
464
 
449
- def authenticate(self, credentials: str): # type: ignore
465
+ def authenticate(self, credentials: str):
450
466
  try:
451
467
  # Parse the outer JSON structure
452
468
  parsed_credentials = json.loads(credentials)
@@ -30,7 +30,7 @@ class Database:
30
30
  """
31
31
  self.db_url = db_url
32
32
  self.engine = sqlalchemy.create_engine(db_url)
33
- self.scoped_session = scoped_session(sessionmaker(bind=self.engine)) # type: ignore
33
+ self.scoped_session = scoped_session(sessionmaker(bind=self.engine))
34
34
 
35
35
  def prepare_db(self):
36
36
  """
@@ -91,7 +91,7 @@ class AzureStorageProviderService(BaseStorageProviderService):
91
91
  try:
92
92
  accounts_client = self.get_accounts_client()
93
93
  return [
94
- Storage(StorageProvider.AzureStorage, i.name, i.creation_time) # type: ignore
94
+ Storage(StorageProvider.AzureStorage, i.name, i.creation_time)
95
95
  for i in accounts_client.storage_accounts.list()
96
96
  ]
97
97
  except Exception as ex:
@@ -198,9 +198,11 @@ class AzureStorageProviderService(BaseStorageProviderService):
198
198
  """
199
199
  try:
200
200
  if not storage_path:
201
- raise AzureMissingContainerError("Container is required for Azure storage")
201
+ raise AzureMissingContainerError(
202
+ "Container is required for Azure storage"
203
+ )
202
204
 
203
- containers_client = self.get_containers_client(storage)
205
+ containers_client = self.get_containers_client(storage)
204
206
 
205
207
  storage_path_parts = storage_path.split("/", 1)
206
208
 
@@ -4,8 +4,8 @@ Utility functions for the Sourcerer application.
4
4
  This module provides various utility functions used throughout the application,
5
5
  including UUID generation, MIME type detection, and file type checking.
6
6
  """
7
-
8
7
  import mimetypes
8
+ import secrets
9
9
  import uuid
10
10
  from pathlib import Path
11
11
 
@@ -102,3 +102,117 @@ class Singleton(type):
102
102
  if cls not in cls._instances:
103
103
  cls._instances[cls] = super().__call__(*args, **kwargs)
104
104
  return cls._instances[cls]
105
+
106
+
107
+ def generate_unique_name() -> str:
108
+ """
109
+ Generate a unique name for a file or directory.
110
+
111
+ Returns:
112
+ str: A unique name
113
+ """
114
+ adjectives = [
115
+ "goofy",
116
+ "quirky",
117
+ "snappy",
118
+ "witty",
119
+ "bubbly",
120
+ "zany",
121
+ "wonky",
122
+ "clumsy",
123
+ "cheeky",
124
+ "sassy",
125
+ "cryptic",
126
+ "shadowy",
127
+ "enigmatic",
128
+ "arcane",
129
+ "veiled",
130
+ "hidden",
131
+ "phantasmal",
132
+ "whispering",
133
+ "hollow",
134
+ "ghostly",
135
+ "mighty",
136
+ "fierce",
137
+ "brave",
138
+ "bold",
139
+ "ironclad",
140
+ "unyielding",
141
+ "stormforged",
142
+ "grim",
143
+ "feral",
144
+ "dauntless",
145
+ "stellar",
146
+ "vivid",
147
+ "luminous",
148
+ "glimmering",
149
+ "blazing",
150
+ "radiant",
151
+ "shimmering",
152
+ "snazzy",
153
+ "flashy",
154
+ "dazzling",
155
+ ]
156
+
157
+ names = [
158
+ "gandalf",
159
+ "merlin",
160
+ "morgana",
161
+ "radagast",
162
+ "saruman",
163
+ "galadriel",
164
+ "smaug",
165
+ "elminster",
166
+ "ambrosius",
167
+ "balrog",
168
+ "sauron",
169
+ "rivendell",
170
+ "azkaban",
171
+ "gryffindor",
172
+ "slytherin",
173
+ "rowena",
174
+ "helga",
175
+ "alatar",
176
+ "pellinore",
177
+ "nimue",
178
+ "glorfindel",
179
+ "melian",
180
+ "feanor",
181
+ "titania",
182
+ "oberon",
183
+ "cerberus",
184
+ "phoenix",
185
+ "gryphon",
186
+ "hydra",
187
+ "basilisk",
188
+ "leviathan",
189
+ "wraith",
190
+ "djinn",
191
+ "fae",
192
+ "nymph",
193
+ "dryad",
194
+ "selkie",
195
+ "witchking",
196
+ "morwen",
197
+ "telvanni",
198
+ "daedric",
199
+ "argonian",
200
+ "auriel",
201
+ "azura",
202
+ "boethiah",
203
+ "nocturnal",
204
+ "zarthos",
205
+ "shadar",
206
+ "kobold",
207
+ "lich",
208
+ "oracle",
209
+ "summoner",
210
+ "geomancer",
211
+ "runeweaver",
212
+ "voidcaller",
213
+ "planewalker",
214
+ ]
215
+
216
+ adjective = secrets.choice(adjectives)
217
+ name = secrets.choice(names)
218
+ return f"{adjective}_{name}"