1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
|
{ lib, ... }:
let
ocrContent = "Music Test";
musicFileName = "Example";
musicFile = "${musicFileName}.mp3";
ocrPauseColor = "#FF00FF";
ocrStartColor = "#00FFFF";
in
{
name = "lomiri-music-app-standalone";
meta.maintainers = lib.teams.lomiri.members;
nodes.machine =
{ config, pkgs, ... }:
{
imports = [
./common/auto.nix
./common/user-account.nix
./common/x11.nix
];
services.xserver.enable = true;
environment = {
# Setup video
etc."${musicFile}".source =
pkgs.runCommand musicFile
{
nativeBuildInputs = with pkgs; [
ffmpeg # produce music
(imagemagick.override { ghostscriptSupport = true; }) # produce OCR-able cover image
];
}
''
magick -size 400x400 canvas:white -pointsize 40 -fill black -annotate +100+100 '${ocrContent}' output.png
ffmpeg -re \
-f lavfi -i anullsrc=channel_layout=mono:sample_rate=44100 \
-i output.png \
-map 0:0 -map 1:0 \
-id3v2_version 3 \
-metadata:s:v title="Album cover" \
-metadata:s:v comment="Cover (front)" \
-t 120 \
$out -loglevel fatal
'';
systemPackages =
with pkgs;
[
xdg-user-dirs # generate XDG dirs
xdotool # mouse movement
]
++ (with pkgs.lomiri; [
mediascanner2
lomiri-music-app
lomiri-thumbnailer
# To check if playback actually works, or is broken due to missing codecs, we need to make the app's icons more OCR-able
(lib.meta.hiPrio (
suru-icon-theme.overrideAttrs (old: {
# Colour the background in special colours, which we can OCR for
postPatch = (old.postPatch or "") + ''
substituteInPlace suru/actions/scalable/media-playback-pause.svg \
--replace-fail 'fill:none' 'fill:${ocrPauseColor}'
substituteInPlace suru/actions/scalable/media-playback-start.svg \
--replace-fail 'fill:none' 'fill:${ocrStartColor}'
'';
})
))
]);
variables = {
UITK_ICON_THEME = "suru";
};
};
# Get mediascanner-2.0.service
services.desktopManager.lomiri.enable = lib.mkForce true;
# ...but stick with icewm
services.displayManager.defaultSession = lib.mkForce "none+icewm";
systemd.tmpfiles.settings = {
"10-lomiri-music-app-test-setup" = {
"/root/Music".d = {
mode = "0755";
user = "root";
group = "root";
};
"/root/Music/${musicFile}"."C+".argument = "/etc/${musicFile}";
};
};
i18n.supportedLocales = [ "all" ];
};
enableOCR = true;
testScript = ''
from collections.abc import Callable
import tempfile
import subprocess
pauseColor: str = "${ocrPauseColor}"
startColor: str = "${ocrStartColor}"
# Based on terminal-emulators.nix' check_for_pink
def check_for_color(color: str) -> Callable[[bool], bool]:
def check_for_color_retry(final=False) -> bool:
with tempfile.NamedTemporaryFile() as tmpin:
machine.send_monitor_command("screendump {}".format(tmpin.name))
cmd = 'convert {} -define histogram:unique-colors=true -format "%c" histogram:info:'.format(
tmpin.name
)
ret = subprocess.run(cmd, shell=True, capture_output=True)
if ret.returncode != 0:
raise Exception(
"image analysis failed with exit code {}".format(ret.returncode)
)
text = ret.stdout.decode("utf-8")
return color in text
return check_for_color_retry
machine.wait_for_x()
# mediascanner2 needs XDG dirs to exist
machine.succeed("xdg-user-dirs-update")
# mediascanner2 needs to have run, is only started automatically by Lomiri
machine.systemctl("start mediascanner-2.0.service", "root")
# Need to wait abit to make sure our test file gets scanned & added to the database.
# No good feedback on when this is done... Prolly some time after extractor sub-service is started.
machine.wait_for_console_text("Started \S*com.lomiri.MediaScanner2.Extractor")
machine.sleep(10)
with subtest("lomiri music launches"):
machine.succeed("lomiri-music-app >&2 &")
machine.wait_for_console_text("Queue is empty")
machine.sleep(10)
machine.send_key("alt-f10")
machine.sleep(2)
machine.wait_for_text("favorite music")
machine.screenshot("lomiri-music")
with subtest("lomiri music plays music"):
machine.succeed("xdotool mousemove 30 720 click 1") # Skip intro
machine.sleep(2)
machine.wait_for_window("Albums")
machine.succeed("xdotool mousemove 25 45 click 1") # Open categories
machine.sleep(2)
machine.succeed("xdotool mousemove 25 240 click 1") # Switch to Tracks category
machine.sleep(2)
machine.wait_for_window("Tracks")
machine.screenshot("lomiri-music_listing")
# Ensure pause colours isn't present already
assert (
check_for_color(pauseColor)(True) == False
), "pauseColor {} was present on the screen before we selected anything!".format(pauseColor)
machine.succeed("xdotool mousemove 25 120 click 1") # Select the track
# Waiting for pause icon to be displayed
with machine.nested("Waiting for the screen to have pauseColor {} on it:".format(pauseColor)):
retry(check_for_color(pauseColor))
machine.screenshot("lomiri-music_playback")
# Ensure play colours isn't present already
assert (
check_for_color(startColor)(True) == False
), "startColor {} was present on the screen before we were expecting it to be!".format(startColor)
machine.succeed("xdotool mousemove 860 480 click 1") # Pause track (only works if app can actually decode the file)
# Waiting for play icon to be displayed
with machine.nested("Waiting for the screen to have startColor {} on it:".format(startColor)):
retry(check_for_color(startColor))
machine.screenshot("lomiri-music_paused")
# Lastly, check if song details like title & generated cover image got extracted properly
# if not, indicates an issue with mediascanner / lomiri-thumbnailer
machine.wait_for_text("${musicFileName}")
machine.wait_for_text("${ocrContent}")
machine.succeed("pkill -f lomiri-music-app")
with subtest("lomiri music localisation works"):
machine.succeed("env LANG=de_DE.UTF-8 lomiri-music-app .mp4 >&2 &")
machine.wait_for_console_text("Restoring library queue")
machine.sleep(10)
machine.send_key("alt-f10")
machine.sleep(2)
machine.wait_for_window("Titel")
machine.screenshot("lomiri-music_localised")
'';
}
|