Update of /cvsroot/gtkpod/libgpod/bindings/python
In directory sc8-pr-cvs2.sourceforge.net:/tmp/cvs-serv30122/bindings/python
Modified Files:
gpod.i.in ipod.py
Log Message:
Add some PhotoDB reading features, thanks to John Carr for prompting.
Index: gpod.i.in
===================================================================
RCS file: /cvsroot/gtkpod/libgpod/bindings/python/gpod.i.in,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- gpod.i.in 14 Jan 2007 20:29:38 -0000 1.3
+++ gpod.i.in 26 Mar 2007 14:00:54 -0000 1.4
@@ -1,7 +1,7 @@
/* File : gpod.i.in */
/*
- Copyright (C) 2005 Nick Piper <nick-gtkpod at nickpiper co uk>
+ Copyright (C) 2007 Nick Piper <nick-gtkpod at nickpiper co uk>
Part of the gtkpod project.
URL: http://www.gtkpod.org/
@@ -46,7 +46,9 @@
#include "db-itunes-parser.h"
#include "db-parse-context.h"
#include "itdb.h"
+#include "itdb_device.h"
#include "itdb_private.h"
+#include <gdk-pixbuf/gdk-pixbuf.h>
/* include prototypes for all functions so builds using
* -Wmissing-prototypes don't fail. */
@@ -59,8 +61,17 @@
PyObject* sw_get_playlist_tracks(Itdb_Playlist *pl);
PyObject* sw_set_track_userdata(Itdb_Track *track, PyObject *data);
PyObject* sw_get_track_userdata(Itdb_Track *track);
-PyObject *sw__track_extra_duplicate (PyObject *data);
+PyObject* sw__track_extra_duplicate (PyObject *data);
+PyObject* sw_get_photoalbums(Itdb_PhotoDB *db);
+PyObject* sw_get_photoalbum(GList *list, gint index);
+PyObject* sw_get_photos(Itdb_PhotoDB *db);
+PyObject* sw_get_photo(GList *list, gint index);
+PyObject* sw_get_artwork_thumbnails(Itdb_Artwork *artwork);
+PyObject* sw_get_photoalbum_members(Itdb_PhotoAlbum *album);
+PyObject* sw_ipod_device_to_dict(Itdb_Device *device);
+PyObject* sw_save_itdb_thumb(Itdb_PhotoDB *itdb, Itdb_Thumb *thumb, const
gchar *filename);
void sw__track_extra_destroy (PyObject *data);
+void hash_table_to_pydict(gpointer key, gpointer value, gpointer user_data);
void SWIG_init(void);
PyObject* sw_get_tracks(Itdb_iTunesDB *itdb) {
@@ -169,10 +180,127 @@
return Py_None;
}
}
-
+
+ PyObject* sw_get_photoalbums(Itdb_PhotoDB *db) {
+ PyObject *list;
+ gint i;
+ GList *l;
+ list = PyList_New(g_list_length(db->photoalbums));
+ for (l = db->photoalbums, i = 0; l; l = l->next, ++i) {
+ PyList_SET_ITEM(list, i, SWIG_NewPointerObj((void*)(l->data),
+SWIGTYPE_p__Itdb_PhotoAlbum, 0));
+ }
+ return list;
+ }
+
+ PyObject* sw_get_artwork_thumbnails(Itdb_Artwork *artwork) {
+ PyObject *list;
+ gint i;
+ GList *l;
+ list = PyList_New(g_list_length(artwork->thumbnails));
+ for (l = artwork->thumbnails, i = 0; l; l = l->next, ++i) {
+ PyList_SET_ITEM(list, i, SWIG_NewPointerObj((void*)(l->data),
SWIGTYPE_p__Itdb_Thumb, 0));
+ }
+ return list;
+ }
+
+
+PyObject* sw_get_photoalbum(GList *list, gint index) {
+ GList *position;
+ if ( (index >= g_list_length(list)) || index < 0 ) {
+ PyErr_SetString(PyExc_IndexError, "Value out of range");
+ return NULL;
+ }
+ position = g_list_nth(list, index);
+ return SWIG_NewPointerObj((void*)(position->data),
SWIGTYPE_p__Itdb_PhotoAlbum, 0);
+ }
+
+ PyObject* sw_get_photoalbum_members(Itdb_PhotoAlbum *album) {
+ PyObject *list;
+ gint i;
+ GList *l;
+ list = PyList_New(g_list_length(album->members));
+ for (l = album->members, i = 0; l; l = l->next, ++i) {
+ gint photo_id = GPOINTER_TO_INT(l->data);
+ PyList_SET_ITEM(list, i, PyInt_FromLong((long)photo_id));
+ }
+ return list;
+ }
+
+ PyObject* sw_get_photos(Itdb_PhotoDB *db) {
+ PyObject *list;
+ gint i;
+ GList *l;
+ list = PyList_New(g_list_length(db->photos));
+ for (l = db->photos, i = 0; l; l = l->next, ++i) {
+ PyList_SET_ITEM(list, i, SWIG_NewPointerObj((void*)(l->data),
+SWIGTYPE_p__Itdb_Artwork, 0));
+ }
+ return list;
+ }
+
+PyObject* sw_get_photo(GList *list, gint index) {
+ GList *position;
+ if ( (index >= g_list_length(list)) || index < 0 ) {
+ PyErr_SetString(PyExc_IndexError, "Value out of range");
+ return NULL;
+ }
+ position = g_list_nth(list, index);
+ return SWIG_NewPointerObj((void*)(position->data), SWIGTYPE_p__Itdb_Artwork,
0);
+ }
+
+ void hash_table_to_pydict(gpointer key,
+ gpointer value,
+ gpointer user_data) {
+ PyDict_SetItemString((PyObject *)user_data,
+ (char *)key,
+ PyString_FromString(value));
+ }
+
+ PyObject* sw_ipod_device_to_dict(Itdb_Device *device) {
+ PyObject* sysinfo;
+ if (device == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ } else {
+ sysinfo = PyDict_New();
+ g_hash_table_foreach(device->sysinfo,
+ hash_table_to_pydict,
+ (gpointer) sysinfo);
+ return Py_BuildValue("{s:s,s:i,s:i,s:O}",
+ "mountpoint",
+ device->mountpoint,
+ "musicdirs",
+ device->musicdirs,
+ "byte_order",
+ device->byte_order,
+ "sysinfo",
+ sysinfo);
+ }
+ }
+
+ PyObject* sw_save_itdb_thumb(Itdb_PhotoDB *itdb, Itdb_Thumb *thumb, const
gchar *filename) {
+ GdkPixbuf *pixbuf;
+
+ pixbuf = itdb_thumb_get_gdk_pixbuf (itdb->device, thumb);
+
+ if (pixbuf != NULL) {
+ gdk_pixbuf_save (pixbuf, filename, "png", NULL, NULL);
+ gdk_pixbuf_unref (pixbuf);
+ Py_INCREF(Py_True);
+ return Py_True;
+ } else {
+ Py_INCREF(Py_False);
+ return Py_False;
+ }
+ }
%}
+%init %{
+ g_type_init ();
+%}
+
%include "gpod_doc.i"
# be nicer to decode these utf8 strings into Unicode objects in the C
@@ -287,6 +415,10 @@
$result = PyLong_FromUnsignedLong($1);
}
+%typemap(out) gint16 {
+ $result = PyLong_FromLong($1);
+}
+
%typemap(out) guint8 {
$result = PyInt_FromLong($1);
}
@@ -306,5 +438,13 @@
PyObject* sw_get_playlist_tracks(Itdb_Playlist *pl);
PyObject* sw_set_track_userdata(Itdb_Track *track, PyObject *data);
PyObject* sw_get_track_userdata(Itdb_Track *track);
+PyObject* sw_get_photoalbums(Itdb_PhotoDB *db);
+PyObject* sw_get_photoalbum(GList *list, gint index);
+PyObject* sw_get_photos(Itdb_PhotoDB *db);
+PyObject* sw_get_photo(GList *list, gint index);
+PyObject* sw_get_photoalbum_members(Itdb_PhotoAlbum *album);
+PyObject* sw_get_artwork_thumbnails(Itdb_Artwork *artwork);
+PyObject* sw_ipod_device_to_dict(Itdb_Device *device);
+PyObject* sw_save_itdb_thumb(Itdb_PhotoDB *itdb, Itdb_Thumb *thumb, const
gchar *filename);
%include "@top_srcdir@/src/itdb.h"
Index: ipod.py
===================================================================
RCS file: /cvsroot/gtkpod/libgpod/bindings/python/ipod.py,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- ipod.py 12 Feb 2007 08:29:36 -0000 1.14
+++ ipod.py 26 Mar 2007 14:00:54 -0000 1.15
@@ -13,6 +13,7 @@
import os
import locale
import socket
+import datetime
defaultencoding = locale.getpreferredencoding()
@@ -24,6 +25,10 @@
"""Exception for track errors."""
pass
+class PhotoException(RuntimeError):
+ """Exception for track errors."""
+ pass
+
class Database:
"""An iTunes database.
@@ -717,3 +722,244 @@
gpod.itdb_playlist_remove_track(self._pl, track._track)
else:
raise DatabaseException("Playlist %s does not contain %s" % (self,
track))
+
+class PhotoDatabase:
+ """An iTunes Photo database"""
+ def __init__(self, mountpoint="/mnt/ipod"):
+ """Create a Photo database object"""
+ self._itdb = gpod.itdb_photodb_parse(mountpoint, None)
+
+ def __str__(self):
+ return self.__repr__()
+
+ def __repr__(self):
+ return "<PhotoDatabase Mountpoint:%s Albums:%s Photos:%s>" % (
+ repr(self.device['mountpoint']),
+ gpod.sw_get_list_len(self._itdb.photoalbums),
+ len(self))
+
+ def close(self):
+ pass
+
+ def __len__(self):
+ return gpod.sw_get_list_len(self._itdb.photos)
+
+ def __getitem__(self, index):
+ if type(index) == types.SliceType:
+ return [self[i] for i in xrange(*index.indices(len(self)))]
+ else:
+ if index < 0:
+ index += len(self)
+ return Photo(proxied_photo=gpod.sw_get_photo(self._itdb.photos,
index),
+ ownerdb=self)
+ def get_device(self):
+ return gpod.sw_ipod_device_to_dict(self._itdb.device)
+
+ def get_photoalbums(self):
+ """Get all photo albums."""
+ return _PhotoAlbums(self)
+
+ PhotoAlbums = property(get_photoalbums)
+ device = property(get_device)
+
+class _PhotoAlbums:
+ def __init__(self, db):
+ self._db = db
+
+ def __len__(self):
+ return gpod.sw_get_list_len(self._db._itdb.photoalbums)
+
+ def __nonzero__(self):
+ return True
+
+ def __getitem__(self, index):
+ if type(index) == types.SliceType:
+ return [self[i] for i in xrange(*index.indices(len(self)))]
+ else:
+ if index < 0:
+ index += len(self)
+ return PhotoAlbum(self._db,
+
proxied_photoalbum=gpod.sw_get_photoalbum(self._db._itdb.photoalbums,
+ index))
+
+ def __repr__(self):
+ return "<PhotoAlbums from %s>" % self._db
+
+ def __call__(self, name):
+ if type(name) in (types.TupleType, types.ListType):
+ return [self.__call__(name=i) for i in name]
+ else:
+ pa = gpod.itdb_photodb_photoalbum_by_name(self._db._itdb,
+ name)
+ if pa:
+ return PhotoAlbum(self._db,
+ proxied_playlist=pa)
+ else:
+ raise KeyError("Album with name %s not found." % repr(name))
+
+
+class PhotoAlbum:
+ """A Photo Album in an iTunes database."""
+
+ def __init__(self, parent_db, title="New Album",
+ pos=-1, proxied_photoalbum=None):
+
+ self._db = parent_db
+ if proxied_photoalbum:
+ self._pa = proxied_photoalbum
+ else:
+ raise NotImplemented("Can't create new Photo Albums yet")
+
+ def get_name(self):
+ """Get the name of the photo album."""
+ return self._pa.name
+
+ def set_name(self, name):
+ """Set the name for the photo album."""
+ self._pa.name = name
+
+ def get_album_type(self):
+ return self._pa.album_type
+
+ name = property(get_name, set_name)
+ album_type = property(get_album_type)
+
+ def __str__(self):
+ return self.__repr__()
+
+ def __repr__(self):
+ return "<PhotoAlbum Title:%s Photos:%d Type:%d>" % (
+ repr(self.name),
+ len(self),
+ self.album_type)
+
+ def __getitem__(self, index):
+ if type(index) == types.SliceType:
+ return [self[i] for i in xrange(*index.indices(len(self)))]
+ else:
+ if index < 0:
+ index += len(self)
+ return Photo(proxied_photo=gpod.sw_get_photo(self._pa.members,
index),
+ ownerdb=self._db)
+
+ def __len__(self):
+ return gpod.sw_get_list_len(self._pa.members)
+
+ def __nonzero__(self):
+ return True
+
+class Photo:
+ """A photo in an iTunes Photo database."""
+
+ _proxied_attributes =
("id","creation_date","digitized_date","artwork_size")
+
+ def __init__(self, filename=None,
+ proxied_photo=None, ownerdb=None):
+ """Create a Photo object."""
+
+ if filename:
+ # maybe use itdb_photodb_add_photo ?
+ raise NotImplemented("Can't create new Photos from files yet")
+ elif proxied_photo:
+ self._photo = proxied_photo
+ self._database = ownerdb
+ else:
+ self._photo = gpod.itdb_artwork_new()
+
+ def __str__(self):
+ return self.__repr__()
+
+ def __repr__(self):
+ return "<Photo ID:%s Creation:'%s' Digitized:'%s' Size:%s>" % (
+ repr(self['id']),
+ self['creation_date'].strftime("%c"),
+ self['digitized_date'].strftime("%c"),
+ repr(self['artwork_size']))
+
+ def keys(self):
+ return list(self._proxied_attributes)
+
+ def items(self):
+ return [self[k] for k in self._proxied_attributes]
+
+ def pairs(self):
+ return [(k, self[k]) for k in self._proxied_attributes]
+
+ def __getitem__(self, item):
+ if item in self._proxied_attributes:
+ attr = getattr(self._photo, item)
+ if item.endswith("_date"):
+ try:
+ return datetime.datetime.fromtimestamp(attr)
+ except:
+ return datetime.datetime.fromtimestamp(0)
+ else:
+ return attr
+ else:
+ raise KeyError('No such key: %s' % item)
+
+ def __setitem__(self, item, value):
+ if type(value) == types.UnicodeType:
+ value = value.encode('UTF-8','replace')
+ if item in self._proxied_attributes:
+ return setattr(self._photo, item, value)
+ else:
+ raise KeyError('No such key: %s' % item)
+
+ def get_thumbnails(self):
+ return [Thumbnail(proxied_thumbnail=t, ownerphoto=self) for t in
gpod.sw_get_artwork_thumbnails(self._photo)]
+
+ thumbnails = property(get_thumbnails)
+
+class Thumbnail:
+ """A thumbnail in an Photo."""
+
+ _proxied_attributes =
("type","filename","rotation","offset","size","width","height",
+ "horizontal_padding", "vertical_padding")
+
+ def __init__(self, proxied_thumbnail=None, ownerphoto=None):
+ """Create a thumbnail object."""
+
+ if not proxied_thumbnail:
+ raise NotImplemented("Can't create new Thumbnails from scratch,
create Photos instead")
+
+ self._thumbnail = proxied_thumbnail
+ self.__photo = ownerphoto # so the photo doesn't get gc'd
+
+ def __str__(self):
+ return self.__repr__()
+
+ def __repr__(self):
+ return "<Thumbnail Filename:%s Size:%d Width:%d Height:%d>" % (
+ repr(self['filename']),
+ self['size'],
+ self['width'],
+ self['height'])
+
+ def keys(self):
+ return list(self._proxied_attributes)
+
+ def items(self):
+ return [self[k] for k in self._proxied_attributes]
+
+ def pairs(self):
+ return [(k, self[k]) for k in self._proxied_attributes]
+
+ def __getitem__(self, item):
+ if item in self._proxied_attributes:
+ return getattr(self._thumbnail, item)
+ else:
+ raise KeyError('No such key: %s' % item)
+
+ def __setitem__(self, item, value):
+ if type(value) == types.UnicodeType:
+ value = value.encode('UTF-8','replace')
+ if item in self._proxied_attributes:
+ return setattr(self._thumbnail, item, value)
+ else:
+ raise KeyError('No such key: %s' % item)
+
+ def save_image(self,filename):
+ return gpod.sw_save_itdb_thumb(
+ self.__photo._database._itdb,
+ self._thumbnail,filename)
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
gtkpod-cvs2 mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/gtkpod-cvs2