123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086 |
- <?php
- /* GNU FM -- a free network service for sharing your music listening habits
- Copyright (C) 2009 Free Software Foundation, Inc
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- require_once($install_path . '/database.php');
- require_once($install_path . '/data/Artist.php');
- // require_once($install_path . '/data/Group.php');
- require_once($install_path . '/data/Track.php');
- require_once($install_path . '/data/User.php');
- require_once($install_path . '/data/sanitize.php');
- require_once($install_path . '/utils/linkeddata.php');
- require_once($install_path . '/utils/arc/ARC2.php');
- require_once($install_path . '/utils/resolve-external.php');
- require_once($install_path . '/utils/licenses.php');
- require_once($install_path . '/utils/rewrite-encode.php');
- require_once($install_path . '/temp-utils.php'); // this is extremely dodgy and shameful
- require_once($install_path . '/data/clientcodes.php');
- /**
- * Provides access to server-wide data
- *
- * All methods are statically accessible
- */
- class Server {
- /**
- * Retrieves a list of recent scrobbles
- *
- * @param int $number The number of scrobbles to return
- * @param int $userid The user id to return scrobbles for
- * @param int $offset Amount of entries to skip before returning scrobbles
- * @param int $from Only return scrobbles with time higher than this timestamp
- * @param int $to Only return scrobbles with time lower than this timestamp
- * @return array Scrobbles or null in case of failure
- */
- static function getRecentScrobbles($number = 10, $userid = false, $offset = 0, $from = false, $to = false) {
- global $adodb;
- $adodb->SetFetchMode(ADODB_FETCH_ASSOC);
- if ($userid) {
- $params = array();
- $query = 'SELECT s.*, lt.userid as loved FROM Scrobbles s LEFT JOIN Loved_Tracks lt ON (s.track=lt.track AND s.artist=lt.artist AND s.userid=lt.userid) WHERE s.userid=?';
- $params[] = $userid;
- if ($from) {
- $query .= ' AND s.time>?';
- $params[] = (int) $from;
- }
- if ($to) {
- $query .= ' AND s.time<?';
- $params[] = (int) $to;
- }
- } else {
- $params = array();
- $query = 'SELECT s.* FROM Scrobbles s';
- if ($from) {
- $query .= ' WHERE s.time>?';
- $params[] = (int) $from;
- if ($to) {
- $query .= ' AND s.time<?';
- $params[] = (int) $to;
- }
- } else {
- if ($to) {
- $query .= ' WHERE s.time<?';
- $params[] = (int) $to;
- }
- }
- }
- $query .= ' ORDER BY s.time DESC LIMIT ? OFFSET ?';
- $params[] = (int) $number;
- $params[] = (int) $offset;
- try {
- $res = $adodb->CacheGetAll(60, $query, $params);
- } catch (Exception $e) {
- reportError($e->getMessage(), $e->getTraceAsString());
- return null;
- }
- if($userid) {
- $username = uniqueid_to_username($userid);
- $userurl = Server::getUserURL($username);
- }
- $result = array();
- foreach ($res as &$i) {
- $row = sanitize($i);
- if(!$userid) {
- $row['username'] = uniqueid_to_username($row['userid']);
- $row['userurl'] = Server::getUserURL($row['username']);
- } else {
- $row['username'] = $username;
- $row['userurl'] = $userurl;
- }
- if ($row['album']) {
- $row['albumurl'] = Server::getAlbumURL($row['artist'], $row['album']);
- }
- $row['artisturl'] = Server::getArtistURL($row['artist']);
- $row['trackurl'] = Server::getTrackURL($row['artist'], $row['album'], $row['track']);
- $row['timehuman'] = human_timestamp($row['time']);
- $row['timeiso'] = date('c', (int)$row['time']);
- $row['id'] = identifierScrobbleEvent($row['username'], $row['artist'], $row['track'], $row['album'], $row['time'], $row['mbid'], $row['artist_mbid'], $row['album_mbid']);
- $row['id_artist'] = identifierArtist($row['username'], $row['artist'], $row['track'], $row['album'], $row['time'], $row['mbid'], $row['artist_mbid'], $row['album_mbid']);
- $row['id_track'] = identifierTrack($row['username'], $row['artist'], $row['track'], $row['album'], $row['time'], $row['mbid'], $row['artist_mbid'], $row['album_mbid']);
- $row['id_album'] = identifierAlbum($row['username'], $row['artist'], $row['track'], $row['album'], $row['time'], $row['mbid'], $row['artist_mbid'], $row['album_mbid']);
- if (!$row['album_image']) {
- $row['album_image'] = false;
- } else {
- $row['album_image'] = resolve_external_url($row['album_image']);
- }
- if ($row['artwork_license'] == 'amazon') {
- $row['album_image'] = str_replace('SL160', 'SL50', $row['album_image']);
- }
- $row['licenseurl'] = $row['license'];
- $row['license'] = simplify_license($row['licenseurl']);
- $result[] = $row;
- }
- return $result;
- }
- /**
- * Retrieves a list of popular artists
- *
- * @param int $limit The number of artists to return
- * @param int $offset Skip this number of rows before returning artists
- * @param bool $streamable Only return streamable artists
- * @param int $begin Only use scrobbles with time higher than this timestamp
- * @param int $end Only use scrobbles with time lower than this timestamp
- * @param int $userid Only return results from this userid
- * @param int $cache Caching period in seconds
- * @return array An array of artists ((artist, freq, artisturl) ..) or empty array in case of failure
- */
- static function getTopArtists($limit = 21, $offset = 0, $streamable = False, $begin = null, $end = null, $userid = null, $cache = 600) {
- global $adodb;
- $query = ' SELECT artist, COUNT(artist) as freq FROM Scrobbles s';
- if ($streamable) {
- $query .= ' INNER JOIN Artist a ON s.artist=a.name WHERE a.streamable=1';
- $andquery = True;
- } else {
- if($begin || $end || $userid) {
- $query .= ' WHERE';
- $andquery = False;
- }
- }
- if($begin) {
- //change time resolution to full hours (for easier caching)
- $begin = $begin - ($begin % 3600);
-
- $andquery ? $query .= ' AND' : $andquery = True ;
- $query .= ' time>' . (int)$begin;
- }
- if($end) {
- //change time resolution to full hours (for easier caching)
- $end = $end - ($end % 3600);
-
- $andquery ? $query .= ' AND' : $andquery = True ;
- $query .= ' time<' . (int)$end;
- }
- if($userid) {
- $andquery ? $query .= ' AND' : $andquery = True ;
- $query .= ' userid=' . (int)$userid;
- }
- $query .= ' GROUP BY artist ORDER BY freq DESC LIMIT ' . (int)$limit . ' OFFSET ' . (int)$offset;
- $adodb->SetFetchMode(ADODB_FETCH_ASSOC);
- try {
- $data = $adodb->CacheGetAll($cache, $query);
- } catch (Exception $e) {
- return array();
- }
- $result = array();
- foreach ($data as &$i) {
- $row = sanitize($i);
- $row['artisturl'] = Server::getArtistURL($row['artist']);
- $result[] = $row;
- }
- return $result;
- }
- /**
- * Retrieves a list of loved artists
- *
- * @param int $limit The number of artists to return
- * @param int $offset Skip this number of rows before returning artists
- * @param bool $streamable Only return streamable artists
- * @param int $userid Only return results from this userid
- * @param int $cache Caching period in seconds
- * @return array Artists ((artist, freq, artisturl) ..) or empty array in case of failure
- */
- static function getLovedArtists($limit = 20, $offset = 0, $streamable = False, $userid = null, $cache = 600) {
- global $adodb;
- $query = ' SELECT artist, COUNT(artist) as freq FROM Loved_Tracks lt INNER JOIN Artist a ON a.name=lt.artist';
- if ($streamable) {
- $query .= ' WHERE a.streamable=1';
- $andquery = True;
- } else {
- if ($userid) {
- $query .= ' WHERE';
- $andquery = False;
- }
- }
- if ($userid) {
- $andquery ? $query .= ' AND' : null;
- $query .= ' userid=' . (int)$userid;
- }
- $query .= ' GROUP BY artist ORDER BY freq DESC LIMIT ' . (int)$limit . ' OFFSET ' . (int)$offset;
- $adodb->SetFetchMode(ADODB_FETCH_ASSOC);
- try {
- $data = $adodb->CacheGetAll($cache, $query);
- } catch (Exception $e) {
- return array();
- }
- $result = array();
- if (!empty($data)) {
- foreach ($data as &$i) {
- $row = sanitize($i);
- $row['artisturl'] = Server::getArtistURL($row['artist']);
- $result[] = $row;
- }
- }
- return $result;
- }
- /**
- * Retrieves a list of popular tracks
- *
- * @param int $limit The number of tracks to return
- * @param int $offset Skip this number of rows before returning tracks
- * @param bool $streamable Only return streamable tracks
- * @param int $begin Only use scrobbles with time higher than this timestamp
- * @param int $end Only use scrobbles with time lower than this timestamp
- * @param int $artist Only return results from this artist
- * @param int $userid Only return results from this userid
- * @param int $cache Caching period in seconds
- * @return array Tracks ((artist, track, freq, listeners, artisturl, trackurl) ..) or empty array in case of failure
- */
- static function getTopTracks($limit = 20, $offset = 0, $streamable = False, $begin = null, $end = null, $artist = null, $userid = null, $cache = 600) {
- global $adodb;
- $query = 'SELECT s.artist, s.track, count(s.track) AS freq, count(DISTINCT s.userid) AS listeners FROM Scrobbles s';
-
- if ($streamable) {
- $query .= ' WHERE ROW(s.artist, s.track) IN (SELECT artist_name, name FROM Track WHERE streamable=1)';
- $andquery = True;
- } else {
- if($begin || $end || $userid || $artist) {
- $query .= ' WHERE';
- $andquery = False;
- }
- }
- if($begin) {
- //change time resolution to full hours (for easier caching)
- $begin = $begin - ($begin % 3600);
-
- $andquery ? $query .= ' AND' : $andquery = True ;
- $query .= ' s.time>' . (int)$begin;
- }
- if($end) {
- //change time resolution to full hours (for easier caching)
- $end = $end - ($end % 3600);
-
- $andquery ? $query .= ' AND' : $andquery = True ;
- $query .= ' s.time<' . (int)$end;
- }
- if($userid) {
- $andquery ? $query .= ' AND' : $andquery = True ;
- $query .= ' s.userid=' . (int)$userid;
- }
- if($artist) {
- $andquery ? $query .= ' AND' : $andquery = True;
- $query .= ' lower(s.artist)=lower(' . $adodb->qstr($artist) . ')';
- }
-
- $query .= ' GROUP BY s.track, s.artist ORDER BY freq DESC LIMIT ' . (int)$limit . ' OFFSET ' . (int)$offset;
- $adodb->SetFetchMode(ADODB_FETCH_ASSOC);
- try {
- $data = $adodb->CacheGetAll($cache, $query);
- } catch (Exception $e) {
- return array();
- }
- $result = array();
- foreach ($data as &$i) {
- $row = sanitize($i);
- $row['artisturl'] = Server::getArtistURL($row['artist']);
- $row['trackurl'] = Server::getTrackURL($row['artist'], null, $row['track']);
- $result[] = $row;
- }
- return $result;
- }
- /**
- * Get a list of users with the most listens
- *
- * @param int $limit Amount of results to return
- * @param int $offset Skip this many items before returning results
- * @param int $streamable Only return results for streamable tracks
- * @param int $begin Only use scrobbles with time higher than this timestamp
- * @param int $end Only use scrobbles with time lower than this timestamp
- * @param string $artist Filter results by this artist
- * @param string $track Filter result by this track (need $artist to be set)
- * @param int $cache Caching period in seconds
- * @return array ((userid, freq, username, userurl) ..)
- */
- static function getTopListeners($limit = 10, $offset = 0, $streamable = True, $begin = null, $end = null, $artist = null, $track = null, $cache = 600) {
- global $adodb;
- $params = array();
- $query = 'SELECT s.userid, COUNT(*) as freq FROM Scrobbles s';
- if ($streamable) {
- $query .= ' WHERE ROW(s.artist, s.track) IN (SELECT artist_name, name FROM Track WHERE streamable=1)';
- $andquery = True;
- } else {
- if($begin || $end || $artist) {
- $query .= ' WHERE';
- $andquery = False;
- }
- }
- if($begin) {
- //change time resolution to full hours (for easier caching)
- $begin = $begin - ($begin % 3600);
-
- $andquery ? $query .= ' AND' : $andquery = True ;
- $query .= ' s.time > ?';
- $params[] = (int)$begin;
- }
- if($end) {
- //change time resolution to full hours (for easier caching)
- $end = $end - ($end % 3600);
-
- $andquery ? $query .= ' AND' : $andquery = True ;
- $query .= ' s.time < ?';
- $params[] = (int)$end;
- }
- if($artist) {
- $andquery ? $query .= ' AND' : $andquery = True;
- $query .= ' lower(s.artist)=lower(?)';
- $params[] = $artist;
- if($track) {
- $andquery ? $query .= ' AND' : $andquery = True;
- $query .= ' lower(s.track)=lower(?)';
- $params[] = $track;
- }
- }
-
- $query .= ' GROUP BY s.userid ORDER BY freq DESC LIMIT ? OFFSET ?';
- $params[] = (int)$limit;
- $params[] = (int)$offset;
- try {
- $adodb->SetFetchMode(ADODB_FETCH_ASSOC);
- $res = $adodb->CacheGetAll($cache, $query, $params);
- }catch (Exception $e) {
- return array();
- }
- foreach($res as &$row) {
- $row['username'] = uniqueid_to_username($row['userid']);
- $row['userurl'] = Server::getUserURL($row['username']);
- $result[] = $row;
- }
- return $result;
- }
- /**
- * Retrieves a list of loved tracks
- *
- * @param int $limit The number of tracks to return
- * @param int $offset Skip this number of rows before returning tracks
- * @param bool $streamable Only return streamable tracks
- * @param int $artist Only return results from this artist
- * @param int $userid Only return results from this userid
- * @param int $cache Caching period in seconds
- * @return array Tracks ((artist, track, freq, listeners, artisturl, trackurl) ..) or empty array in case of failure
- */
- static function getLovedTracks($limit = 20, $offset = 0, $streamable = False, $artist = null, $userid = null, $cache = 600) {
- global $adodb;
- $query = 'SELECT lt.artist, lt.track, max(lt.time) as time, count(lt.track) AS freq FROM Loved_Tracks lt';
-
- if ($streamable) {
- $query .= ' WHERE ROW(lt.artist, lt.track) IN (SELECT artist_name, name FROM Track WHERE streamable=1)';
- $andquery = True;
- } else {
- if($userid || $artist) {
- $query .= ' WHERE';
- $andquery = False;
- }
- }
- if($userid) {
- $andquery ? $query .= ' AND' : $andquery = True ;
- $query .= ' lt.userid=' . (int)$userid;
- }
- if($artist) {
- $andquery ? $query .= ' AND' : $andquery = True;
- $query .= ' lower(lt.artist)=lower(' . $adodb->qstr($artist) . ')';
- }
-
- $query .= ' GROUP BY lt.track, lt.artist ORDER BY freq DESC, time DESC LIMIT ' . (int)$limit . ' OFFSET ' . (int)$offset;
- $adodb->SetFetchMode(ADODB_FETCH_ASSOC);
- try {
- $data = $adodb->CacheGetAll($cache, $query);
- } catch (Exception $e) {
- return array();
- }
- $result = array();
- foreach ($data as &$i) {
- $row = sanitize($i);
- $row['artisturl'] = Server::getArtistURL($row['artist']);
- $row['trackurl'] = Server::getTrackURL($row['artist'], null, $row['track']);
- $result[] = $row;
- }
- return $result;
- }
- /**
- * Get a list of users
- *
- * @param string $alpha Search for user names starting with this string
- */
- static function getUserList($alpha) {
- global $adodb;
- $alpha .= '%';
- $query = 'SELECT username from Users where username LIKE ' . $adodb->qstr($alpha) . ' ORDER BY username ASC';
- $adodb->SetFetchMode(ADODB_FETCH_ASSOC);
- $data = $adodb->CacheGetAll(7200, $query);
- if (!$data) {
- throw new Exception('ERROR ' . $query);
- }
- return $data;
- }
- /**
- * Retrieves a list of the currently playing tracks
- *
- * @param int $number The maximum number of tracks to return
- * @param string $username The name of the user to retrieve playing tracks for
- * @return array Now playing data or null in case of failure
- */
- static function getNowPlaying($number = 1, $username = false) {
- global $adodb;
- $adodb->SetFetchMode(ADODB_FETCH_ASSOC);
- try {
- if ($username) {
- $data = $adodb->CacheGetAll(1, 'SELECT
- ss.userid,
- n.artist,
- n.track,
- n.album,
- client,
- api_key,
- n.mbid,
- t.license
- FROM Now_Playing n
- LEFT OUTER JOIN Scrobble_Sessions ss
- ON n.sessionid=ss.sessionid
- LEFT OUTER JOIN Track t
- ON lower(n.artist) = lower(t.artist_name)
- AND lower(n.album) = lower(t.album_name)
- AND lower(n.track) = lower(t.name)
- AND lower(n.mbid) = lower(t.mbid)
- WHERE ss.userid= ' . username_to_uniqueid($username) . '
- ORDER BY t.streamable DESC, n.expires DESC LIMIT ' . (int)($number));
- } else {
- $data = $adodb->CacheGetAll(60, 'SELECT
- ss.userid,
- n.artist,
- n.track,
- n.album,
- client,
- n.mbid,
- t.license
- FROM Now_Playing n
- LEFT OUTER JOIN Scrobble_Sessions ss
- ON n.sessionid=ss.sessionid
- LEFT OUTER JOIN Track t
- ON lower(n.artist) = lower(t.artist_name)
- AND lower(n.album) = lower(t.album_name)
- AND lower(n.track) = lower(t.name)
- AND lower(n.mbid) = lower(t.mbid)
- ORDER BY t.streamable DESC, n.expires DESC LIMIT ' . (int)($number));
- }
- } catch (Exception $e) {
- return null;
- }
- $result = array();
- foreach ($data as &$i) {
- $row = sanitize($i);
-
- $client = getClientData($row['client'], $row['api_key']);
- $row['clientcode'] = $client['code'];
- $row['clientapi_key'] = $client['code'];
- $row['clientname'] = $client['name'];
- $row['clienturl'] = $client['url'];
- $row['clientfree'] = $client['free'];
-
- $row['username'] = uniqueid_to_username($row['userid']);
- $row['userurl'] = Server::getUserURL($row['username']);
- $row['artisturl'] = Server::getArtistURL($row['artist']);
- $row['trackurl'] = Server::getTrackURL($row['artist'], $row['album'], $row['track']);
- if ($username) {
- $row['loved'] = $adodb->CacheGetOne(60, 'SELECT Count(*) FROM Loved_Tracks WHERE artist='
- . $adodb->qstr($row['artist'])
- . ' AND track=' . $adodb->qstr($row['track'])
- . ' AND userid=' . $row['userid']);
- }
- // We really want to get an image URI from the database and only fall back to qm50.png if we can't find an image.
- $row['albumart'] = $base_url . 'themes/' . $default_theme . '/images/qm50.png';
- $row['licenseurl'] = $row['license'];
- $row['license'] = simplify_license($row['licenseurl']);
- $result[] = $row;
- }
- return $result;
- }
- /**
- * Gets the URL to a user's profile page
- *
- * The get*URL functions are implemented here rather than in their respective
- * objects so that we can produce URLs without needing to build whole objects.
- *
- * @param string $username The user name we want a URL for
- * @param string $component Type of URL to return
- * @param string $params Trailing get parameters
- * @return string URL to the user's profile
- */
- static function getUserURL ($username, $component = 'profile', $params = false) {
- global $friendly_urls, $base_url;
- if ($component == 'edit') {
- return $base_url . '/user-edit.php';
- } else if ($component == 'delete') {
- return $base_url . '/delete-profile.php';
- } else if ($friendly_urls) {
- if ($component == 'profile') {
- $component = '';
- } else {
- $component = "/{$component}";
- }
- return $base_url . '/user/' . rewrite_encode($username) . $component . ($params ? '?' . $params : null);
- } else {
- return $base_url . "/user-{$component}.php?user=" . rawurlencode($username) . ($params ? '&' . $params : null);
- }
- }
- /**
- * Gets the URL to a group's page
- *
- * @param string $groupname The group we want a URL for
- * @return string URL to the group's page
- */
- static function getGroupURL($groupname) {
- global $friendly_urls, $base_url;
- if ($friendly_urls) {
- return $base_url . '/group/' . rewrite_encode($groupname);
- } else {
- return $base_url . '/group.php?group=' . rawurlencode($groupname);
- }
- }
- /**
- * Gets the URL to an artist's page
- *
- * @param string $artist The artist we want a URL for
- * @param string $component Type of URL to return
- * @return string URL to the artist's page
- */
- static function getArtistURL($artist, $component = '') {
- global $friendly_urls, $base_url;
- if ($friendly_urls) {
- return $base_url . '/artist/' . rewrite_encode($artist) . '/' . $component;
- } else {
- if ($component) {
- return $base_url . '/artist-' . $component . '.php?artist=' . rawurlencode($artist);
- } else {
- return $base_url . '/artist.php?artist=' . rawurlencode($artist);
- }
- }
- }
- /**
- * Gives the URL to the management interface for an artist
- *
- * @param string $artist The artist we want a URL for
- * @return string URL for an artist's management interface
- */
- static function getArtistManagementURL($artist) {
- global $friendly_urls, $base_url;
- if ($friendly_urls) {
- return Server::getArtistURL($artist) . '/manage';
- } else {
- return $base_url . '/artist-manage.php?artist=' . rawurlencode($artist);
- }
- }
- /**
- * Gives the URL for managers to add a new album to an artist
- *
- * @param string $artist The artist we want a URL for
- * @return string URL for adding albums to an artist
- */
- static function getAddAlbumURL($artist) {
- global $friendly_urls, $base_url;
- if ($friendly_urls) {
- return Server::getArtistURL($artist) . '/album/add';
- } else {
- return $base_url . '/album-add.php?artist=' . rawurlencode($artist);
- }
- }
- /**
- * Gets the URL to an album's page
- *
- * @param string $artist The artist name of the album
- * @param string $album The name of the album
- * @return string URL to the album's page
- */
- static function getAlbumURL($artist, $album) {
- global $friendly_urls, $base_url;
- if ($friendly_urls) {
- return $base_url . '/artist/' . rewrite_encode($artist) . '/album/' . rewrite_encode($album);
- } else {
- return $base_url . '/album.php?artist=' . rawurlencode($artist) . '&album=' . rawurlencode($album);
- }
- }
- /**
- * Gives the URL for managers to add a new track to an album
- *
- * @param string $artist The artist name of the album
- * @param string $album The name of the album
- * @return string URL for adding tracks to an album
- */
- static function getAddTrackURL($artist, $album) {
- global $friendly_urls, $base_url;
- if ($friendly_urls) {
- return Server::getAlbumURL($artist, $album) . '/track/add';
- } else {
- return $base_url . '/track-add.php?artist=' . rawurlencode($artist) . '&album=' . rawurlencode($album);
- }
- }
- /**
- * Gets the URL to a track's page
- *
- * @param string $artist The artist name of the track
- * @param string $album The album name of this track (optional)
- * @param string $track The name of the track
- * @param string $component Type of page
- * @return string URL to the track's page
- */
- static function getTrackURL($artist, $album, $track, $component = '') {
- global $friendly_urls, $base_url;
- if($friendly_urls) {
- $trackurl = $base_url . '/artist/' . rewrite_encode($artist);
- if($album) {
- $trackurl .= '/album/' . rewrite_encode($album);
- }
- $trackurl .= '/track/' . rewrite_encode($track);
- if($component) {
- $trackurl .= '/' . $component;
- }
- } else {
- if($component) {
- $trackurl = $base_url . '/track-' . $component . '.php?artist=' . rawurlencode($artist)
- . '&album=' . rawurlencode($album) . '&track=' . rawurlencode($track);
- } else {
- $trackurl = $base_url . '/track.php?artist=' . rawurlencode($artist)
- . '&album=' . rawurlencode($album) . '&track=' . rawurlencode($track);
- }
- }
- return $trackurl;
- }
- /**
- * Gets the URL to a track's edit page
- *
- * @param string $artist The artist name of the track
- * @param string $album The album name of this track (optional)
- * @param string $track The name of the track
- * @return string URL to the track's edit page
- */
- static function getTrackEditURL($artist, $album, $track) {
- global $friendly_urls, $base_url;
- if ($friendly_urls && $album) {
- return $base_url . '/artist/' . rewrite_encode($artist) . '/album/' . rewrite_encode($album) . '/track/' . rewrite_encode($track) . '/edit';
- } else if ($friendly_urls) {
- return $base_url . '/artist/' . rewrite_encode($artist) . '/track/' . rewrite_encode($track) . '/edit';
- } else {
- return $base_url . '/track-add.php?artist=' . rawurlencode($artist) . '&album=' . rawurlencode($album) . '&track=' . rawurlencode($track);
- }
- }
- static function getAlbumEditURL($artist, $album) {
- global $friendly_urls, $base_url;
- if ($friendly_urls) {
- return $base_url . '/artist/' . rewrite_encode($artist) . '/album/' . rewrite_encode($album) . '/edit';
- } else {
- return $base_url . '/album-add.php?artist=' . rawurlencode($artist) . '&album=' . rawurlencode($album);
- }
- }
- /**
- * Gets the URL to a tag's page
- *
- * @param string $tag The name of the tag
- * @return string URL to the tag's page
- */
- static function getTagURL($tag) {
- global $friendly_urls, $base_url;
- if ($friendly_urls) {
- return $base_url . '/tag/' . rewrite_encode($tag);
- } else {
- return $base_url . '/tag.php?tag=' . rawurlencode($tag);
- }
- }
- static function getLocationDetails($name) {
- global $adodb;
- if (!$name) {
- return array();
- }
- $adodb->SetFetchMode(ADODB_FETCH_ASSOC);
- $rv = $adodb->GetRow('SELECT p.latitude, p.longitude, p.country, c.country_name, c.wikipedia_en '
- . 'FROM Places p '
- . 'LEFT JOIN Countries c ON p.country=c.country '
- . 'WHERE p.location_uri=' . $adodb->qstr($name, 'text'));
- if ($rv) {
- if (!($rv['latitude'] && $rv['longitude'] && $rv['country'])) {
- $parser = ARC2::getRDFXMLParser();
- $parser->parse($name);
- $index = $parser->getSimpleIndex();
- $rv = array(
- 'latitude' => $index[$name]['http://www.w3.org/2003/01/geo/wgs84_pos#lat'][0],
- 'longitude' => $index[$name]['http://www.w3.org/2003/01/geo/wgs84_pos#long'][0],
- 'country' => strtoupper(substr($index[$name]['http://www.geonames.org/ontology#inCountry'][0], -2))
- );
- $adodb->Execute(sprintf('UPDATE Places SET latitude=%s, longitude=%s, country=%s WHERE location_uri=%s',
- $adodb->qstr($rv['latitude']),
- $adodb->qstr($rv['longitude']),
- $adodb->qstr($rv['country']),
- $adodb->qstr($name)));
- }
- } else {
- $parser = ARC2::getRDFXMLParser();
- $parser->parse($name);
- $index = $parser->getSimpleIndex();
- $rv = array(
- 'latitude' => $index[$name]['http://www.w3.org/2003/01/geo/wgs84_pos#lat'][0],
- 'longitude' => $index[$name]['http://www.w3.org/2003/01/geo/wgs84_pos#long'][0],
- 'country' => strtoupper(substr($index[$name]['http://www.geonames.org/ontology#inCountry'][0], -2))
- );
- $adodb->Execute(sprintf('INSERT INTO Places (location_uri, latitude, longitude, country) VALUES (%s, %s, %s, %s)',
- $adodb->qstr($name),
- $adodb->qstr($rv['latitude']),
- $adodb->qstr($rv['longitude']),
- $adodb->qstr($rv['country'])));
- }
- return $rv;
- }
- /**
- * Log in to the radio server
- *
- * @param string $station The station to be played
- * @param string $username The user to associate this session with (optional)
- * @param string $session_id Allows for a custom session id to be set, allowing for compatibility with webservices
- * @return string Session key to be used for streaming
- */
- static function getRadioSession($station, $username = false, $session_id = false) {
- global $adodb;
- if (!$session_id) {
- $session_id = md5(mt_rand() . time());
- }
- // Remove any previous station for this session id
- $adodb->Execute('DELETE FROM Radio_Sessions WHERE session = ' . $adodb->qstr($session_id));
- if ($username) {
- $sql = 'INSERT INTO Radio_Sessions(username, session, url, expires) VALUES ('
- . $adodb->qstr($username) . ','
- . $adodb->qstr($session_id) . ','
- . $adodb->qstr($station) . ','
- . (int)(time() + 86400) . ')';
- } else {
- $sql = 'INSERT INTO Radio_Sessions(session, url, expires) VALUES ('
- . $adodb->qstr($session_id) . ','
- . $adodb->qstr($station) . ','
- . (int)(time() + 86400) . ')';
- }
- $res = $adodb->Execute($sql);
- return $session_id;
- }
- /**
- * Log in to web services
- *
- * @param string $username The user to create a session for
- * @return string The web service session key
- */
- static function getWebServiceSession($username) {
- global $adodb;
- $sk = md5(mt_rand() . time());
- $token = md5(mt_rand() . time());
- $adodb->Execute('INSERT INTO Auth(token, sk, expires, username) VALUES ('
- . $adodb->qstr($token) . ', '
- . $adodb->qstr($sk) . ', '
- . (int)(time() + 86400) . ', '
- . $adodb->qstr($username) . ')');
- return $sk;
- }
- /**
- * Get scrobble session ID for a user.
- *
- * Gets the most recent scrobble session ID for userid,
- * or creates a new session ID if it can't find one.
- *
- * @param int userid (required) User ID.
- * @param string api_key (optional) Client API key (32 characters)
- * @param int expire_limit (optional) Amount of time in seconds before session will expire (defaults to 86400 = 24 hours)
- * @return string Scrobble session ID
- */
- static function getScrobbleSession($userid, $api_key = null, $expire_limit = 86400) {
- //TODO Add code to remove expired sessions (this is currently only done in gnukebox)
- global $adodb;
- $query = 'SELECT sessionid FROM Scrobble_Sessions WHERE userid = ? AND expires > ?';
- $params = array( (int) $userid, time());
- if (strlen($api_key) == 32) {
- $query .= ' AND api_key=?';
- $params[] = $api_key;
- } elseif (strlen($api_key) == 3) {
- // api_key is really a 3 char client code (2.0-scrobble-proxy.php sends client code in api_key)
- $query .= ' AND client=?';
- $client_id = $api_key;
- $params[] = $client_id;
- // we dont want to insert a 3 char code as api_key in db
- $api_key = null;
- }
- $sessionid = $adodb->GetOne($query, $params);
- if (!$sessionid) {
- $sessionid = md5(mt_rand() . time());
- $expires = time() + (int) $expire_limit;
- $query = 'INSERT INTO Scrobble_Sessions(userid, sessionid, client, expires, api_key) VALUES (?,?,?,?,?)';
- $params = array($userid, $sessionid, $client_id, $expires, $api_key);
- try {
- $adodb->Execute($query, $params);
- } catch (Exception $e) {
- return null;
- }
- }
- return $sessionid;
- }
- /**
- * Get all artists
- *
- * @return array Artists ordered by name
- */
- static function getAllArtists() {
- global $adodb;
- $sql = 'SELECT * from Artist ORDER by name';
- $adodb->SetFetchMode(ADODB_FETCH_ASSOC);
- try {
- $res = $adodb->CacheGetAll(86400, $sql);
- } catch (Exception $e) {
- return null;
- }
- $result = array();
- foreach ($res as &$i) {
- $row = sanitize($i);
- $row['artisturl'] = Server::getArtistURL($row['name']);
- $result[] = $row;
- }
- return $result;
- }
- /**
- * Search for users, artists or tags
- *
- * Does a lower-case search of %search_term%
- *
- * @param string $search_term
- * @param string $search_type Type of search, artist|user|tag
- * @param int $limit How many items to return
- * @param bool $streamable Only return streamable artists
- * @return array Results
- */
- static function search($search_term, $search_type, $limit = 40, $streamable = false) {
- global $adodb;
- if ($search_term) {
- switch ($search_type) {
- case 'artist':
- $table = 'Artist';
- $search_fields[] = 'name';
- $data_fields[] = 'name';
- $data_fields[] = 'bio_summary';
- $data_fields[] = 'streamable';
- $data_fields[] = 'image_small';
- $data_fields[] = 'image_medium';
- $data_fields[] = 'image_large';
- break;
- case 'user':
- $table = 'Users';
- $search_fields[] = 'username';
- $search_fields[] = 'fullname';
- $data_fields[] = 'username';
- $data_fields[] = 'fullname';
- $data_fields[] = 'bio';
- break;
- case 'tag':
- $table = 'Tags';
- $search_fields[] = 'tag';
- $data_fields[] = 'tag';
- break;
- default:
- return array();
- }
- $sql = 'SELECT DISTINCT ';
- for ($i = 0; $i < count($data_fields); $i++) {
- $sql .= $data_fields[$i];
- if ($i < count($data_fields) - 1) {
- $sql .= ', ';
- }
- }
- $sql .= ' FROM ' . $table . ' WHERE ';
- for ($i = 0; $i < count($search_fields); $i++) {
- if ($i > 0) {
- $sql .= ' OR ';
- }
- $sql .= 'LOWER(' . $search_fields[$i] . ') LIKE LOWER(' . $adodb->qstr('%' . $search_term . '%') . ')';
- }
- if ($streamable) {
- $sql .= " AND streamable = 1 ";
- }
- $sql .= 'LIMIT ' . $limit;
- $res = $adodb->CacheGetAll(600, $sql);
- $result = array();
- foreach ($res as &$i) {
- $row = sanitize($i);
- switch ($search_type) {
- case 'artist':
- $row['url'] = Server::getArtistURL($row['name']);
- break;
- case 'user':
- $row['url'] = Server::getUserURL($row['username']);
- break;
- case 'tag':
- $row['url'] = Server::getTagURL($row['tag']);
- break;
- }
- $result[] = $row;
- }
- }
- return $result;
- }
- /**
- * Create a random authentication token and return it
- *
- * @return string Token.
- */
- static function getAuthToken() {
- global $adodb;
- $key = md5(time() . rand());
- $expires = (int) (time() + 3600);
- $query = 'INSERT INTO Auth(token, expires) VALUES(?,?)';
- $params = array($key, $expires);
- try {
- $adodb->Execute($query, $params);
- return $key;
- } catch (Exception $e) {
- reportError($e->getMessage(), $e->getTraceAsString());
- }
- }
- }
|