python-rockbox 0.1.0__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.
- python_rockbox/__init__.py +4 -0
- python_rockbox/py.typed +0 -0
- python_rockbox/tags.py +226 -0
- python_rockbox/wps.py +77 -0
- python_rockbox-0.1.0.dist-info/METADATA +66 -0
- python_rockbox-0.1.0.dist-info/RECORD +7 -0
- python_rockbox-0.1.0.dist-info/WHEEL +4 -0
python_rockbox/py.typed
ADDED
|
File without changes
|
python_rockbox/tags.py
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Tags(Enum):
|
|
5
|
+
"""
|
|
6
|
+
All WPS tags from Rockbox 4.0 represented as enums.
|
|
7
|
+
|
|
8
|
+
Tag enums are ordered and sectioned by position in manual.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
# Status Bar (D.1)
|
|
12
|
+
DISPLAY_STATUSBAR = "we"
|
|
13
|
+
HIDE_STATUSBAR = "wd"
|
|
14
|
+
INBUILT_STATUSBAR = "wi"
|
|
15
|
+
|
|
16
|
+
# Hardware (D.2)
|
|
17
|
+
HAS_CLOCK = "cc"
|
|
18
|
+
HAS_RADIO = "tp"
|
|
19
|
+
HAS_TOUCHSCREEN = "Tp"
|
|
20
|
+
|
|
21
|
+
# Metadata (D.3)
|
|
22
|
+
ARTIST_NAME = "ia"
|
|
23
|
+
COMPOSER_NAME = "ic"
|
|
24
|
+
ALBUM_ARTIST = "iA"
|
|
25
|
+
ALBUM_NAME = "id"
|
|
26
|
+
GROUPING = "iG"
|
|
27
|
+
TRACK_NUMBER = "in"
|
|
28
|
+
TRACK_TITLE = "it"
|
|
29
|
+
SONG_COMMENT = "iC"
|
|
30
|
+
ID3_VERSION = "iv"
|
|
31
|
+
SONG_YEAR = "iy"
|
|
32
|
+
DISC_NUMBER = "ik"
|
|
33
|
+
|
|
34
|
+
# Viewports (D.4)
|
|
35
|
+
VIEWPORT = "V"
|
|
36
|
+
VIEWPORT_FG = "Vf"
|
|
37
|
+
VIEWPORT_BG = "Vb"
|
|
38
|
+
VIEWPORT_STYLE = "Vs"
|
|
39
|
+
PRELOAD_VIEWPORT = "Vl"
|
|
40
|
+
DISPLAY_VIEWPORT = "Vd"
|
|
41
|
+
UI_VIEWPORT = "Vi"
|
|
42
|
+
INFO_VIEWPORT = "VI"
|
|
43
|
+
VIEWPORT_ON_BACKDROP = "VB"
|
|
44
|
+
|
|
45
|
+
# Fonts (D.5)
|
|
46
|
+
DEFINE_FONT = "Fl"
|
|
47
|
+
|
|
48
|
+
# Coloring Tags (D.6)
|
|
49
|
+
DRAW_RECTANGLE = "dr"
|
|
50
|
+
|
|
51
|
+
# Power (D.7)
|
|
52
|
+
BATTERY_PERCENTAGE = "bl"
|
|
53
|
+
BATTERY_VOLTS = "bv"
|
|
54
|
+
BATTERY_TIME = "bt"
|
|
55
|
+
IS_CHARGING = "bp"
|
|
56
|
+
CHARGING_BATTERY = "bc"
|
|
57
|
+
SLEEP_TIMER = "bs"
|
|
58
|
+
|
|
59
|
+
# File Information (D.8)
|
|
60
|
+
FILE_BITRATE = "fb"
|
|
61
|
+
FILE_CODEC = "fc"
|
|
62
|
+
FILE_FREQUENCY_HZ = "ff"
|
|
63
|
+
FILE_FREQUENCY_KHZ = "fk"
|
|
64
|
+
FILE_NAME_EXTENSION = "fm"
|
|
65
|
+
FILE_NAME = "fn"
|
|
66
|
+
FILE_PATH = "fp"
|
|
67
|
+
FILE_SIZE = "fs"
|
|
68
|
+
AVERAGE_BITRATE = "fv"
|
|
69
|
+
SEGMENT_FROM_END = "d"
|
|
70
|
+
|
|
71
|
+
# Playlist/Song (D.9)
|
|
72
|
+
PROGRESS_BAR = "pb"
|
|
73
|
+
SONG_PERCENTAGE = "px"
|
|
74
|
+
SONG_TIME = "pc"
|
|
75
|
+
PLAYLIST_ENTRIES = "pe"
|
|
76
|
+
PEAK_METER = "pm"
|
|
77
|
+
PEAK_LEFT_CHANNEL = "pL"
|
|
78
|
+
PEAK_RIGHT_CHANNEL = "pR"
|
|
79
|
+
PLAYLIST_NAME = "pn"
|
|
80
|
+
PLAYLIST_POSITION = "pp"
|
|
81
|
+
PLAYLIST_PERCENTAGE = "pP"
|
|
82
|
+
SONG_TIME_REMAINING = "pr"
|
|
83
|
+
IS_SHUFFLE = "ps"
|
|
84
|
+
TOTAL_TRACK_TIME = "pt"
|
|
85
|
+
VOLUME = "pv"
|
|
86
|
+
TRACK_STARTING = "pS"
|
|
87
|
+
TRACK_ENDING = "pE"
|
|
88
|
+
|
|
89
|
+
# Playlist Viewer (D.10)
|
|
90
|
+
PLAYLIST_VIEWPORT = "Vp"
|
|
91
|
+
|
|
92
|
+
# Runtime Database (D.11)
|
|
93
|
+
SONG_PLAYCOUNT = "rp"
|
|
94
|
+
SONG_RATING = "rr"
|
|
95
|
+
SONG_AUTOSCORE = "ra"
|
|
96
|
+
|
|
97
|
+
# Sound/DSP Settings (D.12)
|
|
98
|
+
PLAYBACK_PITCH = "Sp"
|
|
99
|
+
CROSSFADE_SETTING = "xf"
|
|
100
|
+
REPLAYGAIN_VALUE = "rg"
|
|
101
|
+
|
|
102
|
+
# Hold (D.13)
|
|
103
|
+
IS_HOLD_SWITCH = "mh"
|
|
104
|
+
|
|
105
|
+
# Virtual LED (D.14)
|
|
106
|
+
IS_HARDDISK = "lh"
|
|
107
|
+
|
|
108
|
+
# Repeat Mode (D.15)
|
|
109
|
+
REPEAT_MODE = "mm"
|
|
110
|
+
|
|
111
|
+
# Playback Mode (D.16)
|
|
112
|
+
PLAYBACK_STATUS = "mp"
|
|
113
|
+
|
|
114
|
+
# Current Screen (D.17)
|
|
115
|
+
CURRENT_SCREEN = "cs"
|
|
116
|
+
|
|
117
|
+
# List Title (D.18)
|
|
118
|
+
TITLE_TEXT = "Lt"
|
|
119
|
+
TITLE_ICON = "Li"
|
|
120
|
+
|
|
121
|
+
# List Skinning (D.19)
|
|
122
|
+
CURRENT_ITEM_TEXT = "LT"
|
|
123
|
+
CURRENT_ITEM_ICON = "LI"
|
|
124
|
+
CURRENT_ITEM_INDEX = "LN"
|
|
125
|
+
ITEM_ROW_NUMBER = "LR"
|
|
126
|
+
ITEM_COLUMN_NUMBER = "LC"
|
|
127
|
+
ITEM_IS_SELECTED = "Lc"
|
|
128
|
+
SCROLL_BAR_TAG = "LB"
|
|
129
|
+
VIEWPORT_ITEM_DRAW = "Lb"
|
|
130
|
+
|
|
131
|
+
# Changing Volume (D.20)
|
|
132
|
+
IS_VOLUME_CHANGING = "mv"
|
|
133
|
+
|
|
134
|
+
# Settings (D.21)
|
|
135
|
+
SETTING_VALUE = "St"
|
|
136
|
+
QUICKSCREEN_TOP_NAME = "QT"
|
|
137
|
+
QUICKSCREEN_TOP_VALUE = "Qt"
|
|
138
|
+
QUICKSCREEN_RIGHT_NAME = "QR"
|
|
139
|
+
QUICKSCREEN_RIGHT_VALUE = "Qr"
|
|
140
|
+
QUICKSCREEN_BOTTOM_NAME = "QB"
|
|
141
|
+
QUICKSCREEN_BOTTOM_VALUE = "Qb"
|
|
142
|
+
QUICKSCREEN_LEFT_NAME = "QL"
|
|
143
|
+
QUICKSCREEN_LEFT_VALUE = "Ql"
|
|
144
|
+
|
|
145
|
+
# Images (D.22):
|
|
146
|
+
BACKDROP_IMAGE = "X"
|
|
147
|
+
IMAGE = "x"
|
|
148
|
+
PRELOAD_IMAGE = "xl"
|
|
149
|
+
DISPLAY_IMAGE = "xd"
|
|
150
|
+
NINE_PATCH_IMAGE = "x9"
|
|
151
|
+
ALBUM_ART_SETTINGS = "Cl"
|
|
152
|
+
DISPLAY_ALBUM_ART = "Cd"
|
|
153
|
+
IS_ALBUM_ART = "C"
|
|
154
|
+
|
|
155
|
+
# FM Radio (D.23)
|
|
156
|
+
TUNER_TUNED = "tt"
|
|
157
|
+
FM_SCAN_OR_PRESET = "tm"
|
|
158
|
+
IS_FM_STEREO = "ts"
|
|
159
|
+
MINIMUM_FREQUENCY = "ta"
|
|
160
|
+
MAXIMUM_FREQUENCY = "tb"
|
|
161
|
+
CURRENT_FREQUENCY_MHZ = "tf"
|
|
162
|
+
CURRENT_PRESET_ID = "Ti"
|
|
163
|
+
CURRENT_PRESET_FREQUENCY = "Tf"
|
|
164
|
+
PRESET_COUNTT = "Tc"
|
|
165
|
+
IS_RDS = "tx"
|
|
166
|
+
RDS_NAME = "ty"
|
|
167
|
+
RDS_TEXT = "tz"
|
|
168
|
+
FM_SIGNAL_STRENGTH = "tr"
|
|
169
|
+
|
|
170
|
+
# Alignment (D.24)
|
|
171
|
+
ALIGN_LEFT = "al"
|
|
172
|
+
ALIGN_START = "aL"
|
|
173
|
+
ALIGN_CENTER = "ac"
|
|
174
|
+
ALIGN_RIGHT = "ar"
|
|
175
|
+
ALIGN_END = "aR"
|
|
176
|
+
NEXT_TAG_DIRECTION = "ax"
|
|
177
|
+
DEFINE_ALIGN_OPTIONS = "Sr"
|
|
178
|
+
|
|
179
|
+
# Conditional Tags (D.25)
|
|
180
|
+
IF = "if"
|
|
181
|
+
AND = "and"
|
|
182
|
+
OR = "or"
|
|
183
|
+
|
|
184
|
+
# Sublime Tags (D.26)
|
|
185
|
+
SUBLIME_DISPLAY_CYCLE_TIME = "t"
|
|
186
|
+
|
|
187
|
+
# Time and Date (D.27)
|
|
188
|
+
DAY_OF_MONTH = "cd"
|
|
189
|
+
ZERO_PADDED_MONTH_DAY = "ce"
|
|
190
|
+
TIME_FORMAT = "cf"
|
|
191
|
+
ZERO_PADDED_24_HOUR = "cH"
|
|
192
|
+
NORMAL_24_HOUR = "ck"
|
|
193
|
+
ZERO_PADDED_12_HOUR = "cI"
|
|
194
|
+
NORMAL_12_HOUR = "cl"
|
|
195
|
+
MONTH_OF_YEAR = "cm"
|
|
196
|
+
MINUTES = "cM"
|
|
197
|
+
SECONDS = "cS"
|
|
198
|
+
YEAR_2_DIGIT = "cy"
|
|
199
|
+
YEAR_4_DIGIT = "cY"
|
|
200
|
+
CAPITAL_AM_PM = "cP"
|
|
201
|
+
AM_PM = "cp"
|
|
202
|
+
WEEKDAY = "ca"
|
|
203
|
+
MONTH = "cb"
|
|
204
|
+
DAY_OF_WEEK_1_INDEX = "cu"
|
|
205
|
+
DAY_OF_WEEK_0_INDEX = "cw"
|
|
206
|
+
|
|
207
|
+
# Text Translation (D.28)
|
|
208
|
+
TRANSLATION = "Sx"
|
|
209
|
+
|
|
210
|
+
# Bar Tags (D.29)
|
|
211
|
+
DRAW_AS_BAR = "XX"
|
|
212
|
+
|
|
213
|
+
# Misc. Tags (D.30)
|
|
214
|
+
TAG_SUBSTRING = "ss"
|
|
215
|
+
READ_LINE_FILE = "ft"
|
|
216
|
+
LEFT_PARENTHESIS = "("
|
|
217
|
+
RIGHT_PARENTHESIS = ")"
|
|
218
|
+
COMMA = ","
|
|
219
|
+
PERCENT_SIGN = "%"
|
|
220
|
+
LEFT_THAN = "<"
|
|
221
|
+
PIPE = "|"
|
|
222
|
+
GREATER_THAN = ">"
|
|
223
|
+
SEMICOLON = ";"
|
|
224
|
+
HASHTAG = "#"
|
|
225
|
+
POUND = "#"
|
|
226
|
+
LINE_SHOULD_SCROLL = "s"
|
python_rockbox/wps.py
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
from .tags import Tags
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Color:
|
|
5
|
+
def __init__(self, color: str) -> None:
|
|
6
|
+
"""Rockbox formatted RGB Hex color code"""
|
|
7
|
+
self.color = self.normalize_color(color)
|
|
8
|
+
|
|
9
|
+
@staticmethod
|
|
10
|
+
def normalize_color(color: str) -> str:
|
|
11
|
+
"""Normalizes hex color to Rockbox format"""
|
|
12
|
+
color = color.upper().removeprefix("#")
|
|
13
|
+
|
|
14
|
+
# Convert to 6 character hex code if needed
|
|
15
|
+
if len(color) == 3:
|
|
16
|
+
color = "".join(c * 2 for c in color)
|
|
17
|
+
return color
|
|
18
|
+
|
|
19
|
+
def __str__(self) -> str:
|
|
20
|
+
return self.color
|
|
21
|
+
|
|
22
|
+
def __repr__(self) -> str:
|
|
23
|
+
return self.color
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class Tag:
|
|
27
|
+
def __init__(self, tag: Tag | Tags | str, *args) -> None:
|
|
28
|
+
"""
|
|
29
|
+
Class representation of a Rockbox WPS tag.
|
|
30
|
+
|
|
31
|
+
Ex: `Tag(Tags.DISPLAY_IMAGE, "X")` = `%xd(X)`
|
|
32
|
+
"""
|
|
33
|
+
if isinstance(tag, Tag):
|
|
34
|
+
self.tag: str = tag.tag
|
|
35
|
+
self.arguments: tuple = tag.arguments
|
|
36
|
+
else:
|
|
37
|
+
if isinstance(tag, Tags):
|
|
38
|
+
self.tag: str = tag.value
|
|
39
|
+
else:
|
|
40
|
+
self.tag: str = tag
|
|
41
|
+
self.arguments: tuple = args
|
|
42
|
+
|
|
43
|
+
def render_simple_tag(self) -> str:
|
|
44
|
+
"""Renders a tag with no arguments"""
|
|
45
|
+
return f"%{self.tag}"
|
|
46
|
+
|
|
47
|
+
def render_argument_tag(self) -> str:
|
|
48
|
+
"""Renders a tag that has arguments"""
|
|
49
|
+
rendered_args = ", ".join(map(str, self.arguments))
|
|
50
|
+
return f"%{self.tag}({rendered_args})"
|
|
51
|
+
|
|
52
|
+
def __repr__(self) -> str:
|
|
53
|
+
if self.arguments:
|
|
54
|
+
return self.render_argument_tag()
|
|
55
|
+
else:
|
|
56
|
+
return self.render_simple_tag()
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class Match:
|
|
60
|
+
def __init__(
|
|
61
|
+
self, tag: Tag | Tags | str, cases: list[Tag | Match]
|
|
62
|
+
) -> None:
|
|
63
|
+
"""Class representation of Rockbox WPS conditional"""
|
|
64
|
+
if isinstance(tag, Tags):
|
|
65
|
+
self.tag: Tag = Tag(tag.value)
|
|
66
|
+
else:
|
|
67
|
+
self.tag: Tag = Tag(tag)
|
|
68
|
+
self.cases: list[Tag | Match] = cases
|
|
69
|
+
|
|
70
|
+
def _render_match(self) -> str:
|
|
71
|
+
rendered_cases: list = []
|
|
72
|
+
for case in self.cases:
|
|
73
|
+
rendered_cases.append(case.__repr__())
|
|
74
|
+
return f"%?{self.tag.tag}<{"|".join(rendered_cases)}>"
|
|
75
|
+
|
|
76
|
+
def __repr__(self) -> str:
|
|
77
|
+
return self._render_match()
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: python-rockbox
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Create and manipulate WPS tags from Python
|
|
5
|
+
Author: Stormy
|
|
6
|
+
Author-email: Stormy <oohstormy@gmail.com>
|
|
7
|
+
Requires-Python: >=3.14
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
|
|
10
|
+
# python-rockbox
|
|
11
|
+
|
|
12
|
+
Create and manipulate WPS tags from Python
|
|
13
|
+
|
|
14
|
+
### Currently supported:
|
|
15
|
+
* All tags from Rockbox 4.0 (via `Tags` class)
|
|
16
|
+
* Tags (`Tag` class)
|
|
17
|
+
* Conditionals (`Match` class)
|
|
18
|
+
|
|
19
|
+
## Example
|
|
20
|
+
|
|
21
|
+
This conditional that displays an appropriate battery bitmap:
|
|
22
|
+
```py
|
|
23
|
+
wps = Match(
|
|
24
|
+
Tags.IS_CHARGING,
|
|
25
|
+
[
|
|
26
|
+
Tag(Tags.DISPLAY_IMAGE, "A"),
|
|
27
|
+
Match(
|
|
28
|
+
Tags.BATTERY_PERCENTAGE,
|
|
29
|
+
[
|
|
30
|
+
Tag(Tags.DISPLAY_IMAGE, "B"),
|
|
31
|
+
Tag(Tags.DISPLAY_IMAGE, "C"),
|
|
32
|
+
Tag(Tags.DISPLAY_IMAGE, "D"),
|
|
33
|
+
Tag(Tags.DISPLAY_IMAGE, "E"),
|
|
34
|
+
Tag(Tags.DISPLAY_IMAGE, "F"),
|
|
35
|
+
],
|
|
36
|
+
),
|
|
37
|
+
],
|
|
38
|
+
)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Would `__repr__` to:
|
|
42
|
+
```c
|
|
43
|
+
%?bp<%xd(A)|%?bl<%xd(B)|%xd(C)|%xd(D)|%xd(E)|%xd(F)>>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Install
|
|
47
|
+
|
|
48
|
+
To install locally, make sure you have the following installed:
|
|
49
|
+
* A modern version of Python 3 (I target 3.14)
|
|
50
|
+
* git
|
|
51
|
+
* pip
|
|
52
|
+
|
|
53
|
+
First, clone the repository:
|
|
54
|
+
```sh
|
|
55
|
+
git clone https://git.0stormy.xyz/stormy/python-rockbox.git
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Next, change directories into the folder you just cloned:
|
|
59
|
+
```sh
|
|
60
|
+
cd python-rockbox
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Finally, install it locally with:
|
|
64
|
+
```sh
|
|
65
|
+
pip install -e .
|
|
66
|
+
```
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
python_rockbox/__init__.py,sha256=Qw9EQK2LUs0kjJ4ELUPODbJiLsqTaxyAAZmsYSEmVCY,102
|
|
2
|
+
python_rockbox/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
+
python_rockbox/tags.py,sha256=S_ZtZGZU2qC-b3pdfg8XT2QI-mDFvsS4eTbZnQFOlXo,4946
|
|
4
|
+
python_rockbox/wps.py,sha256=C-m_IXiqcWDJwA0mlj_w5kB4Yn_TEO7X0dQHAUZ7r34,2234
|
|
5
|
+
python_rockbox-0.1.0.dist-info/WHEEL,sha256=jK0lbM7sVtq70msNoYotEXYS3OJMDdns2CRgyjhimnE,81
|
|
6
|
+
python_rockbox-0.1.0.dist-info/METADATA,sha256=x6TgsM1JfiZkW6CnUkfoR1lTfqwTEomuCcB7B_Z0nsA,1383
|
|
7
|
+
python_rockbox-0.1.0.dist-info/RECORD,,
|