commit eea2a9a4b26b0c43e35c980e13abd6e5833564ff Author: Steffen Vogel Date: Tue Aug 17 01:22:49 2010 +0200 initial import diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f16baa8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.settings +.cproject +.project +.classpath + diff --git a/README b/README new file mode 100644 index 0000000..4f7faed --- /dev/null +++ b/README @@ -0,0 +1,29 @@ +Here are the urls which i extracted out of the Noxon firmware: + +RadioNativeEntries +RadioNative01 + RootName Podcasts + RootUrl http://radio567.vtuner.com/setupapp/radio567/asp/BrowseXML/navXML.asp?gofile=S-ByLocation + LoginUrl http://radio567.vtuner.com/setupapp/radio567/asp/BrowseXML/loginXML.asp?token=0 + RetrieveFavsURL http://radio567.vtuner.com/setupapp/radio567/asp/BrowseXML/FavXML.asp?empty=&sFavName=My%5F%5FFavorites + +RadioNative02 + RootName My NOXON + RootUrl http://gatekeeper.my-noxon.net/RadioNative.php + LoginUrl http://gatekeeper.my-noxon.net/RadioNativeLogin.php + RetrieveFavsURL http://gatekeeper.my-noxon.net/RadioNativeFavorites.php + +RadioNative03 + RootName StarXed Services + RootUrl http://starxed.homelinux.org/radionative-multi/index.xml + LoginUrl http://noxonserver.de/RadioNativeLogin.php + RetrieveFavsURL http://starxed.homelinux.org/radionative-multi/favs.php + +MultiRadioStationDB +MRSDB01 + UserFriendlyName Internet Radio + url0 http://www.radio579.com/setupapp/bluewin/asp/rsdb/update.asp + +Here a sample url request to vtuner for the rsdb (mac and uid changed): + +http://www.radio579.com/setupapp/bluewin/asp/rsdb/update.asp?mac=############&uid=############################&ver=EMPTY&xml=2.0&mime=audio/mpeg-url&sw=24.6392&bl=6166&hw=158.0&up=13693&lang=ger&st=15167&rel=0 diff --git a/Server/add.php b/Server/add.php new file mode 100644 index 0000000..70b9931 --- /dev/null +++ b/Server/add.php @@ -0,0 +1,45 @@ += ' . $row['rgt'] , $site['db']['connection']); + mysql_query('UPDATE tree SET lft=lft+2 WHERE lft > ' . $row['rgt'] , $site['db']['connection']); + mysql_query('INSERT INTO nodes SET + name = \'' . $_POST['name'] . '\', + type = \'' . $_POST['type'] . '\', + description = \'' . $_POST['description'] . '\', + bitrate = ' . (int) $_POST['bitrate'] . ', + url = \'' . $_POST['url'] . '\', + mime_type = \'' . $_POST['mime_type'] . '\', + location = \'' . $_POST['location'] . '\', + bookmark = \'' . $_POST['bookmark'] . '\'', $site['db']['connection']); + mysql_query('INSERT INTO tree (node_id, lft, rgt) VALUES (' . mysql_insert_id() . ', ' . $row['rgt'] . ', ' . $row['rgt'] . ' + 1)' , $site['db']['connection']); + echo 'Node added successfully!
+ back'; +} +else { + echo '
+ + + + + + + + + +
Type
Name
Description
Bitrate
URL
Mime Type
Location
Bookmark
+ +
'; +} +?> \ No newline at end of file diff --git a/Server/arrow_down.png b/Server/arrow_down.png new file mode 100644 index 0000000..2c4e279 Binary files /dev/null and b/Server/arrow_down.png differ diff --git a/Server/arrow_left.png b/Server/arrow_left.png new file mode 100644 index 0000000..5dc6967 Binary files /dev/null and b/Server/arrow_left.png differ diff --git a/Server/arrow_right.png b/Server/arrow_right.png new file mode 100644 index 0000000..b1a1819 Binary files /dev/null and b/Server/arrow_right.png differ diff --git a/Server/arrow_up.png b/Server/arrow_up.png new file mode 100644 index 0000000..1ebb193 Binary files /dev/null and b/Server/arrow_up.png differ diff --git a/Server/config.php b/Server/config.php new file mode 100644 index 0000000..96442f7 --- /dev/null +++ b/Server/config.php @@ -0,0 +1,30 @@ + \ No newline at end of file diff --git a/Server/control_play.png b/Server/control_play.png new file mode 100644 index 0000000..0846555 Binary files /dev/null and b/Server/control_play.png differ diff --git a/Server/del.php b/Server/del.php new file mode 100644 index 0000000..cf9b953 --- /dev/null +++ b/Server/del.php @@ -0,0 +1,25 @@ +'; +} +else { + $result = mysql_query('SELECT lft, rgt, node_id FROM tree WHERE id = ' . (int) $_GET['id'] . ' LIMIT 1', $site['db']['connection']); + $row = mysql_fetch_assoc($result); + + if (mysql_num_rows($result) < 2) + mysql_query('DELETE FROM nodes WHERE id = ' . (int) $row['node_id'], $site['db']['connection']); + mysql_query('DELETE FROM tree WHERE lft BETWEEN ' . $row['lft'] . ' AND ' . $row['rgt'], $site['db']['connection']); + mysql_query('UPDATE tree SET lft=lft-ROUND((' . $row['rgt'] . ' - ' . $row['lft'] . ' + 1)) WHERE lft > ' . $row['rgt'], $site['db']['connection']); + mysql_query('UPDATE tree SET rgt=rgt-ROUND((' . $row['rgt'] . ' - ' . $row['lft'] . ' + 1)) WHERE rgt > ' . $row['rgt'], $site['db']['connection']); + + echo 'Node successfully deleted!
'; +} + +echo 'back'; + +?> \ No newline at end of file diff --git a/Server/delete.png b/Server/delete.png new file mode 100644 index 0000000..08f2493 Binary files /dev/null and b/Server/delete.png differ diff --git a/Server/directory.png b/Server/directory.png new file mode 100644 index 0000000..784e8fa Binary files /dev/null and b/Server/directory.png differ diff --git a/Server/display.png b/Server/display.png new file mode 100644 index 0000000..8b8b1ca Binary files /dev/null and b/Server/display.png differ diff --git a/Server/edit.php b/Server/edit.php new file mode 100644 index 0000000..7becf06 --- /dev/null +++ b/Server/edit.php @@ -0,0 +1,46 @@ + + back'; +} +else { + $result = mysql_query('SELECT * FROM nodes WHERE id = ' . (int) $_GET['id'], $site['db']['connection']); + $row = mysql_fetch_assoc($result); + + echo '
+ + + + + + + + + +
Type
Name
Description
Bitrate
URL
Mime Type
Location
Bookmark
+ +
'; +} + +?> \ No newline at end of file diff --git a/Server/edit.png b/Server/edit.png new file mode 100644 index 0000000..0bfecd5 Binary files /dev/null and b/Server/edit.png differ diff --git a/Server/functions.php b/Server/functions.php new file mode 100644 index 0000000..af6d32a --- /dev/null +++ b/Server/functions.php @@ -0,0 +1,11 @@ + \ No newline at end of file diff --git a/Server/import_vtuner.php b/Server/import_vtuner.php new file mode 100644 index 0000000..b4405c8 --- /dev/null +++ b/Server/import_vtuner.php @@ -0,0 +1,156 @@ + + + + + VTuner.com Importer + + + +

VTuner.com Importer

'; + +//$rsdb_xml = file_get_contents($config['vtuner']['url'] . '?mac=' . $config['noxon']['mac'] . '&uid=' . $config['vtuner']['uid'] . '&lang=' . $config['vtuner']['lang']); +$rsdb_xml = file_get_contents('../full_rsdb.xml'); + +$rsdb_dom = new DOMDocument(); +$rsdb_dom->preserveWhiteSpace = false; +$rsdb_dom->loadXML($rsdb_xml); + +if ($_GET['cmd'] == 'import') { + // Stations + $stationList = $rsdb_dom->getElementsByTagName('station_list')->item(0); + echo $stationList->getElementsByTagName('station')->length . ' Stationen'; + + $counter = 0; + $sql_pre = 'REPLACE INTO nodes (id, type, name, description, bitrate, url, mime_type) VALUES ' . "\n"; + + foreach ($stationList->getElementsByTagName('station') as $station) { + if($counter % 50 == 0) { + $sql = substr($sql, 0, -3); + mysql_query($sql, $site['db']['connection']); + echo '.'; flush(); + $sql = $sql_pre; + } + $sql .= '(' . (int) $station->getElementsByTagName('id')->item(0)->nodeValue . ', \'station\', \'' . mysql_real_escape_string($station->getElementsByTagName('station_name')->item(0)->nodeValue) . '\', \'' . mysql_real_escape_string($station->getElementsByTagName('station_description')->item(0)->nodeValue) . '\', ' . (int) $station->getElementsByTagName('bw')->item(0)->nodeValue . ', \'' . mysql_real_escape_string($station->getElementsByTagName('url')->item(0)->nodeValue) . '\', \'' . mysql_real_escape_string($station->getElementsByTagName('mime_type')->item(0)->nodeValue) . '\'), ' . "\n"; + $counter++; + } + + if(mysql_affected_rows() > 0) { + echo '

' . $counter . ' stations successfully imported!

'; + } + else { + echo '

Sorry we had a problem during the importing process:
' . mysql_error() . '

'; + echo '
' . $sql . '
'; + } + + //Structure + $dirList = $rsdb_dom->getElementsByTagName('directory_list')->item(0); + + $sql = 'REPLACE INTO tree (node_id, lft, rgt) VALUES ' . "\n"; + + $curNode = $dirList; + $counter = 0; + $level = 0; + $lft[$level] = 0; + + while($curNode) { + switch ($curNode->nodeName) { + case 'dir': + mysql_query('REPLACE INTO nodes (type, name) VALUES (\'directory\', \'' . mysql_real_escape_string($curNode->attributes->getNamedItem('name')->nodeValue) . '\')'); + $id[$level] = mysql_insert_id(); + + //echo 'found dir: ' . $curNode->getAttribute('name') . ' and added to nodes with id: ' . mysql_insert_id() . '
'; + + break; + case 'station': + $id[$level] = (int) $curNode->nodeValue; + + //echo 'found station: ' . $curNode->nodeValue . '
'; + + break; + default: + break; + } + + if ($curNode->hasChildNodes() && strpos($curNode->nodeName, 'dir') !== false) { + $curNode = $curNode->firstChild; + $level++; + $lft[$level] = $lft[$level - 1] + 1; + + //echo 'entering subtree (level: ' . $level . ')
'; + } + else { + $rgt[$level] = $lft[$level] + 1; + $sql .= '(' . $id[$level] . ', ' . $lft[$level] . ', ' . $rgt[$level] . '), ' . "\n"; + echo 'next node (level: ' . $level . '): (' . $id[$level] . ', ' . $lft[$level] . ', ' . $rgt[$level] . ')
'; + $lft[$level] = $rgt[$level] + 1; + + if ($curNode->nextSibling) { + $curNode = $curNode->nextSibling; + } + else { + do { + $level--; + $rgt[$level] = $rgt[$level + 1] + 1; + $sql .= '(' . $id[$level] . ', ' . $lft[$level] . ', ' . $rgt[$level] . '), ' . "\n"; + echo 'leave subtree (level: ' . $level . '): (' . $id[$level] . ', ' . $lft[$level] . ', ' . $rgt[$level] . ')
'; + $lft[$level] = $rgt[$level] + 1; + + if ($level == 1) break 2; + + $curNode = $curNode->parentNode; + } while (!$curNode->nextSibling); + + $curNode = $curNode->nextSibling; + } + } + + + /*if($counter % 50 == 0 && $sql != '') { + $sql = substr($sql, 0, -3); + mysql_query($sql, $site['db']['connection']); + echo '.'; flush(); + $sql = $sql_pre; + echo mysql_error(); + }*/ + $counter++; + } + + $sql = substr($sql, 0, -3); + mysql_query($sql, $site['db']['connection']); + + if(mysql_affected_rows() > 0) { + echo '

' . $counter . ' nodes successfully imported!

'; + } + else { + echo '

Sorry we had a problem during the importing process:
' . mysql_error() . '

'; + } + + echo '
' . $sql . '
'; + +} +else { + echo '

Database Info

+ + + + + + + +
Version' . $rsdb_dom->firstChild->attributes->getNamedItem('version')->nodeValue . '
Stationen' . $rsdb_dom->firstChild->attributes->getNamedItem('station_count')->nodeValue . '
Format Version' . $rsdb_dom->firstChild->attributes->getNamedItem('format_version')->nodeValue . '
Server URL' . $rsdb_dom->getElementsByTagName('database_info')->item(0)->getElementsByTagName('server_url')->item(0)->nodeValue . '
Name' . $rsdb_dom->getElementsByTagName('database_info')->item(0)->getElementsByTagName('name')->item(0)->nodeValue . '
Service' . $rsdb_dom->getElementsByTagName('database_info')->item(0)->getElementsByTagName('service')->item(0)->nodeValue . '
+

Do you really want to import ' . $rsdb_dom->firstChild->attributes->getNamedItem('station_count')->nodeValue . ' Station to your DB?
+ YES

'; +} + +echo ' +'; + +?> \ No newline at end of file diff --git a/Server/index.php b/Server/index.php new file mode 100644 index 0000000..4b24d97 --- /dev/null +++ b/Server/index.php @@ -0,0 +1,39 @@ + + + + + Noxon Remote Radio Database Manager 1.0 + + + +

Noxon Remote Radio Database Manager

'; + +$result = mysql_query('SELECT * FROM (SELECT child.id, child.node_id, COUNT(*)-1 AS level, ROUND((child.rgt - child.lft - 1) / 2) AS offspring FROM tree AS child, tree AS parent WHERE child.lft BETWEEN parent.lft AND parent.rgt GROUP BY child.lft ORDER BY child.lft) tmptree INNER JOIN nodes ON nodes.id = tmptree.node_id', $site['db']['connection']); +//$result = mysql_query('SELECT * FROM (SELECT id, node_id FROM tree WHERE rgt = lft + 1 ORDER BY lft) tmptree LEFT JOIN nodes ON nodes.id = tmptree.node_id', $site['db']['connection']); + + + +echo ' + '; +while ($row = mysql_fetch_assoc($result)) { + echo ''; + + echo '' ; +} +echo '
NameLevelSubstationsActions
'; + for ($i = 0; $i < $row['level'] + 1; $i++) + echo '  '; + + echo ' ' . $row['name'] . '' . $row['level'] . '' . $row['offspring'] . '' . (($row['type'] == 'station') ? 'play' : '') . 'deleteedit
'; + +echo 'delete all'; + +echo ' +' + +?> \ No newline at end of file diff --git a/Server/init.php b/Server/init.php new file mode 100644 index 0000000..24b244e --- /dev/null +++ b/Server/init.php @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/Server/rsdb.php b/Server/rsdb.php new file mode 100644 index 0000000..15c5284 --- /dev/null +++ b/Server/rsdb.php @@ -0,0 +1,94 @@ +createElement('station_db'); + +$databaseInfo = $dom->createElement('database_info'); +$databaseInfo->appendChild($dom->createElement('format', $config['rsdb']['format_version'])); +$databaseInfo->appendChild($dom->createElement('name', $config['rsdb']['name'])); +$databaseInfo->appendChild($dom->createElement('server_url', 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'])); +$databaseInfo->appendChild($dom->createElement('service', $config['rsdb']['service'])); + +$stationList = new StationList($dom); + +$stationDb->appendChild($databaseInfo); +$stationDb->appendChild($stationList->getNode()); + + +$result = mysql_query('SELECT child.id, child.node_id, COUNT(*)-1 AS level FROM tree AS child, tree AS parent WHERE child.lft BETWEEN parent.lft AND parent.rgt GROUP BY child.lft ORDER BY child.lft', $site['db']['connection']); + +$directoryList = $dom->createElement('directory_list'); + + +$dom->appendChild($stationDb); + +echo $dom->saveXML(); + +class Station { + public $dom; + public $id = 0; + public $name; + public $description; + public $bitrate; + public $url; + public $mime_type; + + function Station($dom, $id, $name, $description, $bitrate, $url, $mime_type) { + $this->dom = $dom; + $this->id = $id; + $this->name = $name; + $this->description = $description; + $this->bitrate = $bitrate; + $this->url = $url; + $this->mime_type = $mime_type; + } + + function getNode() { + $station = $this->dom->createElement('station'); + $station->appendChild($this->dom->createElement('id', $this->id)); + $station->appendChild($this->dom->createElement('station_name', $this->name)); + $station->appendChild($this->dom->createElement('description', $this->description)); + $station->appendChild($this->dom->createElement('bw', $this->bitrate)); + $station->appendChild($this->dom->createElement('url', $this->url)); + $station->appendChild($this->dom->createElement('mime_type', $this->mime_type)); + + return $station; + } +} + +class StationList { + public $stations = array(); + private $dom; + + function StationList($dom) { + $this->dom = $dom; + } + + function getStations() { + global $config; + global $site; + + $stations = array(); + + $result = mysql_query('SELECT * FROM ' . $config['db']['tables']['nodes'] . ' WHERE type = \'station\'', $site['db']['connection']); + + while ($row = mysql_fetch_assoc($result)) { + array_push($stations, new Station($this->dom, $row['id'], $row['name'], $row['description'], $row['bitrate'], $row['url'], $row['mime_type'])); + } + return $stations; + } + + function getNode() { + $stationList = $this->dom->createElement('station_list'); + + foreach ($this->getStations() as $station) { + $stationList->appendChild($station->getNode()); + } + + return $stationList; + } + +} +?> \ No newline at end of file diff --git a/Server/services.php b/Server/services.php new file mode 100644 index 0000000..15c5adc --- /dev/null +++ b/Server/services.php @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/Server/sql.sql b/Server/sql.sql new file mode 100644 index 0000000..e96d46c --- /dev/null +++ b/Server/sql.sql @@ -0,0 +1 @@ +SELECT nodes.name, nodes.type, tmptree.id, tmptree.level FROM (SELECT child.id, child.node_id, COUNT(*)-1 AS level FROM tree AS child, tree AS parent WHERE child.lft BETWEEN parent.lft AND parent.rgt GROUP BY child.lft ORDER BY child.lft) tmptree LEFT JOIN nodes ON nodes.id = tmptree.node_id; \ No newline at end of file diff --git a/Server/station.png b/Server/station.png new file mode 100644 index 0000000..f54bf73 Binary files /dev/null and b/Server/station.png differ diff --git a/Server/stylesheet.css b/Server/stylesheet.css new file mode 100644 index 0000000..1dc8a50 --- /dev/null +++ b/Server/stylesheet.css @@ -0,0 +1,15 @@ +.button { + border: 0; +} + +.tree_table_head { + font-weight: bold; +} + +.add_space { + height: 5px; +} + +.add_space:hover { + background-color: #4BEC4E; +} \ No newline at end of file diff --git a/Server/up.png b/Server/up.png new file mode 100644 index 0000000..1ebb193 Binary files /dev/null and b/Server/up.png differ diff --git a/ampache/Noxon.plugin.php b/ampache/Noxon.plugin.php new file mode 100644 index 0000000..4c60fbe --- /dev/null +++ b/ampache/Noxon.plugin.php @@ -0,0 +1,147 @@ +load to + // fill em out + private $user; + private $pass; + private $serverCaption; + private $strAmpacheServerURL; + private $strAmpacheServerLANURL; + + /** + * Constructor + * This function does nothing... + */ + public function __construct() { + + return true; + } // PluginNoxon + + /** + * install + * This is a required plugin function it inserts the required preferences + * into Ampache + */ + public function install() { + + Preference::insert('noxon_user','Noxon Username','','25','string','plugins'); + Preference::insert('noxon_pass','Noxon Password','','25','string','plugins'); + Preference::insert('noxon_serverCaption','Noxon Server Caption','My ampache Server','25','string','plugins'); + Preference::insert('noxon_strAmpacheServerURL','Noxon Ampache URL',$this->getLocalNetworkURL(),'25','string','plugins'); + Preference::insert('noxon_strAmpacheServerLANURL','Noxon Ampache LAN URL (optional)',$this->getLocalNetworkURL(),'25','string','plugins'); + } // install + + /** + * uninstall + * This is a required plugin function it removes the required preferences from + * the database returning it to its origional form + */ + public function uninstall() { + + Preference::delete('noxon_user'); + Preference::delete('noxon_pass'); + Preference::delete('noxon_serverCaption'); + Preference::delete('noxon_strAmpacheServerURL'); + Preference::delete('noxon_strAmpacheServerLANURL'); + } // uninstall + + /** + * Error management + */ + public function _setError( $str ) { + $this->_errorStr = "
".$str; + } + + public function getError() { + return $this->_errorStr; + } + + /** + * load + * This loads up the data we need into this object, this stuff comes from the "Server Config plugins" + * it's passed as a key'd array + */ + public function load() { + + if (! $this->user = Config::get('noxon_user')) { + $this->_setError( "Error Noxon plugin: User Config not set" ); + return false; + } + + if (! $this->pass = Config::get('noxon_pass')) { + $this->_setError( "Error Noxon plugin: Password Config not set" ); + return false; + } + + if (! $this->serverCaption = ereg_replace( "[^0-9a-zA-Z_]", " ", Config::get('noxon_serverCaption'))) { + $this->_setError( "Error Noxon plugin: Server Caption Config not set" ); + return false; + } + + if (! $this->strAmpacheServerURL = Config::get('noxon_strAmpacheServerURL')) { + $this->_setError( "Error Noxon plugin: Ampache Server URL Config not set" ); + return false; + } + + /* optional */ + + $this->strAmpacheServerLANURL = Config::get('noxon_strAmpacheServerLANURL'); + + return true; + } + + public function register() { + + if ($this->load()) { + + $register = new RegisterMyNoxon($this->user, $this->pass, $this->strAmpacheServerURL, $this->strAmpacheServerLANURL, $this->serverCaption); + + if (! $ret = $register->register()) { + $this->_setError( $register->getError() ); + } + + return $ret; + } + return false; + } + + public function unregister() { + + if ($this->load()) { + + $register = new RegisterMyNoxon($this->user, $this->pass, $this->strAmpacheServerURL, $this->strAmpacheServerLANURL, $this->serverCaption); + + if (! $ret = $register->unregister()) { + $this->_setError( $register->getError() ); + } + + return $ret; + } + return false; + } + + /** + * SX: Get the expected URL of the Ampache Server in order to get a probably valid default + */ + private function getLocalNetworkURL() { + $strFileName = explode("admin/modules.php",$_SERVER['SCRIPT_NAME']); + return "http://".$_SERVER['HTTP_HOST'].":".$_SERVER['SERVER_PORT'].$strFileName[0]."modules/plugins/Noxon_xml.server.php"; + } + +} // end AmpacheNoxon + +?> \ No newline at end of file diff --git a/ampache/Noxon/AmpacheConnectorLocal.php b/ampache/Noxon/AmpacheConnectorLocal.php new file mode 100644 index 0000000..49fe58c --- /dev/null +++ b/ampache/Noxon/AmpacheConnectorLocal.php @@ -0,0 +1,264 @@ +_XMLStr2Array($xml, "id", array("name")); + } + + public function artist_albums($filter = null, $offset = null, $limit = null) { + + $artist = new Artist($filter); + + $albums = $artist->get_albums(); + + // Set the offset + xmlData::set_offset($offset); + xmlData::set_limit($limit); + $xml = xmlData::albums($albums); + + return $this->_XMLStr2Array($xml, "id", array("name", "artist", "year", "tracks", "disk", "art")); + } + + public function artist_songs($filter = null, $offset = null, $limit = null) { + + $artist = new Artist($filter); + $songs = $artist->get_songs(); + + // Set the offset + xmlData::set_offset($offset); + xmlData::set_limit($limit); + $xml = xmlData::songs($songs); + + return $this->_XMLStr2Array($xml, "id", array("title", "artist", "album", "genre", "track", "time", "url")); + } + + public function albums($filter = null, $offset = null, $limit = null) { + + Browse::reset_filters(); + Browse::set_type('album'); + Browse::set_sort('name','ASC'); + + if ($filter) { + Browse::set_filter('alpha_match',$filter); + } + $albums = Browse::get_objects(); + + // Set the offset + xmlData::set_offset($offset); + xmlData::set_limit($limit); + $xml = xmlData::albums($albums); + + return $this->_XMLStr2Array($xml, "id", array("name", "artist", "year", "tracks", "disk", "art")); + } + + public function album_songs($filter = null, $offset = null, $limit = null) { + + $album = new Album($filter); + $songs = $album->get_songs(); + + // Set the offset + xmlData::set_offset($offset); + xmlData::set_limit($limit); + $xml = xmlData::songs($songs); + + return $this->_XMLStr2Array($xml, "id", array("title", "artist", "album", "genre", "track", "time", "url")); + } + + public function genres($filter = null, $offset = null, $limit = null) { + + Browse::reset_filters(); + Browse::set_type('genre'); + Browse::set_sort('name','ASC'); + + if ($filter) { + Browse::set_filter('alpha_match',$filter); + } + $genres = Browse::get_objects(); + + // Set the offset + xmlData::set_offset($offset); + xmlData::set_limit($limit); + $xml = xmlData::genres($genres); + + return $this->_XMLStr2Array($xml, "id", array("name", "songs", "albums", "artists")); + } + + public function genre_artists($filter = null, $offset = null, $limit = null) { + + $genre = new Genre($filter); + $artists = $genre->get_artists(); + + xmlData::set_offset($offset); + xmlData::set_limit($limit); + $xml = xmlData::artists($artists); + + return $this->_XMLStr2Array($xml, "id", array("name")); + } + + public function genre_albums($filter = null, $offset = null, $limit = null) { + + $genre = new Genre($filter); + $albums = $genre->get_albums(); + + xmlData::set_offset($offset); + xmlData::set_limit($limit); + $xml = xmlData::albums($albums); + + return $this->_XMLStr2Array($xml, "id", array("name", "artist", "year", "tracks", "disk", "art")); + } + + public function genre_songs($filter = null, $offset = null, $limit = null) { + + $genre = new Genre($filter); + $songs = $genre->get_songs(); + + xmlData::set_offset($offset); + xmlData::set_limit($limit); + $xml = xmlData::songs($songs); + + return $this->_XMLStr2Array($xml, "id", array("title", "artist", "album", "genre", "track", "time", "url")); + } + + public function songs($filter = null, $offset = null, $limit = null) { + + Browse::reset_filters(); + Browse::set_type('song'); + Browse::set_sort('title','ASC'); + + if ($filter) { + Browse::set_filter('alpha_match',$filter); + } + $songs = Browse::get_objects(); + + // Set the offset + xmlData::set_offset($offset); + xmlData::set_limit($limit); + $xml = xmlData::songs($songs); + + return $this->_XMLStr2Array($xml, "id", array("title", "artist", "album", "genre", "track", "time", "url")); + } + + public function playlists($filter = null, $offset = null, $limit = null) { + + Browse::reset_filters(); + Browse::set_type('playlist'); + Browse::set_sort('name','ASC'); + + if ($filter) { + Browse::set_filter('alpha_match',$filter); + } + + $playlist_ids = Browse::get_objects(); + + xmlData::set_offset($offset); + xmlData::set_limit($limit); + $xml = xmlData::playlists($playlist_ids); + return $this->_XMLStr2Array($xml, "id", array("name", "owner", "items")); + } + + public function playlist_songs($filter = null, $offset = null, $limit = null) { + + $playlist = new Playlist($filter); + $items = $playlist->get_items(); + + foreach ($items as $object) { + if ($object['type'] == 'song') { + $songs[] = $object['object_id']; + } + } // end foreach + + xmlData::set_offset($offset); + xmlData::set_limit($limit); + $xml = xmlData::songs($songs); + + return $this->_XMLStr2Array($xml, "id", array("title", "artist", "album", "genre", "track", "time", "url")); + } + + public function isConnected() { + return true; + } + + /** + * Error management + */ + public function _setError( $str ) { + $this->_errorStr = "
".$str; + } + + public function getError() { + return $this->_errorStr; + } + + /** + PRIVATE FUNCTIONS + **/ + + private function _XMLStr2Array($xmlStr, $key, $fieldsList) { + // Repair a possibly broken XML String when the config Item is set + if (NoxonConfig::$repairXML) { + $xmlStr = str_replace("]]_setError("BAD_XML"); + return false; + } + + // valid request ? + if (isset($xml->error) === true) { + $this->_setError("INVALID_REQUEST"); + return false; + } + + $arr = array(); + foreach ($xml as $val) { + $tmp = array(); + foreach ($fieldsList as $field) { + $tmp[$field] = strval($val->$field); + } + $arr[strval($val[$key])] = $tmp; + } + + return ($arr); + } + +} + +?> \ No newline at end of file diff --git a/ampache/Noxon/AmpacheConnectorRemote.php b/ampache/Noxon/AmpacheConnectorRemote.php new file mode 100644 index 0000000..69665fd --- /dev/null +++ b/ampache/Noxon/AmpacheConnectorRemote.php @@ -0,0 +1,207 @@ +_serverUrl = $serverUrl; + $this->_key = $key; + + $xml = $this->_requestServer("handshake"); + + // valid login ? + if (isset($xml->auth) === false) { + $this->_setError("BAD_LOGIN"); + return; + } + + // Yeah, we are connected ! + $this->_isConnected = true; + // we keep the authorized key + $this->_auth = $xml->auth; + } + + /** + PUBLIC FUNCTIONS + **/ + + public function artists($filter = null, $offset = null, $limit = null) { + + if ($xml = $this->_requestServer("artists", $filter, $offset, $limit)) { + return $this->_XML2Array($xml, "id", array("name")); + } + return false; + } + + public function artist_albums($filter = null, $offset = null, $limit = null) { + + if ($xml = $this->_requestServer("artist_albums", $filter, $offset, $limit)) { + return $this->_XML2Array($xml, "id", array("name", "artist", "year", "tracks", "disk", "art")); + } + return false; + } + + public function artist_songs($filter = null, $offset = null, $limit = null) { + + if ($xml = $this->_requestServer("artist_songs", $filter, $offset, $limit)) { + return $this->_XML2Array($xml, "id", array("title", "artist", "album", "genre", "track", "time", "url")); + } + return false; + } + + public function albums($filter = null, $offset = null, $limit = null) { + + if ($xml = $this->_requestServer("albums", $filter, $offset, $limit)) { + return $this->_XML2Array($xml, "id", array("name", "artist", "year", "tracks", "disk", "art")); + } + return false; + } + + public function album_songs($filter = null, $offset = null, $limit = null) { + + if ($xml = $this->_requestServer("album_songs", $filter, $offset, $limit)) { + return $this->_XML2Array($xml, "id", array("title", "artist", "album", "genre", "track", "time", "url")); + } + return false; + } + + public function genres($filter = null, $offset = null, $limit = null) { + + if ($xml = $this->_requestServer("genres", $filter, $offset, $limit)) { + return $this->_XML2Array($xml, "id", array("name", "songs", "albums", "artists")); + } + return false; + } + + public function genre_artists($filter = null, $offset = null, $limit = null) { + + if ($xml = $this->_requestServer("genre_artists", $filter, $offset, $limit)) { + return $this->_XML2Array($xml, "id", array("name")); + } + return false; + } + + public function genre_albums($filter = null, $offset = null, $limit = null) { + + if ($xml = $this->_requestServer("genre_albums", $filter, $offset, $limit)) { + return $this->_XML2Array($xml, "id", array("name", "artist", "year", "tracks", "disk", "art")); + } + return false; + } + + public function genre_songs($filter = null, $offset = null, $limit = null) { + + if ($xml = $this->_requestServer("genre_songs", $filter, $offset, $limit)) { + return $this->_XML2Array($xml, "id", array("title", "artist", "album", "genre", "track", "time", "url")); + } + return false; + } + + public function songs($filter = null, $offset = null, $limit = null) { + + if ($xml = $this->_requestServer("songs", $filter, $offset, $limit)) { + return $this->_XML2Array($xml, "id", array("title", "artist", "album", "genre", "track", "time", "url")); + } + return false; + } + + public function playlists($filter = null, $offset = null, $limit = null) { + if ($xml = $this->_requestServer("playlists", $filter, $offset, $limit)) { + return $this->_XML2Array($xml, "id", array("name", "owner", "items")); + } + return false; + } + + public function playlist_songs($filter = null, $offset = null, $limit = null) { + + if ($xml = $this->_requestServer("playlist_songs", $filter, $offset, $limit)) { + return $this->_XML2Array($xml, "id", array("title", "artist", "album", "genre", "track", "time", "url")); + } + return false; + } + + public function isConnected() { + return $this->_isConnected; + } + + public function getError() { + return $this->_errorStr; + } + + /** + PRIVATE FUNCTIONS + **/ + + private function _requestServer( $action, $filter = null, $offset = null, $limit = null ) { + + if ($action == "handshake") { + + $timestamp = time(); + $passphrase = md5($timestamp . $this->_key); + $url = $this->_serverUrl."?action=handshake&auth=$passphrase×tamp=$timestamp"; + } + else { + + $filter = ( $filter ) ? "&filter=".intval( $filter ) : ""; + $offset = ( $offset ) ? "&offset=".intval( $offset ) : ""; + $limit = ( $limit ) ? "&limit=".intval( $limit ) : ""; + + $url = $this->_serverUrl."?action=".$action."&auth=".$this->_auth.$filter.$offset.$limit; + } + + // URL corrects ? + $xmlData = @file_get_contents($url); + if ($xmlData === false) { + $this->_setError("BAD_URL"); + return false; + } + + // XML Data ? + $xml = @simplexml_load_string($xmlData); + if ($xml === false) { + $this->_setError("BAD_XML"); + return false; + } + + // valid request ? + if (isset($xml->error) === true) { + $this->_setError("INVALID_REQUEST"); + return false; + } + + return ($xml); + } + + private function _XML2Array($xml, $key, $fieldsList) { + + $arr = array(); + foreach ($xml as $val) { + $tmp = array(); + foreach ($fieldsList as $field) { + $tmp[$field] = strval($val->$field); + } + $arr[strval($val[$key])] = $tmp; + } + + return ($arr); + } + + private function _setError($errorStr) { + $this->_errorStr = $errorStr; + } +} + +?> \ No newline at end of file diff --git a/ampache/Noxon/NoxonConfig.php b/ampache/Noxon/NoxonConfig.php new file mode 100644 index 0000000..e04bba6 --- /dev/null +++ b/ampache/Noxon/NoxonConfig.php @@ -0,0 +1,71 @@ + \ No newline at end of file diff --git a/ampache/Noxon/NoxonUIHandler.php b/ampache/Noxon/NoxonUIHandler.php new file mode 100644 index 0000000..a1b23c8 --- /dev/null +++ b/ampache/Noxon/NoxonUIHandler.php @@ -0,0 +1,289 @@ +amcConnector = new AmpacheConnectorLocal(); + } + else { + $this->amcConnector = new AmpacheConnectorRemote(NoxonConfig::$ampacheUrl."/server/xml.server.php", NoxonConfig::$passphrase); + } + if (!$this->amcConnector->isConnected()) { + throw new Exception("NoxonUIHandler::AmpacheConnector::ConnectionFailed"); + } + + $this->mySpeller = new Speller(NoxonConfig::$spellerCriticalMass); + + } + + function isConnected() { + return $this->amcConnector->isConnected(); + } + + private function initGETData(&$inArray=null, $index, $inDefault) { + if ($inArray!=null) + if (!isset($inArray[$index]) || $inArray[$index]==null) { + $inArray[$index]=$inDefault; + } + } + + /** Standard Receiver for GETData */ + function processRequest($rhs) { + // Any base URL provided ? + if (isset($rhs["script.baseURL"])) { + $this->strBaseURL = $rhs["script.baseURL"]; + + $result = new RnListOfItems(); + foreach (Array("filter","action","speller_filter","dlang") as $ele) { + $this->initGETData($rhs, $ele, ""); + } + + /* + * SX: Substitute the Country code for an Element of the + * Internationalization Set. + * + * "Belangrijke" Fix for Noxon3.7 bug : Device reports "jpn" + * when device language set to dutch. + */ + $rhs["dlang"] = Internat::substituteCountryCode(($rhs["dlang"]=="jpn")?"NL" : $rhs["dlang"]); + + switch ($rhs["action"]) { + + case "artists" : + case "speller" : + $artists = $this->amcConnector->artists($rhs["filter"]); + + /* + * The Speller is used when : + * - it is enabled in the configuration AND the user selected the speller menuitem + * - in any case if the list length is above the devices critical mass + */ + + if ( (NoxonConfig::$blUseSpeller && $rhs["action"]=="speller") || sizeof($artists) > 400 ) { + // If Artist Count is above Noxons Critical mass, ignore the user setting + // and use the speller anyway. + + // Start Speller + if ( $this->mySpeller->isBelowCriticalMass($rhs["speller_filter"],$artists,"name") ) { + // If current scope is below critical mass + foreach ($this->mySpeller->getFilteredSubset() as $id => $artist ) { + $result->addToList($this->AmpElement2DirElement($id, + $artist['name'] , "artist_albums")); + } + } + else { + // Our Subset is above the critical mass. Prepare another run. + foreach ($this->mySpeller->getNextRunElements() as $id => $dummy ) { + $result->addToList($this->AmpElement2DirElement("", + $id."..." , "speller","&speller_filter=".urlencode($id)) ); + } + } + } // Speller activated ? + else{ + // No Speller + foreach ($artists as $id => $artist ) { + $result->addToList($this->AmpElement2DirElement($id, + $artist['name'] , "artist_albums")); + } + } // No Speller + + break; + case "artist_albums": + $albums= $this->amcConnector->artist_albums($rhs["filter"]); + foreach ($albums as $id => $album ) { + $result->addToList($this->AmpElement2DirElement($id, + $album['name'] , "album_songs")); + } + break; + + case "playlist_songs": + $songs = $this->amcConnector->playlist_songs($rhs["filter"]); + // fall through + + case "similar_songs": + // Check whether it is a fall-through or not + if (!isset ($songs)) { + $songs = $this->amcConnector->genre_songs($rhs["filter"]); + // Create a subset if structure is too large + $arrSize = sizeof($songs); + if ($arrSize >= NoxonConfig::$maxSimilarSongItems ) { + shuffle($songs); + $arrSize = NoxonConfig::$maxSimilarSongItems; + $songs = array_slice($songs,0,$arrSize); + } + } // fi isset songs + // fall through + + case "album_songs": + // Check whether it is a fall-through or not + if (!isset ($songs)) { + $songs = $this->amcConnector->album_songs($rhs["filter"]); + } // fi isset songs + + foreach ($songs as $id => $song ) { + $strBkm = "&aid="."0"."&gid=".$song["genre"]; + if (isset($rhs["server.httpHostname"]) + && NoxonConfig::$remapStreamingURLs==true) { + $result->addToList($this->AmpSongToStationElement($id, + $song , $rhs["server.httpHostname"], $strBkm) ); + } + else { + $result->addToList($this->AmpSongToStationElement($id, + $song, null, $strBkm )); + } + } + break; + + case "song_smiley": + $menuItems = $this->getMenu("cna_song",$rhs["dlang"]); + foreach ($menuItems as $index => $MenuItem) { + $result->addToList($this->AmpElement2DirElement($rhs["gid"], + $MenuItem["caption"], $index , $MenuItem["getdata"] )); + } + break; + + case "genres": + $genres = $this->amcConnector->genres($rhs["filter"]); + foreach ($genres as $id => $playlist ) { + $result->addToList($this->AmpElement2DirElement($id, + $playlist['name']." (".$playlist['artists']." Artists)" , "genre_artists")); + } + break; + + case "genre_artists": + $artists = $this->amcConnector->genre_artists($rhs["filter"]); + foreach ($artists as $id => $artist ) { + $result->addToList($this->AmpElement2DirElement($id, + $artist['name'] , "artist_albums")); + } + break; + + + + case "playlists": + $playlists = $this->amcConnector->playlists($rhs["filter"]); + foreach ($playlists as $id => $playlist ) { + $result->addToList($this->AmpElement2DirElement($id, + $playlist['name'] , "playlist_songs")); + } + break; + + default: + // Present Main Menu; + $menuItems = $this->getMenu("root",$rhs["dlang"]); + foreach ($menuItems as $index => $MenuItem) { + $result->addToList($this->AmpElement2DirElement("", $MenuItem["caption"], $index , $MenuItem["getdata"] )); + } + break; + + } // esac action + return ($result->toString()); + + } + else { + //TODO : Throw Exception here + } + } + + /** + * Returns the Ampache Menus + * + * @param string $inMnuID + * @param string $inLang + * @return menu Array + */ + function getMenu($inMnuID, $inLang) { + $result = Array(); + if ($this->isConnected()) { + switch ($inMnuID) { + case "root": + $result["artists"]["caption"] = Internat::getString($inLang,"artistalbums"); + $result["artists"]["getdata"] = ""; + // Add the Speller menuentry when activated in config + if (NoxonConfig::$blUseSpeller) { + $result["speller"]["caption"] = Internat::getString($inLang,"artistssearch"); + $result["speller"]["getdata"] = ""; + } + $result["genres"]["caption"] = Internat::getString($inLang,"genres"); + $result["genres"]["getdata"] = ""; + $result["playlists"]["caption"] = Internat::getString($inLang,"playlists"); + $result["playlists"]["getdata"] = ""; + break; + + case "cna_song": + $result["genre_artists"]["caption"] = Internat::getString($inLang,"similar_artists"); + $result["genre_artists"]["getdata"] = ""; + $result["similar_songs"]["caption"] = Internat::getString($inLang,"similar_titles"); + $result["similar_songs"]["getdata"] = ""; + break; + + } // esac + + } // fi isConnected ? + return $result; + } + + function AmpElement2DirElement ($inId, $inName ,$inFilialAction ,$getData="") { + $result = new RnDir(); + $result->Title = utf8_decode($inName); + $result->Url = $this->strBaseURL."?action=".$inFilialAction."&filter=".$inId.$getData."&token=".NoxonConfig::getToken(); + return $result; + } + + function AmpSongToStationElement ($inId, $inSong, $inRemap=null, $inBookmarkGETData=null) { + $result = new RnStation(); + // Remap URL to non-Local Address if Ampache Server is on local machine + if ($inRemap) { + $url = str_replace("http://127.0.0.1", $inRemap, $inSong['url']); + } + else $url = $inSong['url']; + $result->Name = utf8_decode($inSong['title']); + $result->Url = $url; + if ( true || $inBookmarkGETData!=null) { + $result->Bookmark = $this->strBaseURL."?action=song_smiley&".$inBookmarkGETData."&token=".NoxonConfig::getToken(); + } + return $result; + } + + static function AmpElement2MessageElement ($inMessage) { + $result = new RnDir(); + $result->Title = $inMessage; + return $result; + } + + static function getNoxonError ($inStrErrorMsg) { + $result = new RnListOfItems(); + $result->addToList(NoxonUIHandler::AmpElement2MessageElement($inStrErrorMsg)); + return ($result->toString()); + } + + +} + +?> \ No newline at end of file diff --git a/ampache/Noxon/RegisterMyNoxon.php b/ampache/Noxon/RegisterMyNoxon.php new file mode 100644 index 0000000..f47ecf0 --- /dev/null +++ b/ampache/Noxon/RegisterMyNoxon.php @@ -0,0 +1,118 @@ +user = $user; + $this->pass = $pass; + $this->strAmpacheServerURL = $strAmpacheServerURL; + $this->strAmpacheServerLANURL = $strAmpacheServerLANURL; + $this->serverCaption = $serverCaption; + } + + /** + * register to the my-noxon site + */ + public function register() { + $ret = $this->_request_my_noxon("add"); + return $ret; + } + + /** + * unregister to the my-noxon site + */ + public function unregister() { + $ret = $this->_request_my_noxon("remove"); + return $ret; + } + + /** + * Error management + */ + public function _setError( $str ) { + $this->_errorStr = "
".$str; + } + + public function getError() { + return $this->_errorStr; + } + + /** + * private function to request the my-noxon site + */ + private function _request_my_noxon($strAction) { + + // include needed class + require_once 'UDSAuth.php'; + + if ( ! in_array( $strAction, array( "add", "remove" ) ) ) { + $this->_setError( "Error RegisterMyNoxon class: action must be 'add' or 'remove'" ); + return false; + } + + // Create a new Instance of Auth with Blowfish Keys for Ampache + $myHash = new UDSAuth($this->inStrBFishKey, $this->inStrBFishIV, $this->inStrToken); + // Encrypt username and password + $encryptedHash = $myHash->encryptHash($this->user, UDSAuth::createPasswordHash($this->pass, $this->user) ); + + //SX: Retrieve the Token + $strGETToken = "?token=".NoxonConfig::getToken(); + + if (! $this->strAmpacheServerLANURL) { + $this->strAmpacheServerLANURL = $this->strAmpacheServerURL; + } + + $request = $this->strRegistrationURL."?action=".$strAction + ."&AuthHash=".$myHash->hex2string($encryptedHash) + ."&destinationURL=".urlencode($this->strAmpacheServerURL.$strGETToken) + ."&destinationLANURL=".urlencode($this->strAmpacheServerLANURL.$strGETToken) + ."&displayname=".urlencode($this->serverCaption) + ."&family=".urlencode($this->strApplication); + + echo 'Request URL: ' . $request; + + + + // URL corrects ? + $xmlData = @file_get_contents($request); + + if ($xmlData === false) { + $this->_setError( "Error RegisterMyNoxon class: URL not corrects" ); + return false; + } + + // XML Data ? + $xml = @simplexml_load_string($xmlData); + if ($xml === false) { + $this->_setError( "Error RegisterMyNoxon class: Response is not XML" ); + return false; + } + + // valid request ? + if (strval($xml->ActionResult) != 'true') { + $this->_setError( "Error RegisterMyNoxon class: Invalid request : '".strval($xml->ErrorCode)."'" ); + return false; + } + + return true; + } + +} + +?> \ No newline at end of file diff --git a/ampache/Noxon/Speller.php b/ampache/Noxon/Speller.php new file mode 100644 index 0000000..8bd2cfd --- /dev/null +++ b/ampache/Noxon/Speller.php @@ -0,0 +1,98 @@ +criticalMass = $inCriticalMass; + } + + /* + * IsBelowCriticalMass + * + * Populates the Search Index and starts the Speller + * + * Parametres: + * $inStrFilter : Current Filter Text ("A".."JEA") + * $inData : Reference to Array with Data for the speller + * $strAlphaIndex : Alpha-Index Column of the Array for Sorting + * + * Returns: + * (bool) TRUE : filtered resultset size is below critical mass, + * FALSE: more items than critical mass. + * One more run should be made in application logic + * + * Post-Run Actions in Application Logic : + * getNextRunElements : Returns the Stringlets for the Next Run + * i.E. A -> AB, AC, AX + * + * getFilteredSubset : Returns a copy of the $inData with only + * the entries that match the filter. + * Should be used if result below critical mass + */ + function isBelowCriticalMass ($inStrFilter, &$inData, $strAlphaIndex) { + if (isset($inStrFilter)) { + $ipos = strlen($inStrFilter)+1; + // Output Items + $this->strFilterSubset = Array(); + // Speller next Run Items + $this->strNextRunElements = Array(); + $inStrFilter = strtoupper($inStrFilter); + + // Generate Wordbook with current Input Filter + + $this->strAlphaItems = Array(); + foreach ($inData as $arrayIndex => $data) { + $strSpellerLength = trim(strtoupper(substr($data[$strAlphaIndex],0,$ipos))); + if (substr($strSpellerLength,0,$ipos-1) == $inStrFilter) { + $this->strNextRunElements[$strSpellerLength] = true; + $this->strFilterSubset[$arrayIndex] = $data; + } + } + + // Is result below critical mass ? + if (sizeof($this->strFilterSubset) <= $this->criticalMass) { + // Future: Try to recurse into getSpellerData to look if we can go deeper + return true; + } // fi + else { + // Still more possibilities than wanted, return input filters for next run. + // Sort NextElements Array only here to increase speed + ksort($this->strNextRunElements); + return false; + } + } + } + + function getNextRunElements() { + return ($this->strNextRunElements); + } + + function getFilteredSubset() { + return ($this->strFilterSubset); + } +} // Speller + +?> \ No newline at end of file diff --git a/ampache/Noxon/UDSAuth.php b/ampache/Noxon/UDSAuth.php new file mode 100644 index 0000000..b392611 --- /dev/null +++ b/ampache/Noxon/UDSAuth.php @@ -0,0 +1,89 @@ + \0xf \0xf + */ + function string2hex($str) { + $ret=""; + for($i=0;$istrBFishKey = $this->string2hex($inStrBFishKey); + $this->strBFishIV = $this->string2hex($inStrBFishIV); + $this->strToken = $inStrToken; + } // construct + + function isValidToken() { + return $this->blValidToken; + } + + function encryptHash ($inStrUser, $inStrPassword, $inBlDestroyPassword = false ) { + $strUnencryptedHash = $inStrUser + .chr(10).chr(13).$inStrPassword + .chr(10).chr(13).$this->strToken + .chr(10).chr(13); + + $strEncHash = mcrypt_cbc(MCRYPT_BLOWFISH,$this->strBFishKey, $strUnencryptedHash,MCRYPT_ENCRYPT,$this->strBFishIV); + return $strEncHash; + } + +} // class UDSAuth +?> \ No newline at end of file diff --git a/ampache/Noxon/internat.php b/ampache/Noxon/internat.php new file mode 100644 index 0000000..28e3e43 --- /dev/null +++ b/ampache/Noxon/internat.php @@ -0,0 +1,127 @@ + Array( "EN"=> "Artist/Albums", + "DE"=> "Interpret/Alben", + "FR"=> "Artiste/Album", + "NL"=> "Artiest/Album", + "IT"=> "Artista/Album", + "ES"=> "Artista/Album" ), + "artistssearch" + => Array( "EN"=> "Artists (Search)", + "DE"=> "Interpret (Suche) ", + "FR"=> "Artistes (Chercher)", + "NL"=> "Artiest (Zoek)", + "IT"=> "Artista (Cerca)", + "ES"=> "Artista (búsqueda)" ), + "genres" + => Array( "EN"=> "Genres", + "DE"=> "Musikrichtungen", + "FR"=> "Genres", + "NL"=> "Genres", + "IT"=> "Genere", + "ES"=> "Genero" ), + "playlists" + => Array( "EN"=> "Playlists", + "DE"=> "Wiedergabelisten", + "FR"=> "Listes de lecture", + "NL"=> "Playlists", + "IT"=> "Playlist", + "ES"=> "Lista de reproducción" ), + "similar_artists" + => Array( "EN"=> "Similar Artists", + "DE"=> "Ähnliche Interpreten", + "FR"=> "Interprètes semblables", + "NL"=> "Vergelijkbare Artiesten", + "IT"=> "Artisti simili", + "ES"=> "Artistas similares" ), + "similar_titles" + => Array( "EN"=> "Similar Titles", + "DE"=> "Ähnliche Titel", + "FR"=> "Titres semblables", + "NL"=> "Vergelijkbare Titels", + "IT"=> "Titoli simili", + "ES"=> "Títulos similares" ) + + ); + + /** + * Substitutes various Country Codes to the ones used in this class + * + * @param string $rhs + * @return string + */ + static function substituteCountryCode ($rhs="") { + switch (strtolower($rhs)) { + case "49": + case "ger": + case "deu": + return "DE"; + break; + + case "01": + case "44": + case "eng": + return "EN"; + break; + + case "33": + case "fre": + case "fra": + return "FR"; + break; + + case "31": + case "nld": + case "dut": + return "NL"; + break; + + case "ita": + case "itl": + return "IT"; + break; + + case "esp": + case "spa": + case "spn": + case "cas": + case "cat": + return "ES"; + break; + default: + return $rhs; + } + } + + /** + * Request internationalized String + * + * If language is not found, english will be used as default. + * + * input : $inLang = Target Language + * $inIndex = Target Item + */ + static function getString($inLang, $inIndex) { + $inLang = strtoupper($inLang); + if (isset(Internat::$stbl[$inIndex])) { + if (isset(Internat::$stbl[$inIndex][$inLang]) + && Internat::$stbl[$inIndex][$inLang]!="" ) { + return Internat::$stbl[$inIndex][$inLang]; + } + else return Internat::$stbl[$inIndex]["EN"]; + } + else return "..."; + } + +} + +?> \ No newline at end of file diff --git a/ampache/Noxon/xml/RnDir.php b/ampache/Noxon/xml/RnDir.php new file mode 100644 index 0000000..3cb5097 --- /dev/null +++ b/ampache/Noxon/xml/RnDir.php @@ -0,0 +1,14 @@ +".$this->Type."\r\n".$this->Title."\r\n".$this->Url."\r\n".$this->NoAudioContent."\r\n".$this->BackUrl."\r\n".$this->BookmarkShow."\r\n"; + } + + } + +?> \ No newline at end of file diff --git a/ampache/Noxon/xml/RnListOfItems.php b/ampache/Noxon/xml/RnListOfItems.php new file mode 100644 index 0000000..d215700 --- /dev/null +++ b/ampache/Noxon/xml/RnListOfItems.php @@ -0,0 +1,29 @@ +items,$rhs); + } + } + + function toString() { + $elements = Array(); + foreach($this->items as $element) { + array_push($elements,"\r\n".$element->__toString().""); + } + $cache = ($this->NoCache) ? "Yes\r\n" : ""; + return "\r\n\r\n".$cache.implode("\r\n",$elements)."\r\n\r\n"; + } + +} + +?> \ No newline at end of file diff --git a/ampache/Noxon/xml/RnStation.php b/ampache/Noxon/xml/RnStation.php new file mode 100644 index 0000000..b0849c7 --- /dev/null +++ b/ampache/Noxon/xml/RnStation.php @@ -0,0 +1,14 @@ +".$this->Type."\r\n".$this->Id."\r\n".$this->Name."\n".$this->Url."\r\n".$this->Description."\r\n".$this->Format."\r\n".$this->Location."\r\n".$this->Bandwidth."\r\n".$this->Mine."\r\n".$this->Bookmark."\r\n"; + } + + } + +?> \ No newline at end of file diff --git a/ampache/Noxon_register.php b/ampache/Noxon_register.php new file mode 100644 index 0000000..cfc583b --- /dev/null +++ b/ampache/Noxon_register.php @@ -0,0 +1,25 @@ +register()) { + echo "Registration Successful"; +} +else { + echo "Registration Failed :
"; + echo $noxon->getError(); +} + +?> \ No newline at end of file diff --git a/ampache/Noxon_xml.server.php b/ampache/Noxon_xml.server.php new file mode 100644 index 0000000..60f5161 --- /dev/null +++ b/ampache/Noxon_xml.server.php @@ -0,0 +1,66 @@ +processRequest($NoxonUIRequest)); + +?> \ No newline at end of file diff --git a/full_rsdb.xml b/full_rsdb.xml new file mode 100644 index 0000000..6563d78 --- /dev/null +++ b/full_rsdb.xml @@ -0,0 +1,1088 @@ + + + + 2.0 + vTuner +http://www.radio579.com/setupapp/bluewin/asp/rsdb/update.asp + Basic e1139 + + +440002 +Log on to radio579.com +24 +http://www.radio246.com/setupapp/bluewin/mp3/440002.mp3m3u + + +440003 +001b9e22e9ec is the ID# for your Media Adapter +24 +http://www.radio246.com/setupapp/bluewin/mp3/440003.mp3m3u + + +440004 +What is Super Guide? + +24 +http://www.radio246.com/setupapp/bluewin/mp3/440004.mp3m3u + + +440005 +What is included in Super Guide? + +24 +http://www.radio246.com/setupapp/bluewin/mp3/440005.mp3m3u + + +440006 +How do I buy Super Guide? + +24 +http://www.radio246.com/setupapp/bluewin/mp3/440006.mp3m3u + + +440007 +What is Trial Super Guide? + +24 +http://www.radio246.com/setupapp/bluewin/mp3/440007.mp3m3u + + +440008 +What is Basic Guide? + +24 +http://www.radio246.com/setupapp/bluewin/mp3/440008.mp3m3u + + +440009 +Why don't I have Super Guide any more? + +24 +http://www.radio246.com/setupapp/bluewin/mp3/440009.mp3m3u + + +440010 +How can I get Super Guide back again? + +24 +http://www.radio246.com/setupapp/bluewin/mp3/440010.mp3m3u + + +440011 +What is buffering? + +24 +http://www.radio246.com/setupapp/bluewin/mp3/440011.mp3m3u + + +440012 +Why do stations not work sometimes? + +24 +http://www.radio246.com/setupapp/bluewin/mp3/440012.mp3m3u + + +440013 +Why do stations disappear from my list? + +24 +http://www.radio246.com/setupapp/bluewin/mp3/440013.mp3m3u + + +440014 +Why isn't my favorite Internet radio station on the station list? + +24 +http://www.radio246.com/setupapp/bluewin/mp3/440014.mp3m3u + + +440015 +How do I ask other questions? + +24 +http://www.radio246.com/setupapp/bluewin/mp3/440015.mp3m3u + + + 24 + KWUR Washington Univ. + The ultimate variety with folk, rap/hip-hop, classical, blues, dance, metal, etc. + 260 + http://kwurmail.wustl.edu:8000/128 + m3u + + + 90 + AFN American Freedom Network + KHNC 1360AM THE LION Conservative News Talk Radio + 24 + http://64.72.126.49:3030/ + m3u + + + 296 + SnakeNet Metal Radio + SnakeNet Heavy Metal Radio, an affiliate of OnlineMusic.Com, is an internet only heavy metal radio station broadcasting in Shoutcast MP3 Audio, Real Audio and Windows Media Format (asf). + 128 + http://205.188.215.231:8016/ + m3u + + + 381 + WREK Georgia Tech + Georgia Tech's wildly diverse WREK plays jazz, gospel, reggae, classical, classic rock, heavy metal and much more. + 128 + http://slack.wrek.gatech.edu:8000/wrek_live-128kb + m3u + + + 688 + KKJZ kjazz NPR + KLON-FM 88.1 is a 24 hour public, member-supported jazz, blues and information station serving Los Angeles and Orange Counties and distributed nationwide via cable and satellite access. + 64 + http://www.live365.com/play/312920 + m3u + + + 952 + CFMB + Radio Montreal broadcasts diverse programming in over twenty languages. + 32 + http://www.live365.com/play/cfmb + m3u + + + 1338 + Radio Silver Rain + Our broadcast is generally based on the popular music: the Best European Hits of the 90's, most famous retro-tunes of the 50's and the 60's, disco of the 70's and the 80's, and some less techno. + 24 + http://radio.silver.ru:8000/ + m3u + + + 3487 + DubLab + Dedicated to the growth of new and positive music. Dub, jazz, soul, funk, hip-hop, drum & bass, house and more. + 128 + http://205.188.215.225:8008/ + m3u + + + 4177 + WWJC The Light + Your Home for Solid Gospal Music + 64 + http://74.213.164.94:8000 + m3u + + + 4392 + WBHM NPR + classical music streaming to the Internet from Birmingham, Alabama with a touch of NPR here and there. + 56 + http://www.wbhm.org:8000/live + m3u + + + 4540 + Bide et Musique + Une soirée sans thème, exclusivement dansante, avec musicalement un best of des différentes thématiques de Bide&Musique (80s, D.A, Bide, Musique), ça vous dit ? + 128 + http://relay2.bide-et-musique.com:9100/ + m3u + + + 4598 + ACB Radio Mainstream + ACB Radio is radio made by the blind for the blind. + 24 + http://acbradio.org:6246/ + m3u + + + 4615 + Radio Universidad de Chile + + 24 + http://stream.radio.uchile.cl:8000/ + m3u + + + 4899 + Deutschlandradio Kultur + Kultur ist überall + 48 + http://dradio-mp3.t-bn.de/dlr_live + m3u + + + 4938 + Oldie Radio + Oldies rund um die Uhr + 128 + http://www.oldie-radio.de:8000/ + m3u + + + 5448 + WBRS Brandeis Univ. + WBRS is Brandeis University's noncommercial radio station. WBRS programming supports an all-genre format, with a policy of playing everything that gets sent to us. + 40 + http://www.live365.com/play/289801 + m3u + + + 5617 + KSBR + KSBR's primary format is contemporary jazz, but it also has weekend specialty shows featuring other musical styles like reggae, folk, ragtime, rock, Latin jazz, blues, and hip-hop music. + 64 + http://216.235.81.101:15006/ + m3u + + + 5790 + Bass Drive + 24x7 Drum & Bass radio, featuring broadcasts from DJs and venues around the globe + 128 + http://aol.streams.bassdrive.com:8012 + m3u + + + 6786 + Accent Radio Network(ARN) + Promoting a God-centered view of health and healing. + 32 + http://live.str3am.com:2150/ + m3u + + + 10304 + WPON + The best talk in town & Detroit's rare oldies + 24 + http://audio.birach.com:9010/ + m3u + + + 11441 + KNAK Radio for the Family + Restoring God, Family and Country + 24 + http://nyc01.egihosting.com:6224/ + m3u + + + 12210 + Ef-Ei + + 96 + http://159.148.205.66:8000 + m3u + + + 12492 + Sky.fm Modern Jazz + Sky.fm is an Internet radio network offering a variety of channels for your enjoyment + 96 + http://205.188.215.227:8008/ + m3u + + + 12493 + Sky.fm Mostly Classical + The Mostly Classical channel is our main relaxation channel. You'll find an excellent compilation of classical composers and contemporary works. Typical composers include Bach, Mozart, and Vivaldi. + 96 + http://scfire-ntc-aa03.stream.aol.com:80/stream/1006 + m3u + + + 12513 + Digitally Imported Chillout + Digitally Imported Radio is a streaming radio station dedicated to playing the best European Hi-NRG, Techno, and Trance music + 96 + http://scfire-chi-aa01.stream.aol.com:80/stream/1035 + m3u + + + 12757 + Pro FM + Pro Fm is a web dance radio station located in the Netherlands. + 192 + http://streamserver1.udis.nl:8200/ + m3u + + + 12874 + KKJL K Jewel + + 32 + http://franklin.tbo.net:8018/ + m3u + + + 12997 + KHCR Joy FM + Joy FM is a radio ministry that uses Contemporary Christian Music to share the love of Jesus Christ. Our desire is that listeners will find Jesus in all we say and do. + 32 + http://www.live365.com/play/293486 + m3u + + + 13020 + WLVF Gospel + A gospel radio station located in Haines City, Florida. As a ministry of Landmark Baptist Church, WLVF reaches the Central Florida area via radio waves and the entire world through the internet. + 32 + http://www.live365.com/play/287833 + m3u + + + 13032 + WXHL Reach FM + An FM station that appeals to listeners important to our succeB. We did it with the fastest growing music segment and format in America today, Contemporary Christian Music. + 16 + http://www.live365.com/play/292542 + m3u + + + 13093 + MikeyRadio + DJ Mikey Mike Plays The Best R&amp;B/Soul Music All Day, All Nite 24-7-365 + 24 + http://stream.mikeyradio.com:8000/ + m3u + + + 13417 + Radio Paradise + Eclectic intelligent rock - music info &amp; listener community at radioparadise.com + 128 + http://scfire-chi0l-2.stream.aol.com:80/stream/1048 + m3u + + + 13490 + New Orleans Radio + New Orleans Radio was created to produce and deliver regional custom music, information, and original programming to the global Internet community on a continuous 24-hour-per-day, 7-day-per-week + 96 + http://70.84.35.130:8002/ + m3u + + + 13724 + Nashville FM + nonstop hot new country + 128 + http://broadband.nashvillefm.net:5502/ + m3u + + + 14523 + The 1920s Radio Network + We play 20's 30's 40's big band and old time radio 24/7. + 64 + http://tess.fast-serv.com:8570/ + m3u + + + 16070 + Sky.fm Best of the 80s + SKY.fm plays your favorite 80s hits 24 hours a day. Catch memorable hits from artists such as The Police, Cyndi Lauper, Duran Duran, Madonna, Depeche Mode + 96 + http://scfire-chi-aa02.stream.aol.com:80/stream/1013 + m3u + + + 16406 + Klara Continuo + Klara continuo zendt non-stop de beste stukken van de grootste meesters in de meest beklijvende uitvoeringen uit. + 96 + http://mp3.streampower.be/klaracontinuo-high + m3u + + + 17482 + WCUR West Chester University + Radio for West Chester University. + 80 + http://144.26.57.251:8000 + m3u + + + 17926 + WORC Power + WORC-AM, the only 100% 24 hour 7 day Hispanic radio station in Central/Eastern Massachusetts. + 24 + http://70.85.72.122:8100/ + m3u + + + 18213 + Radio Luxembourg + Radio Luxembourg, The Best In Classic Rock. The Legend Is Back with your favourite DJ's + 128 + http://s8.mediastreaming.it:7050/ + m3u + + + 18265 + Pan African Allstars Radio + For the best in African Music on the Internet, browse through our website. Check Out our African Music DVDs. From North to South and East To West we bring you the best Music from the continent. + 48 + http://tess.fast-serv.com:8580/ + m3u + + + + + + 12049 + + + + + 13417 + + + 13417 + + + + + 12513 + + + 12513 + + + + + 14523 + + + 14523 + + + + + 13490 + + + 13490 + + + + + 12997 + 4177 + 13032 + + + 12997 + 4177 + 13032 + + + + + 18213 + + + 18213 + + + + + 4899 + 16406 + 12493 + 4392 + + + 16406 + + + 4899 + + + 12493 + 4392 + + + + + 24 + 4615 + 5448 + 17482 + 381 + + + 4615 + + + 24 + 5448 + 17482 + 381 + + + + + 13724 + + + 13724 + + + + + 12757 + 1338 + + + 12757 + + + 1338 + + + + + 5790 + 3487 + + + 5790 + 3487 + + + + + 13093 + 13020 + + + 13093 + 13020 + + + + + 296 + + + 296 + + + + + 688 + 5617 + 13093 + 13490 + 12492 + + + 688 + 5617 + 13093 + 13490 + 12492 + + + + + 17926 + + + 17926 + + + + + 12874 + 4938 + 16070 + 10304 + + + 4938 + + + 12874 + 16070 + 10304 + + + + + 688 + 4392 + + + 688 + 4392 + + + + + 13093 + + + 13093 + + + + + 13417 + + + 13417 + + + + + 4540 + 12210 + + + 4540 + + + 12210 + + + + + 952 + + + 952 + + + + + 18265 + + + 18265 + + + + + 4598 + 4899 + + + 4899 + + + 4598 + + + + + 11441 + + + 11441 + + + + + 6786 + 12997 + + + 6786 + 12997 + + + + + 90 + + + 90 + + + + + + + + + 16406 + + + 16406 + + + + + 4540 + + + 4540 + + + + + 4899 + 4938 + + + 4899 + + + 4938 + + + 4899 + + + + + 12210 + + + 12210 + + + + + 18213 + + + 18213 + + + + + 13724 + 12757 + + + 13724 + + + 12757 + + + + + 1338 + + + 1338 + + + + + + 5790 + 12513 + 3487 + 13093 + 13724 + 13490 + 12757 + 13417 + 16070 + 12492 + 12493 + 296 + 14523 + + + 13417 + + + 12513 + + + 14523 + + + 13490 + + + 12493 + + + 13724 + + + 12757 + + + 5790 + 3487 + + + 13093 + + + 296 + + + 13093 + 13490 + 12492 + + + 16070 + + + 13417 + + + + + + 952 + + + 952 + + + + + + 4392 + + + 4392 + + + 4392 + + + + + 3487 + 12874 + 688 + 5617 + 13417 + + + 13417 + + + 3487 + + + 688 + 5617 + + + 12874 + + + 688 + + + 13417 + + + + + 90 + + + 90 + + + + + 6786 + 13020 + + + 13020 + + + 6786 + + + + + 18265 + 381 + + + 381 + + + 18265 + + + + + 5790 + + + 5790 + + + + + 13490 + + + 13490 + + + 13490 + + + + + 13032 + + + 13032 + + + + + 5448 + 17926 + + + 5448 + + + 17926 + + + + + 13093 + 10304 + + + 13093 + + + 13093 + + + 10304 + + + + + 4177 + + + 4177 + + + + + 12997 + 24 + + + 12997 + + + 24 + + + 12997 + + + + + 12513 + 16070 + 12492 + 12493 + + + 12513 + + + 12493 + + + 12492 + + + 16070 + + + + + 296 + + + 296 + + + + + 17482 + + + 17482 + + + + + 11441 + + + 11441 + + + + + 14523 + + + 14523 + + + + + 4598 + + + 4598 + + + + + + + + 4615 + + + 4615 + + + + + +440002 +440003 +440004 +440005 +440006 +440007 +440008 +440009 +440010 +440011 +440012 +440013 +440014 +440015 + + + + diff --git a/http_basic_auth_main.py.patch b/http_basic_auth_main.py.patch new file mode 100644 index 0000000..18bd4fd --- /dev/null +++ b/http_basic_auth_main.py.patch @@ -0,0 +1,33 @@ +--- main.py 2008-09-09 21:44:07.000000000 +0200 ++++ main.py.new 2008-09-09 21:47:28.000000000 +0200 +@@ -8,6 +8,7 @@ + import cgi + import os + import string ++import base64 + + import config + import lastfm +@@ -112,6 +113,22 @@ + clientsock.close() + return + ++ # Check for authentification ++ if not http.has_key("Authorization") or string.split(http["Authorization"], " ")[1] != base64.b64encode(self.username + ":" + self.password): ++ cont = "\r\n\r\n\r\nError\r\n\r\n\r\n\r\n

401 Unauthorised.

\r\n\r\n\r\n" ++ print "Wrong or missing authentification" ++ try: ++ clientsock.sendall("HTTP/1.0 401 UNAUTHORIZED\r\n"); ++ clientsock.sendall("Content-Type: text/html\r\n") ++ clientsock.sendall("WWW-Authenticate: Basic realm=\"Private Stream\"\r\n") ++ clientsock.sendall("Allow: GET\r\n") ++ clientsock.sendall("\r\n") ++ clientsock.sendall(cont) ++ clientsock.close() ++ except socket.error: ++ clientsock.close() ++ return ++ + tmp = string.split(req[0][1], "?", 1) + station = tmp[0] + if len(tmp) > 1: diff --git a/rsdb_format.xml b/rsdb_format.xml new file mode 100644 index 0000000..2fb7fc1 --- /dev/null +++ b/rsdb_format.xml @@ -0,0 +1,28 @@ + + + + 2.0 + vTuner + http://www.radio579.com/setupapp/bluewin/asp/rsdb/update.asp + PREMIUM + + + + 1 + Last.fm Proxy + Just a Proxy for the Social Music Network Last.fm + 96 + http://87.230.33.74:2944/lastfm.mp3?pw=qU4rK5m1n1m4l&user=steffenvogel + m3u + + + + + + + 1 + + + + + diff --git a/service_format.xml b/service_format.xml new file mode 100644 index 0000000..d619677 --- /dev/null +++ b/service_format.xml @@ -0,0 +1,28 @@ + + + + Display + Your Streaming device is unknown! Please register at www.besonic.com! + + + Dir + Demo playlists + http://gatekeeper.my-noxon.net/RadioNative.php?service=1&node=playlist&token=215385555997023 + true + + + + + Station + + Ellen_Klinghammer - Mess - live *sample* + http://webservices.besonic.com/audio/00-1b-9e-22-e9-ec/124122.mp3 + + + + + + http://gatekeeper.my-noxon.net/RadioNative.php?service=10002&node=21cb40ef2acb0b15e2eea1c731de4472&token=08920a9358128a9 + + +