summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Piper <nicholas@users.sourceforge.net>2006-04-09 16:38:12 +0000
committerNicholas Piper <nicholas@users.sourceforge.net>2006-04-09 16:38:12 +0000
commit08de30de7733b07a17eed911ca1d4f02b030ad42 (patch)
treebf60b90d0264d105ca06038d2da0137e58c926f3
parentde94dbec8470b576f057a0862f7316b93559e6a5 (diff)
downloadlibgpod-08de30de7733b07a17eed911ca1d4f02b030ad42.tar.gz
libgpod-08de30de7733b07a17eed911ca1d4f02b030ad42.tar.xz
libgpod-08de30de7733b07a17eed911ca1d4f02b030ad42.zip
Very start of a much nicer API from Python
git-svn-id: https://gtkpod.svn.sf.net/svnroot/gtkpod/libgpod/trunk@1242 f01d2545-417e-4e96-918e-98f8d0dbbcb6
-rw-r--r--bindings/python/Makefile.am9
-rw-r--r--bindings/python/examples/Makefile.am4
-rwxr-xr-xbindings/python/examples/playwith_ipod_api.py14
-rw-r--r--bindings/python/gpod.i32
-rw-r--r--bindings/python/ipod.py147
5 files changed, 203 insertions, 3 deletions
diff --git a/bindings/python/Makefile.am b/bindings/python/Makefile.am
index af4e9e1..8dba92c 100644
--- a/bindings/python/Makefile.am
+++ b/bindings/python/Makefile.am
@@ -1,7 +1,8 @@
SUBDIRS = examples
EXTRA_DIST = \
- gpod.i
+ gpod.i \
+ ipod.py
CLEANFILES = \
*.py* \
@@ -31,9 +32,13 @@ install-pythonDATA: $(python_DATA)
$(mkinstalldirs) $(DESTDIR)$(pythondir)
$(INSTALL_PROGRAM) _gpod.so $(DESTDIR)$(pythondir)/_gpod.so
$(INSTALL_DATA) gpod.py $(DESTDIR)$(pythondir)/gpod.py
+ $(INSTALL_DATA) ipod.py $(DESTDIR)$(pythondir)/ipod.py
$(PYTHON) -c 'from py_compile import compile; compile("$(DESTDIR)$(pythondir)/gpod.py")'
$(PYTHON) -O -c 'from py_compile import compile; compile("$(DESTDIR)$(pythondir)/gpod.py")'
+ $(PYTHON) -c 'from py_compile import compile; compile("$(DESTDIR)$(pythondir)/ipod.py")'
+ $(PYTHON) -O -c 'from py_compile import compile; compile("$(DESTDIR)$(pythondir)/ipod.py")'
uninstall-pythonDATA: $(python_DATA)
- rm -f $(DESTDIR)$(pythondir)/_gpod.so $(DESTDIR)$(pythondir)/gpod.py
+ rm -f $(DESTDIR)$(pythondir)/_gpod.so
+ rm -f $(DESTDIR)$(pythondir)/gpod.py $(DESTDIR)$(pythondir)/ipod.py
endif
diff --git a/bindings/python/examples/Makefile.am b/bindings/python/examples/Makefile.am
index 93cf41c..89f76fc 100644
--- a/bindings/python/examples/Makefile.am
+++ b/bindings/python/examples/Makefile.am
@@ -1,2 +1,4 @@
-EXTRA_DIST = coverart_fetch.py toy_around.py tag_genre_from_audioscrobber.py add_song.py
+EXTRA_DIST = coverart_fetch.py toy_around.py \
+ tag_genre_from_audioscrobber.py add_song.py \
+ playwith_ipod_api.py
diff --git a/bindings/python/examples/playwith_ipod_api.py b/bindings/python/examples/playwith_ipod_api.py
new file mode 100755
index 0000000..544de5b
--- /dev/null
+++ b/bindings/python/examples/playwith_ipod_api.py
@@ -0,0 +1,14 @@
+#!/usr/bin/python
+
+import ipod
+
+db = ipod.Database()
+
+for track in db[4:20]:
+ print track
+ print track['title']
+
+filename = "/mp3/Blondie/No_Exit/Blondie_-_Maria.mp3"
+t = ipod.Track(from_file=filename)
+print t
+
diff --git a/bindings/python/gpod.i b/bindings/python/gpod.i
index 1c0edc7..7103ecf 100644
--- a/bindings/python/gpod.i
+++ b/bindings/python/gpod.i
@@ -49,6 +49,20 @@ PyObject* sw_get_tracks(Itdb_iTunesDB *itdb) {
return list;
}
+PyObject* sw_get_track(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_Track, 0);
+ }
+
+PyObject* sw_get_list_len(GList *list) {
+ return PyInt_FromLong(g_list_length(list));
+ }
+
PyObject* sw_get_playlist_tracks(Itdb_Playlist *pl) {
PyObject *list;
gint i;
@@ -88,12 +102,28 @@ typedef char gchar;
}
}
+%typemap(out) guint64 {
+ $result = PyLong_FromLong($1);
+}
+
+%typemap(out) guint32 {
+ $result = PyInt_FromLong($1);
+}
+
+%typemap(out) guint16 {
+ $result = PyInt_FromLong($1);
+}
+
+
%typemap(out) guint8 {
$result = PyInt_FromLong($1);
}
typedef int gboolean;
+typedef long gint64;
typedef int gint32;
+typedef int gint16;
+typedef int gint;
typedef unsigned int guint32;
@@ -101,6 +131,8 @@ typedef unsigned int guint32;
#define G_END_DECLS
PyObject* sw_get_tracks(Itdb_iTunesDB *itdb);
+PyObject* sw_get_track(GList *list, gint index);
+PyObject* sw_get_list_len(GList *list);
PyObject* sw_get_playlists(Itdb_iTunesDB *itdb);
PyObject* sw_get_playlist_tracks(Itdb_Playlist *pl);
%include "../../src/itdb.h"
diff --git a/bindings/python/ipod.py b/bindings/python/ipod.py
new file mode 100644
index 0000000..3e98310
--- /dev/null
+++ b/bindings/python/ipod.py
@@ -0,0 +1,147 @@
+# This isn't even really started.
+
+import gpod
+import types
+import eyeD3
+
+class DatabaseException(RuntimeError):
+ pass
+
+class TrackException(RuntimeError):
+ pass
+
+class Database:
+ def __init__(self, mountpoint="/mnt/ipod"):
+ self._itdb = itdb = gpod.itdb_parse(mountpoint,
+ None)
+ if not self._itdb:
+ raise DatabaseException("Unable to parse iTunes database at mount point %s" % mountpoint)
+ else:
+ self._itdb.mountpoint = mountpoint
+
+ def close(self):
+ if not gpod.itdb_write(self._itdb, None):
+ raise DatabaseException("Unable to save iTunes database at %s" % mountpoint)
+
+ 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 Track(proxied_track=gpod.sw_get_track(self._itdb.tracks, index))
+
+ def __len__(self):
+ return gpod.sw_get_list_len(self._itdb.tracks)
+
+ def import_file(self, filename):
+ track = Track(filename)
+ track.copy_to_ipod()
+ gpod.itdb_playlist_add_track(gpod.itdb_playlist_mpl(self._itdb),
+ track._track, -1)
+
+
+class Track:
+ _proxied_attributes = ("title","ipod_path","album","artist","genre","filetype",
+ "comment","category","composer","grouping","description",
+ "podcasturl","podcastrss","chapterdata","subtitle","id",
+ "size","tracklen","cd_nr","cds","track_nr","tracks",
+ "bitrate","samplerate","samplerate_low","year","volume",
+ "soundcheck","time_added","time_played","time_modified",
+ "bookmark_time","rating","playcount","playcount2",
+ "recent_playcount","transferred","BPM","app_rating",
+ "type1","type2","compilation","starttime","stoptime",
+ "checked","dbid","drm_userid","visible","filetype_marker",
+ "artwork_count","artwork_size","samplerate2",
+ "time_released","has_artwork","flag1","flag2","flag3","flag4",
+ "lyrics_flag","movie_flag","mark_unplayed","samplecount",
+ "chapterdata_raw","chapterdata_raw_length","artwork",
+ "usertype","userdata","userdata_duplicate","userdata_destroy")
+
+ def __init__(self, from_file=None, proxied_track=None, podcast=False):
+ self._ondiskfilename = None
+ if from_file:
+ self._ondiskfilename = from_file
+ self._track = gpod.itdb_track_new()
+ audiofile = eyeD3.Mp3AudioFile(self._ondiskfilename)
+ tag = audiofile.getTag()
+ print dir(tag)
+ for func, attrib in (('getArtist','artist'),
+ ('getTitle','title'),
+ ('getBPM','BPM'),
+ ('getPlayCount','playcount'),
+ ('getAlbum','album')):
+ value = getattr(tag,func)()
+ if value:
+ self[attrib] = value
+ self['genre'] = tag.getGenre().name
+ disc, of = tag.getDiscNum()
+ if disc is not None:
+ self['cd_nr'] = disc
+ if of is not None:
+ self['cds'] = of
+ n, of = tag.getTrackNum()
+ if n is not None:
+ self['track_nr'] = n
+ if of is not None:
+ self['tracks'] = of
+ self['tracklen'] = audiofile.getPlayTime() * 1000
+ elif proxied_track:
+ self._track = proxied_track
+ else:
+ self._track = gpod.itdb_track_new()
+ self.set_podcast(podcast)
+
+ def copy_to_ipod(self):
+ if gpod.itdb_cp_track_to_ipod(self._track, self._ondiskfilename, None) != 1:
+ raise TrackException('Unable to copy %s to iPod as %s' % (self._ondiskfilename,
+ self))
+
+ def set_podcast(self, value):
+ if value:
+ self['flag1'] = 0x02 # unknown
+ self['flag2'] = 0x01 # skip when shuffling
+ self['flag3'] = 0x01 # remember playback position
+ self['flag4'] = 0x01 # Show Title/Album on the 'Now Playing' page
+ else:
+ self['flag1'] = 0x02 # unknown
+ self['flag2'] = 0x00 # do not skip when shuffling
+ self['flag3'] = 0x00 # do not remember playback position
+ self['flag4'] = 0x00 # Show Title/Album/Artist on the 'New Playing' page
+
+ def __str__(self):
+ return self.__repr__()
+
+ def __repr__(self):
+ return "<Track Artist:%s Title:%s Album:%s>" % (
+ repr(self['artist']),
+ repr(self['title']),
+ repr(self['album']))
+
+ 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._track, item)
+ else:
+ raise KeyError('No such key: %s' % item)
+
+ def __setitem__(self, item, value):
+ #print item, value
+ if type(value) == types.UnicodeType:
+ value = value.encode()
+ if item in self._proxied_attributes:
+ return setattr(self._track, item, value)
+ else:
+ raise KeyError('No such key: %s' % item)
+
+
+class Playlist:
+ pass