Skip to content

Commit

Permalink
Restructure, rewrite, add two new classes: one for loading URI conten…
Browse files Browse the repository at this point in the history
…ts by

2009-02-22  Jonathan Matthew  <[email protected]>

	* plugins/rb/Loader.py:
	* plugins/rb/__init__.py:
	Restructure, rewrite, add two new classes: one for loading URI
	contents by chunks (for downloading large files, progressively parsing
	huge xml documents, etc.), one for performing file modification time
	checks.  Implement all of these using both GIO and gnome-vfs.  GIO
	implementations require pygobject 2.16.0.  The loader classes are now
	intended to be single use (they have state) and operations are
	cancellable.

	Add a helper function to use gtk.show_uri() if available, falling back
	to gnome-vfs otherwise.

	* plugins/lyrics/lyrics/__init__.py:
	* plugins/artdisplay/artdisplay/AmazonCoverArtSearch.py:
	* plugins/artdisplay/artdisplay/LocalCoverArtSearch.py:
	* plugins/artdisplay/artdisplay/PodcastCoverArtSearch.py:
	* plugins/artdisplay/artdisplay/__init__.py:
	Rewrite various bits to create loader instances as required, rather
	than sharing them between submodules.
	
	* plugins/artdisplay/artdisplay/Makefile.am:
	* plugins/artdisplay/artdisplay/LocalCoverArtSearchGIO.py:
	* plugins/artdisplay/artdisplay/CoverArtDatabase.py:
	Add a GIO implementation of the local cover art search.  Requires GIO
	2.15.3 or newer.
	
	* bindings/python/rb.defs:
	* bindings/python/rb.override:
	* lib/rb-file-helpers.c: (rb_find_user_file),
	(rb_find_user_data_file), (rb_find_user_cache_file):
	* lib/rb-file-helpers.h:
	Add function for migrating user cache files from ~/.gnome2 to XDG
	cache directory, add python bindings for various directory helper
	functions.

	* plugins/jamendo/jamendo/JamendoConfigureDialog.py:
	* plugins/jamendo/jamendo/JamendoSource.py:
	Rewrite the catalogue downloading and parsing stuff to use the new
	loader classes.  Rework the download/parse logic a bit so we don't
	parse the catalogue twice if we're downloading a new copy on startup.

	* plugins/magnatune/magnatune/MagnatuneSource.py:
	Rewrite all the catalogue and purchasing code using the new loader
	classes.  The purchasing code is completely untested, but at least the
	idea is right as far as I can tell.
	
	* plugins/coherence/upnp_coherence/__init__.py:
	Add code to get the mime type of the icon using gio, falling back to
	gnome-vfs if that doesn't work

	While gnome-vfs code remains, it's only there as a fallback.
	Fixes #510392.


svn path=/trunk/; revision=6158
  • Loading branch information
Jonathan Matthew authored and Jonathan Matthew committed Feb 22, 2009
1 parent c7bbac0 commit decf4a8
Show file tree
Hide file tree
Showing 19 changed files with 989 additions and 492 deletions.
56 changes: 56 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,59 @@
2009-02-22 Jonathan Matthew <[email protected]>

* plugins/rb/Loader.py:
* plugins/rb/__init__.py:
Restructure, rewrite, add two new classes: one for loading URI
contents by chunks (for downloading large files, progressively parsing
huge xml documents, etc.), one for performing file modification time
checks. Implement all of these using both GIO and gnome-vfs. GIO
implementations require pygobject 2.16.0. The loader classes are now
intended to be single use (they have state) and operations are
cancellable.

Add a helper function to use gtk.show_uri() if available, falling back
to gnome-vfs otherwise.

* plugins/lyrics/lyrics/__init__.py:
* plugins/artdisplay/artdisplay/AmazonCoverArtSearch.py:
* plugins/artdisplay/artdisplay/LocalCoverArtSearch.py:
* plugins/artdisplay/artdisplay/PodcastCoverArtSearch.py:
* plugins/artdisplay/artdisplay/__init__.py:
Rewrite various bits to create loader instances as required, rather
than sharing them between submodules.

* plugins/artdisplay/artdisplay/Makefile.am:
* plugins/artdisplay/artdisplay/LocalCoverArtSearchGIO.py:
* plugins/artdisplay/artdisplay/CoverArtDatabase.py:
Add a GIO implementation of the local cover art search. Requires GIO
2.15.3 or newer.

* bindings/python/rb.defs:
* bindings/python/rb.override:
* lib/rb-file-helpers.c: (rb_find_user_file),
(rb_find_user_data_file), (rb_find_user_cache_file):
* lib/rb-file-helpers.h:
Add function for migrating user cache files from ~/.gnome2 to XDG
cache directory, add python bindings for various directory helper
functions.

* plugins/jamendo/jamendo/JamendoConfigureDialog.py:
* plugins/jamendo/jamendo/JamendoSource.py:
Rewrite the catalogue downloading and parsing stuff to use the new
loader classes. Rework the download/parse logic a bit so we don't
parse the catalogue twice if we're downloading a new copy on startup.

* plugins/magnatune/magnatune/MagnatuneSource.py:
Rewrite all the catalogue and purchasing code using the new loader
classes. The purchasing code is completely untested, but at least the
idea is right as far as I can tell.

* plugins/coherence/upnp_coherence/__init__.py:
Add code to get the mime type of the icon using gio, falling back to
gnome-vfs if that doesn't work

While gnome-vfs code remains, it's only there as a fallback.
Fixes #510392.

2009-02-19 Bastien Nocera <[email protected]>

* shell/rb-shell.c (construct_widgets),
Expand Down
31 changes: 31 additions & 0 deletions bindings/python/rb.defs
Original file line number Diff line number Diff line change
Expand Up @@ -2430,6 +2430,18 @@

;; From rb-file-helpers.h

(define-function music_dir
(in-module "rb")
(c-name "rb_music_dir")
(return-type "const-char*")
)

(define-function dot_dir
(in-module "rb")
(c-name "rb_dot_dir")
(return-type "const-char*")
)

(define-function user_data_dir
(in-module "rb")
(c-name "rb_user_data_dir")
Expand All @@ -2442,4 +2454,23 @@
(return-type "const-char*")
)

(define-function find_user_data_file
(in-module "rb")
(c-name "rb_find_user_data_file")
(return-type "char*")
(parameters
'("const-char*" "name")
'("GError**" "error")
)
)

(define-function find_user_cache_file
(in-module "rb")
(c-name "rb_find_user_cache_file")
(return-type "char*")
(parameters
'("const-char*" "name")
'("GError**" "error")
)
)

1 change: 1 addition & 0 deletions bindings/python/rb.override
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ headers
#include "rb-cut-and-paste-code.h"
#include "rb-dialog.h"
#include "rb-entry-view.h"
#include "rb-file-helpers.h"
#include "rb-library-browser.h"
#include "rb-playlist-source.h"
#include "rb-player.h"
Expand Down
80 changes: 55 additions & 25 deletions lib/rb-file-helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,24 +166,10 @@ rb_music_dir (void)
return dir;
}

/**
* rb_find_user_data_file:
* @name: name of file to find
* @error: returns error information
*
* Determines the full path to use for user-specific files, such as rhythmdb.xml.
* This first checks in the user data directory (see @rb_user_data_dir).
* If the file does not exist in the user data directory, it then checks the
* old .gnome2 directory, moving the file to the user data directory if found there.
* If an error occurs while moving the file, this will be reported through @error
* and the .gnome2 path will be returned.
*
* Returns: allocated string containing the location of the file to use, even if
* an error occurred.
*/
char *
rb_find_user_data_file (const char *name,
GError **error)
static char *
rb_find_user_file (const char *dir,
const char *name,
GError **error)
{
GError *temp_err = NULL;
char *srcpath;
Expand All @@ -192,23 +178,23 @@ rb_find_user_data_file (const char *name,
GFile *dest;
char *use_path;

/* if the file exists in the user data dir, return the path */
destpath = g_build_filename (rb_user_data_dir (), name, NULL);
/* if the file exists in the target dir, return the path */
destpath = g_build_filename (dir, name, NULL);
dest = g_file_new_for_path (destpath);
if (g_file_query_exists (dest, NULL) == TRUE) {
g_object_unref (dest);
rb_debug ("found user data dir path for '%s': %s", name, destpath);
rb_debug ("found user dir path for '%s': %s", name, destpath);
return destpath;
}

/* doesn't exist in the user data dir, so try to move it from the .gnome2 dir */
/* doesn't exist in the target dir, so try to move it from the .gnome2 dir */
srcpath = g_build_filename (rb_dot_dir (), name, NULL);
src = g_file_new_for_path (srcpath);

if (g_file_query_exists (src, NULL)) {
g_file_move (src, dest, G_FILE_COPY_NONE, NULL, NULL, NULL, &temp_err);
if (temp_err != NULL) {
rb_debug ("failed to move user data file '%s' from .gnome2 dir, returning .gnome2 path %s: %s",
rb_debug ("failed to move user file '%s' from .gnome2 dir, returning .gnome2 path %s: %s",
name, srcpath, temp_err->message);

use_path = g_file_get_path (src);
Expand All @@ -219,12 +205,12 @@ rb_find_user_data_file (const char *name,
srcpath, destpath, temp_err->message);
g_error_free (temp_err);
} else {
rb_debug ("moved user data file '%s' from .gnome2 dir, returning user data dir path %s",
rb_debug ("moved user file '%s' from .gnome2 dir, returning user dir path %s",
name, destpath);
use_path = g_file_get_path (dest);
}
} else {
rb_debug ("no existing file for '%s', returning user data dir path %s", name, destpath);
rb_debug ("no existing file for '%s', returning user dir path %s", name, destpath);
use_path = g_file_get_path (dest);
}

Expand All @@ -237,6 +223,50 @@ rb_find_user_data_file (const char *name,
return use_path;
}

/**
* rb_find_user_data_file:
* @name: name of file to find
* @error: returns error information
*
* Determines the full path to use for user-specific files, such as rhythmdb.xml.
* This first checks in the user data directory (see @rb_user_data_dir).
* If the file does not exist in the user data directory, it then checks the
* old .gnome2 directory, moving the file to the user data directory if found there.
* If an error occurs while moving the file, this will be reported through @error
* and the .gnome2 path will be returned.
*
* Returns: allocated string containing the location of the file to use, even if
* an error occurred.
*/
char *
rb_find_user_data_file (const char *name,
GError **error)
{
return rb_find_user_file (rb_user_data_dir (), name, error);
}

/**
* rb_find_user_cache_file:
* @name: name of file to find
* @error: returns error information
*
* Determines the full path to use for user-specific cached files.
* This first checks in the user cache directory (see @rb_user_cache_dir).
* If the file does not exist in the user cache directory, it then checks the
* old .gnome2 directory, moving the file to the user cache directory if found there.
* If an error occurs while moving the file, this will be reported through @error
* and the .gnome2 path will be returned.
*
* Returns: allocated string containing the location of the file to use, even if
* an error occurred.
*/
char *
rb_find_user_cache_file (const char *name,
GError **error)
{
return rb_find_user_file (rb_user_cache_dir (), name, error);
}

void
rb_file_helpers_init (void)
{
Expand Down
2 changes: 2 additions & 0 deletions lib/rb-file-helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ const char * rb_music_dir (void);

char * rb_find_user_data_file (const char *name,
GError **error);
char * rb_find_user_cache_file (const char *name,
GError **error);

char * rb_canonicalise_uri (const char *uri);

Expand Down
7 changes: 4 additions & 3 deletions plugins/artdisplay/artdisplay/AmazonCoverArtSearch.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import locale
import urllib

import rb
import rhythmdb

LICENSE_KEY = "18C3VZN9HCECM5G3HQG2"
Expand All @@ -43,10 +44,9 @@
class Bag: pass

class AmazonCoverArtSearch (object):
def __init__ (self, loader):
def __init__ (self):
self.searching = False
self.cancel = False
self.loader = loader
self.db = None
self.entry = None
(self.tld, self.encoding) = self.__get_locale ()
Expand Down Expand Up @@ -168,7 +168,8 @@ def search_next (self):
job += 1

# Retrieve search for keyword
self.loader.get_url (url, self.on_search_response)
l = rb.Loader()
l.get_url (url, self.on_search_response)
return True

def __unmarshal (self, element):
Expand Down
24 changes: 17 additions & 7 deletions plugins/artdisplay/artdisplay/CoverArtDatabase.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,18 @@

from PodcastCoverArtSearch import PodcastCoverArtSearch
from AmazonCoverArtSearch import AmazonCoverArtSearch
from LocalCoverArtSearch import LocalCoverArtSearch

from urllib import unquote

try:
# try to use the gio implementation, fall back to gnome-vfs if that
# isn't available.
import gio
if gio.pygio_version > (2,15,2): # probably
from LocalCoverArtSearchGIO import LocalCoverArtSearch
except:
from LocalCoverArtSearch import LocalCoverArtSearch

ART_SEARCHES_LOCAL = [LocalCoverArtSearch]
ART_SEARCHES_REMOTE = [PodcastCoverArtSearch, AmazonCoverArtSearch]
OLD_ART_FOLDER = '~/.gnome2/rhythmbox/covers'
Expand Down Expand Up @@ -88,7 +96,6 @@ def release (self, item, ticket):

class CoverArtDatabase (object):
def __init__ (self):
self.loader = rb.Loader()
self.ticket = TicketSystem ()

def build_art_cache_filename (self, db, entry, extension):
Expand All @@ -109,15 +116,17 @@ def build_art_cache_filename (self, db, entry, extension):

def engines (self, blist):
for Engine in ART_SEARCHES_LOCAL:
yield Engine (self.loader), Engine.__name__, False
yield Engine (), Engine.__name__, False
for Engine in ART_SEARCHES_REMOTE:
if Engine.__name__ not in blist:
yield Engine (self.loader), Engine.__name__, True
yield Engine (), Engine.__name__, True

def set_pixbuf_from_uri (self, db, entry, uri, callback):
def loader_cb (data):
self.set_pixbuf (db, entry, self.image_data_load (data), callback)
self.loader.get_url (str (uri), loader_cb)

l = rb.Loader()
l.get_url (str (uri), loader_cb)

def set_pixbuf (self, db, entry, pixbuf, callback):
if entry is None or pixbuf is None:
Expand All @@ -135,7 +144,7 @@ def set_pixbuf (self, db, entry, pixbuf, callback):
callback (entry, pixbuf, art_location)
for Engine in ART_SEARCHES_LOCAL:
try:
Engine (self.loader).save_pixbuf (db, entry, pixbuf)
Engine ().save_pixbuf (db, entry, pixbuf)
except AttributeError:
pass

Expand Down Expand Up @@ -191,7 +200,8 @@ def image_search (self, plexer, db, st_album, st_artist, entry, callback):
print "got empty url from engine %s." % (engine)
continue

yield self.loader.get_url (str (url), plexer.send ())
l = rb.Loader()
yield l.get_url (str (url), plexer.send ())
_, (data, ) = plexer.receive ()
pixbuf = self.image_data_load (data)
if pixbuf:
Expand Down
4 changes: 2 additions & 2 deletions plugins/artdisplay/artdisplay/LocalCoverArtSearch.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ def shared_prefix_length (a, b):


class LocalCoverArtSearch:
def __init__ (self, loader):
self.loader = loader
def __init__ (self):
pass

def _load_dir_cb (self, handle, files, exception, (results, on_search_completed_cb, entry, args)):
for f in files:
Expand Down
Loading

0 comments on commit decf4a8

Please sign in to comment.