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