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.
Files changed (67) hide show
  1. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/PKG-INFO +1 -1
  2. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/pyproject.toml +1 -1
  3. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/pyproject.toml.orig +1 -1
  4. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/networks/pylast_adapter.py +41 -17
  5. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/LICENSE +0 -0
  6. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/README.md +0 -0
  7. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/__init__.py +0 -0
  8. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/application.py +0 -0
  9. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/cli/__init__.py +0 -0
  10. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/cli/app.py +0 -0
  11. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/cli/commands/__init__.py +0 -0
  12. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/cli/commands/common.py +0 -0
  13. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/cli/commands/discard.py +0 -0
  14. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/cli/commands/profile.py +0 -0
  15. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/cli/commands/resume.py +0 -0
  16. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/cli/commands/status.py +0 -0
  17. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/cli/commands/sync.py +0 -0
  18. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/cli/configuration.py +0 -0
  19. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/cli/context.py +0 -0
  20. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/cli/dashboard.py +0 -0
  21. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/cli/presenters.py +0 -0
  22. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/cli/verification.py +0 -0
  23. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/exceptions.py +0 -0
  24. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/models/__init__.py +0 -0
  25. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/models/network_config.py +0 -0
  26. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/models/retry_policy.py +0 -0
  27. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/models/scrobble.py +0 -0
  28. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/models/sync_progress.py +0 -0
  29. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/models/sync_queue_item.py +0 -0
  30. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/models/sync_request.py +0 -0
  31. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/models/sync_result.py +0 -0
  32. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/models/sync_session.py +0 -0
  33. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/models/sync_status.py +0 -0
  34. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/models/sync_verification.py +0 -0
  35. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/networks/__init__.py +0 -0
  36. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/networks/factory.py +0 -0
  37. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/networks/gnufm.py +0 -0
  38. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/networks/pylast_mapper.py +0 -0
  39. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/profiles/__init__.py +0 -0
  40. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/profiles/factory.py +0 -0
  41. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/profiles/keyring_store.py +0 -0
  42. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/profiles/models.py +0 -0
  43. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/profiles/paths.py +0 -0
  44. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/profiles/protocols.py +0 -0
  45. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/profiles/resolver.py +0 -0
  46. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/profiles/service.py +0 -0
  47. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/profiles/toml_store.py +0 -0
  48. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/protocols/__init__.py +0 -0
  49. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/protocols/network.py +0 -0
  50. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/protocols/repositories.py +0 -0
  51. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/py.typed +0 -0
  52. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/repositories/__init__.py +0 -0
  53. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/repositories/database.py +0 -0
  54. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/repositories/queue_repository.py +0 -0
  55. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/repositories/schema.py +0 -0
  56. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/repositories/session_repository.py +0 -0
  57. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/repositories/snapshot_repository.py +0 -0
  58. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/services/__init__.py +0 -0
  59. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/services/comparison_service.py +0 -0
  60. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/services/metadata_service.py +0 -0
  61. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/services/range_resolver.py +0 -0
  62. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/services/recovery_service.py +0 -0
  63. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/services/retry_service.py +0 -0
  64. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/services/snapshot_service.py +0 -0
  65. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/services/submission_service.py +0 -0
  66. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/src/syncfm_core/services/sync_service.py +0 -0
  67. {syncfm_core-0.2.0 → syncfm_core-0.2.1}/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.0
3
+ Version: 0.2.1
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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "syncfm-core"
3
- version = "0.2.0"
3
+ version = "0.2.1"
4
4
  description = "Reusable synchronization engine and CLI for Last.fm, Libre.fm and GNU.fm networks."
5
5
  readme = "README.md"
6
6
  license = "GPL-3.0-or-later"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "syncfm-core"
3
- version = "0.2.0"
3
+ version = "0.2.1"
4
4
  description = "Reusable synchronization engine and CLI for Last.fm, Libre.fm and GNU.fm networks."
5
5
  readme = "README.md"
6
6
  license = "GPL-3.0-or-later"
@@ -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 matching the supplied range or limit.
137
-
138
- Args:
139
- start_timestamp: Earliest playback timestamp to include.
140
- end_timestamp: Latest playback timestamp to include.
141
- limit: Maximum number of scrobbles to return.
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
- Returns:
144
- Matching playback events.
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=limit,
154
- time_from=start_timestamp,
155
- time_to=end_timestamp,
158
+ limit=api_limit,
159
+ time_from=api_start_timestamp,
160
+ time_to=api_end_timestamp,
156
161
  stream=False,
157
162
  )
158
- return [
159
- self._mapper.to_scrobble(played_track) for played_track in played_tracks
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