%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /data/www_bck/varak.net_bck/ampache.varak.net/lib/class/
Upload File :
Create Path :
Current File : //data/www_bck/varak.net_bck/ampache.varak.net/lib/class/recommendation.class.php

<?php
/* vim:set softtabstop=4 shiftwidth=4 expandtab: */
/**
 *
 * LICENSE: GNU General Public License, version 2 (GPLv2)
 * Copyright 2001 - 2014 Ampache.org
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License v2
 * as published by the Free Software Foundation.
 *
 * 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 */

class Recommendation
{
    /**
     * Constructor
     * Not on my watch, boyo.
     */
    private function __construct()
    {
        return false;
    } //constructor

    /**
     * get_lastfm_results
     * Runs a last.fm query and returns the parsed results
     */
    public static function get_lastfm_results($method, $query)
    {
        $api_key = AmpConfig::get('lastfm_api_key');
        $api_base = "http://ws.audioscrobbler.com/2.0/?method=";
        $url = $api_base . $method . '&api_key=' . $api_key . '&' . $query;
        debug_event('Recommendation', 'search url : ' . $url, 5);

        $options = array();
        if (AmpConfig::get('proxy_host') AND AmpConfig::get('proxy_port')) {
            $proxy = array();
            $proxy[] = AmpConfig::get('proxy_host') . ':' . AmpConfig::get('proxy_port');
            if (AmpConfig::get('proxy_user')) {
                $proxy[] = AmpConfig::get('proxy_user');
                $proxy[] = AmpConfig::get('proxy_pass');
            }
            $options['proxy'] = $proxy;
        }
        $request = Requests::get($url, array(), $options);
        $content = $request->body;

        return simplexml_load_string($content);
    } // get_lastfm_results

    /**
     * gc
     *
     * This cleans out old recommendations cache
     */
    public static function gc()
    {
        Dba::write('DELETE FROM `recommendation` WHERE `last_update` < ?', array((time() - 604800)));
    }

    protected static function get_recommendation_cache($type, $id, $get_items = false)
    {
        self::gc();

        $sql = "SELECT `id`, `last_update` FROM `recommendation` WHERE `object_type` = ? AND `object_id` = ?";
        $db_results = Dba::read($sql, array($type, $id));

        if ($cache = Dba::fetch_assoc($db_results)) {
            if ($get_items) {
                $cache['items'] = array();
                $sql = "SELECT `recommendation_id`, `name`, `rel`, `mbid` FROM `recommendation_item` WHERE `recommendation` = ?";
                $db_results = Dba::read($sql, array($cache['id']));
                while ($results = Dba::fetch_assoc($db_results)) {
                    $cache['items'][] = array(
                        'id' => $results['recommendation_id'],
                        'name' => $results['name'],
                        'rel' => $results['rel'],
                        'mbid' => $results['mbid'],
                    );
                }
            }
        }

        return $cache;
    }

    protected static function delete_recommendation_cache($type, $id)
    {
        $cache = self::get_recommendation_cache($type, $id);
        if ($cache['id']) {
            Dba::write('DELETE FROM `recommendation_item` WHERE `recommendation` = ?', array($cache['id']));
            Dba::write('DELETE FROM `recommendation` WHERE `id` = ?', array($cache['id']));
        }
    }

    protected static function update_recommendation_cache($type, $id, $recommendations)
    {
        self::delete_recommendation_cache($type, $id);
        $sql = "INSERT INTO `recommendation` (`object_type`, `object_id`, `last_update`) VALUES (?, ?, ?)";
        Dba::write($sql, array($type, $id, time()));
        $insertid = Dba::insert_id();
        foreach ($recommendations as $recommendation) {
            $sql = "INSERT INTO `recommendation_item` (`recommendation`, `recommendation_id`, `name`, `rel`, `mbid`) VALUES (?, ?, ?, ?, ?)";
            Dba::write($sql, array($insertid, $recommendation['id'], $recommendation['name'], $recommendation['rel'], $recommendation['mbid']));
        }
    }

    /**
     * get_songs_like
     * Returns a list of similar songs
     */
    public static function get_songs_like($song_id, $limit = 5, $local_only = true)
    {
        $song = new Song($song_id);

        if (isset($song->mbid)) {
            $query = 'mbid=' . rawurlencode($song->mbid);
        } else {
            $query = 'track=' . rawurlencode($song->title);
        }

        $cache = self::get_recommendation_cache('song', $song_id, true);
        if (!$cache['id']) {
            $similars = array();
            $xml = self::get_lastfm_results('track.getsimilar', $query);

            if ($xml->similartracks) {
                foreach ($xml->similartracks->children() as $child) {
                    $name = $child->name;
                    $local_id = null;

                    $artist_name = $child->artist->name;
                    $s_artist_name = Catalog::trim_prefix($artist_name);

                    $sql = "SELECT `song`.`id` FROM `song` " .
                        "LEFT JOIN `artist` ON " .
                        "`song`.`artist`=`artist`.`id` ";
                    if (AmpConfig::get('catalog_disable')) {
                        $sql .= "LEFT JOIN `catalog` ON `song`.`catalog` = `catalog`.`id` ";
                    }
                    $sql .= "WHERE `song`.`title` = ? " .
                        "AND `artist`.`name` = ? ";
                    if (AmpConfig::get('catalog_disable')) {
                        $sql .= "AND `catalog`.`enabled` = '1'";
                    }

                    $db_result = Dba::read($sql, array($name, $s_artist_name['string']));

                    if ($result = Dba::fetch_assoc($db_result)) {
                        $local_id = $result['id'];
                    }

                    if (is_null($local_id)) {
                        debug_event('Recommendation', "$name did not match any local song", 5);
                        $similars[] = array(
                            'id' => null,
                            'name' => $name,
                            'rel' => $artist_name
                        );
                    } else {
                        debug_event('Recommendation', "$name matched local song $local_id", 5);
                        $similars[] = array(
                            'id' => $local_id,
                            'name' => $name
                        );
                    }
                }

                if (count($similars) > 0) {
                    self::update_recommendation_cache('song', $song_id, $similars);
                }
            }
        }

        if (!isset($similars) || count($similars) == 0) {
            $similars = $cache['items'];
        }
        if ($similars) {
            $results = array();
            foreach ($similars as $similar) {
                if (!$local_only || !is_null($similar['id'])) {
                    $results[] = $similar;
                }

                if ($limit && count($results) >= $limit) {
                    break;
                }
            }
        }

        if (isset($results)) {
            return $results;
        }

        return false;
    }

    /**
     * get_artists_like
     * Returns a list of similar artists
     */
    public static function get_artists_like($artist_id, $limit = 10, $local_only = true)
    {
        $artist = new Artist($artist_id);

        $cache = self::get_recommendation_cache('artist', $artist_id, true);
        if (!$cache['id']) {
            $similars = array();
            $query = 'artist=' . rawurlencode($artist->name);

            $xml = self::get_lastfm_results('artist.getsimilar', $query);

            foreach ($xml->similarartists->children() as $child) {
                $name = $child->name;
                $mbid = (string) $child->mbid;
                $local_id = null;

                // First we check by MBID
                if ($mbid) {
                    $sql = "SELECT `artist`.`id` FROM `artist` WHERE `mbid` = ?";
                    if (AmpConfig::get('catalog_disable')) {
                        $sql .= " AND " . Catalog::get_enable_filter('artist', '`artist`.`id`');
                    }
                    $db_result = Dba::read($sql, array($mbid));
                    if ($result = Dba::fetch_assoc($db_result)) {
                        $local_id = $result['id'];
                    }
                }

                // Then we fall back to the less likely to work exact
                // name match
                if (is_null($local_id)) {
                    $searchname = Catalog::trim_prefix($name);
                    $searchname = Dba::escape($searchname['string']);
                    $sql = "SELECT `artist`.`id` FROM `artist` WHERE `name` = ?";
                    if (AmpConfig::get('catalog_disable')) {
                        $sql .= " AND " . Catalog::get_enable_filter('artist', '`artist`.`id`');
                    }
                    $db_result = Dba::read($sql, array($searchname));
                    if ($result = Dba::fetch_assoc($db_result)) {
                        $local_id = $result['id'];
                    }
                }

                // Then we give up
                if (is_null($local_id)) {
                    debug_event('Recommendation', "$name did not match any local artist", 5);
                    $similars[] = array(
                        'id' => null,
                        'name' => $name,
                        'mbid' => $mbid
                    );
                } else {
                    debug_event('Recommendation', "$name matched local artist " . $local_id, 5);
                    $similars[] = array(
                        'id' => $local_id,
                        'name' => $name
                    );
                }
            }

            if (count($similars) > 0) {
                self::update_recommendation_cache('artist', $artist_id, $similars);
            }
        }

        if (!isset($similars) || count($similars) == 0) {
            $similars = $cache['items'];
        }
        if ($similars) {
            $results = array();
            foreach ($similars as $similar) {
                if (!$local_only || !is_null($similar['id'])) {
                    $results[] = $similar;
                }

                if ($limit && count($results) >= $limit) {
                    break;
                }
            }
        }

        if (isset($results)) {
            return $results;
        }

        return false;
    } // get_artists_like

    /**
     * get_artist_info
     * Returns artist information
     */
    public static function get_artist_info($artist_id, $fullname='')
    {
        $artist = null;
        if ($artist_id) {
            $artist = new Artist($artist_id);
            $artist->format();
            $fullname = $artist->f_full_name;

            // Data newer than 6 months, use it
            if (($artist->last_update + 15768000) > time()) {
                $results = array();
                $results['summary'] = $artist->summary;
                $results['placeformed'] = $artist->placeformed;
                $results['yearformed'] = $artist->yearformed;
                $results['largephoto'] = Art::url($artist->id, 'artist');
                $results['megaphoto'] = $results['largephoto'];
                return $results;
            }
        }

        $query = 'artist=' . rawurlencode($fullname);

        $xml = self::get_lastfm_results('artist.getinfo', $query);

        $results = array();
        $results['summary'] = strip_tags(preg_replace("#<a href=([^<]*)Last\.fm</a>.#", "", (string) $xml->artist->bio->summary));
        $results['placeformed'] = (string) $xml->artist->bio->placeformed;
        $results['yearformed'] = (string) $xml->artist->bio->yearformed;
        $results['largephoto'] = $xml->artist->image[2];
        $results['megaphoto'] = $xml->artist->image[4];

        if ($artist) {
            if (!empty($results['summary']) || !empty($results['megaphoto'])) {
                $artist->update_artist_info($results['summary'], $results['placeformed'], $results['yearformed']);

                $image = Art::get_from_source(array('url' => $results['megaphoto']), 'artist');
                $rurl = pathinfo($results['megaphoto']);
                $mime = 'image/' . $rurl['extension'];
                $art = new Art($artist->id, 'artist');
                $art->reset();
                $art->insert($image, $mime);
                $results['largephoto'] = Art::url($artist->id, 'artist');
                $results['megaphoto'] = $results['largephoto'];
            }
        }

        return $results;
    } // get_artist_info

} // end of recommendation class

Zerion Mini Shell 1.0