Update of /cvsroot/gtkpod/libgpod/bindings/python
In directory sc8-pr-cvs2.sourceforge.net:/tmp/cvs-serv16912/python

Modified Files:
        Makefile.am __init__.py gpod.i.in gtkpod.py ipod.py 
Log Message:
Use gtkdoc documentation for python docstrings, topped up with docstrings by 
Todd Zullinger.

Index: Makefile.am
===================================================================
RCS file: /cvsroot/gtkpod/libgpod/bindings/python/Makefile.am,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- Makefile.am 13 Jan 2007 12:41:22 -0000      1.17
+++ Makefile.am 14 Jan 2007 20:29:38 -0000      1.18
@@ -4,6 +4,8 @@
         README.in           \
         __init__.py         \
         gpod.i.in           \
+        gpod_doc.i.in       \
+        gtkdoc-to-swig.xsl  \
         gtkpod.py           \
         ipod.py
 
@@ -12,6 +14,7 @@
         *.pyo               \
         _gpod.so            \
         gpod.py             \
+        gpod_doc.i          \
         gpod_wrap.*
 
 DISTCLEANFILES =            \
@@ -28,7 +31,7 @@
 
 if HAVE_PYTHON
 BUILT_SOURCES = gpod_wrap.c
-SWIG_INTERFACES = gpod.i
+SWIG_INTERFACES = gpod.i gpod_doc.i
 LIBGPOD_CFLAGS += -fno-strict-aliasing
 INCLUDES = -I$(top_srcdir)/src
 
@@ -41,6 +44,14 @@
 _gpod_la_LDFLAGS = -module -avoid-version
 _gpod_la_LIBADD = $(LIBGPOD_LIBS) $(top_builddir)/src/libgpod.la
 
+gpod_doc.i: $(srcdir)/gpod_doc.i.in $(srcdir)/gtkdoc-to-swig.xsl
+       cat $< > $@
+if ENABLE_GTK_DOC
+       -for xml in $(top_srcdir)/docs/reference/xml/*.xml; do \
+           xsltproc $(srcdir)/gtkdoc-to-swig.xsl $$xml; \
+       done >> $@
+endif
+
 gpod_wrap.c: $(SWIG_INTERFACES) $(nodist_gpod_PYTHON)
        $(SWIG) -python $(INCLUDES) -o $@ $<
 

Index: __init__.py
===================================================================
RCS file: /cvsroot/gtkpod/libgpod/bindings/python/__init__.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- __init__.py 6 May 2006 16:27:22 -0000       1.1
+++ __init__.py 14 Jan 2007 20:29:38 -0000      1.2
@@ -1,6 +1,12 @@
+"""Manage tracks and playlists on an iPod.
+
+The gpod module allows you to add and remove tracks, create and edit
+playlists, and other iPod tasks.
+
+"""
+
 from gpod import *
 from ipod import *
 
 __all__ = ["DatabaseException", "TrackException",
            "Database","Track","Playlist"]
-

Index: gpod.i.in
===================================================================
RCS file: /cvsroot/gtkpod/libgpod/bindings/python/gpod.i.in,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- gpod.i.in   14 Jan 2007 20:15:27 -0000      1.2
+++ gpod.i.in   14 Jan 2007 20:29:38 -0000      1.3
@@ -28,7 +28,17 @@
 
 */
 
-%module gpod
+%define DOCSTRING
+"This module gives access to an iPod's content. It provides an easy to
+use API to retrieve the list of files and playlists stored on an iPod,
+modify them, and save them back to the iPod.
+
+This module implements the libgpod C API as directly as possible in
+Python.  See the main gpod module for a more traditional Python
+interface."
+%enddef
+
+%module(docstring=DOCSTRING) gpod
 %{
 #include "db-artwork-debug.h" 
 #include "db-artwork-parser.h" 
@@ -163,6 +173,8 @@
  
 %}
 
+%include "gpod_doc.i"
+
 # be nicer to decode these utf8 strings into Unicode objects in the C
 # layer. Here we are leaving it to the Python side, and just giving
 # them utf8 encoded Strings.

Index: gtkpod.py
===================================================================
RCS file: /cvsroot/gtkpod/libgpod/bindings/python/gtkpod.py,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- gtkpod.py   27 Nov 2006 11:56:07 -0000      1.2
+++ gtkpod.py   14 Jan 2007 20:29:38 -0000      1.3
@@ -1,3 +1,5 @@
+"""Read and write Gtkpod extended info files."""
+
 import sha
 import os
 import socket
@@ -9,12 +11,15 @@
 hostname = socket.gethostname()
 
 class ParseError(Exception):
+    """Exception for parse errors."""
     pass
 
 class SyncError(Exception):
+    """Exception for sync errors."""
     pass
 
 def sha1_hash(filename):
+    """Return an SHA1 hash on the first 16k of a file."""
     import struct
     # only hash the first 16k
     hash_len = 4*4096
@@ -25,6 +30,15 @@
     return hash.hexdigest()
 
 def write(filename, db, itunesdb_file):
+    """Save extended info to a file.
+
+    db is a gpod.Database instance
+
+    Extended info is written for the iTunesDB specified in
+    itunesdb_file
+
+    """
+
     file = open(filename, "w")
 
     def write_pair(name, value):
@@ -53,6 +67,15 @@
     write_pair("id", "xxx")
 
 def parse(filename, db, itunesdb_file=None):
+    """Load extended info from a file.
+
+    db is a gpod.Database instance
+
+    If itunesdb_file is set and it's hash is valid some expensive
+    checks are skipped.
+
+    """
+
     tracks_by_id  = {}
     tracks_by_sha = {}    
     id = 0

Index: ipod.py
===================================================================
RCS file: /cvsroot/gtkpod/libgpod/bindings/python/ipod.py,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- ipod.py     30 May 2006 15:23:29 -0000      1.9
+++ ipod.py     14 Jan 2007 20:29:38 -0000      1.10
@@ -1,6 +1,8 @@
-"""Documentation for this module.
+"""Manage tracks and playlists on an iPod.
+
+You should normally just import the gpod module which will import the
+classes and methods provided here.
 
-More details.
 """
 
 import gpod
@@ -10,13 +12,41 @@
 import os
 
 class DatabaseException(RuntimeError):
+    """Exception for database errors."""
     pass
 
 class TrackException(RuntimeError):
+    """Exception for track errors."""
     pass
 
 class Database:
+    """An iTunes database.
+
+    A database contains playlists and tracks.
+
+    """
+
     def __init__(self, mountpoint="/mnt/ipod", local=False, localdb=None):
+        """Create a Database object.
+
+        You can create the object from a mounted iPod or from a local
+        database file.
+
+        To use a mounted iPod:
+
+            db = gpod.Database('/mnt/ipod')
+
+        To use a local database file:
+
+            db = gpod.Database(localdb='/path/to/iTunesDB')
+
+        If you specify local=True then the default local database from
+        gtkpod will be used (~/.gtkpod/local_0.itdb):
+
+            db = gpod.Database(local=True)
+
+        """
+
         if local or localdb:
             if localdb:
                 self._itdb_file = localdb
@@ -37,7 +67,7 @@
 
     def __str__(self):
         return self.__repr__()
-    
+
     def __repr__(self):
         return "<Database Filename:%s Playlists:%s Tracks:%s>" % (
             repr(self._itdb.filename),
@@ -45,12 +75,21 @@
             len(self))
 
     def _load_gtkpod_extended_info(self):
+        """Read extended information from a gtkpod .ext file."""
         itdbext_file = "%s.ext" % (self._itdb_file)
 
         if os.path.exists(self._itdb_file) and os.path.exists(itdbext_file):
             gtkpod.parse(itdbext_file, self, self._itdb_file)
 
     def close(self):
+        """Save and close the database.
+
+        Note: If you are working with an iPod you should normally call
+        copy_delayed_files() prior to close() to ensure that newly
+        added or updated tracks are transferred to the iPod.
+
+        """
+
         if not gpod.itdb_write_file(self._itdb, self._itdb_file, None):
             raise DatabaseException("Unable to save iTunes database %s" % self)
         itdbext_file = "%s.ext" % (self._itdb_file)        
@@ -68,6 +107,11 @@
         return gpod.sw_get_list_len(self._itdb.tracks)
 
     def import_file(self, filename):
+        """Import a file.
+
+        filename is added to the end of the master playlist.
+
+        """
         track = Track(filename)
         track.copy_to_ipod()
         gpod.itdb_playlist_add_track(gpod.itdb_playlist_mpl(self._itdb),
@@ -77,9 +121,26 @@
         gpod.itdb_free(self._itdb)
 
     def add(self, track, pos=-1):
+        """Add a track to a database.
+
+        If pos is set the track will be inserted at that position.  By
+        default the track will be added at the end of the database.
+
+        """
+
         gpod.itdb_track_add(self._itdb, track._track, pos)
 
     def remove(self, item, harddisk=False, ipod=True):
+        """Remove a playlist or track from a database.
+
+        item is either a playlist or track object.
+
+        If harddisk is True the item will be removed from the the hard drive.
+
+        If ipod is True the item will be removed from the iPod.
+
+        """
+
         if isinstance(item, Playlist):
             if ipod or harddisk:
                 # remove all the tracks that were in this playlist
@@ -109,12 +170,15 @@
             raise DatabaseException("Unable to remove a %s from database" % 
type(item))
 
     def get_master(self):
+        """Get the Master playlist."""
         return 
Playlist(self,proxied_playlist=gpod.itdb_playlist_mpl(self._itdb))
 
     def get_podcasts(self):
+        """Get the podcasts playlist."""
         return 
Playlist(self,proxied_playlist=gpod.itdb_playlist_podcasts(self._itdb))
 
     def get_playlists(self):
+        """Get all playlists."""
         return _Playlists(self)
 
     Master   = property(get_master)
@@ -122,12 +186,25 @@
     Playlists= property(get_playlists) 
 
     def smart_update(self):
+        """Update all smart playlists."""
         gpod.itdb_spl_update_all(self._itdb)
 
     def new_Playlist(self,*args,**kwargs):
+        """Create a new Playlist.
+
+        See Playlist.__init__() for details.
+
+        """
+
         return Playlist(self, *args,**kwargs)
 
     def new_Track(self,**kwargs):
+        """Create a new Track.
+
+        See Track.__init__() for details.
+
+        """
+
         track = Track(**kwargs)
         self.add(track)
         if kwargs.has_key('podcast') and kwargs['podcast'] == True:
@@ -137,6 +214,19 @@
         return track
 
     def copy_delayed_files(self,callback=False):
+        """Copy files not marked as transferred to the iPod.
+
+        callback is an optional function that will be called for each
+        track that is copied.  It will be passed the following
+        arguments:
+
+            database -> the database object
+            track    -> the track being copied
+            iterator -> the current track number being copied
+            total    -> the total tracks to be copied
+
+        """
+
         if not gpod.itdb_get_mountpoint(self._itdb):
             # we're not working with a real ipod.
             return
@@ -157,10 +247,22 @@
             track.copy_to_ipod()
 
 class Track:
+    """A track in an iTunes database.
+
+    A track contains information like the artist, title, album, etc.
+    It also contains data like the location on the iPod, whether there
+    is artwork stored, the track has lyrics, etc.
+
+    Information from a gtkpod extended info file (if one exists for
+    the iTunesDB) is also available in Track['userdata'].
+
+    The information is stored in a dictionary.
+
+    """
+
     # Note we don't free the underlying structure, as it's still used
     # by the itdb.
-    
-    
+
     _proxied_attributes = 
("title","ipod_path","album","artist","genre","filetype",
                            
"comment","category","composer","grouping","description",
                            
"podcasturl","podcastrss","chapterdata","subtitle","id",
@@ -179,6 +281,20 @@
 
     def __init__(self, filename=None, from_file=None,
                  proxied_track=None, podcast=False):
+        """Create a Track object.
+
+        If from_file or filename is set, the file specified will be
+        used to create the track.
+
+        If proxied_track is set, it is expected to be an Itdb_Track
+        object.
+
+        If podcast is True then the track will be setup as a Podcast,
+        unless proxied_track is set. 
+
+        """
+
+        # XXX couldn't from_file and filename be merged? 
         if from_file:
             filename = from_file
         if filename:
@@ -218,9 +334,10 @@
             self._track = proxied_track
         else:
             self._track = gpod.itdb_track_new()
-        self.set_podcast(podcast)
+            self.set_podcast(podcast)
 
     def copy_to_ipod(self):
+        """Copy the track to the iPod."""
         self['userdata']['md5_hash'] = gtkpod.sha1_hash(
             self['userdata']['filename_locale'])
         if not gpod.itdb_get_mountpoint(self._track.itdb):
@@ -234,21 +351,37 @@
         return True
 
     def ipod_filename(self):
+        """Get the full path to the track on the iPod.
+
+        Note (from the libgpod documentation): This code works around
+        a problem on some systems and might return a filename with
+        different case than the original filename. Don't copy it back
+        to track unless you must.
+
+        """
+
         return gpod.itdb_filename_on_ipod(self._track)
 
     def set_podcast(self, value):
+        """Mark the track as a podcast.
+
+        If value is True flags appropriate for podcasts are set,
+        otherwise those flags are unset.
+
+        """
+
         if value:
             self['skip_when_shuffling'] = 0x01
             self['remember_playback_position'] = 0x01
-            self['flag4'] = 0x01 # Show Title/Album on the 'Now Playing' page  
          
+            self['flag4'] = 0x01 # Show Title/Album on the 'Now Playing' page
         else:
             self['skip_when_shuffling'] = 0x00
             self['remember_playback_position'] = 0x00
-            self['flag4'] = 0x00 # Show Title/Album/Artist on the 'New 
Playing' page
+            self['flag4'] = 0x00 # Show Title/Album/Artist on the 'Now 
Playing' page
 
     def __str__(self):
         return self.__repr__()
-    
+
     def __repr__(self):
         return "<Track Artist:%s Title:%s Album:%s>" % (
             repr(self['artist']),
@@ -284,6 +417,8 @@
         else:
             raise KeyError('No such key: %s' % item)
 
+# XXX would this be better as a public variable so that the docs would
+# list valid sort order values?
 _playlist_sorting = {
     1:'playlist',
     2:'unknown2',
@@ -323,7 +458,7 @@
 
     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)))]
@@ -336,7 +471,7 @@
 
     def __repr__(self):
         return "<Playlists from %s>" % self._db
-    
+
     def __call__(self, id=None, number=None, name=None):
         if ((id and (number or name)) or (number and name)):
             raise ValueError("Only specify id, number OR name")
@@ -373,10 +508,30 @@
                                     proxied_playlist=pl)
                 else:
                     raise KeyError("Playlist with number %s not found." % 
repr(number))
-        
+
 class Playlist:
+    """A playlist in an iTunes database."""
+
     def __init__(self, parent_db, title="New Playlist",
                  smart=False, pos=-1, proxied_playlist=None):
+        """Create a playlist object.
+
+        parent_db is the database object to which the playlist
+        belongs.
+
+        title is a string that provides a name for the playlist.
+
+        If smart is true the playlist will be a smart playlist.
+
+        If pos is set the track will be inserted at that position.  By
+        default the playlist will be added at the end of the database.
+
+        If proxied_playlist is set it is expected to be an
+        Itdb_Playlist object (as returned by gpod.sw_get_playlist() or
+        similar functions).
+
+        """
+
         self._db = parent_db
         if proxied_playlist:
             self._pl = proxied_playlist
@@ -389,32 +544,71 @@
             gpod.itdb_playlist_add(self._db._itdb, self._pl, pos)
 
     def smart_update(self):
+        """Update the content of the smart playlist."""
         gpod.itdb_spl_update(self._pl)
 
     def randomize(self):
+        """Randomizes the playlist."""
         gpod.itdb_playlist_randomize(self._pl)
 
     def get_name(self):
+        """Get the name of the playlist."""
         return self._pl.name
+
     def set_name(self, name):
+        """Set the name for the playlist."""
         self._pl.name = name
+
     def get_id(self):
+        """Get the id of the playlist."""
         return self._pl.id
+
+    # XXX would this be more aptly named is_smart?  If it was, I think
+    # the docstring could skip the explanation of the return value.
+    # (Same question for get_master and get_podcast.)
     def get_smart(self):
+        """Check if the playlist is smart or not.
+
+        Returns True for a smart playlist, False for a regular
+        playlist.
+
+        """
+
         if self._pl.is_spl == 1:
             return True
         return False
+
     def get_master(self):
+        """Check if the playlist is the master playlist (MPL).
+
+        Returns True if the playlist is the MPL, False if not.
+
+        """
+
         if gpod.itdb_playlist_is_mpl(self._pl) == 1:
             return True
         return False
+
     def get_podcast(self):
+        """Check if the playlist is the podcasts playlist.
+
+        Returns True if the playlist is the podcasts playlist, False
+        if not.
+
+        """
+
         if gpod.itdb_playlist_is_podcasts(self._pl) == 1:
             return True
         return False
+
     def get_sort(self):
+        """Get the sort order for the playlist."""
         return _playlist_sorting[self._pl.sortorder]
+
+    # XXX how does one find out what values are allowed for order without
+    # poking into this file?  (See similar question @ _playlist_order)
     def set_sort(self, order):
+        """Set the sort order for the playlist."""
         order = order.lower()
         for k, v in _playlist_sorting.items():
             if v == order:
@@ -431,7 +625,7 @@
 
     def __str__(self):
         return self.__repr__()
-    
+
     def __repr__(self):
         return "<Playlist Title:%s Sort:%s Smart:%s Master:%s Podcast:%s 
Tracks:%d>" % (
             repr(self.name),
@@ -440,7 +634,7 @@
             repr(self.master),
             repr(self.podcast),
             len(self))
-        
+
     def __getitem__(self, index):
         if type(index) == types.SliceType:
             return [self[i] for i in xrange(*index.indices(len(self)))]
@@ -461,11 +655,26 @@
             return True
         else:
             return False
-    
+
     def add(self, track, pos=-1):
+        """Add a track to the playlist.
+
+        track is a track object to add.
+
+        If pos is set the track will be inserted at that position.  By
+        default the track will be added at the end of the playlist.
+
+        """
+
         gpod.itdb_playlist_add_track(self._pl, track._track, pos)
 
     def remove(self, track):
+        """Remove a track from the playlist.
+
+        track is a track object to remove.
+
+        """
+
         if self.__contains__(track):
             gpod.itdb_playlist_remove_track(self._pl, track._track)
         else:


-------------------------------------------------------------------------
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