data-sourcerer 0.1.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 (95) hide show
  1. data_sourcerer-0.1.0.dist-info/METADATA +52 -0
  2. data_sourcerer-0.1.0.dist-info/RECORD +95 -0
  3. data_sourcerer-0.1.0.dist-info/WHEEL +5 -0
  4. data_sourcerer-0.1.0.dist-info/entry_points.txt +2 -0
  5. data_sourcerer-0.1.0.dist-info/licenses/LICENSE +21 -0
  6. data_sourcerer-0.1.0.dist-info/top_level.txt +1 -0
  7. sourcerer/__init__.py +15 -0
  8. sourcerer/domain/__init__.py +13 -0
  9. sourcerer/domain/access_credentials/__init__.py +7 -0
  10. sourcerer/domain/access_credentials/entities.py +53 -0
  11. sourcerer/domain/access_credentials/exceptions.py +17 -0
  12. sourcerer/domain/access_credentials/repositories.py +84 -0
  13. sourcerer/domain/access_credentials/services.py +91 -0
  14. sourcerer/domain/file_system/__init__.py +7 -0
  15. sourcerer/domain/file_system/entities.py +70 -0
  16. sourcerer/domain/file_system/exceptions.py +17 -0
  17. sourcerer/domain/file_system/services.py +64 -0
  18. sourcerer/domain/shared/__init__.py +6 -0
  19. sourcerer/domain/shared/entities.py +18 -0
  20. sourcerer/domain/storage_provider/__init__.py +7 -0
  21. sourcerer/domain/storage_provider/entities.py +86 -0
  22. sourcerer/domain/storage_provider/exceptions.py +17 -0
  23. sourcerer/domain/storage_provider/services.py +130 -0
  24. sourcerer/infrastructure/__init__.py +13 -0
  25. sourcerer/infrastructure/access_credentials/__init__.py +7 -0
  26. sourcerer/infrastructure/access_credentials/exceptions.py +16 -0
  27. sourcerer/infrastructure/access_credentials/registry.py +120 -0
  28. sourcerer/infrastructure/access_credentials/repositories.py +119 -0
  29. sourcerer/infrastructure/access_credentials/services.py +396 -0
  30. sourcerer/infrastructure/db/__init__.py +6 -0
  31. sourcerer/infrastructure/db/config.py +73 -0
  32. sourcerer/infrastructure/db/models.py +47 -0
  33. sourcerer/infrastructure/file_system/__init__.py +7 -0
  34. sourcerer/infrastructure/file_system/exceptions.py +89 -0
  35. sourcerer/infrastructure/file_system/services.py +147 -0
  36. sourcerer/infrastructure/storage_provider/__init__.py +7 -0
  37. sourcerer/infrastructure/storage_provider/exceptions.py +78 -0
  38. sourcerer/infrastructure/storage_provider/registry.py +84 -0
  39. sourcerer/infrastructure/storage_provider/services.py +509 -0
  40. sourcerer/infrastructure/utils.py +106 -0
  41. sourcerer/presentation/__init__.py +12 -0
  42. sourcerer/presentation/app.py +36 -0
  43. sourcerer/presentation/di_container.py +46 -0
  44. sourcerer/presentation/screens/__init__.py +0 -0
  45. sourcerer/presentation/screens/critical_error/__init__.py +0 -0
  46. sourcerer/presentation/screens/critical_error/main.py +78 -0
  47. sourcerer/presentation/screens/critical_error/styles.tcss +41 -0
  48. sourcerer/presentation/screens/file_system_finder/main.py +248 -0
  49. sourcerer/presentation/screens/file_system_finder/styles.tcss +44 -0
  50. sourcerer/presentation/screens/file_system_finder/widgets/__init__.py +0 -0
  51. sourcerer/presentation/screens/file_system_finder/widgets/file_system_navigator.py +810 -0
  52. sourcerer/presentation/screens/main/__init__.py +0 -0
  53. sourcerer/presentation/screens/main/main.py +469 -0
  54. sourcerer/presentation/screens/main/messages/__init__.py +0 -0
  55. sourcerer/presentation/screens/main/messages/delete_request.py +12 -0
  56. sourcerer/presentation/screens/main/messages/download_request.py +12 -0
  57. sourcerer/presentation/screens/main/messages/preview_request.py +10 -0
  58. sourcerer/presentation/screens/main/messages/resizing_rule.py +21 -0
  59. sourcerer/presentation/screens/main/messages/select_storage_item.py +11 -0
  60. sourcerer/presentation/screens/main/messages/uncheck_files_request.py +8 -0
  61. sourcerer/presentation/screens/main/messages/upload_request.py +10 -0
  62. sourcerer/presentation/screens/main/mixins/__init__.py +0 -0
  63. sourcerer/presentation/screens/main/mixins/resize_containers_watcher_mixin.py +144 -0
  64. sourcerer/presentation/screens/main/styles.tcss +32 -0
  65. sourcerer/presentation/screens/main/widgets/__init__.py +0 -0
  66. sourcerer/presentation/screens/main/widgets/gradient.py +45 -0
  67. sourcerer/presentation/screens/main/widgets/resizing_rule.py +67 -0
  68. sourcerer/presentation/screens/main/widgets/storage_content.py +691 -0
  69. sourcerer/presentation/screens/main/widgets/storage_list_sidebar.py +143 -0
  70. sourcerer/presentation/screens/preview_content/__init__.py +0 -0
  71. sourcerer/presentation/screens/preview_content/main.py +59 -0
  72. sourcerer/presentation/screens/preview_content/styles.tcss +26 -0
  73. sourcerer/presentation/screens/provider_creds_list/__init__.py +0 -0
  74. sourcerer/presentation/screens/provider_creds_list/main.py +164 -0
  75. sourcerer/presentation/screens/provider_creds_list/styles.tcss +65 -0
  76. sourcerer/presentation/screens/provider_creds_registration/__init__.py +0 -0
  77. sourcerer/presentation/screens/provider_creds_registration/main.py +264 -0
  78. sourcerer/presentation/screens/provider_creds_registration/styles.tcss +42 -0
  79. sourcerer/presentation/screens/question/__init__.py +0 -0
  80. sourcerer/presentation/screens/question/main.py +31 -0
  81. sourcerer/presentation/screens/question/styles.tcss +33 -0
  82. sourcerer/presentation/screens/shared/__init__.py +0 -0
  83. sourcerer/presentation/screens/shared/containers.py +13 -0
  84. sourcerer/presentation/screens/shared/widgets/__init__.py +0 -0
  85. sourcerer/presentation/screens/shared/widgets/button.py +54 -0
  86. sourcerer/presentation/screens/shared/widgets/labeled_input.py +80 -0
  87. sourcerer/presentation/screens/storage_action_progress/__init__.py +0 -0
  88. sourcerer/presentation/screens/storage_action_progress/main.py +476 -0
  89. sourcerer/presentation/screens/storage_action_progress/styles.tcss +43 -0
  90. sourcerer/presentation/settings.py +31 -0
  91. sourcerer/presentation/themes/__init__.py +0 -0
  92. sourcerer/presentation/themes/github_dark.py +21 -0
  93. sourcerer/presentation/utils.py +69 -0
  94. sourcerer/settings.py +72 -0
  95. sourcerer/utils.py +32 -0
@@ -0,0 +1,147 @@
1
+ """
2
+ File system service implementation.
3
+
4
+ This module provides a concrete implementation of the BaseFileSystemService
5
+ interface for interacting with the local file system.
6
+ """
7
+
8
+ from pathlib import Path
9
+
10
+ from sourcerer.domain.file_system.entities import ListDirOutput
11
+ from sourcerer.domain.file_system.services import BaseFileSystemService
12
+ from sourcerer.infrastructure.file_system.exceptions import (
13
+ ReadFileException,
14
+ ListDirException,
15
+ )
16
+ from sourcerer.infrastructure.utils import custom_sort_key
17
+
18
+
19
+ class FileSystemService(BaseFileSystemService):
20
+ """
21
+ Implementation of the file system service for local file operations.
22
+
23
+ This class provides methods for interacting with the local file system,
24
+ implementing the BaseFileSystemService interface. It handles operations
25
+ like reading, writing, listing, and searching files within a specified
26
+ working directory.
27
+ """
28
+
29
+ ACCESS_DENIED_ERROR = "Access denied: Path outside work directory"
30
+ FILE_NOT_FOUND_ERROR = "File does not exist"
31
+ MOVING_FILE_ERROR = "Moving file error"
32
+
33
+ def __init__(self, work_dir: Path | str):
34
+ """
35
+ Initialize a FileSystemService instance with the specified working directory.
36
+
37
+ Args:
38
+ work_dir (Path or str): The path to the working directory. If a string is provided,
39
+ it will be converted to a Path object.
40
+ """
41
+ self.work_dir = work_dir if isinstance(work_dir, Path) else Path(work_dir)
42
+
43
+ def read(self, path: Path) -> str:
44
+ """
45
+ Reads and processes the contents of a file located at the specified path.
46
+
47
+ This method will attempt to open the file, read its content, and perform
48
+ any necessary processing on the data. It assumes that the file is in
49
+ a format appropriate for the specific application logic and that the
50
+ given path is accessible.
51
+
52
+ Args:
53
+ path (Path): The path to the file to read.
54
+
55
+ Returns:
56
+ str: The processed data extracted from the file.
57
+
58
+ Raises:
59
+ ReadFileException: An error occurred during the file read operation.
60
+ """
61
+
62
+ if not isinstance(path, Path):
63
+ raise ReadFileException("file_path must be a Path object")
64
+ if not path.exists():
65
+ raise ReadFileException(f"File not found: {path}")
66
+ self.validate_path_within_work_dir(path, ReadFileException)
67
+ try:
68
+ return path.read_text()
69
+ except Exception as e:
70
+ raise ReadFileException(f"Error reading file: {e}") from e
71
+
72
+ def list_dir(
73
+ self,
74
+ path: Path,
75
+ relative_paths: bool = False,
76
+ recursively=False,
77
+ max_items: int | None = None,
78
+ ) -> ListDirOutput:
79
+ """
80
+ List all files and directories within the specified directory.
81
+
82
+ Args:
83
+ path (Path): The path to the directory.
84
+ relative_paths (bool): Whether to return relative paths or full paths.
85
+ recursively (bool): Whether iterate recursively over the content.
86
+ max_items (int | None): Maximum number of items to return.
87
+
88
+ Returns:
89
+ ListDirOutput: A data class containing the list of files and directories within the specified path.
90
+ - files (list[Path]): Sorted list of file paths
91
+ - directories (list[Path]): Sorted list of directory paths
92
+
93
+ Raises:
94
+ ListDirException: If the path is invalid, directory doesn't exist, or path is not a directory.
95
+
96
+ """
97
+ if not isinstance(path, Path):
98
+ raise ListDirException("Path must be a Path object")
99
+ if not path.exists():
100
+ raise ListDirException(f"Directory not found: {path}")
101
+ if not path.is_dir():
102
+ raise ListDirException(f"Path is not a directory: {path}")
103
+ try:
104
+ path.relative_to(self.work_dir)
105
+ except ValueError as e:
106
+ raise ListDirException("Access denied: Path outside work directory") from e
107
+ try:
108
+ files = []
109
+ directories = []
110
+
111
+ entries = path.rglob("*") if recursively else path.iterdir()
112
+ items = 0
113
+ for entry in entries:
114
+ if max_items and items > max_items:
115
+ raise ListDirException(
116
+ f"Too many items, max processable dir size: {max_items}"
117
+ )
118
+ items += 1
119
+ target = files if entry.is_file() else directories
120
+ target.append(entry.relative_to(path) if relative_paths else entry)
121
+ return ListDirOutput(
122
+ files=sorted(files, key=custom_sort_key),
123
+ directories=sorted(directories, key=custom_sort_key),
124
+ )
125
+ except PermissionError as e:
126
+ raise ListDirException(f"Access denied: {e}") from e
127
+ except Exception as e:
128
+ raise ListDirException(f"Error listing directory: {e}") from e
129
+
130
+ def validate_path_within_work_dir(self, path: Path, exception_class: type) -> None:
131
+ """
132
+ Validates if a path is within the working directory.
133
+
134
+ This method checks if the given path is contained within the working directory
135
+ to prevent unauthorized access to files outside the designated work area.
136
+
137
+ Args:
138
+ path (Path): The path to validate
139
+ exception_class (type): The exception class to raise if validation fails
140
+
141
+ Raises:
142
+ exception_class: If the path is outside the working directory
143
+ """
144
+ try:
145
+ path.relative_to(self.work_dir)
146
+ except ValueError as e:
147
+ raise exception_class(self.ACCESS_DENIED_ERROR) from e
@@ -0,0 +1,7 @@
1
+ """
2
+ Storage provider infrastructure module.
3
+
4
+ This package provides concrete implementations of the storage provider
5
+ service interfaces defined in the domain layer, along with
6
+ infrastructure-specific exceptions and utilities.
7
+ """
@@ -0,0 +1,78 @@
1
+ """
2
+ Storage provider exception classes.
3
+
4
+ This module defines exception classes for handling errors that occur
5
+ during interactions with cloud storage providers.
6
+ """
7
+
8
+ from sourcerer.domain.storage_provider.exceptions import BaseStorageProviderException
9
+
10
+
11
+ class CredentialsNotFoundException(BaseStorageProviderException):
12
+ """
13
+ Exception raised when credentials are not found for a cloud storage provider.
14
+
15
+ This exception is a specific case of BaseStorageProviderException
16
+ and should be used to indicate that the required credentials for
17
+ accessing a cloud storage service are missing or not configured.
18
+ """
19
+
20
+
21
+ class ListStoragesException(BaseStorageProviderException):
22
+ """
23
+ Exception raised for errors that occur during the listing of cloud storage services.
24
+
25
+ This exception is a specific case of BaseStorageProviderException
26
+ and is used to indicate issues encountered when attempting to retrieve
27
+ a list of available storage services from a cloud provider.
28
+ """
29
+
30
+
31
+ class StoragePermissionException(BaseStorageProviderException):
32
+ """
33
+ Exception raised for permission-related errors in cloud storage operations.
34
+
35
+ This exception is triggered when there is an issue with permissions
36
+ while accessing or modifying resources in a cloud storage service.
37
+ """
38
+
39
+
40
+ class ListStorageItemsException(BaseStorageProviderException):
41
+ """
42
+ Exception raised when an error occurs while listing items in cloud storage.
43
+
44
+ This exception is a specific case of BaseStorageProviderException
45
+ and is used to indicate issues encountered during the retrieval of
46
+ storage items from a cloud storage provider.
47
+ """
48
+
49
+
50
+ class ReadStorageItemsException(BaseStorageProviderException):
51
+ """
52
+ Exception raised for errors encountered while reading items from cloud storage.
53
+
54
+ This exception is a specific case of BaseStorageProviderException
55
+ and should be used to indicate issues that occur during the retrieval
56
+ of data from cloud storage services.
57
+ """
58
+
59
+
60
+ class DeleteStorageItemsException(BaseStorageProviderException):
61
+ """
62
+ Exception raised for errors that occur during the deletion of storage items.
63
+
64
+ This exception is a specific type of BaseStorageProviderException
65
+ and is used to indicate issues encountered when attempting to delete
66
+ items from a cloud storage service.
67
+ """
68
+
69
+
70
+ class UploadStorageItemsException(BaseStorageProviderException):
71
+ """
72
+ Exception raised for errors that occur during the upload of items
73
+ to cloud storage.
74
+
75
+ This exception is a specific case of BaseStorageProviderException
76
+ and is used to signal issues encountered while uploading data to
77
+ cloud storage services.
78
+ """
@@ -0,0 +1,84 @@
1
+ """
2
+ Registry for storage provider service implementations.
3
+
4
+ This module provides a registry system for managing different types of
5
+ storage provider services.
6
+ """
7
+
8
+ import functools
9
+ from typing import Type, Dict
10
+
11
+ from sourcerer.domain.storage_provider.services import BaseStorageProviderService
12
+ from sourcerer.infrastructure.utils import Singleton
13
+
14
+
15
+ class StorageProviderRegistry(metaclass=Singleton):
16
+ """
17
+ Registry for storage provider service implementations.
18
+
19
+ This singleton class maintains a registry of storage provider service
20
+ implementations organized by provider identifier.
21
+ """
22
+
23
+ def __init__(self, *args, **kwargs):
24
+ """Initialize the registry with an empty dictionary."""
25
+ super().__init__(*args, **kwargs)
26
+ self._items_: Dict[str, type] = {}
27
+
28
+ def register(self, storage_provider: str, cls: Type[BaseStorageProviderService]):
29
+ """
30
+ Register a storage provider service implementation.
31
+
32
+ Args:
33
+ storage_provider (str): The provider identifier
34
+ cls (Type[BaseStorageProviderService]): The service class to register
35
+ """
36
+ self._items_[storage_provider] = cls
37
+
38
+ def get(self):
39
+ """
40
+ Get all registered storage provider services.
41
+
42
+ Returns:
43
+ dict: Dictionary of all registered storage provider services
44
+ """
45
+ return self._items_
46
+
47
+ def get_by_provider(self, provider):
48
+ """
49
+ Get a storage provider service by provider identifier.
50
+
51
+ Args:
52
+ provider (str): The provider identifier
53
+
54
+ Returns:
55
+ Type[BaseStorageProviderService]: The storage provider service class
56
+ """
57
+ return self._items_.get(provider)
58
+
59
+
60
+ def storage_provider(provider: str):
61
+ """
62
+ Decorator for registering storage provider service implementations.
63
+
64
+ Args:
65
+ provider (str): The provider identifier
66
+
67
+ Returns:
68
+ callable: Decorator function
69
+ """
70
+
71
+ def wrapper(cls):
72
+ storage_provider_registry.register(provider, cls)
73
+
74
+ @functools.wraps(cls)
75
+ def wrapped(*args, **kwargs):
76
+ return cls(*args, **kwargs)
77
+
78
+ return wrapped
79
+
80
+ return wrapper
81
+
82
+
83
+ # Singleton registry instance
84
+ storage_provider_registry = StorageProviderRegistry()