syncfm-core 0.2.0__tar.gz → 0.2.1__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.0 → syncfm_core-0.2.1}/PKG-INFO +1 -1
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/pyproject.toml +1 -1
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/pyproject.toml.orig +1 -1
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/networks/pylast_adapter.py +41 -17
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/LICENSE +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/README.md +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/__init__.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/application.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/cli/__init__.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/cli/app.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/cli/commands/__init__.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/cli/commands/common.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/cli/commands/discard.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/cli/commands/profile.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/cli/commands/resume.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/cli/commands/status.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/cli/commands/sync.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/cli/configuration.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/cli/context.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/cli/dashboard.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/cli/presenters.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/cli/verification.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/exceptions.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/models/__init__.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/models/network_config.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/models/retry_policy.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/models/scrobble.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/models/sync_progress.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/models/sync_queue_item.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/models/sync_request.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/models/sync_result.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/models/sync_session.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/models/sync_status.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/models/sync_verification.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/networks/__init__.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/networks/factory.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/networks/gnufm.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/networks/pylast_mapper.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/profiles/__init__.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/profiles/factory.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/profiles/keyring_store.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/profiles/models.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/profiles/paths.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/profiles/protocols.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/profiles/resolver.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/profiles/service.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/profiles/toml_store.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/protocols/__init__.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/protocols/network.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/protocols/repositories.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/py.typed +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/repositories/__init__.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/repositories/database.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/repositories/queue_repository.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/repositories/schema.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/repositories/session_repository.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/repositories/snapshot_repository.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/services/__init__.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/services/comparison_service.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/services/metadata_service.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/services/range_resolver.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/services/recovery_service.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/services/retry_service.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/services/snapshot_service.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/services/submission_service.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/services/sync_service.py +0 -0
- {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/services/verification_service.py +0 -0
|
@@ -133,34 +133,58 @@ class PyLastNetworkAdapter:
|
|
|
133
133
|
end_timestamp: int | None = None,
|
|
134
134
|
limit: int | None = None,
|
|
135
135
|
) -> list[Scrobble]:
|
|
136
|
-
"""Return scrobbles
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
start_timestamp
|
|
140
|
-
|
|
141
|
-
|
|
136
|
+
"""Return scrobbles within the inclusive timestamp range."""
|
|
137
|
+
api_start_timestamp = (
|
|
138
|
+
start_timestamp - 1
|
|
139
|
+
if start_timestamp is not None and start_timestamp > 0
|
|
140
|
+
else None
|
|
141
|
+
)
|
|
142
|
+
api_end_timestamp = (
|
|
143
|
+
end_timestamp + 1
|
|
144
|
+
if end_timestamp is not None
|
|
145
|
+
else None
|
|
146
|
+
)
|
|
142
147
|
|
|
143
|
-
|
|
144
|
-
|
|
148
|
+
api_limit = (
|
|
149
|
+
None
|
|
150
|
+
if limit is not None
|
|
151
|
+
and (start_timestamp is not None or end_timestamp is not None)
|
|
152
|
+
else limit
|
|
153
|
+
)
|
|
145
154
|
|
|
146
|
-
Raises:
|
|
147
|
-
NetworkError: If pylast cannot retrieve playback history.
|
|
148
|
-
InvalidNetworkResponseError: If returned playback data is malformed.
|
|
149
|
-
"""
|
|
150
155
|
try:
|
|
151
156
|
user = self._network.get_user(self._username)
|
|
152
157
|
played_tracks = user.get_recent_tracks(
|
|
153
|
-
limit=
|
|
154
|
-
time_from=
|
|
155
|
-
time_to=
|
|
158
|
+
limit=api_limit,
|
|
159
|
+
time_from=api_start_timestamp,
|
|
160
|
+
time_to=api_end_timestamp,
|
|
156
161
|
stream=False,
|
|
157
162
|
)
|
|
158
|
-
|
|
159
|
-
self._mapper.to_scrobble(played_track)
|
|
163
|
+
scrobbles = [
|
|
164
|
+
self._mapper.to_scrobble(played_track)
|
|
165
|
+
for played_track in played_tracks
|
|
160
166
|
]
|
|
161
167
|
except pylast.PyLastError as error:
|
|
162
168
|
raise self.translate_error(error) from error
|
|
163
169
|
|
|
170
|
+
filtered_scrobbles = [
|
|
171
|
+
scrobble
|
|
172
|
+
for scrobble in scrobbles
|
|
173
|
+
if (
|
|
174
|
+
start_timestamp is None
|
|
175
|
+
or scrobble.timestamp >= start_timestamp
|
|
176
|
+
)
|
|
177
|
+
and (
|
|
178
|
+
end_timestamp is None
|
|
179
|
+
or scrobble.timestamp <= end_timestamp
|
|
180
|
+
)
|
|
181
|
+
]
|
|
182
|
+
|
|
183
|
+
if limit is not None:
|
|
184
|
+
return filtered_scrobbles[:limit]
|
|
185
|
+
|
|
186
|
+
return filtered_scrobbles
|
|
187
|
+
|
|
164
188
|
def get_latest_scrobble_timestamp(self) -> int | None:
|
|
165
189
|
"""Return the latest scrobble timestamp, if one exists."""
|
|
166
190
|
scrobbles = self.get_scrobbles(limit=1)
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|