Skip to content

Commit 2859d06

Browse files
committed
Simplifying the architecture and speeding up the operation
Now the configuration file will be read and checked only when it is really necessary.
1 parent 9ce04c5 commit 2859d06

File tree

9 files changed

+62
-56
lines changed

9 files changed

+62
-56
lines changed

fcloud/cli/fcloud.py

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
from dropbox.files import FolderMetadata
1010

1111
from ..models.settings import AuthData
12+
from ..models.drivers import Drivers
13+
from ..models.settings import Config as _Config
1214
from .protocol import FcloudProtocol
1315
from .protocol import SomeStr
1416

@@ -18,6 +20,7 @@
1820
from ..utils.cfl import read_cfl
1921

2022
from .groups.config import Config
23+
from .groups.dropbox import Dropbox
2124
from ..exceptions.cfl_errors import CFLError
2225
from ..exceptions.driver_exceptions import DriverException
2326
from ..drivers.base import CloudProtocol
@@ -32,33 +35,34 @@ class Fcloud(FcloudProtocol):
3235

3336
def __init__(
3437
self,
35-
auth: AuthData,
36-
main_folder: Path,
37-
service: CloudProtocol,
38-
cfl_extension: str,
3938
available_clouds: list[str],
39+
config: Optional[_Config] = None,
4040
without_driver: bool = False,
4141
):
4242
"""
4343
Args:
44-
auth (AuthData): Dataclass that stores cloud authorisation data in it
45-
main_folder (Path): Folder path for saving files on the cloud
46-
service (CloudProtocol): Driver class
47-
cfl_extension (str): Default extension for cfl files
4844
available_clouds (list[str]): List of supported cloud storage
45+
config (_Config, optional): Dataclass containing: service (driver name),
46+
main_folder, cloud authorization data, cfl_extension
4947
without_driver (bool, optional): Use if necessary to ignore the cloud
5048
connection. For example for tests, --help, etc. Defaults to False.
5149
"""
50+
# init subcommands `fcloud config`, `fcloud dropbox` ...
5251
self.config = Config(available_clouds)
52+
self.dropbox = Dropbox()
53+
54+
if without_driver:
55+
return
56+
5357
try:
54-
if not without_driver:
55-
self._driver: CloudProtocol = service(auth, main_folder)
58+
driver = Drivers[config.service].value
59+
self._driver: CloudProtocol = driver(config.auth, config.main_folder)
5660
except DriverException as er:
5761
echo_error((er.title, er.message))
5862

59-
self._auth: AuthData = auth
60-
self._main_folder: Path = main_folder
61-
self._cfl_extension = cfl_extension
63+
self._auth: AuthData = config.auth
64+
self._main_folder: Path = config.main_folder
65+
self._cfl_extension = config.cfl_extension
6266

6367
def _to_path(self, path: SomeStr) -> Path:
6468
return Path(str(path))

fcloud/cli/groups/config.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,13 @@
77

88
from ...exceptions.driver_errors import DriverError
99

10-
from .dropbox import Dropbox
11-
1210

1311
class Config:
1412
"""Use to edit the configuration"""
1513

1614
def __init__(self, available_clouds: list[str], path: Optional[Path] = None):
1715
if path is None:
1816
path = Path(environ.get("FCLOUD_CONFIG_PATH"))
19-
self.dropbox = Dropbox()
2017
self._path = path
2118
self._available = available_clouds
2219

fcloud/cli/groups/dropbox.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from os import environ
44
from textwrap import dedent
55

6+
from ...config import not_empty
67
from ...drivers.dropbox.config_error import DropboxConfigError
78
from ...exceptions.base_errors import FcloudError
89

@@ -22,14 +23,13 @@ def get_token(self):
2223
config = configparser.ConfigParser()
2324
config.read(environ.get("FCLOUD_CONFIG_PATH"))
2425
app_key = get_config_data("DROPBOX", "app_key")
26+
not_empty("app_key", app_key, "DROPBOX")
2527

26-
if not app_key:
27-
echo_error(DropboxConfigError.app_key_empty_error)
2828
token = input(
2929
dedent(
30-
f"""
31-
Get the token at this link: {self._auth_link.format(app_key)}\n
32-
Your token: """
30+
f"""\
31+
Get the token at this link: {self._auth_link.format(app_key)}\n
32+
Your token: """
3333
)
3434
)
3535

fcloud/cli/protocol.py

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
from typing import TypeVar
77
from typing import Optional
88

9-
from ..models.settings import AuthData
10-
from ..drivers.base import CloudProtocol
9+
from ..models.settings import Config as _Config
10+
1111

1212
# Data received from the user that Fire
1313
# can convert to another data type
@@ -24,20 +24,15 @@ class FcloudProtocol(Protocol):
2424

2525
def __init__(
2626
self,
27-
auth: AuthData,
28-
main_folder: Path,
29-
service: CloudProtocol,
30-
cfl_extension: str,
3127
available_clouds: list[str],
32-
wihtout_driver: bool = False,
28+
config: Optional[_Config] = None,
29+
without_driver: bool = False,
3330
):
3431
"""
3532
Args:
36-
auth (AuthData): Dataclass that stores cloud authorisation data in it
37-
main_folder (Path): Folder path for saving files on the cloud
38-
service (CloudProtocol): Driver class
39-
cfl_extension (str): Default extension for cfl files
4033
available_clouds (list[str]): List of supported cloud storage
34+
config (_Config, optional): Dataclass containing: service (driver name),
35+
main_folder, cloud authorization data, cfl_extension
4136
without_driver (bool, optional): Use if necessary to ignore the cloud
4237
connection. For example for tests, --help, etc. Defaults to False.
4338
"""

fcloud/config.py

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,17 @@
1414
from .utils.config import get_config_data
1515

1616

17-
def not_empty(key: str, value: str) -> None | NoReturn:
18-
if value == "" or value == ".":
19-
title, message = ConfigError.field_emty_error
20-
echo_error((title.format(key), message.format(key)))
17+
def not_empty(
18+
key: str, value: str, section: str = "FCLOUD", quit_afer: bool = True
19+
) -> None | NoReturn:
20+
if not (value == "" or value == "."):
21+
return
22+
23+
title, message = ConfigError.field_emty_error
24+
echo_error(
25+
(title.format(key), message.format(section, key)),
26+
need_to_quit=quit_afer,
27+
)
2128

2229

2330
def read_config(available_clouds: list[str], path: Optional[Path] = None) -> Config:
@@ -26,29 +33,32 @@ def read_config(available_clouds: list[str], path: Optional[Path] = None) -> Con
2633

2734
if not path.exists():
2835
echo_error(ConfigError.config_not_found)
29-
3036
config = configparser.ConfigParser()
3137
config.read(path, encoding="utf-8")
3238

39+
# service
3340
cloud = get_config_data(
3441
"FCLOUD", "service", error=ConfigError.service_error, config=config
3542
).lower()
3643
if cloud not in available_clouds:
3744
title, message = DriverError.driver_error
3845
echo_error((title, message.format(cloud)))
3946

40-
cloud_settings = get_config_data(
41-
cloud.upper(), error=ConfigError.section_error, config=config
42-
)
43-
47+
# cfl_extension
4448
cfl_extension = get_config_data("FCLOUD", "cfl_extension", config=config)
4549

50+
# main_folder
4651
main_folder = Path(
4752
get_config_data(
4853
"FCLOUD", "main_folder", error=ConfigError.main_folder_error, config=config
4954
)
5055
).as_posix()
5156

57+
# Section, for cloud storage settings
58+
cloud_settings = get_config_data(
59+
cloud.upper(), error=ConfigError.section_error, config=config
60+
)
61+
5262
auth_model = AuthData[cloud.lower()].value
5363

5464
fields = {
@@ -57,7 +67,8 @@ def read_config(available_clouds: list[str], path: Optional[Path] = None) -> Con
5767
"main_folder": main_folder,
5868
}
5969
for key, value in (fields | dict(cloud_settings)).items():
60-
not_empty(key, value)
70+
section = "FCLOUD" if key in fields else cloud
71+
not_empty(key, value, section.upper())
6172

6273
return Config(
6374
service=cloud,

fcloud/exceptions/config_errors.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class ConfigError(FileError):
3232
field_emty_error = (
3333
"The required '{}' field is missing",
3434
dedent("""\
35-
The field required by fcloud is empty. Use 'fcloud config set-parametr FCLOUD {} <value>' to set the required value.
35+
The field required by fcloud is empty. Use 'fcloud config set-parametr {} {} <value>' to set the required value.
3636
* Substitute the required value in place of <value>.
3737
"""),
3838
)

fcloud/exceptions/driver_errors.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ class DriverError(FcloudError):
66

77
driver_error = (
88
"Driver Error",
9-
"""Can`t find any driver for '{}'""",
9+
"""Can`t find any driver for '{}'. Officially supported drivers: https://fcloud.tech/docs/#cloud-storage-supported""",
1010
)
1111

1212
connection_error = (

fcloud/main.py

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
from fire import Fire
77

88
from .config import read_config
9-
from .models.drivers import Drivers
10-
from .cli.groups.config import Config
119
from .cli.fcloud import Fcloud
1210

1311

@@ -22,18 +20,18 @@ def main():
2220
if len(sys.argv) == 1:
2321
tprint("FCLOUD")
2422
return
25-
elif sys.argv[1] == "config":
26-
Fire(Config(available_clouds, path), sys.argv[2:], "fcloud config")
2723

28-
config = read_config(available_clouds, path)
29-
driver = Drivers[config.service].value
24+
sub_command = sys.argv[1] in ["config", *available_clouds]
25+
without_driver = sub_command or "--help" in sys.argv
26+
if not without_driver:
27+
config = read_config(available_clouds, path)
28+
else:
29+
config = None
30+
3031
cli = Fcloud(
31-
auth=config.auth,
32-
main_folder=config.main_folder,
33-
service=driver,
34-
cfl_extension=config.cfl_extension,
3532
available_clouds=available_clouds,
36-
without_driver="--help" in sys.argv,
33+
config=config,
34+
without_driver=without_driver,
3735
)
3836

3937
Fire(cli, name="fcloud")

fcloud/utils/error.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ def echo_error(
88
error_data: tuple[str, str],
99
need_to_quit: bool = True,
1010
stderr: Optional[TextIO] = sys.stderr,
11+
msg_type="Error",
1112
) -> NoReturn | None:
1213
"""Function to call an error in the console
1314
@@ -19,7 +20,7 @@ def echo_error(
1920
title, message = error_data
2021

2122
print(
22-
f"\r\nError: {title}\r\n{message}",
23+
f"\r{msg_type}: {title}\r\n{message}",
2324
file=stderr,
2425
)
2526

0 commit comments

Comments
 (0)