* Rafael Laboissiere <raf...@laboissiere.net> [2009-03-30 16:31]: > * Thomas Perl <t...@thpinfo.com> [2009-03-30 13:00]: > > > The following seems to work for users of MTP devices so far (see the > > attachment to that bug): > > > > http://bugs.gpodder.org/show_bug.cgi?id=307 > > Thanks for the info. The changes to pymtp.py are different from those > that I proposed before. I will test both versions eventually and will > let you know.
My version was not working properly, so forget about the previous patch. I merged both version for pymtp.py and the resulting debdiff is attached below. I tested it with a Zen Creative device and creation of a track from file worked using the modified sendtrack.py script in the package (notice that this script is patched to work with python-id3 instead of using the pyid3lib module, which does not seem to be available in Debian). I am Cc:ing this reply to the upstream author. Let us see what he thinks. Although it would need more tests, I would go ahead and upload this changed version of the package to unstable, otherwise the libmtp transiton will be blocked. Indeed python-pymtp is the last blocker for the transition (Cc:ing also to debian-release, accordingly). Cheers, -- Rafael
diff -u pymtp-0.0.4/build/lib/pymtp.py pymtp-0.0.4/build/lib/pymtp.py --- pymtp-0.0.4/build/lib/pymtp.py +++ pymtp-0.0.4/build/lib/pymtp.py @@ -167,6 +167,7 @@ LIBMTP_File._fields_ = [("item_id", ctypes.c_uint32), ("parent_id", ctypes.c_uint32), + ("storage_id", ctypes.c_uint32), ("filename", ctypes.c_char_p), ("filesize", ctypes.c_uint64), ("filetype", ctypes.c_int), @@ -183,8 +184,10 @@ LIBMTP_Track._fields_ = [("item_id", ctypes.c_uint32), ("parent_id", ctypes.c_uint32), + ("storage_id", ctypes.c_uint32), ("title", ctypes.c_char_p), ("artist", ctypes.c_char_p), + ("composer", ctypes.c_char_p), ("genre", ctypes.c_char_p), ("album", ctypes.c_char_p), ("date", ctypes.c_char_p), @@ -277,6 +280,8 @@ return self.no_tracks LIBMTP_Playlist._fields_ = [("playlist_id", ctypes.c_uint32), + ("parent_id", ctypes.c_uint32), + ("storage_id", ctypes.c_uint32), ("name", ctypes.c_char_p), ("tracks", ctypes.POINTER(ctypes.c_uint32)), ("no_tracks", ctypes.c_uint32), @@ -293,6 +298,7 @@ LIBMTP_Folder._fields_ = [("folder_id", ctypes.c_uint32), ("parent_id", ctypes.c_uint32), + ("storage_id", ctypes.c_uint32), ("name", ctypes.c_char_p), ("sibling", ctypes.POINTER(LIBMTP_Folder)), ("child", ctypes.POINTER(LIBMTP_Folder))] @@ -819,7 +825,7 @@ else: return LIBMTP_Filetype["UNKNOWN"] - def send_file_from_file(self, source, target, parent=0, callback=None): + def send_file_from_file(self, source, target, callback=None): """ Sends a file from the filesystem to the connected device and stores it at the target filename inside the parent. @@ -831,9 +837,6 @@ @param source: The path on the filesystem where the file resides @type target: str @param target: The target filename on the device - @type parent: int or 0 - @param parent: The parent directory for the file to go - into; If 0, the file goes into main directory @type callback: function or None @param callback: The function provided to libmtp to receive callbacks from ptp. Callback function must @@ -856,7 +859,7 @@ filesize=os.stat(source).st_size) ret = self.mtp.LIBMTP_Send_File_From_File(self.device, source, \ - ctypes.pointer(metadata), callback, None, parent) + ctypes.pointer(metadata), callback, None) if (ret != 0): self.debug_stack() @@ -864,7 +867,7 @@ return metadata.item_id - def send_track_from_file(self, source, target, metadata, parent=0, callback=None): + def send_track_from_file(self, source, target, metadata, callback=None): """ Sends a track from the filesystem to the connected device @@ -875,9 +878,6 @@ @param target: The target filename on the device @type metadata: LIBMTP_Track @param metadata: The track metadata - @type parent: int or 0 - @param parent: The parent directory for the track; - if 0, the track will be placed in the base dir. @type callback: function or None @param callback: The function provided to libmtp to receive callbacks from ptp. Callback function must @@ -896,12 +896,11 @@ callback = Progressfunc(callback) metadata.filename = target - metadata.parent_id = parent metadata.filetype = self.find_filetype(source) metadata.filesize = os.stat(source).st_size ret = self.mtp.LIBMTP_Send_Track_From_File(self.device, source, \ - ctypes.pointer(metadata), callback, None, parent) + ctypes.pointer(metadata), callback, None) if (ret != 0): self.debug_stack() @@ -1031,14 +1030,14 @@ if (self.device == None): raise NotConnected - ret = self.mtp.LIBMTP_Get_Playlist(self.device, playlist_id).contents - - if (ret != 0): + try: + ret = self.mtp.LIBMTP_Get_Playlist(self.device, playlist_id).contents + except ValueError: raise ObjectNotFound return ret - def create_new_playlist(self, metadata, parent=0): + def create_new_playlist(self, metadata): """ Creates a new playlist based on the metadata object passed. @@ -1046,8 +1045,6 @@ @type metadata: LIBMTP_Playlist @param metadata: A LIBMTP_Playlist object describing the playlist - @type parent: int or 0 - @param parent: The parent ID or 0 for base @rtype: int @return: The object ID of the new playlist """ @@ -1055,13 +1052,13 @@ if (self.device == None): raise NotConnected - ret = self.mtp.LIBMTP_Create_New_Playlist(self.device, ctypes.pointer(metadata), parent) + ret = self.mtp.LIBMTP_Create_New_Playlist(self.device, ctypes.pointer(metadata)) - if (ret == 0): + if (ret != 0): self.debug_stack() raise CommandFailed - return ret + return metadata.playlist_id def update_playlist(self, metadata): """ @@ -1173,7 +1170,7 @@ return ret - def create_folder(self, name, parent=0): + def create_folder(self, name, parent=0, storage=0): """ This creates a new folder in the parent. If the parent is 0, it will go in the main directory. @@ -1182,6 +1179,9 @@ @param name: The name for the folder @type parent: int @param parent: The parent ID or 0 for main directory + @type storage: int + @param storage: The storage id or 0 to create the new folder + on the primary storage @rtype: int @return: Returns the object ID of the new folder """ @@ -1189,7 +1189,7 @@ if (self.device == None): raise NotConnected - ret = self.mtp.LIBMTP_Create_Folder(self.device, name, parent) + ret = self.mtp.LIBMTP_Create_Folder(self.device, name, parent, storage) if (ret == 0): self.debug_stack() diff -u pymtp-0.0.4/debian/changelog pymtp-0.0.4/debian/changelog --- pymtp-0.0.4/debian/changelog +++ pymtp-0.0.4/debian/changelog @@ -1,3 +1,16 @@ +pymtp (0.0.4-1.1) unstable; urgency=low + + * Non-maintainer upload + * debian/control: Depends on libmtp8 + * pymtp.py: Adapt to libmtp8. Functions changed: + + MTP.send_file_from_file + + MTP.send_track_from_file + + MTP.create_new_playlist + + MTP.create_folder + * examples/send{file,track}.py: Adjust + + -- Rafael Laboissiere <raf...@debian.org> Sun, 29 Mar 2009 23:13:36 +0200 + pymtp (0.0.4-1) unstable; urgency=low * Initial release (Closes: #489547) diff -u pymtp-0.0.4/debian/control pymtp-0.0.4/debian/control --- pymtp-0.0.4/debian/control +++ pymtp-0.0.4/debian/control @@ -10,7 +10,7 @@ Package: python-pymtp Architecture: all -Depends: python, libmtp7, ${shlibs:Depends}, ${misc:Depends} +Depends: python, libmtp8, ${shlibs:Depends}, ${misc:Depends} Description: Pythonic binding to LibMTP to interact with MTP devices PyMTP is a Pythonic binding to LibMTP that allows Python programs to interact with LibMTP-supported devices. These devices include only in patch2: unchanged: --- pymtp-0.0.4.orig/pymtp.py +++ pymtp-0.0.4/pymtp.py @@ -167,6 +167,7 @@ LIBMTP_File._fields_ = [("item_id", ctypes.c_uint32), ("parent_id", ctypes.c_uint32), + ("storage_id", ctypes.c_uint32), ("filename", ctypes.c_char_p), ("filesize", ctypes.c_uint64), ("filetype", ctypes.c_int), @@ -183,8 +184,10 @@ LIBMTP_Track._fields_ = [("item_id", ctypes.c_uint32), ("parent_id", ctypes.c_uint32), + ("storage_id", ctypes.c_uint32), ("title", ctypes.c_char_p), ("artist", ctypes.c_char_p), + ("composer", ctypes.c_char_p), ("genre", ctypes.c_char_p), ("album", ctypes.c_char_p), ("date", ctypes.c_char_p), @@ -277,6 +280,8 @@ return self.no_tracks LIBMTP_Playlist._fields_ = [("playlist_id", ctypes.c_uint32), + ("parent_id", ctypes.c_uint32), + ("storage_id", ctypes.c_uint32), ("name", ctypes.c_char_p), ("tracks", ctypes.POINTER(ctypes.c_uint32)), ("no_tracks", ctypes.c_uint32), @@ -293,6 +298,7 @@ LIBMTP_Folder._fields_ = [("folder_id", ctypes.c_uint32), ("parent_id", ctypes.c_uint32), + ("storage_id", ctypes.c_uint32), ("name", ctypes.c_char_p), ("sibling", ctypes.POINTER(LIBMTP_Folder)), ("child", ctypes.POINTER(LIBMTP_Folder))] @@ -819,7 +825,7 @@ else: return LIBMTP_Filetype["UNKNOWN"] - def send_file_from_file(self, source, target, parent=0, callback=None): + def send_file_from_file(self, source, target, callback=None): """ Sends a file from the filesystem to the connected device and stores it at the target filename inside the parent. @@ -831,9 +837,6 @@ @param source: The path on the filesystem where the file resides @type target: str @param target: The target filename on the device - @type parent: int or 0 - @param parent: The parent directory for the file to go - into; If 0, the file goes into main directory @type callback: function or None @param callback: The function provided to libmtp to receive callbacks from ptp. Callback function must @@ -856,7 +859,7 @@ filesize=os.stat(source).st_size) ret = self.mtp.LIBMTP_Send_File_From_File(self.device, source, \ - ctypes.pointer(metadata), callback, None, parent) + ctypes.pointer(metadata), callback, None) if (ret != 0): self.debug_stack() @@ -864,7 +867,7 @@ return metadata.item_id - def send_track_from_file(self, source, target, metadata, parent=0, callback=None): + def send_track_from_file(self, source, target, metadata, callback=None): """ Sends a track from the filesystem to the connected device @@ -875,9 +878,6 @@ @param target: The target filename on the device @type metadata: LIBMTP_Track @param metadata: The track metadata - @type parent: int or 0 - @param parent: The parent directory for the track; - if 0, the track will be placed in the base dir. @type callback: function or None @param callback: The function provided to libmtp to receive callbacks from ptp. Callback function must @@ -896,12 +896,11 @@ callback = Progressfunc(callback) metadata.filename = target - metadata.parent_id = parent metadata.filetype = self.find_filetype(source) metadata.filesize = os.stat(source).st_size ret = self.mtp.LIBMTP_Send_Track_From_File(self.device, source, \ - ctypes.pointer(metadata), callback, None, parent) + ctypes.pointer(metadata), callback, None) if (ret != 0): self.debug_stack() @@ -1031,14 +1030,14 @@ if (self.device == None): raise NotConnected - ret = self.mtp.LIBMTP_Get_Playlist(self.device, playlist_id).contents - - if (ret != 0): + try: + ret = self.mtp.LIBMTP_Get_Playlist(self.device, playlist_id).contents + except ValueError: raise ObjectNotFound return ret - def create_new_playlist(self, metadata, parent=0): + def create_new_playlist(self, metadata): """ Creates a new playlist based on the metadata object passed. @@ -1046,8 +1045,6 @@ @type metadata: LIBMTP_Playlist @param metadata: A LIBMTP_Playlist object describing the playlist - @type parent: int or 0 - @param parent: The parent ID or 0 for base @rtype: int @return: The object ID of the new playlist """ @@ -1055,13 +1052,13 @@ if (self.device == None): raise NotConnected - ret = self.mtp.LIBMTP_Create_New_Playlist(self.device, ctypes.pointer(metadata), parent) + ret = self.mtp.LIBMTP_Create_New_Playlist(self.device, ctypes.pointer(metadata)) - if (ret == 0): + if (ret != 0): self.debug_stack() raise CommandFailed - return ret + return metadata.playlist_id def update_playlist(self, metadata): """ @@ -1173,7 +1170,7 @@ return ret - def create_folder(self, name, parent=0): + def create_folder(self, name, parent=0, storage=0): """ This creates a new folder in the parent. If the parent is 0, it will go in the main directory. @@ -1182,6 +1179,9 @@ @param name: The name for the folder @type parent: int @param parent: The parent ID or 0 for main directory + @type storage: int + @param storage: The storage id or 0 to create the new folder + on the primary storage @rtype: int @return: Returns the object ID of the new folder """ @@ -1189,7 +1189,7 @@ if (self.device == None): raise NotConnected - ret = self.mtp.LIBMTP_Create_Folder(self.device, name, parent) + ret = self.mtp.LIBMTP_Create_Folder(self.device, name, parent, storage) if (ret == 0): self.debug_stack() only in patch2: unchanged: --- pymtp-0.0.4.orig/examples/sendtrack.py +++ pymtp-0.0.4/examples/sendtrack.py @@ -9,7 +9,7 @@ sys.path.insert(0, "../") import pymtp -import pyid3lib +from ID3 import * def usage(): print "Usage: %s <source> <target> <parent>\n(The parent id can be 0 for the root directory)" % (sys.argv[0]) @@ -26,20 +26,19 @@ target = sys.argv[2] parent = int(sys.argv[3]) - id3data = pyid3lib.tag(source) + id3data = ID3(source) - metadata = pymtp.LIBMTP_Track() + metadata = pymtp.LIBMTP_Track() + metadata.parent_id = parent; - if (hasattr(id3data, 'artist')): + if (hasattr(id3data, 'artist')): metadata.artist = id3data.artist if (hasattr(id3data, 'title')): metadata.title = id3data.title if (hasattr(id3data, 'album')): metadata.album = id3data.album - if (hasattr(id3data, 'tracknum')): - metadata.tracknumber = id3data.tracknum - - track_id = mtp.send_track_from_file(source, target, metadata, parent=parent) + + track_id = mtp.send_track_from_file(source, target, metadata) print "Created new track with ID: %s" % (track_id) mtp.disconnect() only in patch2: unchanged: --- pymtp-0.0.4.orig/examples/sendfile.py +++ pymtp-0.0.4/examples/sendfile.py @@ -12,7 +12,7 @@ import pyid3lib def usage(): - print "Usage: %s <source> <target> <parent>\n(The parent id can be 0 for the root directory)" % (sys.argv[0]) + print "Usage: %s <source> <target>" % (sys.argv[0]) def main(): if len(sys.argv) <= 3: @@ -24,9 +24,8 @@ source = sys.argv[1] target = sys.argv[2] - parent = int(sys.argv[3]) - file_id = mtp.send_file_from_file(source, target, parent=parent) + file_id = mtp.send_file_from_file(source, target) print "Created new track with ID: %s" % (file_id) mtp.disconnect()