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

Modified Files:
        gtkpod.py ipod.py 
Log Message:
        * ChangeLog
          INSTALL_CVS
          configure.ac
          bindings/python/gtkpod.py
          bindings/python/ipod.py
          bindings/python/examples/add_song.py
          bindings/python/examples/create_mp3_tags_from_itdb.py:

          updates and fixes from Nicholas Piper.



Index: gtkpod.py
===================================================================
RCS file: /cvsroot/gtkpod/libgpod/bindings/python/gtkpod.py,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- gtkpod.py   23 Jan 2007 14:10:40 -0000      1.7
+++ gtkpod.py   12 Feb 2007 08:29:36 -0000      1.8
@@ -2,16 +2,11 @@
 
 import sha
 import os
-import socket
 import types
-import locale
 
 # This file is originally stolen from pypod-0.5.0
 # http://superduper.net/index.py?page=pypod
-# I hope that's ok, both works are GPL.
-
-hostname = socket.gethostname()
-defaultencoding = locale.getpreferredencoding()
+# and reworked significantly since then.
 
 class ParseError(Exception):
     """Exception for parse errors."""
@@ -45,18 +40,9 @@
     file = open(filename, "w")
 
     def write_pair(name, value):
-        if isinstance(value,types.UnicodeType):
-            # encode as UTF-8
-            value = value.encode("utf-8")
-        elif isinstance(value,types.StringType):
-            # assume it's in our default locale, so decode
-            # then re-encode as UTF-8
-            value = unicode(value,
-                            defaultencoding).encode("utf-8")
-        else:
+        if type(value) not in (types.StringType, types.UnicodeType):
+            # e.g., an integer
             value = str(value)
-            
-            
         file.write("=".join([name, value]))
         file.write('\n')
 
@@ -67,23 +53,6 @@
         write_pair("id", track['id'])
         if not track['userdata']:
             track['userdata'] = {}
-        if track['ipod_path']:
-            track['userdata']['filename_ipod'] = track['ipod_path']
-        hash_name = 'sha1_hash'
-        try:
-            del track['userdata'][hash_name]
-        except KeyError:
-            # recent gpod uses sha1_hash, older uses md5_hash            
-            try:
-                del track['userdata'][hash_name]
-                hash_name = 'md5_hash'
-            except KeyError:
-                # we'll just write a sha1_hash then
-                pass
-        if track['userdata'].has_key('filename_locale') and not 
track['userdata'].has_key(hash_name):
-            if os.path.exists(track['userdata']['filename_locale']):
-                track['userdata'][hash_name] = sha1_hash(
-                    track['userdata']['filename_locale'])
         [write_pair(i[0],i[1]) for i in track['userdata'].items()]
 
     write_pair("id", "xxx")
@@ -98,44 +67,42 @@
 
     """
 
-    tracks_by_id  = {}
-    tracks_by_sha = {}    
-    id = 0
-    ext_hash_valid = True
-
-    for track in db:
-        track['userdata'] = {}
-
-    for track in db:
-        tracks_by_id[track['id']] = track
-
-    track = None
-    file = open(filename)
+    ext_hash_valid = False
     ext_data = {}
-    ext_block = None
-    for line in file:
+    
+    for line in open(filename).readlines():
         parts = line.strip().split("=", 1)
         if len(parts) != 2:
             print parts
         name, value = parts
         if name == "id":
-            if ext_block:
-                ext_data[id] = ext_block
-            if value != 'xxx':
-                id = int(value)
-                ext_block = {}
+            if value == 'xxx':
+                break
+            id = int(value)
+            ext_data[id] = {}
         elif name == "version":
             pass
         elif name == "itunesdb_hash":
-            if itunesdb_file and sha1_hash(itunesdb_file) != value:
-                ext_hash_valid = False
+            if itunesdb_file and sha1_hash(itunesdb_file) == value:
+                ext_hash_valid = True
         else:
-            ext_block[name] = value
+            # value is a string of undetermined encoding at the moment
+            ext_data[id][name] = value
 
+    # now add each extended info block to the track it goes with
+    # equiv. of fill_in_extended_info()
     if ext_hash_valid:
-        for id,ext_block in ext_data.items():
-            tracks_by_id[id]['userdata'] = ext_block
+        # the normal case
+        for track in db:
+            try:
+                track['userdata'] = ext_data[track['id']]
+            except KeyError:
+                # no userdata available...
+                track['userdata'] = {}
     else:
+        # the iTunesDB was changed, so id's will be wrong.
+        # match up using hash instead
+        tracks_by_sha = {}    
         for track in db:
             # make a dict to allow us to find each track by the sha1_hash
             tracks_by_sha[sha1_hash(track.ipod_filename())] = track

Index: ipod.py
===================================================================
RCS file: /cvsroot/gtkpod/libgpod/bindings/python/ipod.py,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- ipod.py     10 Feb 2007 23:14:23 -0000      1.13
+++ ipod.py     12 Feb 2007 08:29:36 -0000      1.14
@@ -7,9 +7,14 @@
 
 import gpod
 import types
-import eyeD3
+from mutagen.mp3 import MP3
+import mutagen.id3
 import gtkpod
 import os
+import locale
+import socket
+
+defaultencoding = locale.getpreferredencoding()
 
 class DatabaseException(RuntimeError):
     """Exception for database errors."""
@@ -159,7 +164,7 @@
                     pl.remove(item)
             if harddisk:
                 try:
-                    filename = item['userdata']['filename_locale']
+                    filename = item._userdata_into_default_locale('filename')
                 except KeyError, e:
                     raise TrackException("Unable to remove %s from hard disk, 
no filename available." % item)
                 os.unlink(filename)
@@ -238,7 +243,7 @@
         for track in self:
             try:
                 transferred = int(track['userdata']['transferred'])
-            except KeyError:
+            except (KeyError, TypeError):
                 transferred = 1
             if not transferred:
                 to_copy.append(track)
@@ -283,7 +288,7 @@
                            
"chapterdata_raw","chapterdata_raw_length","artwork",
                            "usertype")
 
-    def __init__(self, filename=None, from_file=None,
+    def __init__(self, filename=None,
                  proxied_track=None, podcast=False, ownerdb=None):
         """Create a Track object.
 
@@ -298,52 +303,44 @@
 
         """
 
-        # XXX couldn't from_file and filename be merged? 
-        if from_file:
-            filename = from_file
         if filename:
             self._track = gpod.itdb_track_new()
-            self['userdata'] = {'filename_locale': filename,
-                                'transferred': 0}
+            self['userdata'] = {'transferred': 0,
+                                'hostname': socket.gethostname(),
+                                'charset':defaultencoding}
+            self['userdata']['pc_mtime'] = os.stat(filename).st_mtime
+            self._set_userdata_utf8('filename',filename)
+            possible_image = 
os.path.join(os.path.split(filename)[0],'folder.jpg')
+            if os.path.exists(possible_image):
+                self.set_thumbnail(possible_image)
             try:
-                audiofile = 
eyeD3.Mp3AudioFile(self['userdata']['filename_locale'])
-            except eyeD3.tag.InvalidAudioFormatException, e:
+                audiofile = MP3(self._userdata_into_default_locale('filename'))
+            except Exception, e:
                 raise TrackException(str(e))
-            tag = audiofile.getTag()
-            for func, attrib in (('getArtist','artist'),
-                                 ('getTitle','title'),
-                                 ('getBPM','BPM'),
-                                 ('getPlayCount','playcount'),
-                                 ('getAlbum','album')):
+            for tag, attrib in (('TPE1','artist'),
+                                ('TIT2','title'),
+                                ('TBPM','BPM'),
+                                ('TCON','genre'),
+                                ('TALB','album'),
+                                ('TPOS',('cd_nr','cds')),
+                                ('TRCK',('track_nr','tracks'))):
                 try:
-                    value = getattr(tag,func)()
-                    if value:
-                        self[attrib] = value
-                except AttributeError:
+                    value = audiofile[tag]
+                    if isinstance(value,mutagen.id3.NumericPartTextFrame):
+                        parts = map(int,value.text[0].split("/"))
+                        if len(parts) == 2:
+                            self[attrib[0]], self[attrib[1]] = parts
+                        elif len(parts) == 1:
+                            self[attrib[0]] = parts[0]                         
  
+                    elif isinstance(value,mutagen.id3.TextFrame):
+                        self[attrib] = value.text[0].encode('UTF-8','replace')
+                except KeyError:
                     pass
             if self['title'] is None:
-                self['title'] = os.path.splitext(os.path.split(filename)[1])[0]
-            try:
-                self['genre'] = tag.getGenre().name
-            except AttributeError:
-                pass
-            try:
-                disc, of = tag.getDiscNum()
-                if disc is not None:
-                    self['cd_nr'] = disc
-                if of is not None:
-                    self['cds'] = of
-            except AttributeError:
-                pass
-            try:            
-                n, of = tag.getTrackNum()
-                if n is not None:
-                    self['track_nr'] = n
-                if of is not None:
-                    self['tracks'] = of
-            except AttributeError:
-                pass
-            self['tracklen'] = audiofile.getPlayTime() * 1000
+                self['title'] = os.path.splitext(
+                    os.path.split(filename)[1])[0].decode(
+                    defaultencoding).encode('UTF-8')
+            self['tracklen'] = int(audiofile.info.length * 1000)
             self.set_podcast(podcast)
         elif proxied_track:
             self._track = proxied_track
@@ -352,18 +349,47 @@
             self._track = gpod.itdb_track_new()
             self.set_podcast(podcast)
 
+    def _set_userdata_utf8(self, key, value):
+        self['userdata']['%s_locale' % key] = value
+        try:
+            self['userdata']['%s_utf8'   % key] = 
value.decode(self['userdata']['charset']).encode('UTF-8')
+        except UnicodeDecodeError, e:
+            # string clearly isn't advertised charset.  I prefer to
+            # not add the _utf8 version as we can't actually generate
+            # it. Maybe we'll have to populate a close-fit though.
+            pass
+
+    def _userdata_into_default_locale(self, key):
+        # to cope with broken filenames, we should trust the _locale version 
more,
+        # an even that may not really be in self['userdata']['charset']
+        if self['userdata']['charset'] == defaultencoding:
+            # don't try translate it or check it's actually valid, in case it 
isn't.
+            return self['userdata']['%s_locale' % key]
+        # our filesystem is in a different encoding to the filename, so
+        # try to convert it. The UTF-8 version is likely best to try first?
+        if self['userdata'].has_key('%s_utf8' % key):
+            unicode_value = self['userdata']['%s_utf8' % key].decode('UTF-8')
+        else:
+            unicode_value = self['userdata']['%s_locale' % 
key].decode(self['userdata']['charset'])
+        return unicode_value.encode(defaultencoding)
+
+    def set_thumbnail(self, filename):
+        gpod.itdb_track_set_thumbnails(self._track, filename)
+        self._set_userdata_utf8('thumbnail', filename)
+
     def copy_to_ipod(self):
         """Copy the track to the iPod."""
-        self['userdata']['md5_hash'] = gtkpod.sha1_hash(
-            self['userdata']['filename_locale'])
+        self['userdata']['sha1_hash'] = 
gtkpod.sha1_hash(self._userdata_into_default_locale('filename'))
         if not gpod.itdb_get_mountpoint(self._track.itdb):
             return False
-        self['userdata']['transferred'] = 1
         if gpod.itdb_cp_track_to_ipod(self._track,
-                                      self['userdata']['filename_locale'], 
None) != 1:
+                                      
self._userdata_into_default_locale('filename'),
+                                      None) != 1:
             raise TrackException('Unable to copy %s to iPod as %s' % (
-                self['userdata']['filename_locale'],
+                self._userdata_into_default_locale('filename'),
                 self))
+        self['userdata']['transferred'] = 1
+        self['userdata']['filename_ipod'] = self.ipod_filename()
         return True
 
     def ipod_filename(self):
@@ -422,20 +448,17 @@
             raise KeyError('No such key: %s' % item)
 
     def __setitem__(self, item, value):
-        #print item, value
         if item == "userdata":
             gpod.sw_set_track_userdata(self._track, value)
             return
         if type(value) == types.UnicodeType:
-            value = value.encode('UTF-8','ignore')
+            value = value.encode('UTF-8','replace')
         if item in self._proxied_attributes:
             return setattr(self._track, item, value)
         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 = {
+playlist_sorting = {
     1:'playlist',
     2:'unknown2',
     3:'songtitle',
@@ -619,14 +642,12 @@
 
     def get_sort(self):
         """Get the sort order for the playlist."""
-        return _playlist_sorting[self._pl.sortorder]
+        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():
+        for k, v in playlist_sorting.items():
             if v == order:
                 self._pl.sortorder = v
                 return


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier.
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
gtkpod-cvs2 mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/gtkpod-cvs2

Reply via email to