pyrekordbox 0.4.1__py3-none-any.whl → 0.4.3__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.
@@ -4,9 +4,19 @@
4
4
 
5
5
  import logging
6
6
  from contextlib import contextmanager
7
+ from datetime import datetime
8
+ from typing import TYPE_CHECKING, Any, Iterator, List, Tuple, Type
7
9
 
8
10
  from sqlalchemy.orm.exc import ObjectDeletedError
9
11
 
12
+ if TYPE_CHECKING:
13
+ from .database import Rekordbox6Database
14
+ from .tables import AgentRegistry
15
+
16
+
17
+ Instances = Any
18
+ RegistryUpdateItem = Tuple[Instances, str, str, Any]
19
+
10
20
  logger = logging.getLogger(__name__)
11
21
 
12
22
 
@@ -27,15 +37,15 @@ class RekordboxAgentRegistry:
27
37
  The Rekordbox database instance.
28
38
  """
29
39
 
30
- __update_sequence__ = list()
31
- __update_history__ = list()
40
+ __update_sequence__: List[RegistryUpdateItem] = list()
41
+ __update_history__: List[RegistryUpdateItem] = list()
32
42
  __enabled__ = True
33
43
 
34
- def __init__(self, db):
44
+ def __init__(self, db: "Rekordbox6Database") -> None:
35
45
  self.db = db
36
46
 
37
47
  @classmethod
38
- def on_update(cls, instance, key, value):
48
+ def on_update(cls, instance: Instances, key: str, value: Any) -> None:
39
49
  """Called when an instance of a database model is updated.
40
50
 
41
51
  Parameters
@@ -52,7 +62,7 @@ class RekordboxAgentRegistry:
52
62
  cls.__update_sequence__.append((instance, "update", key, value))
53
63
 
54
64
  @classmethod
55
- def on_create(cls, instance):
65
+ def on_create(cls, instance: Instances) -> None:
56
66
  """Called when an instance of a database model is created.
57
67
 
58
68
  Parameters
@@ -65,7 +75,7 @@ class RekordboxAgentRegistry:
65
75
  cls.__update_sequence__.append((instance, "create", "", ""))
66
76
 
67
77
  @classmethod
68
- def on_delete(cls, instance):
78
+ def on_delete(cls, instance: Instances) -> None:
69
79
  """Called when an instance of a database model is deleted.
70
80
 
71
81
  Parameters
@@ -83,7 +93,7 @@ class RekordboxAgentRegistry:
83
93
  cls.__update_sequence__.append((instance, "delete", "", ""))
84
94
 
85
95
  @classmethod
86
- def on_move(cls, instances):
96
+ def on_move(cls, instances: Instances) -> None:
87
97
  """Called when instanced of a database model are moved.
88
98
 
89
99
  Parameters
@@ -96,24 +106,24 @@ class RekordboxAgentRegistry:
96
106
  cls.__update_sequence__.append((instances, "move", "", ""))
97
107
 
98
108
  @classmethod
99
- def clear_buffer(cls):
109
+ def clear_buffer(cls) -> None:
100
110
  """Clears the update buffer and update history."""
101
111
  cls.__update_history__.extend(cls.__update_sequence__)
102
112
  cls.__update_sequence__.clear()
103
113
 
104
114
  @classmethod
105
- def enable_tracking(cls):
115
+ def enable_tracking(cls) -> None:
106
116
  """Enables the tracking of database changes."""
107
117
  cls.__enabled__ = True
108
118
 
109
119
  @classmethod
110
- def disable_tracking(cls):
120
+ def disable_tracking(cls) -> None:
111
121
  """Disables the tracking of database changes."""
112
122
  cls.__enabled__ = False
113
123
 
114
124
  @classmethod
115
125
  @contextmanager
116
- def disabled(cls):
126
+ def disabled(cls) -> Iterator[Type["RekordboxAgentRegistry"]]:
117
127
  """Context manager to temporarily disable the tracking of database changes.
118
128
 
119
129
  Examples
@@ -132,7 +142,7 @@ class RekordboxAgentRegistry:
132
142
  if enabled:
133
143
  cls.enable_tracking()
134
144
 
135
- def get_registries(self):
145
+ def get_registries(self) -> Any:
136
146
  """Returns all agent registries.
137
147
 
138
148
  Returns
@@ -141,7 +151,7 @@ class RekordboxAgentRegistry:
141
151
  """
142
152
  return self.db.get_agent_registry()
143
153
 
144
- def get_registry(self, key):
154
+ def get_registry(self, key: str) -> Any:
145
155
  """Returns the agent registry with the given key.
146
156
 
147
157
  Parameters
@@ -155,7 +165,7 @@ class RekordboxAgentRegistry:
155
165
  """
156
166
  return self.db.get_agent_registry(registry_id=key)
157
167
 
158
- def get_string(self, key):
168
+ def get_string(self, key: str) -> str:
159
169
  """Returns the string value of the registry with the given key.
160
170
 
161
171
  Parameters
@@ -167,9 +177,10 @@ class RekordboxAgentRegistry:
167
177
  -------
168
178
  value : str
169
179
  """
170
- return self.db.get_agent_registry(registry_id=key).str_1
180
+ reg: "AgentRegistry" = self.db.get_agent_registry(registry_id=key)
181
+ return reg.str_1
171
182
 
172
- def get_text(self, key):
183
+ def get_text(self, key: str) -> str:
173
184
  """Returns the text value of the registry with the given key.
174
185
 
175
186
  Parameters
@@ -181,9 +192,10 @@ class RekordboxAgentRegistry:
181
192
  -------
182
193
  value : str
183
194
  """
184
- return self.db.get_agent_registry(registry_id=key).text_1
195
+ reg: "AgentRegistry" = self.db.get_agent_registry(registry_id=key)
196
+ return reg.text_1
185
197
 
186
- def get_int(self, key):
198
+ def get_int(self, key: str) -> int:
187
199
  """Returns the integer value of the registry with the given key.
188
200
 
189
201
  Parameters
@@ -195,9 +207,10 @@ class RekordboxAgentRegistry:
195
207
  -------
196
208
  value : int
197
209
  """
198
- return self.db.get_agent_registry(registry_id=key).int_1
210
+ reg: "AgentRegistry" = self.db.get_agent_registry(registry_id=key)
211
+ return reg.int_1
199
212
 
200
- def get_date(self, key):
213
+ def get_date(self, key: str) -> datetime:
201
214
  """Returns the date value of the registry with the given key.
202
215
 
203
216
  Parameters
@@ -209,9 +222,10 @@ class RekordboxAgentRegistry:
209
222
  -------
210
223
  value : datetime.datetime
211
224
  """
212
- return self.db.get_agent_registry(registry_id=key).date_1
225
+ reg: "AgentRegistry" = self.db.get_agent_registry(registry_id=key)
226
+ return reg.date_1
213
227
 
214
- def set_string(self, key, value):
228
+ def set_string(self, key: str, value: str) -> None:
215
229
  """Sets the string value of the registry with the given key.
216
230
 
217
231
  Parameters
@@ -223,7 +237,7 @@ class RekordboxAgentRegistry:
223
237
  """
224
238
  self.db.get_agent_registry(registry_id=key).str_1 = value
225
239
 
226
- def set_text(self, key, value):
240
+ def set_text(self, key: str, value: str) -> None:
227
241
  """Sets the text value of the registry with the given key.
228
242
 
229
243
  Parameters
@@ -235,7 +249,7 @@ class RekordboxAgentRegistry:
235
249
  """
236
250
  self.db.get_agent_registry(registry_id=key).text_1 = value
237
251
 
238
- def set_int(self, key, value):
252
+ def set_int(self, key: str, value: int) -> None:
239
253
  """Sets the integer value of the registry with the given key.
240
254
 
241
255
  Parameters
@@ -247,7 +261,7 @@ class RekordboxAgentRegistry:
247
261
  """
248
262
  self.db.get_agent_registry(registry_id=key).int_1 = value
249
263
 
250
- def set_date(self, key, value):
264
+ def set_date(self, key: str, value: datetime) -> None:
251
265
  """Sets the date value of the registry with the given key.
252
266
 
253
267
  Parameters
@@ -259,12 +273,12 @@ class RekordboxAgentRegistry:
259
273
  """
260
274
  self.db.get_agent_registry(registry_id=key).date_1 = value
261
275
 
262
- def get_local_update_count(self):
276
+ def get_local_update_count(self) -> int:
263
277
  """Returns the current global local USN (unique sequence number)."""
264
- reg = self.db.get_agent_registry(registry_id="localUpdateCount")
278
+ reg: "AgentRegistry" = self.db.get_agent_registry(registry_id="localUpdateCount")
265
279
  return reg.int_1
266
280
 
267
- def set_local_update_count(self, value):
281
+ def set_local_update_count(self, value: int) -> None:
268
282
  """Sets the global local USN (unique sequence number).
269
283
 
270
284
  Parameters
@@ -272,10 +286,10 @@ class RekordboxAgentRegistry:
272
286
  value : int
273
287
  The new USN value.
274
288
  """
275
- reg = self.db.get_agent_registry(registry_id="localUpdateCount")
289
+ reg: "AgentRegistry" = self.db.get_agent_registry(registry_id="localUpdateCount")
276
290
  reg.int_1 = value
277
291
 
278
- def increment_local_update_count(self, num=1):
292
+ def increment_local_update_count(self, num: int = 1) -> int:
279
293
  """Increments the global local USN (unique sequence number) by the given number.
280
294
 
281
295
  Parameters
@@ -290,11 +304,11 @@ class RekordboxAgentRegistry:
290
304
  """
291
305
  if not isinstance(num, int) or num < 1:
292
306
  raise ValueError("The USN can only be increment by a positive integer!")
293
- reg = self.db.get_agent_registry(registry_id="localUpdateCount")
307
+ reg: "AgentRegistry" = self.db.get_agent_registry(registry_id="localUpdateCount")
294
308
  reg.int_1 = reg.int_1 + num
295
309
  return reg.int_1
296
310
 
297
- def autoincrement_local_update_count(self, set_row_usn=True):
311
+ def autoincrement_local_update_count(self, set_row_usn: bool = True) -> int:
298
312
  """Auto-increments the global local USN (unique sequence number).
299
313
 
300
314
  The number of changes in the update buffer is used to determine the
@@ -312,10 +326,10 @@ class RekordboxAgentRegistry:
312
326
  The new global local USN.
313
327
  """
314
328
  reg = self.db.get_agent_registry(registry_id="localUpdateCount")
315
- usn = reg.int_1
329
+ usn: int = reg.int_1
316
330
  self.disable_tracking()
317
331
  self.db.flush()
318
- with self.db.session.no_autoflush:
332
+ with self.db.no_autoflush:
319
333
  for instances, op, _, _ in self.__update_sequence__.copy():
320
334
  usn += 1
321
335
  if set_row_usn:
@@ -7,11 +7,11 @@ import xml.etree.cElementTree as xml
7
7
  from dataclasses import dataclass
8
8
  from datetime import datetime
9
9
  from enum import Enum, IntEnum
10
- from typing import List, Union
10
+ from typing import Any, Dict, List, Tuple, Union
11
11
 
12
12
  from dateutil.relativedelta import relativedelta # noqa
13
13
  from sqlalchemy import and_, not_, or_
14
- from sqlalchemy.sql.elements import BooleanClauseList
14
+ from sqlalchemy.sql.elements import ColumnElement
15
15
 
16
16
  from .tables import DjmdContent
17
17
 
@@ -99,7 +99,7 @@ _DATE_OPS = [
99
99
  ]
100
100
 
101
101
  # Defines the valid operators for each property
102
- VALID_OPS = {
102
+ VALID_OPS: Dict[str, Any] = {
103
103
  Property.ARTIST: _STR_OPS,
104
104
  Property.ALBUM: _STR_OPS,
105
105
  Property.ALBUM_ARTIST: _STR_OPS,
@@ -126,7 +126,7 @@ VALID_OPS = {
126
126
  }
127
127
 
128
128
  # Defines the column names in the DB for properties that are directly mapped
129
- PROPERTY_COLUMN_MAP = {
129
+ PROPERTY_COLUMN_MAP: Dict[str, str] = {
130
130
  Property.ARTIST: "ArtistName",
131
131
  Property.ALBUM: "AlbumName",
132
132
  Property.ALBUM_ARTIST: "AlbumArtistName",
@@ -152,7 +152,7 @@ PROPERTY_COLUMN_MAP = {
152
152
  Property.YEAR: "ReleaseYear",
153
153
  }
154
154
 
155
- TYPE_CONVERSION = {
155
+ TYPE_CONVERSION: Dict[str, Any] = {
156
156
  Property.BPM: int,
157
157
  Property.STOCK_DATE: lambda x: datetime.strptime(x, "%Y-%m-%d"),
158
158
  Property.DATE_CREATED: lambda x: datetime.strptime(x, "%Y-%m-%d"),
@@ -176,7 +176,7 @@ class Condition:
176
176
  value_left: Union[str, int]
177
177
  value_right: Union[str, int]
178
178
 
179
- def __post_init__(self):
179
+ def __post_init__(self) -> None:
180
180
  if self.property not in PROPERTIES:
181
181
  raise ValueError(
182
182
  f"Invalid property: '{self.property}'! Supported properties: {PROPERTIES}"
@@ -196,15 +196,15 @@ class Condition:
196
196
 
197
197
  def left_bitshift(x: int, nbit: int = 32) -> int:
198
198
  """Left shifts an N bit integer with sign change."""
199
- return x - 2**nbit
199
+ return int(x - 2**nbit)
200
200
 
201
201
 
202
202
  def right_bitshift(x: int, nbit: int = 32) -> int:
203
203
  """Right shifts an N bit integer with sign change."""
204
- return x + 2**nbit
204
+ return int(x + 2**nbit)
205
205
 
206
206
 
207
- def _get_condition_values(cond):
207
+ def _get_condition_values(cond: Condition) -> Tuple[Any, Any]:
208
208
  val_left = cond.value_left
209
209
  val_right = cond.value_right
210
210
  func = None
@@ -223,7 +223,7 @@ def _get_condition_values(cond):
223
223
  pass
224
224
 
225
225
  if val_left == "":
226
- val_left = None
226
+ val_left = None # type: ignore
227
227
 
228
228
  return val_left, val_right
229
229
 
@@ -304,12 +304,12 @@ class SmartList:
304
304
  cond = Condition(prop, int(operator), unit, value_left, value_right)
305
305
  self.conditions.append(cond)
306
306
 
307
- def filter_clause(self) -> BooleanClauseList:
307
+ def filter_clause(self) -> ColumnElement[bool]:
308
308
  """Return a SQLAlchemy filter clause matching the content of the smart playlist.
309
309
 
310
310
  Returns
311
311
  -------
312
- BooleanClauseList
312
+ ColumnElement[bool]
313
313
  A filter list macthing the contents of the smart playlist.
314
314
  """
315
315
  logical_op = and_ if self.logical_operator == LogicalOperator.ALL else or_