syncfm-core 0.2.3__tar.gz → 0.2.5__tar.gz
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.
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/PKG-INFO +2 -4
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/README.md +1 -3
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/pyproject.toml +1 -1
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/pyproject.toml.orig +1 -1
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/models/sync_progress.py +2 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/profiles/models.py +3 -3
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/services/sync_service.py +20 -1
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/LICENSE +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/__init__.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/application.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/cli/__init__.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/cli/app.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/cli/commands/__init__.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/cli/commands/common.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/cli/commands/discard.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/cli/commands/profile.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/cli/commands/resume.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/cli/commands/status.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/cli/commands/sync.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/cli/configuration.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/cli/context.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/cli/dashboard.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/cli/presenters.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/cli/verification.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/exceptions.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/models/__init__.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/models/network_config.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/models/retry_policy.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/models/scrobble.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/models/sync_queue_item.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/models/sync_request.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/models/sync_result.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/models/sync_session.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/models/sync_status.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/models/sync_verification.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/networks/__init__.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/networks/factory.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/networks/gnufm.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/networks/pylast_adapter.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/networks/pylast_mapper.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/profiles/__init__.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/profiles/factory.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/profiles/keyring_store.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/profiles/paths.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/profiles/protocols.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/profiles/resolver.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/profiles/service.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/profiles/toml_store.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/protocols/__init__.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/protocols/network.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/protocols/repositories.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/py.typed +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/repositories/__init__.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/repositories/database.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/repositories/queue_repository.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/repositories/schema.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/repositories/session_repository.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/repositories/snapshot_repository.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/services/__init__.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/services/comparison_service.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/services/metadata_service.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/services/range_resolver.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/services/recovery_service.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/services/retry_service.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/services/snapshot_service.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/services/submission_service.py +0 -0
- {syncfm_core-0.2.3 → syncfm_core-0.2.5}/src/syncfm_core/services/verification_service.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: syncfm-core
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.5
|
|
4
4
|
Summary: Reusable synchronization engine and CLI for Last.fm, Libre.fm and GNU.fm networks.
|
|
5
5
|
Keywords: lastfm,librefm,gnufm,scrobble,music
|
|
6
6
|
Author: Hirad
|
|
@@ -78,9 +78,7 @@ checkout instead of an installed tool.
|
|
|
78
78
|
|
|
79
79
|
### 1. Create network profiles
|
|
80
80
|
|
|
81
|
-
Create one profile for each account.
|
|
82
|
-
letter or number and may contain lowercase letters, numbers, underscores, and
|
|
83
|
-
hyphens.
|
|
81
|
+
Create one profile for each account.
|
|
84
82
|
|
|
85
83
|
```console
|
|
86
84
|
syncfm profile add lastfm-main \
|
|
@@ -51,9 +51,7 @@ checkout instead of an installed tool.
|
|
|
51
51
|
|
|
52
52
|
### 1. Create network profiles
|
|
53
53
|
|
|
54
|
-
Create one profile for each account.
|
|
55
|
-
letter or number and may contain lowercase letters, numbers, underscores, and
|
|
56
|
-
hyphens.
|
|
54
|
+
Create one profile for each account.
|
|
57
55
|
|
|
58
56
|
```console
|
|
59
57
|
syncfm profile add lastfm-main \
|
|
@@ -4,6 +4,7 @@ from collections.abc import Callable
|
|
|
4
4
|
from dataclasses import dataclass
|
|
5
5
|
|
|
6
6
|
from syncfm_core.models.scrobble import Scrobble
|
|
7
|
+
from syncfm_core.models.sync_request import SyncRange
|
|
7
8
|
from syncfm_core.models.sync_session import SyncPhase
|
|
8
9
|
|
|
9
10
|
|
|
@@ -17,6 +18,7 @@ class SyncProgress:
|
|
|
17
18
|
current_scrobble: Scrobble | None = None
|
|
18
19
|
current_scrobble_completed: bool = False
|
|
19
20
|
current_scrobble_failed: bool = False
|
|
21
|
+
sync_range: SyncRange | None = None
|
|
20
22
|
|
|
21
23
|
def __post_init__(self) -> None:
|
|
22
24
|
"""Validate progress values."""
|
|
@@ -7,7 +7,7 @@ from enum import StrEnum
|
|
|
7
7
|
from syncfm_core.exceptions import ConfigurationError
|
|
8
8
|
from syncfm_core.models.network_config import NetworkType
|
|
9
9
|
|
|
10
|
-
_PROFILE_NAME_PATTERN = re.compile(r"^[
|
|
10
|
+
_PROFILE_NAME_PATTERN = re.compile(r"^[A-Za-z0-9][A-Za-z0-9_.-]*$")
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class SecretStorage(StrEnum):
|
|
@@ -85,8 +85,8 @@ class NetworkProfile:
|
|
|
85
85
|
"""Validate profile configuration."""
|
|
86
86
|
if not _PROFILE_NAME_PATTERN.fullmatch(self.name):
|
|
87
87
|
raise ConfigurationError(
|
|
88
|
-
"Profile name must start with a
|
|
89
|
-
"
|
|
88
|
+
"Profile name must start with a letter or number and may only contain "
|
|
89
|
+
"letters, numbers, underscores (_), hyphens (-), dashes (-), and dots (.)."
|
|
90
90
|
)
|
|
91
91
|
if not self.username.strip():
|
|
92
92
|
raise ConfigurationError("A profile username must be provided.")
|
|
@@ -87,6 +87,10 @@ class SyncService:
|
|
|
87
87
|
"""
|
|
88
88
|
self._validate_profile_pair(source_profile, target_profile)
|
|
89
89
|
sync_range = self._range_resolver.resolve(request, target)
|
|
90
|
+
self._report_phase(
|
|
91
|
+
SyncPhase.CREATED,
|
|
92
|
+
sync_range=sync_range,
|
|
93
|
+
)
|
|
90
94
|
session = self._create_session(
|
|
91
95
|
source,
|
|
92
96
|
target,
|
|
@@ -130,6 +134,16 @@ class SyncService:
|
|
|
130
134
|
"""
|
|
131
135
|
session = self.get_session(session_id)
|
|
132
136
|
self._validate_resume_networks(session, source, target)
|
|
137
|
+
|
|
138
|
+
sync_range = SyncRange(
|
|
139
|
+
start_timestamp=session.start_timestamp,
|
|
140
|
+
end_timestamp=session.end_timestamp,
|
|
141
|
+
)
|
|
142
|
+
self._report_phase(
|
|
143
|
+
session.phase,
|
|
144
|
+
sync_range=sync_range,
|
|
145
|
+
)
|
|
146
|
+
|
|
133
147
|
self._record_resume_profiles(
|
|
134
148
|
session,
|
|
135
149
|
source_profile,
|
|
@@ -289,7 +303,11 @@ class SyncService:
|
|
|
289
303
|
self._session_repository.update_phase(session_id, phase)
|
|
290
304
|
self._report_phase(phase)
|
|
291
305
|
|
|
292
|
-
def _report_phase(
|
|
306
|
+
def _report_phase(
|
|
307
|
+
self,
|
|
308
|
+
phase: SyncPhase,
|
|
309
|
+
sync_range: SyncRange | None = None,
|
|
310
|
+
) -> None:
|
|
293
311
|
"""Report a synchronization phase to the frontend."""
|
|
294
312
|
if self._progress_callback is not None:
|
|
295
313
|
self._progress_callback(
|
|
@@ -297,6 +315,7 @@ class SyncService:
|
|
|
297
315
|
phase=phase,
|
|
298
316
|
completed=0,
|
|
299
317
|
total=0,
|
|
318
|
+
sync_range=sync_range,
|
|
300
319
|
)
|
|
301
320
|
)
|
|
302
321
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|