-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnow_playing.d
More file actions
133 lines (110 loc) · 3.56 KB
/
Copy pathnow_playing.d
File metadata and controls
133 lines (110 loc) · 3.56 KB
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
import std.conv;
import std.file;
import std.stdio;
import std.string;
import std.process;
string get_elevation() {
auto result = executeShell("command -v doas");
if (result.status != 0)
return "sudo";
return "doas";
}
bool have_playerctl() {
string sudo = get_elevation();
auto result = executeShell("command -v playerctl");
if (result.status != 0) {
// When playerctl is not found:
// Prompt to install with typical package managers.
writeln("Please install playerctl.\n");
writefln("%s apt install playerctl", sudo);
writefln("%s pacman -S playerctl", sudo);
writefln("%s xbps-install -S playerctl\n", sudo);
}
return result.status == 0;
}
bool check_not_playing() {
auto result = executeShell("playerctl metadata");
return result.status != 0;
}
int display_error(string message) {
writefln("Error: %s.\n", message);
return -1;
}
int print_playing(string[] players, string[] filters, int num_chars) {
if (players.length == 0) {
return display_error("No players configured");
}
string cmd = format("playerctl --player=%s metadata --format \"{{ artist }} - {{ title }}\"",
strip(players.join(",")));
auto playing = executeShell(format("%s | cut -c1-%d", strip(cmd), num_chars));
string track = strip(playing.output);
// Apply filters to track.
foreach (f; filters) {
track = track.replace(f, "");
}
// Fix spacing.
track = track.replace("- ", "-");
track = track.replace(" ", " ");
writeln(strip(track));
return 0;
}
string[] read_cfg(string cfg_file) {
string[] items = new string[0];
if (!exists(cfg_file)) {
return items;
}
auto f = File(cfg_file);
foreach (line; f.byLine()) {
string l = strip(to!string(line));
// Ignore any comment lines in configuration file.
if (!l.startsWith("#")) {
if (cfg_file == "/etc/now_playing/players.cfg") {
l = l.toLower(); // players should be in lowercase.
}
items ~= l; // Append player (priority order) or filters.
}
}
return items;
}
int display_usage(string program, int num_chars) {
writefln("Usage: %s [-h|--help][-t|--truncate n]", program);
writeln("\nWhere n is number of characters to truncate to (n > 0).");
writefln("If the -t switch is omitted, that is %d chars.", num_chars);
return 0;
}
int main(string[] args) {
immutable string program = "now_playing";
int num_chars = 48; // Truncate now_playing track to 48 characters by default.
if (args.length > 1) {
int i = 0;
foreach (a; args) {
if (a == "-h" || a == "--help") {
return display_usage(program, num_chars);
}
else if ((args.length == 3)
&& (a == "-t" || a == "--truncate")) {
try {
num_chars = to!int(args[(i+1)]);
if (num_chars <= 0) {
return display_error("Truncation must be > 0 chars");
}
}
catch (Exception) {
return display_error("Truncation must be an integer");
}
}
i++;
}
}
if (!have_playerctl())
return -1;
if (check_not_playing()) {
writeln("...");
return 0;
}
immutable string cfg_dir = "/etc/now_playing";
return print_playing(
read_cfg(format("%s/players.cfg", cfg_dir)),
read_cfg(format("%s/filters.cfg", cfg_dir)),
num_chars);
}