summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul 'flowerysong' Arthur <flowerysong00@yahoo.com>2010-10-06 16:58:31 +0000
committerPaul 'flowerysong' Arthur <flowerysong00@yahoo.com>2010-10-06 16:58:31 +0000
commit4f3d8851cf325cf5a8465ca6880c48f74629b449 (patch)
tree1eee4932b98ae7dc956fb30e71ff1a3996e46887
parent2066c7908b5a033415022ad50102be48e2c4d4ab (diff)
downloadampache-4f3d8851cf325cf5a8465ca6880c48f74629b449.tar.gz
ampache-4f3d8851cf325cf5a8465ca6880c48f74629b449.tar.bz2
ampache-4f3d8851cf325cf5a8465ca6880c48f74629b449.zip
Break everyone's config by changing metadata gathering.
-rw-r--r--config/ampache.cfg.php.dist16
-rwxr-xr-xdocs/CHANGELOG2
-rw-r--r--docs/PLUGINS2
-rw-r--r--lib/class/preference.class.php4
-rw-r--r--lib/class/vainfo.class.php309
-rw-r--r--lib/init.php2
-rw-r--r--modules/plugins/MusicBrainz.plugin.php98
7 files changed, 292 insertions, 141 deletions
diff --git a/config/ampache.cfg.php.dist b/config/ampache.cfg.php.dist
index 165c769d..0a828ee7 100644
--- a/config/ampache.cfg.php.dist
+++ b/config/ampache.cfg.php.dist
@@ -211,11 +211,17 @@ require_localnet_session = "true"
; music. If none of the listed tags are found then
; ampache will default to the first tag format
; that was found.
-; POSSIBLE VALUES: id3v1 id3v2 file vorbiscomment
-; quicktime ape asf
-; DEFAULT: id3v2,id3v1 vorbiscomment quicktime ape
-; asf file
-tag_order = "id3v2,id3v1,vorbiscomment,quicktime,ape,asf,file"
+; POSSIBLE VALUES: ape asf avi id3v1 id3v2 lyrics3 mpeg quicktime riff
+; vorbiscomment
+; DEFAULT: id3v2 id3v1 vorbiscomment quicktime ape asf avi mpeg riff
+getid3_tag_order = "id3v2,id3v1,vorbiscomment,quicktime,ape,asf,avi,mpeg,riff"
+
+; This determines the order in which metadata sources are used (and in the
+; case of plugins, checked)
+; POSSIBLE VALUES (builtins): filename and getID3
+; POSSIBLE VALUES (plugins): MusicBrainz, plus any others you've installed.
+; DEFAULT: getID3 filename
+metadata_order = "getID3,filename"
; Un comment if don't want ampache to follow symlinks
; DEFAULT: false
diff --git a/docs/CHANGELOG b/docs/CHANGELOG
index 9c3bb3c8..736df610 100755
--- a/docs/CHANGELOG
+++ b/docs/CHANGELOG
@@ -4,6 +4,8 @@
--------------------------------------------------------------------------
v.3.6-Alpha1
+ - Partial MusicBrainz metadata gathering via plugin
+ - Metadata code cleanup, support for plugins as metadata sources
- New plugin architecture
- Fixed display charset issue with catalog add/update
- Fixed handling of temporary playlists with >100 items
diff --git a/docs/PLUGINS b/docs/PLUGINS
index 910a9e1a..27519582 100644
--- a/docs/PLUGINS
+++ b/docs/PLUGINS
@@ -20,6 +20,8 @@ The following public methods may be implemented:
Finally, for the plugin to actually be useful one or more of the following hooks
should be implemented as a public method:
+ get_metadata(Array $metadata)
+ The passed array contains the best metadata we've got.
save_rating(Rating $rating, int $new_value)
save_songplay(Song $song)
diff --git a/lib/class/preference.class.php b/lib/class/preference.class.php
index bc2e9b2e..7eb78f65 100644
--- a/lib/class/preference.class.php
+++ b/lib/class/preference.class.php
@@ -323,8 +323,8 @@ class Preference {
* become an array and boolean everythings
*/
public static function fix_preferences($results) {
- $arrays = array('auth_methods', 'tag_order', 'art_order',
- 'amazon_base_urls');
+ $arrays = array('auth_methods', 'getid3_tag_order',
+ 'metadata_order', 'art_order', 'amazon_base_urls');
foreach ($arrays as $item) {
$results[$item] = trim($results[$item])
diff --git a/lib/class/vainfo.class.php b/lib/class/vainfo.class.php
index 330ebe61..8bf717a5 100644
--- a/lib/class/vainfo.class.php
+++ b/lib/class/vainfo.class.php
@@ -146,8 +146,8 @@ class vainfo {
*/
public function get_info() {
- // If this is broken, don't waste time figuring it out a second time, just return
- // their rotting carcass of a media file back on the pile
+ // If this is broken, don't waste time figuring it out a second
+ // time, just return their rotting carcass of a media file.
if ($this->_broken) {
$this->tags = $this->set_broken();
return true;
@@ -164,12 +164,17 @@ class vainfo {
/* Figure out what type of file we are dealing with */
$this->type = $this->_get_type();
- /* Get the general information about this file */
- $info = $this->_get_info();
+ $enabled_sources = (array)Config::get('metadata_order');
- /* Gets the Tags */
- $this->tags = $this->_get_tags();
- $this->tags['info'] = $info;
+ if (in_array('filename', $enabled_sources)) {
+ $this->tags['filename'] = $this->_parse_filename($this->filename);
+ }
+
+ if (in_array('getID3', $enabled_sources)) {
+ $this->tags['getID3'] = $this->_get_tags();
+ }
+
+ $this->_get_plugin_tags();
} // get_info
@@ -180,13 +185,12 @@ class vainfo {
* tag_order doesn't match anything then it throws up its hands and uses
* everything.
*/
- public static function get_tag_type($results) {
+ public static function get_tag_type($results, $config_key = 'metadata_order') {
- /* Pull in the config option */
- $order = (array)Config::get('tag_order');
+ $order = (array)Config::get($config_key);
- /* Foreach through the defined key order
- * adding them to an ordered array as we go
+ /* Iterate through the defined key order adding them to an
+ * ordered array as we go.
*/
foreach($order as $key) {
@@ -212,120 +216,141 @@ class vainfo {
* key we've decided on and the filename and returns it in a
* sanitized format that ampache can actually use
*/
- public static function clean_tag_info($results,$keys,$filename) {
+ public static function clean_tag_info($results, $keys, $filename = null) {
$info = array();
- $clean_array = array("\n","\t","\r","\0");
- $wipe_array = array("","","","");
+ if ($filename) {
+ $info['file'] = $filename;
+ }
- $info['file'] = $filename;
+ // Iteration!
+ foreach ($keys as $key) {
+ $tags = $results[$key];
- /* These are pulled from the info array */
- $info['bitrate'] = intval($results['info']['bitrate']);
- $info['rate'] = intval($results['info']['sample_rate']);
- $info['mode'] = $results['info']['bitrate_mode'];
+ $info['file'] = $info['file']
+ ? $info['file']
+ : $tags['file'];
- // Convert special version of constant bitrate mode to cbr
- if($info['mode'] == 'con') {
- $info['mode'] = 'cbr';
- }
- $info['size'] = $results['info']['filesize'];
- $info['mime'] = $results['info']['mime'];
- $into['encoding'] = $results['info']['encoding'];
- $info['time'] = intval($results['info']['playing_time']);
- $info['channels'] = intval($results['info']['channels']);
+ $info['bitrate'] = $info['bitrate']
+ ? $info['bitrate']
+ : intval($tags['bitrate']);
- // Specific Audio Flags
- foreach ($keys as $key) {
- if (!$results[$key]['video_codec']) {
- $slash_point = strpos($results[$key]['disk'],'/');
- if ($slash_point !== FALSE) {
- $results[$key]['disk'] = substr($results[$key]['disk'],0,$slash_point);
- }
- /* These are used to generate the correct ID's later */
- $info['title'] = $info['title']
- ? $info['title']
- : stripslashes(trim($results[$key]['title']));
-
- $info['year'] = $info['year']
- ? $info['year']
- : intval($results[$key]['year']);
-
- $info['disk'] = $info['disk']
- ? $info['disk']
- : intval($results[$key]['disk']);
-
- $info['artist'] = $info['artist']
- ? $info['artist']
- : trim($results[$key]['artist']);
-
- $info['album'] = $info['album']
- ? $info['album']
- : trim($results[$key]['album']);
-
- // multiple genre support
- if (!$info['genre']) {
- if (!is_array($results[$key]['genre'])) {
- // not all tag formats will return an array, but we need one
- $info['genre'][] = trim($results[$key]['genre']);
- }
- else {
- // if we trim the array we lose everything after 1st entry
- foreach ($results[$key]['genre'] as $genre) {
- $info['genre'][] = trim($genre);
- }
- }
- }
+ $info['rate'] = $info['rate']
+ ? $info['rate']
+ : intval($tags['rate']);
- $info['mb_trackid'] = $info['mb_trackid']
- ? $info['mb_trackid']
- : trim($results[$key]['mb_trackid']);
+ $info['mode'] = $info['mode']
+ ? $info['mode']
+ : $tags['mode'];
- $info['mb_albumid'] = $info['mb_albumid']
- ? $info['mb_albumid']
- : trim($results[$key]['mb_albumid']);
+ $info['size'] = $info['size']
+ ? $info['size']
+ : $tags['size'];
- $info['mb_artistid'] = $info['mb_artistid']
- ? $info['mb_artistid']
- : trim($results[$key]['mb_artistid']);
+ $info['mime'] = $info['mime']
+ ? $info['mime']
+ : $tags['mime'];
- /* @TODO language doesn't import from id3tag. @momo-i */
- $info['language'] = $info['language']
- ? $info['language']
- : Dba::escape($results[$key]['language']);
+ $info['encoding'] = $info['encoding']
+ ? $info['encoding']
+ : $tags['encoding'];
- $info['lyrics'] = $info['lyrics']
- ? $info['lyrics']
- : str_replace(array("\r\n","\r","\n"), '<br />',strip_tags($results[$key]['unsynchronised lyric']));
+ $info['time'] = $info['time']
+ ? $info['time']
+ : intval($tags['time']);
- $info['track'] = $info['track']
- ? $info['track']
- : intval($results[$key]['track']);
- }
- else {
- $info['resolution_x'] = $info['resolution_x']
- ? $info['resolution_x']
- : intval($results[$key]['resolution_x']);
+ $info['channels'] = $info['channels']
+ ? $info['channels']
+ : $tags['channels'];
+
+ /* These are used to generate the correct IDs later */
+ $info['title'] = $info['title']
+ ? $info['title']
+ : stripslashes(trim($tags['title']));
+
+ $info['year'] = $info['year']
+ ? $info['year']
+ : intval($tags['year']);
- $info['resolution_y'] = $info['resolution_y']
- ? $info['resolution_y']
- : intval($results[$key]['resolution_y']);
+ $info['disk'] = $info['disk']
+ ? $info['disk']
+ : intval($tags['disk']);
- $info['audio_codec'] = $info['audio_codec']
- ? $info['audio_codec']
- : Dba::escape($results[$key]['audio_codec']);
+ $info['artist'] = $info['artist']
+ ? $info['artist']
+ : trim($tags['artist']);
- $info['video_codec'] = $info['video_codec']
- ? $info['video_codec']
- : Dba::escape($results[$key]['video_codec']);
+ $info['album'] = $info['album']
+ ? $info['album']
+ : trim($tags['album']);
+
+ // multiple genre support
+ if ((!$info['genre']) && $tags['genre']) {
+ if (!is_array($tags['genre'])) {
+ // not all tag formats will return an array, but we need one
+ $info['genre'][] = trim($tags['genre']);
+ }
+ else {
+ // if we trim the array we lose everything after 1st entry
+ foreach ($tags['genre'] as $genre) {
+ $info['genre'][] = trim($genre);
+ }
+ }
}
+
+ $info['mb_trackid'] = $info['mb_trackid']
+ ? $info['mb_trackid']
+ : trim($tags['mb_trackid']);
+
+ $info['mb_albumid'] = $info['mb_albumid']
+ ? $info['mb_albumid']
+ : trim($tags['mb_albumid']);
+
+ $info['mb_artistid'] = $info['mb_artistid']
+ ? $info['mb_artistid']
+ : trim($tags['mb_artistid']);
+
+ /* @TODO language doesn't import from id3tag. @momo-i */
+ $info['language'] = $info['language']
+ ? $info['language']
+ : Dba::escape($tags['language']);
+
+ $info['lyrics'] = $info['lyrics']
+ ? $info['lyrics']
+ : str_replace(
+ array("\r\n","\r","\n"),
+ '<br />',
+ strip_tags($tags['lyrics']));
+
+ $info['track'] = $info['track']
+ ? $info['track']
+ : intval($tags['track']);
+
+ $info['resolution_x'] = $info['resolution_x']
+ ? $info['resolution_x']
+ : intval($tags['resolution_x']);
+
+ $info['resolution_y'] = $info['resolution_y']
+ ? $info['resolution_y']
+ : intval($tags['resolution_y']);
+
+ $info['audio_codec'] = $info['audio_codec']
+ ? $info['audio_codec']
+ : Dba::escape($tags['audio_codec']);
+
+ $info['video_codec'] = $info['video_codec']
+ ? $info['video_codec']
+ : Dba::escape($tags['video_codec']);
+ }
+
+ // I really think this belongs somewhere else
+ $slash_point = strpos($info['disk'], '/');
+ if ($slash_point !== false) {
+ $info['disk'] = substr($info['disk'], 0, $slash_point);
}
- // Lyrics3 v2.0
- $info['lyrics'] = $info['lyrics']
- ? $info['lyrics']
- : str_replace(array("\r\n","\r","\n"), '<br />',strip_tags($results['info']['lyrics']['unsynchedlyrics']));
+
return $info;
@@ -394,21 +419,10 @@ class vainfo {
$results = array();
- /* Gather Tag information from the filenames */
- $results['file'] = $this->_parse_filename($this->filename);
-
- /* Return false if we don't have
- * any tags to look at
- */
- if (!is_array($this->_raw['tags'])) {
- return $results;
- }
-
/* The tags can come in many different shapes and colors
- * depending on the encoding time of day and phase of the
- * moon
+ * depending on the encoding time of day and phase of the moon.
*/
- foreach ($this->_raw['tags'] as $key=>$tag_array) {
+ foreach ($this->_raw['tags'] as $key => $tag_array) {
switch ($key) {
case 'vorbiscomment':
debug_event('_get_tags', 'Parsing vorbis', '5');
@@ -461,17 +475,42 @@ class vainfo {
$results[$key] = $this->_parse_id3v2($this->_raw['id3v2']['comments']);
break;
} // end switch
-
} // end foreach
- return $results;
+
+ $cleaned = self::clean_tag_info($results, self::get_tag_type($results, 'getid3_tag_order'), $this->filename);
+ $cleaned = array_merge($cleaned, $this->_get_info());
+ $cleaned['raw'] = $results;
+
+ return $cleaned;
} // _get_tags
/**
+ * _get_plugin_tags
+ * Get additional metadata from plugins
+ */
+ private function _get_plugin_tags() {
+ $tag_order = Config::get('metadata_order');
+ if (!is_array($tag_order)) {
+ $tag_order = array($tag_order);
+ }
+
+ $plugin_names = Plugin::get_plugins('get_metadata');
+ foreach ($tag_order as $key => $tag_source) {
+ if (in_array($tag_source, $plugin_names)) {
+ $plugin = new Plugin($tag_source);
+ if ($plugin->load()) {
+ $this->tags[$tag_source] = $plugin->_plugin->get_metadata(self::clean_tag_info($this->tags, self::get_tag_type($this->tags), $this->filename));
+ }
+ }
+ }
+ } // _get_plugin_tags
+
+ /**
* _get_info
- * This function gathers and returns the general information
- * about a song, vbr/cbr sample rate channels etc
+ * Gather and return the general information about a song (vbr/cbr,
+ * sample rate, channels, etc.)
*/
private function _get_info() {
@@ -481,7 +520,10 @@ class vainfo {
* the audio array
*/
if ($this->_raw['audio']['bitrate_mode']) {
- $array['bitrate_mode'] = $this->_raw['audio']['bitrate_mode'];
+ $array['mode'] = $this->_raw['audio']['bitrate_mode'];
+ if ($array['mode'] == 'con') {
+ $array['mode'] = 'cbr';
+ }
}
if ($this->_raw['audio']['bitrate']) {
$array['bitrate'] = $this->_raw['audio']['bitrate'];
@@ -490,10 +532,10 @@ class vainfo {
$array['channels'] = intval($this->_raw['audio']['channels']);
}
if ($this->_raw['audio']['sample_rate']) {
- $array['sample_rate'] = intval($this->_raw['audio']['sample_rate']);
+ $array['rate'] = intval($this->_raw['audio']['sample_rate']);
}
if ($this->_raw['filesize']) {
- $array['filesize'] = intval($this->_raw['filesize']);
+ $array['size'] = intval($this->_raw['filesize']);
}
if ($this->_raw['encoding']) {
$array['encoding'] = $this->_raw['encoding'];
@@ -502,10 +544,7 @@ class vainfo {
$array['mime'] = $this->_raw['mime_type'];
}
if ($this->_raw['playtime_seconds']) {
- $array['playing_time'] = $this->_raw['playtime_seconds'];
- }
- if ($this->_raw['lyrics3']) {
- $array['lyrics'] = $this->_raw['lyrics3'];
+ $array['time'] = $this->_raw['playtime_seconds'];
}
return $array;
@@ -556,8 +595,10 @@ class vainfo {
$array = array();
/* go through them all! */
- foreach ($tags as $tag=>$data) {
-
+ foreach ($tags as $tag => $data) {
+ if ($tag == 'unsynchedlyrics' || $tag == 'unsynchronised lyric') {
+ $tag = 'lyrics';
+ }
$array[$tag] = $this->_clean_tag($data['0']);
} // end foreach
@@ -927,6 +968,8 @@ class vainfo {
}
} // end foreach matches
+ $results['size'] = filesize($filename);
+
return $results;
} // _parse_filename
diff --git a/lib/init.php b/lib/init.php
index 59f1ba4f..979b500f 100644
--- a/lib/init.php
+++ b/lib/init.php
@@ -91,7 +91,7 @@ if (!function_exists('hash') OR !function_exists('inet_pton') OR (strtoupper(sub
/** This is the version.... fluf nothing more... **/
$results['version'] = '3.6-Alpha1 '. $svn_version;
-$results['int_config_version'] = '10';
+$results['int_config_version'] = '11';
$results['raw_web_path'] = $results['web_path'];
$results['web_path'] = $http_type . $_SERVER['HTTP_HOST'] . $results['web_path'];
diff --git a/modules/plugins/MusicBrainz.plugin.php b/modules/plugins/MusicBrainz.plugin.php
new file mode 100644
index 00000000..89def3f8
--- /dev/null
+++ b/modules/plugins/MusicBrainz.plugin.php
@@ -0,0 +1,98 @@
+<?php
+/* vim:set tabstop=8 softtabstop=8 shiftwidth=8 noexpandtab: */
+/*
+
+ Copyright (c) Ampache.org
+ All rights reserved.
+
+ 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 AmpacheMusicBrainz {
+
+ public $name ='MusicBrainz';
+ public $description ='MusicBrainz metadata integration';
+ public $version ='000001';
+ public $min_ampache ='360003';
+ public $max_ampache ='999999';
+
+ /**
+ * Constructor
+ * This function does nothing
+ */
+ public function __construct() {
+ return true;
+ }
+
+ /**
+ * install
+ * This is a required plugin function
+ */
+ public function install() {
+ return true;
+ } // install
+
+ /**
+ * uninstall
+ * This is a required plugin function
+ */
+ public function uninstall() {
+ return true;
+ } // uninstall
+
+ /**
+ * load
+ * This is a required plugin function; here it populates the prefs we
+ * need for this object.
+ */
+ public function load() {
+ return true;
+ } // load
+
+ /**
+ * get_metadata
+ * Returns song metadata for what we're passed in.
+ */
+ public function get_metadata($song_info) {
+ if (!$mbid = $song_info['mb_trackid']) {
+ return null;
+ }
+
+ $mbquery = new MusicBrainzQuery();
+ $includes = new mbTrackIncludes();
+ $includes = $includes->artist()->releases();
+ try {
+ $track = $mbquery->getTrackById($mbid, $includes);
+ }
+ catch (Exception $e) {
+ return null;
+ }
+
+ $results = array();
+
+ $results['mb_artistid'] = $track->getArtist()->getId();
+ $results['artist'] = $track->getArtist()->getName();
+ $results['title'] = $track->getTitle();
+ if ($track->getNumReleases() == 1) {
+ $release = $track->getReleases();
+ $release = $release[0];
+ $results['album'] = $release->getTitle();
+ }
+
+ return $results;
+ } // get_metadata
+
+} // end AmpacheMusicBrainz
+?>