[Rhythmbox-devel] covert art thingo to play with
- From: Bastien Nocera <hadess hadess net>
- To: Rhythmbox Devel <rhythmbox-devel gnome org>
- Subject: [Rhythmbox-devel] covert art thingo to play with
- Date: 13 Aug 2003 16:20:10 +0100
Heya,
I was bored at work (about an hour before I head off to my holidays),
and I wrote this little program.
It takes a song title (artist included) and creates a desktop file
(~/.Desktop/rb-current.desktop) with a nifty icon of the cover (see
attached shot).
As I'm going on holiday without any computers, here's a TODO list for
people who want to play:
- make it possible to pass artist and complete title (artist + song
title) separately to get better results
- better icon when there's no cover available, or the cover is the
default empty one.
- cache requests and downloaded images
- add to RB, in the song change code, a way to launch this script.
(which script is used should probably be configurable, via gconf only)
(it should probably also only be launched a couple of seconds into the
song...)
Enjoy
--
/Bastien Nocera
http://hadess.net
#2 0x4205a2cc in printf ("Oh my %s\n", preferred_deity) from
/lib/i686/libc.so.6 printf ("Oh my %s\n", preferred_deity);
Segmentation fault
// Under the GPL, hadess@hadess.net
// Compile with:
// gcc -o test-cover `pkg-config --cflags --libs gnome-vfs-2.0 libxml-2.0` test-cover.c
#include <libgnomevfs/gnome-vfs.h>
#include <glib.h>
#include <libxml/tree.h>
#include <libxml/parser.h>
#define SMALL_SIZE "ImageUrlSmall"
#define MEDIUM_SIZE "ImageUrlMedium"
#define LARGE_SIZE "ImageUrlLarge"
#define CURRENT_SIZE SMALL_SIZE
#define READ_CHUNK_SIZE 8192
static char *img_url = NULL;
static void
usage (const char *msg)
{
if (msg != NULL) {
g_print ("Error: %s\n", msg);
}
g_print ("Usage: test-cover <title>\n");
exit (1);
}
static GnomeVFSResult
my_eel_read_entire_file (const char *uri,
int *file_size,
char **file_contents)
{
GnomeVFSResult result;
GnomeVFSHandle *handle;
char *buffer;
GnomeVFSFileSize total_bytes_read;
GnomeVFSFileSize bytes_read;
*file_size = 0;
*file_contents = NULL;
/* Open the file. */
result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
if (result != GNOME_VFS_OK) {
return result;
}
/* Read the whole thing. */
buffer = NULL;
total_bytes_read = 0;
do {
buffer = g_realloc (buffer, total_bytes_read + READ_CHUNK_SIZE); result = gnome_vfs_read (handle,
buffer + total_bytes_read,
READ_CHUNK_SIZE,
&bytes_read);
if (result != GNOME_VFS_OK && result != GNOME_VFS_ERROR_EOF) {
g_free (buffer);
gnome_vfs_close (handle);
return result;
}
/* Check for overflow. */
if (total_bytes_read + bytes_read < total_bytes_read) {
g_free (buffer);
gnome_vfs_close (handle);
return GNOME_VFS_ERROR_TOO_BIG;
}
total_bytes_read += bytes_read;
} while (result == GNOME_VFS_OK);
/* Close the file. */
result = gnome_vfs_close (handle);
if (result != GNOME_VFS_OK) {
g_free (buffer);
return result;
}
/* Return the file. */
*file_size = total_bytes_read;
*file_contents = g_realloc (buffer, total_bytes_read);
return GNOME_VFS_OK;
}
static char *
print_uri (const char *title)
{
char *escaped, *url;
/* Construct the URL */
escaped = gnome_vfs_escape_path_string (title);
url = g_strdup_printf ("http://xml.amazon.com/onca/xml3?t=hadess@hadess.net&dev-t=D1EEUYQ7Y68BJ3&KeywordSearch=%s&mode=music&sort=+pmrank&offer=All&type=lite&page=&f=xml", escaped);
g_free (escaped);
return url;
}
static gboolean
parse_document (xmlDocPtr doc, xmlNodePtr parent)
{
xmlNodePtr node;
for (node = parent->children; node != NULL; node = node->next)
{
if (node->name == NULL) {
continue;
}
if (g_ascii_strcasecmp (node->name, LARGE_SIZE) == 0)
{
img_url = xmlNodeListGetString (doc, node->children, 1);
return TRUE;
}
if (parse_document (doc, node) != FALSE) {
return TRUE;
}
}
}
static void
parse_xml (const char *url)
{
int size;
char *contents = NULL;
xmlDocPtr doc;
xmlNodePtr node;
if (my_eel_read_entire_file (url, &size, &contents) != GNOME_VFS_OK) {
return;
}
contents = g_realloc (contents, size + 1);
contents[size] = '\0';
doc = xmlParseMemory (contents, size);
if (doc == NULL)
doc = xmlRecoverMemory (contents, size);
g_free (contents);
/* If the document has no root, or no name */
if(!doc || !doc->children || !doc->children->name)
{
if (doc != NULL)
xmlFreeDoc(doc);
return;
}
node = doc->children;
parse_document (doc, node);
xmlFreeDoc(doc);
}
static char *
get_desktop_path (void)
{
char *fullpath;
gboolean desktop_exists;
fullpath = g_build_path (G_DIR_SEPARATOR_S, g_get_home_dir (), "Desktop", NULL);
desktop_exists = g_file_test (fullpath, G_FILE_TEST_EXISTS);
g_free (fullpath);
if (desktop_exists == TRUE)
{
return g_build_filename (G_DIR_SEPARATOR_S,
g_get_home_dir (), "Desktop",
"rb-current.desktop", NULL);
} else {
return g_build_filename (G_DIR_SEPARATOR_S,
g_get_home_dir (), ".gnome-desktop",
"rb-current.desktop", NULL);
}
return NULL;
}
static char *
copy_img_local (const char *url)
{
GnomeVFSURI *src_uri, *dest_uri;
GnomeVFSResult result;
char *dest;
if (url == NULL) {
url = "http://g-images.amazon.com/images/G/01/music/icons/music-no-image.gif";
}
dest = g_build_filename (G_DIR_SEPARATOR_S,
g_get_home_dir (), ".gnome2",
"rhythmbox", "rb-current.jpg", NULL);
src_uri = gnome_vfs_uri_new(url);
dest_uri = gnome_vfs_uri_new(dest);
result = gnome_vfs_xfer_uri (src_uri, dest_uri,
GNOME_VFS_XFER_DEFAULT,
GNOME_VFS_XFER_ERROR_MODE_ABORT,
GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE,
NULL, NULL);
gnome_vfs_uri_unref (src_uri);
gnome_vfs_uri_unref (dest_uri);
if (result != GNOME_VFS_OK)
{
g_free (dest);
return NULL;
}
return dest;
}
static gboolean
write_string (GnomeVFSHandle *handle, const char *buf)
{
GnomeVFSResult res;
GnomeVFSFileSize written;
int len;
len = strlen (buf);
res = gnome_vfs_write (handle, buf, len, &written);
if (res != GNOME_VFS_OK || written < len)
{
gnome_vfs_close (handle);
return FALSE;
}
return TRUE;
}
static void
create_desktop_file (const char *title, const char *icon)
{
GnomeVFSHandle *handle;
GnomeVFSResult res;
char *desktop_path, *str;
desktop_path = get_desktop_path ();
if (desktop_path == NULL) {
return;
}
res = gnome_vfs_open (&handle, desktop_path, GNOME_VFS_OPEN_WRITE);
if (res == GNOME_VFS_ERROR_NOT_FOUND)
{
res = gnome_vfs_create (&handle, desktop_path,
GNOME_VFS_OPEN_WRITE, FALSE,
GNOME_VFS_PERM_USER_WRITE
| GNOME_VFS_PERM_USER_READ
| GNOME_VFS_PERM_GROUP_READ);
}
g_free (desktop_path);
if (res != GNOME_VFS_OK) {
return;
}
write_string (handle, "[Desktop Entry]\n");
write_string (handle, "Encoding=UTF-8\n");
str = g_strdup_printf ("Name=%s\n", title);
write_string (handle, str);
g_free (str);
write_string (handle, "Exec=rhythmbox\n");
if (icon != NULL) {
str = g_strdup_printf ("Icon=%s\n", icon);
} else {
str = g_strdup ("Icon=\n");
}
write_string (handle, str);
g_free (str);
write_string (handle, "Terminal=0\n");
write_string (handle, "Type=Application\n");
gnome_vfs_close (handle);
}
int main (int argc, char **argv)
{
char *url, *icon;
if (argc != 2) {
usage (NULL);
}
if (gnome_vfs_init () == FALSE) {
usage ("Can't initialise gnome-vfs");
}
url = print_uri (argv[1]);
parse_xml (url);
g_free (url);
icon = copy_img_local (img_url);
create_desktop_file (argv[1], icon);
return 0;
}
test-cover.png
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]