[arch-commits] Commit in rhythmbox/repos (4 files)
Jan de Groot
jgc at archlinux.org
Sun Jun 22 20:53:54 UTC 2008
Date: Sunday, June 22, 2008 @ 16:53:54
Author: jgc
Revision: 3480
Merged revisions 3426-3479 via svnmerge from
svn+ssh://svn.archlinux.org/home/svn-packages/rhythmbox/trunk
........
r3475 | jgc | 2008-06-22 20:48:32 +0000 (Sun, 22 Jun 2008) | 3 lines
upgpkg: rhythmbox 0.11.5-4
Suggest correct packages, fix dependencies (FS#10111)
Fix cover art fetching (FS#10290)
........
Added:
rhythmbox/repos/extra-x86_64/bgo513851.patch
(from rev 3475, rhythmbox/trunk/bgo513851.patch)
Modified:
rhythmbox/repos/extra-x86_64/ (properties)
rhythmbox/repos/extra-x86_64/PKGBUILD
rhythmbox/repos/extra-x86_64/rhythmbox.install
-------------------+
PKGBUILD | 25 +--
bgo513851.patch | 416 ++++++++++++++++++++++++++++++++++++++++++++++++++++
rhythmbox.install | 18 --
3 files changed, 437 insertions(+), 22 deletions(-)
Property changes on: rhythmbox/repos/extra-x86_64
___________________________________________________________________
Name: svnmerge-integrated
- /rhythmbox/trunk:1-3425
+ /rhythmbox/trunk:1-3479
Modified: extra-x86_64/PKGBUILD
===================================================================
--- extra-x86_64/PKGBUILD 2008-06-22 20:52:06 UTC (rev 3479)
+++ extra-x86_64/PKGBUILD 2008-06-22 20:53:54 UTC (rev 3480)
@@ -3,34 +3,37 @@
pkgname=rhythmbox
pkgver=0.11.5
-pkgrel=3
+pkgrel=4
pkgdesc="An iTunes-like music player/libary"
arch=(i686 x86_64)
license=('GPL')
url="http://www.rhythmbox.org"
-depends=( 'libgpod>=0.6.0' 'libsoup>=2.4.0' 'gnome-media>=2.22.0'
- 'totem-plparser>=2.22.1' 'musicbrainz>=2.1.5'
- 'libsexy>=0.1.11' 'gstreamer0.10-mad' 'nautilus-cd-burner>=2.22.0'
- 'gstreamer0.10-gnomevfs' 'gstreamer0.10-python>=0.10.9'
- 'desktop-file-utils' 'gnome-python>=2.22.0' 'libmtp>=0.2.4'
- 'lirc-utils')
+depends=( 'libgpod>=0.6.0' 'libsoup>=2.4.1' 'gnome-media>=2.22.0'
+ 'totem-plparser>=2.22.3' 'musicbrainz>=2.1.5'
+ 'libsexy>=0.1.11' 'nautilus-cd-burner>=2.22.1' 'libmtp>=0.2.4'
+ 'lirc-utils' 'desktop-file-utils' 'gnome-python>=2.22.1'
+ 'gstreamer0.10-python>=0.10.12' 'gstreamer0.10-base-plugins'
+ 'gstreamer0.10-good-plugins')
makedepends=('perlxml' 'pkgconfig' 'gnome-doc-utils>=0.12.2' 'xulrunner>=1.9')
options=('!libtool' '!emptydirs')
install=rhythmbox.install
source=(http://ftp.gnome.org/pub/GNOME/sources/${pkgname}/0.11/${pkgname}-${pkgver}.tar.bz2
- rb-shell.patch)
-md5sums=('967440dd984ec724e7e7992d5bd57bbd' '9ff9492fe5a6580620ed4a177abc6296')
+ rb-shell.patch
+ bgo513851.patch)
+md5sums=('967440dd984ec724e7e7992d5bd57bbd' '9ff9492fe5a6580620ed4a177abc6296'
+ '94aaeecc50a7551b1eb1b1f3e40bc2cd')
build() {
cd ${startdir}/src/${pkgname}-${pkgver}
patch -Np1 -i ${startdir}/src/rb-shell.patch || return 1
+ patch -Np1 -i ${startdir}/src/bgo513851.patch || return 1
./configure --prefix=/usr --sysconfdir=/etc \
--libexecdir=/usr/lib/rhythmbox \
--localstatedir=/var --disable-static \
--with-cd-burner \
--with-playback=gstreamer-0-10 --enable-daap \
--with-mdns=avahi --disable-scrollkeeper \
- --enable-python
+ --enable-python || return 1
make || return 1
make GCONF_DISABLE_MAKEFILE_SCHEMA_INSTALL=1 DESTDIR=${startdir}/pkg install || return 1
@@ -40,5 +43,5 @@
rm -f ${startdir}/pkg/etc/gconf/schemas/*.schemas
# fix missing artdisplay artwork
- install -m 644 plugins/artdisplay/rhythmbox-missing-artwork.svg ${startdir}/pkg/usr/lib/rhythmbox/plugins/artdisplay/
+ #install -m 644 plugins/artdisplay/rhythmbox-missing-artwork.svg ${startdir}/pkg/usr/lib/rhythmbox/plugins/artdisplay/ || return 1
}
Copied: rhythmbox/repos/extra-x86_64/bgo513851.patch (from rev 3475, rhythmbox/trunk/bgo513851.patch)
===================================================================
--- extra-x86_64/bgo513851.patch (rev 0)
+++ extra-x86_64/bgo513851.patch 2008-06-22 20:53:54 UTC (rev 3480)
@@ -0,0 +1,416 @@
+Update the Amazon cover fetcher to use the new ECS 4.0 API
+---
+ .../artdisplay/artdisplay/AmazonCoverArtSearch.py | 93 +++++++++-----------
+ 1 files changed, 42 insertions(+), 51 deletions(-)
+
+diff --git a/plugins/artdisplay/artdisplay/AmazonCoverArtSearch.py b/plugins/artdisplay/artdisplay/AmazonCoverArtSearch.py
+index 8fb3e78..489d302 100644
+--- a/plugins/artdisplay/artdisplay/AmazonCoverArtSearch.py
++++ b/plugins/artdisplay/artdisplay/AmazonCoverArtSearch.py
+@@ -35,11 +35,13 @@ class AmazonCoverArtSearch (object):
+ self.searching = False
+ self.cancel = False
+ self.loader = loader
++ # "JP is the only locale that correctly takes UTF8 input. All other locales use LATIN1."
++ # http://developer.amazonwebservices.com/connect/entry.jspa?externalID=1295&categoryID=117
+ self._supportedLocales = {
+- "en_US" : ("us", "xml.amazon.com", "music"),
+- "en_GB" : ("uk", "xml-eu.amazon.com", "music"),
+- "de" : ("de", "xml-eu.amazon.com", "music"),
+- "ja" : ("jp", "xml.amazon.co.jp", "music-jp")
++ "en_US" : ("com", "latin1"),
++ "en_GB" : ("co.uk", "latin1"),
++ "de" : ("de", "latin1"),
++ "ja" : ("jp", "utf8")
+ }
+ self.db = None
+ self.entry = None
+@@ -55,10 +57,7 @@ class AmazonCoverArtSearch (object):
+ if self._supportedLocales.has_key (lang):
+ lc_id = lang
+
+- lc_host = self._supportedLocales[lc_id][1]
+- lc_name = self._supportedLocales[lc_id][0]
+- lc_mode = self._supportedLocales[lc_id][2]
+- return ((lc_host, lc_name, lc_mode))
++ return self._supportedLocales[lc_id]
+
+ def search (self, db, entry, on_search_completed_callback, *args):
+ self.searching = True
+@@ -127,15 +126,17 @@ class AmazonCoverArtSearch (object):
+ self.search_next ();
+
+ def __build_url (self, keyword):
+- (lc_host, lc_name, lc_mode) = self.__get_locale ()
+-
+- url = "http://" + lc_host + "/onca/xml3?f=xml"
+- url += "&t=%s" % ASSOCIATE
+- url += "&dev-t=%s" % LICENSE_KEY
+- url += "&type=%s" % 'lite'
+- url += "&locale=%s" % lc_name
+- url += "&mode=%s" % lc_mode
+- url += "&%s=%s" % ('KeywordSearch', urllib.quote (keyword))
++ (tld, encoding) = self.__get_locale ()
++
++ url = "http://ecs.amazonaws." + tld + "/onca/xml" \
++ "?Service=AWSECommerceService" \
++ "&AWSAccessKeyId=" + LICENSE_KEY + \
++ "&AssociateTag=" + ASSOCIATE + \
++ "&ResponseGroup=Images,ItemAttributes" \
++ "&Operation=ItemSearch" \
++ "&SearchIndex=Music" \
++ "&Keywords=" + urllib.quote (keyword.encode (encoding, 'replace'))
++ print "url: '%s'" % (url)
+
+ return url
+
+@@ -161,26 +162,21 @@ class AmazonCoverArtSearch (object):
+
+ def __unmarshal (self, element):
+ rc = Bag ()
+- if isinstance (element, minidom.Element) and (element.tagName == 'Details'):
+- rc.URL = element.attributes["url"].value
+ childElements = [e for e in element.childNodes if isinstance (e, minidom.Element)]
+ if childElements:
+ for child in childElements:
+ key = child.tagName
+ if hasattr (rc, key):
+- if type (getattr (rc, key)) <> type ([]):
++ if not isinstance (getattr (rc, key), list):
+ setattr (rc, key, [getattr (rc, key)])
+- setattr (rc, key, getattr (rc, key) + [self.__unmarshal (child)])
+- elif isinstance(child, minidom.Element) and (child.tagName == 'Details'):
+- setattr (rc,key,[self.__unmarshal(child)])
++ getattr (rc, key).append (self.__unmarshal (child))
++ # get_best_match_urls() wants a list, even if there is only one item/artist
++ elif (child.tagName == "Item") or (child.tagName == "Artist"):
++ setattr (rc, key, [self.__unmarshal(child)])
+ else:
+ setattr (rc, key, self.__unmarshal(child))
+ else:
+ rc = "".join ([e.data for e in element.childNodes if isinstance (e, minidom.Text)])
+- if element.tagName == 'SalesRank':
+- rc = rc.replace ('.', '')
+- rc = rc.replace (',', '')
+- rc = int (rc)
+ return rc
+
+ def on_search_response (self, result_data):
+@@ -194,14 +190,14 @@ class AmazonCoverArtSearch (object):
+ self.search_next()
+ return
+
+- data = self.__unmarshal (xmldoc).ProductInfo
++ data = self.__unmarshal (xmldoc).ItemSearchResponse.Items
+
+- if hasattr(data, 'ErrorMsg'):
++ if hasattr (data.Request, "Errors"):
+ # Search was unsuccessful, try next keyword
+ self.search_next ()
+ else:
+ # We got some search results
+- self.on_search_results (data.Details)
++ self.on_search_results (data.Item)
+
+ def on_search_results (self, results):
+ self.on_search_completed (results)
+@@ -224,10 +220,8 @@ class AmazonCoverArtSearch (object):
+ return s
+
+ def __valid_match (self, item):
+- if item.ImageUrlLarge == "" and item.ImageUrlMedium == "":
+- print "%s doesn't have image URLs; ignoring" % (item.URL)
+- return False
+- return True
++ return (hasattr (item, "LargeImage") or hasattr (item, "MediumImage")) \
++ and hasattr (item, "ItemAttributes")
+
+ def get_best_match_urls (self, search_results):
+ # Default to "no match", our results must match our criteria
+@@ -238,11 +232,11 @@ class AmazonCoverArtSearch (object):
+ if self.search_album != _("Unknown"):
+ album_check = self.__tidy_up_string (self.search_album)
+ for item in search_results:
++ if not hasattr (item.ItemAttributes, "Title"):
++ continue
+
+- # Check for album name in ProductName
+- product_name = self.__tidy_up_string (item.ProductName)
+-
+- if product_name == album_check:
++ album = self.__tidy_up_string (item.ItemAttributes.Title)
++ if album == album_check:
+ # Found exact album, can not get better than that
+ best_match = item
+ break
+@@ -250,8 +244,9 @@ class AmazonCoverArtSearch (object):
+ # Check the results for both an album name that contains the name
+ # we're searching for, and an album name that's a substring of the
+ # name we're searching for
+- elif (best_match is None) and (product_name.find (album_check) != -1
+- or album_check.find (product_name) != -1):
++ elif (best_match is None) and \
++ (album.find (album_check) != -1 or
++ album_check.find (album) != -1):
+ best_match = item
+
+ # If we still have no definite hit, use first result where artist matches
+@@ -261,13 +256,10 @@ class AmazonCoverArtSearch (object):
+ # Check if artist appears in the Artists list
+ hit = False
+ for item in search_results:
++ if not hasattr (item.ItemAttributes, "Artist"):
++ continue
+
+- if type (item.Artists.Artist) <> type ([]):
+- artists = [item.Artists.Artist]
+- else:
+- artists = item.Artists.Artist
+-
+- for artist in artists:
++ for artist in item.ItemAttributes.Artist:
+ artist = self.__tidy_up_string (artist)
+ if artist.find (artist_check) != -1:
+ best_match = item
+@@ -276,10 +268,9 @@ class AmazonCoverArtSearch (object):
+ if hit:
+ break
+
+- if best_match:
+- return filter(lambda x: x != "", [item.ImageUrlLarge, item.ImageUrlMedium])
+- else:
+- return []
++ return [getattr (best_match, size).URL for size in ("LargeImage", "MediumImage")
++ if hasattr (best_match, size)]
+
+- except TypeError:
++ except TypeError, e:
++ print "TypeError: %s" % (e)
+ return []
+Amazon: Use batch requests
+---
+ .../artdisplay/artdisplay/AmazonCoverArtSearch.py | 128 +++++++++++---------
+ 1 files changed, 68 insertions(+), 60 deletions(-)
+
+diff --git a/plugins/artdisplay/artdisplay/AmazonCoverArtSearch.py b/plugins/artdisplay/artdisplay/AmazonCoverArtSearch.py
+index 489d302..13ea35a 100644
+--- a/plugins/artdisplay/artdisplay/AmazonCoverArtSearch.py
++++ b/plugins/artdisplay/artdisplay/AmazonCoverArtSearch.py
+@@ -27,6 +27,10 @@ LICENSE_KEY = "18C3VZN9HCECM5G3HQG2"
+ DEFAULT_LOCALE = "en_US"
+ ASSOCIATE = "webservices-20"
+
++# We are not allowed to batch more than 2 requests at once
++# http://docs.amazonwebservices.com/AWSEcommerceService/4-0/PgCombiningOperations.html
++MAX_BATCH_JOBS = 2
++
+
+ class Bag: pass
+
+@@ -35,29 +39,31 @@ class AmazonCoverArtSearch (object):
+ self.searching = False
+ self.cancel = False
+ self.loader = loader
++ self.db = None
++ self.entry = None
++ (self.tld, self.encoding) = self.__get_locale ()
++
++ def __get_locale (self):
+ # "JP is the only locale that correctly takes UTF8 input. All other locales use LATIN1."
+ # http://developer.amazonwebservices.com/connect/entry.jspa?externalID=1295&categoryID=117
+- self._supportedLocales = {
++ supported_locales = {
+ "en_US" : ("com", "latin1"),
+ "en_GB" : ("co.uk", "latin1"),
+ "de" : ("de", "latin1"),
+ "ja" : ("jp", "utf8")
+ }
+- self.db = None
+- self.entry = None
+
+- def __get_locale (self):
+- default = locale.getdefaultlocale ()
+ lc_id = DEFAULT_LOCALE
+- if default[0] is not None:
+- if self._supportedLocales.has_key (default[0]):
+- lc_id = default[0]
++ default = locale.getdefaultlocale ()[0]
++ if default:
++ if supported_locales.has_key (default):
++ lc_id = default
+ else:
+- lang = default[0].split("_")[0]
+- if self._supportedLocales.has_key (lang):
++ lang = default.split("_")[0]
++ if supported_locales.has_key (lang):
+ lc_id = lang
+
+- return self._supportedLocales[lc_id]
++ return supported_locales[lc_id]
+
+ def search (self, db, entry, on_search_completed_callback, *args):
+ self.searching = True
+@@ -71,6 +77,10 @@ class AmazonCoverArtSearch (object):
+ st_artist = db.entry_get (entry, rhythmdb.PROP_ARTIST) or _("Unknown")
+ st_album = db.entry_get (entry, rhythmdb.PROP_ALBUM) or _("Unknown")
+
++ if st_artist == st_album == _("Unknown"):
++ self.on_search_completed (None)
++ return
++
+ # Tidy up
+
+ # Replace quote characters
+@@ -118,60 +128,53 @@ class AmazonCoverArtSearch (object):
+ self.keywords.append ("%s %s" % (st_artist, st_album))
+ if st_album_no_vol != st_album:
+ self.keywords.append ("%s %s" % (st_artist, st_album_no_vol))
+- if (st_album != _("Unknown")):
+- self.keywords.append ("Various %s" % (st_album))
++ self.keywords.append ("Various %s" % (st_album))
+ self.keywords.append ("%s" % (st_artist))
+
+ # Initiate asynchronous search
+- self.search_next ();
++ self.search_next ()
+
+- def __build_url (self, keyword):
+- (tld, encoding) = self.__get_locale ()
++ def search_next (self):
++ if len (self.keywords) == 0:
++ # No keywords left to search -> no results
++ self.on_search_completed (None)
++ return False
+
+- url = "http://ecs.amazonaws." + tld + "/onca/xml" \
+- "?Service=AWSECommerceService" \
+- "&AWSAccessKeyId=" + LICENSE_KEY + \
+- "&AssociateTag=" + ASSOCIATE + \
+- "&ResponseGroup=Images,ItemAttributes" \
+- "&Operation=ItemSearch" \
+- "&SearchIndex=Music" \
+- "&Keywords=" + urllib.quote (keyword.encode (encoding, 'replace'))
+- print "url: '%s'" % (url)
++ self.searching = True
+
+- return url
++ url = "http://ecs.amazonaws." + self.tld + "/onca/xml" \
++ "?Service=AWSECommerceService" \
++ "&AWSAccessKeyId=" + LICENSE_KEY + \
++ "&AssociateTag=" + ASSOCIATE + \
++ "&ResponseGroup=Images,ItemAttributes" \
++ "&Operation=ItemSearch" \
++ "&ItemSearch.Shared.SearchIndex=Music"
+
+- def search_next (self):
+- self.searching = True
+-
+- if len (self.keywords)==0:
+- keyword = None
+- else:
++ job = 1
++ while job <= MAX_BATCH_JOBS and len (self.keywords) > 0:
+ keyword = self.keywords.pop (0)
++ keyword = keyword.encode (self.encoding, "ignore")
++ keyword = keyword.strip ()
++ keyword = urllib.quote (keyword)
++ url += "&ItemSearch.%d.Keywords=%s" % (job, keyword)
++ job += 1
+
+- if keyword is None:
+- # No keywords left to search -> no results
+- self.on_search_completed (None)
+- ret = False
+- else:
+- # Retrieve search for keyword
+- url = self.__build_url (keyword.strip ())
+- self.loader.get_url (url, self.on_search_response)
+- ret = True
+-
+- return ret
++ # Retrieve search for keyword
++ self.loader.get_url (url, self.on_search_response)
++ return True
+
+ def __unmarshal (self, element):
+ rc = Bag ()
+- childElements = [e for e in element.childNodes if isinstance (e, minidom.Element)]
+- if childElements:
+- for child in childElements:
++ child_elements = [e for e in element.childNodes if isinstance (e, minidom.Element)]
++ if child_elements:
++ for child in child_elements:
+ key = child.tagName
+ if hasattr (rc, key):
+ if not isinstance (getattr (rc, key), list):
+ setattr (rc, key, [getattr (rc, key)])
+ getattr (rc, key).append (self.__unmarshal (child))
+ # get_best_match_urls() wants a list, even if there is only one item/artist
+- elif (child.tagName == "Item") or (child.tagName == "Artist"):
++ elif child.tagName in ("Items", "Item", "Artist"):
+ setattr (rc, key, [self.__unmarshal(child)])
+ else:
+ setattr (rc, key, self.__unmarshal(child))
+@@ -190,14 +193,14 @@ class AmazonCoverArtSearch (object):
+ self.search_next()
+ return
+
+- data = self.__unmarshal (xmldoc).ItemSearchResponse.Items
+-
+- if hasattr (data.Request, "Errors"):
+- # Search was unsuccessful, try next keyword
++ data = self.__unmarshal (xmldoc)
++ if not hasattr (data, "ItemSearchResponse") or \
++ not hasattr (data.ItemSearchResponse, "Items"):
++ # Something went wrong ...
+ self.search_next ()
+ else:
+ # We got some search results
+- self.on_search_results (data.Item)
++ self.on_search_results (data.ItemSearchResponse.Items)
+
+ def on_search_results (self, results):
+ self.on_search_completed (results)
+@@ -227,11 +230,15 @@ class AmazonCoverArtSearch (object):
+ # Default to "no match", our results must match our criteria
+ best_match = None
+
+- search_results = filter(self.__valid_match, search_results)
+- try:
++ for result in search_results:
++ if not hasattr (result, "Item"):
++ # Search was unsuccessful, try next batch job
++ continue
++
++ items = filter(self.__valid_match, result.Item)
+ if self.search_album != _("Unknown"):
+ album_check = self.__tidy_up_string (self.search_album)
+- for item in search_results:
++ for item in items:
+ if not hasattr (item.ItemAttributes, "Title"):
+ continue
+
+@@ -255,7 +262,7 @@ class AmazonCoverArtSearch (object):
+ if best_match is None:
+ # Check if artist appears in the Artists list
+ hit = False
+- for item in search_results:
++ for item in items:
+ if not hasattr (item.ItemAttributes, "Artist"):
+ continue
+
+@@ -268,9 +275,10 @@ class AmazonCoverArtSearch (object):
+ if hit:
+ break
+
+- return [getattr (best_match, size).URL for size in ("LargeImage", "MediumImage")
++ urls = [getattr (best_match, size).URL for size in ("LargeImage", "MediumImage")
+ if hasattr (best_match, size)]
++ if urls:
++ return urls
+
+- except TypeError, e:
+- print "TypeError: %s" % (e)
+- return []
++ # No search was successful
++ return []
Modified: extra-x86_64/rhythmbox.install
===================================================================
--- extra-x86_64/rhythmbox.install 2008-06-22 20:52:06 UTC (rev 3479)
+++ extra-x86_64/rhythmbox.install 2008-06-22 20:53:54 UTC (rev 3480)
@@ -5,13 +5,14 @@
update-desktop-database -q
gtk-update-icon-cache -f -q -t usr/share/icons/hicolor
cat << EOF
-==> Rhythmbox support MP3, OGG and APE by default.
-==> To enable additional formats, install these packages:
-==> WMA : gstreamer0.10-ffmpeg
-==> FLAC : gstreamer0.10-flac
-==> Musepack: gstreamer0.10-musepack
-==> AAC : gstreamer0.10-faad
+==> Rhythmbox uses GStreamer to play media. By default, only plugins from
+==> gst-plugins-good and gst-plugins-base are installed.
+==>
+==> To play additional media formats, more plugins are available from
+==> gstreamer0.10-ugly-plugins, gstreamer0.10-bad-plugins
+==> and gstreamer0.10-ffmpeg packages.
+
EOF
}
@@ -32,8 +33,3 @@
update-desktop-database -q
gtk-update-icon-cache -f -q -t usr/share/icons/hicolor
}
-
-op=$1
-shift
-
-$op $*
More information about the arch-commits
mailing list