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

Reply via email to