add paging support
[noxon-gateway.git] / www / index.php
1 <?php
2 require_once __DIR__ . '/../src/header.php';
3
4 if (strtolower($fullUri) == '/setupapp/radio567/asp/browsexpa/loginxml.asp?token=0'
5     || $fullUri == '/RadioNativeLogin.phpb'
6 ) {
7     //initial login for "internet radio", podcasts and "my noxon"
8     header('Content-type: text/html');
9     readfile($dataDir . 'login-camelcase.xml');
10     exit();
11 } else if ($path == '/setupapp/radio567/asp/BrowseXPA/LoginXML.asp') {
12     //"Internet Radio"
13     $path = '/internetradio/';
14 } else if ($path == '/setupapp/radio567/asp/BrowseXPA/navXML.asp') {
15     //"Podcasts"
16     $path = '/podcasts/';
17 } else if ($path == '/RadioNative.php') {
18     //"My Noxon"
19     $path = '/mynoxon/';
20 } else if ($path == '/setupapp/radio567/asp/BrowseXML/FavXML.asp') {
21     //Internet Radio Station favorites favorited on device
22     sendMessage('Unsupported');
23 } else if ($path == '/RadioNativeFavorites.php') {
24     //Favorites, defined via web interface
25     sendMessage('Unsupported');
26 }
27
28 handleRequest(ltrim($path, '/'));
29
30 function handleRequest($path)
31 {
32     global $varDir;
33     if (strpos($path, '..') !== false) {
34         sendMessage('No');
35         return;
36     }
37
38     if (substr($path, 0, 14) == 'internetradio/') {
39         require_once 'mediatomb.php';
40         handleMediatomb('browse', $path, 'internetradio/');
41         return;
42     } else if (substr($path, 0, 11) == '.mt-single/') {
43         require_once 'mediatomb.php';
44         handleMediatomb('single', $path, '.mt-single/');
45         return;
46     }
47
48
49     $fullPath = $varDir . $path;
50     if (!file_exists($fullPath)) {
51         sendMessage('Not found: ' . $path);
52         return;
53     }
54
55     $ext = pathinfo($path, PATHINFO_EXTENSION);
56     if (is_dir($fullPath)) {
57         sendDir($path);
58     } else if ($ext == 'url') {
59         require_once 'podcasts.php';
60         sendPodcast($path);
61     } else if ($ext == 'txt') {
62         sendTextFile($path);
63     } else if (is_executable($fullPath)) {
64         sendScript($path);
65     } else {
66         sendMessage('Unknown file type');
67     }
68 }
69
70 function pathEncode($urlPath)
71 {
72     return str_replace('%2F', '/', rawurlencode($urlPath));
73 }
74
75 function sendDir($path)
76 {
77     global $varDir;
78
79     $listItems = array();
80     $enablePaging = true;
81
82     $entries = glob(str_replace('//', '/', $varDir . rtrim($path, '/') . '/*'));
83     $count = 0;
84     foreach ($entries as $entry) {
85         $urlPath = pathEncode(substr($entry, strlen($varDir)));
86         $ext = pathinfo($entry, PATHINFO_EXTENSION);
87
88         $titleBase = basename($entry);
89         $titleBase = preg_replace('#^[0-9]+_#', '', $titleBase);
90         if (is_dir($entry)) {
91             ++$count;
92             $listItems[] = getDirItem($titleBase, $urlPath . '/');
93         } else if ($ext == 'url') {
94             //podcast
95             ++$count;
96             $listItems[] = getPodcastItem(basename($titleBase, '.url'), $urlPath);
97         } else if (is_executable($entry)
98             && strpos(basename($entry), '.auto') !== false
99         ) {
100             //automatically execute script while listing this directory
101             addScriptOutput($listItems, $entry);
102             $enablePaging = false;
103         } else if ($ext == 'txt' || is_executable($entry)) {
104             //plain text file
105             ++$count;
106             $listItems[] = getDirItem(basename($titleBase, '.' . $ext), $urlPath);
107         }
108     }
109     if (!$count) {
110         $listItems[] = getMessageItem('No files or folders');
111     }
112     sendListItems($listItems, buildPreviousItem($path), $enablePaging);
113 }
114
115 function sendScript($path)
116 {
117     global $varDir;
118
119     $listItems = array();
120
121     $fullPath = $varDir . $path;
122     addScriptOutput($listItems, $fullPath);
123     sendListItems($listItems, buildPreviousItem($path), false);
124 }
125
126 function addScriptOutput(&$listItems, $fullPath)
127 {
128     exec($fullPath . ' 2>&1', $output, $retVal);
129
130     if ($retVal == 0) {
131         addTextLines($listItems, $output);
132     } else {
133         $listItems[] = getMessageItem('Error executing script');
134         addTextLines($listItems, $output);
135     }
136 }
137
138 function sendTextFile($path)
139 {
140     global $varDir;
141     $listItems = array();
142
143     $lines = file($varDir . $path);
144     addTextLines($listItems, $lines);
145     sendListItems($listItems, buildPreviousItem($path));
146 }
147
148 function addTextLines(&$listItems, $lines)
149 {
150     foreach ($lines as $line) {
151         $line = trim($line);
152         if ($line != '') {
153             $listItems[] = getDisplayItem($line);
154         }
155     }
156 }
157
158 function getDisplayItem($line)
159 {
160     $line = preg_replace('#\s+#', ' ', $line);
161     return '<Item>'
162         . '<ItemType>Display</ItemType>'
163         . '<Display>' . nox_esc($line) . '</Display>'
164         . '</Item>';
165 }
166
167 function getDirItem($title, $urlPath)
168 {
169     global $host1, $host2;
170     return '<Item>'
171         . '<ItemType>Dir</ItemType>'
172         . '<Title>' . nox_esc($title) . '</Title>'
173         . '<UrlDir>' . $host1 . nox_esc($urlPath) . '</UrlDir>'
174         . '<UrlDirBackUp>' . $host2 . nox_esc($urlPath) . '</UrlDirBackUp>'
175         . '</Item>';
176 }
177
178 function getEpisodeItem($title, $fullUrl, $desc, $type)
179 {
180     return '<Item>'
181         . '<ItemType>ShowEpisode</ItemType>'
182         . '<ShowEpisodeName>' . nox_esc($title) . '</ShowEpisodeName>'
183         . '<ShowEpisodeURL>' . htmlspecialchars($fullUrl) . '</ShowEpisodeURL>'
184         . '<ShowDesc>' . nox_esc($desc) . '</ShowDesc>'
185         . '<ShowMime>' . $type . '</ShowMime>'
186         . '</Item>';
187 }
188
189 function getPodcastItem($title, $urlPath)
190 {
191     global $host1;
192     return '<Item>'
193         . '<ItemType>ShowOnDemand</ItemType>'
194         . '<ShowOnDemandName>' . nox_esc($title) . '</ShowOnDemandName>'
195         . '<ShowOnDemandURL>' . $host1 . nox_esc($urlPath) . '</ShowOnDemandURL>'
196         . '</Item>';
197 }
198
199 function getMessageItem($msg)
200 {
201     return '<Item>'
202         . '<ItemType>Message</ItemType>'
203         . '<Message>' . nox_esc($msg) . '</Message>'
204         . '</Item>';
205 }
206
207 function getPreviousItem($urlPath)
208 {
209     global $host1, $host2;
210     return '<Item>'
211         . '<ItemType>Previous</ItemType>'
212         . '<UrlPrevious>' . $host1 . nox_esc($urlPath) . '</UrlPrevious>'
213         . '<UrlPreviousBackUp>' . $host1 . nox_esc($urlPath) . '</UrlPreviousBackUp>'
214         . '</Item>';
215 }
216
217 function buildPreviousItem($urlPath)
218 {
219     $parentDir = dirname($urlPath) . '/';
220     if ($parentDir == '/') {
221         return null;
222     }
223     return getPreviousItem($parentDir);
224 }
225
226 function nox_esc($string)
227 {
228     return utf8_decode(htmlspecialchars($string));
229 }
230
231 function sendMessage($msg)
232 {
233     sendListItems(array(getMessageItem($msg)));
234 }
235
236 function sendListItems($listItems, $previous = null, $enablePaging = true)
237 {
238     $startitems = 1;
239     $enditems   = 100000;
240     if (isset($_GET['startitems'])) {
241         $startitems = (int) $_GET['startitems'];
242     }
243     if (isset($_GET['enditems'])) {
244         $enditems = (int) $_GET['enditems'];
245     }
246
247     if ($enablePaging) {
248         $itemCount = count($listItems);
249     } else {
250         $itemCount = -1;
251     }
252     if ($previous !== null) {
253         $previous .= "\n";
254     }
255
256     $xml = '<?xml version="1.0" encoding="iso-8859-1"?>' . "\n";
257     $xml .= '<?xml-stylesheet type="text/xsl" href="/html.xsl"?>' . "\n";
258     $xml .= '<ListOfItems>' . "\n";
259     $xml .= '<ItemCount>' . $itemCount . '</ItemCount>' . "\n";
260     $xml .= $previous;
261
262     $num = 0;
263     foreach ($listItems as $item) {
264         ++$num;
265         if (!$enablePaging || ($num >= $startitems && $num <= $enditems)) {
266             $xml .= $item . "\n";
267         }
268     }
269     $xml .= "</ListOfItems>\n";
270
271     header('Content-type: text/xml; charset=iso-8859-1');
272     echo $xml;
273 }
274 ?>