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
|
<?php
/**
* Functions the panel frontends access to display their data,
* usually via AJAX calls.
*/
class ApiPanelFrontend
{
/**
* Gets the pc states of the given locations.
*
* @param int[] $idList list of the location ids.
* @return array aggregated PC states
*/
public static function getPcStates(array $idList, string $paneluuid): array
{
$pcStates = array();
foreach ($idList as $id) {
$pcStates[$id] = array(
'id' => $id,
'idle' => 0,
'occupied' => 0,
'offline' => 0,
'broken' => 0,
'standby' => 0,
);
}
$locationInfoList = array();
InfoPanel::appendMachineData($locationInfoList, $idList);
$panel = Database::queryFirst('SELECT paneluuid, panelconfig FROM locationinfo_panel WHERE paneluuid = :paneluuid',
compact('paneluuid'));
$config = json_decode($panel['panelconfig'], true);
foreach ($locationInfoList as $locationInfo) {
$id = $locationInfo['id'];
foreach ($locationInfo['machines'] as $pc) {
$key = strtolower($pc['pcState']);
if (isset($pcStates[$id][$key])) {
if ($config['roomplanner']) {
if (isset($pc['x']) && isset($pc['y'])) {
$pcStates[$id][$key]++;
}
} else {
$pcStates[$id][$key]++;
}
}
}
}
return array_values($pcStates);
}
/**
* Generates a web application manifest for a panel.
*
* @param string $uuid The UUID of the panel.
* @return array The generated manifest file data.
*/
public static function generateManifest(string $uuid): array
{
$row = Database::queryFirst("SELECT panelname FROM locationinfo_panel WHERE paneluuid = :paneluuid",
['paneluuid' => $uuid]);
if ($row === false)
return ['error' => 'Not found'];
$data = [
"name" => $row['panelname'],
"short_name" => $row['panelname'],
"start_url" => "/panel/$uuid",
"display_override" => [
"fullscreen",
"standalone",
"tabbed",
"minimal-ui"
],
"display" => "fullscreen",
"icons" => [
[
"src" => "/panel/style/icon.svg",
"sizes" => "any",
"type" => "image/svg+xml"
]
],
];
foreach (glob('style/icon*.png', GLOB_NOSORT) as $file) {
if (!preg_match('/icon(\d+)\.png$/', $file, $m))
continue;
$data['icons'][] = [
"src" => "/panel/$file",
"sizes" => "${m[1]}x${m[1]}",
"type" => "image/png",
];
}
return $data;
}
/**
* Get last config modification timestamp for given panel.
* This is incomplete however, as it wouldn't react to the
* linked room plan being edited, or added/removed PCs
* etc. So the advice would simply be "if you want the
* panel to reload automatically, hit the edit button
* and click save". Might even add a shortcut
* reload-button to the list of panels at some point.
*
* @param string $paneluuid panels uuid
* @return int UNIX_TIMESTAMP
*/
public static function getLastChangeTs(string $paneluuid): int
{
$panel = Database::queryFirst('SELECT lastchange, locationids FROM locationinfo_panel WHERE paneluuid = :paneluuid',
compact('paneluuid'));
if ($panel === false) {
http_response_code(404);
die('Panel not found');
}
$lastChange = array((int)$panel['lastchange']);
if (!empty($panel['locationids'])) {
$res = Database::simpleQuery('SELECT lastchange FROM locationinfo_locationconfig
WHERE locationid IN (:locs)', array('locs' => explode(',', $panel['locationids'])));
while (($lc = $res->fetchColumn()) !== false) {
$lastChange[] = (int)$lc;
}
}
return max($lastChange);
}
}
|