1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084 |
- <?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();
- 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());
- }
- }
- }
|