1
1
# -*- coding: utf-8 -*-
2
+ """Key Wheel Converter Plugin
3
+ """
2
4
#
3
- # Copyright (C) 2022 Bob Swift (rdswift)
5
+ # Copyright (C) 2022-2025 Bob Swift (rdswift)
4
6
#
5
7
# This program is free software; you can redistribute it and/or
6
8
# modify it under the terms of the GNU General Public License
25
27
PLUGIN_DESCRIPTION = '''
26
28
Adds functions to convert between 'standard', 'camelot', 'open key' and 'traktor' key formats.
27
29
'''
28
- PLUGIN_VERSION = '1.1 '
29
- PLUGIN_API_VERSIONS = ['2.3' , '2.4' , '2.6' , '2.7' ]
30
+ PLUGIN_VERSION = '1.2 '
31
+ PLUGIN_API_VERSIONS = ['2.3' , '2.4' , '2.6' , '2.7' , '2.13' ]
30
32
PLUGIN_LICENSE = "GPL-2.0"
31
33
PLUGIN_LICENSE_URL = "https://www.gnu.org/licenses/gpl-2.0.txt"
32
34
33
35
import re
34
36
35
- # pylint: disable=E0402 (import-error)
36
- from picard import log
37
- from picard .script import register_script_function
37
+
38
+ try :
39
+ from picard import log
40
+ except ModuleNotFoundError :
41
+ class log ():
42
+ """Mocked logger for testing
43
+ """
44
+ # pylint: disable=invalid-name
45
+ # pylint: disable=too-few-public-methods
46
+ @staticmethod
47
+ def debug (* args , ** kwargs ):
48
+ """Mocked degug logger
49
+ """
50
+ return
51
+ try :
52
+ from picard .script import register_script_function
53
+ except ModuleNotFoundError :
54
+ def register_script_function (* args , ** kwargs ):
55
+ """Mocked function for testing
56
+ """
57
+ return
38
58
39
59
40
- # pylint: disable=R0903 (too-few-public-methods)
41
60
class KeyMap ():
42
61
"""
43
62
Class to hold the mapping dictionary. The dictionary is
44
63
stored as a class variable so that it is only generated once.
45
64
"""
65
+ # pylint: disable=too-few-public-methods
46
66
47
67
# Circle of Fifths reference:
48
68
# https://www.circleoffifths.com
@@ -127,6 +147,7 @@ def _matcher(text, out_type):
127
147
Returns:
128
148
str: Value mapped to the key for the specified output type
129
149
"""
150
+ # pylint: disable=consider-using-f-string
130
151
match_text = _parse_input (text )
131
152
if match_text not in KeyMap .keys :
132
153
log .debug ("{0}: Unable to match key: '{1}'" .format (PLUGIN_NAME , text ,))
@@ -144,6 +165,7 @@ def _parse_input(text):
144
165
Returns:
145
166
str: Argument converted to supported key format (if possible)
146
167
"""
168
+ # pylint: disable=too-many-return-statements
147
169
148
170
text = text .strip ()
149
171
if not text :
@@ -161,7 +183,8 @@ def _parse_input(text):
161
183
_char = text [- 1 :].lower ().replace ('m' , 'A' ).replace ('d' , 'B' )
162
184
return "{0}{1}" .format (_num , _char ,)
163
185
164
- if re .match ("[a-g][#bB♭]?[mM]?$" , text ):
186
+ # if re.match("[a-gA-G][#bB♭]?[mM]?$", text):
187
+ if re .match ("[a-gA-G][#Bb]?[mM]?$" , text ):
165
188
# Matches Traktor key format. Fix capitalization for lookup.
166
189
temp = text [0 :1 ].upper () + text [1 :].replace ('♭' , 'b' ).lower ()
167
190
# Handle cases where there are multiple entries for the item
@@ -215,6 +238,8 @@ def key2camelot(parser, text):
215
238
'1A'
216
239
>>> key2camelot(None, '1A ')
217
240
'1A'
241
+ >>> key2camelot(None, 'ABm')
242
+ '1A'
218
243
>>> key2camelot(None, '')
219
244
''
220
245
>>> key2camelot(None, 'A-Flat Minor x')
@@ -238,12 +263,33 @@ def key2camelot(parser, text):
238
263
>>> key2camelot(None, '1x')
239
264
''
240
265
266
+ >>> key2camelot(None, 'A#')
267
+ '6B'
268
+ >>> key2camelot(None, 'A#M')
269
+ '3A'
270
+ >>> key2camelot(None, 'C#')
271
+ '3B'
272
+ >>> key2camelot(None, 'C#M')
273
+ '12A'
274
+ >>> key2camelot(None, 'D#')
275
+ '5B'
276
+ >>> key2camelot(None, 'D#M')
277
+ '2A'
278
+ >>> key2camelot(None, 'F#M')
279
+ '11A'
280
+ >>> key2camelot(None, 'G#')
281
+ '4B'
282
+ >>> key2camelot(None, 'G#M')
283
+ '1A'
284
+
241
285
>>> key2camelot(None, 'c')
242
286
'8B'
243
287
>>> key2camelot(None, 'dB')
244
288
'3B'
245
289
>>> key2camelot(None, 'd#M')
246
290
'2A'
291
+ >>> key2camelot(None, 'D#M')
292
+ '2A'
247
293
"""
248
294
return _matcher (text , 'camelot' )
249
295
@@ -445,15 +491,19 @@ def key2traktor(parser, text):
445
491
'Db'
446
492
>>> key2traktor(None, 'gBM')
447
493
'Gbm'
448
- >>> key2traktor(None, 'g♭M ')
494
+ >>> key2traktor(None, 'gbM ')
449
495
'Gbm'
496
+ >>> key2traktor(None, 'g♭M')
497
+ ''
450
498
>>> key2traktor(None, '')
451
499
''
452
500
"""
453
501
return _matcher (text , 'traktor' )
454
502
455
503
456
- register_script_function (key2camelot , name = 'key2camelot' ,
504
+ register_script_function (
505
+ key2camelot ,
506
+ name = 'key2camelot' ,
457
507
documentation = """`$key2camelot(key)`
458
508
459
509
Returns the key string `key` in camelot key format.
@@ -464,7 +514,9 @@ def key2traktor(parser, text):
464
514
is not recognized as one of the standard keys in the supported formats, then
465
515
an empty string will be returned.""" )
466
516
467
- register_script_function (key2openkey , name = 'key2openkey' ,
517
+ register_script_function (
518
+ key2openkey ,
519
+ name = 'key2openkey' ,
468
520
documentation = """`$key2openkey(key)`
469
521
470
522
Returns the key string `key` in open key format.
@@ -475,7 +527,9 @@ def key2traktor(parser, text):
475
527
is not recognized as one of the standard keys in the supported formats, then
476
528
an empty string will be returned.""" )
477
529
478
- register_script_function (key2standard , name = 'key2standard' ,
530
+ register_script_function (
531
+ key2standard ,
532
+ name = 'key2standard' ,
479
533
documentation = """`$key2standard(key[,symbols])`
480
534
481
535
Returns the key string `key` in standard key format. If the optional argument
@@ -488,7 +542,9 @@ def key2traktor(parser, text):
488
542
is not recognized as one of the standard keys in the supported formats, then
489
543
an empty string will be returned.""" )
490
544
491
- register_script_function (key2traktor , name = 'key2traktor' ,
545
+ register_script_function (
546
+ key2traktor ,
547
+ name = 'key2traktor' ,
492
548
documentation = """`$key2traktor(key)`
493
549
494
550
Returns the key string `key` in traktor key format.
0 commit comments