After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 593641 - Folder support for MTP-Devices
Folder support for MTP-Devices
Status: RESOLVED FIXED
Product: rhythmbox
Classification: Other
Component: Plugins (other)
HEAD
Other Linux
: Normal enhancement
: ---
Assigned To: RhythmBox Maintainers
RhythmBox Maintainers
: 527840 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2009-08-31 09:49 UTC by Karl-Heinz Schneider
Modified: 2010-06-16 07:54 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Folder support for MTP-Devices (7.19 KB, patch)
2009-08-31 09:49 UTC, Karl-Heinz Schneider
needs-work Details | Review
Version 2 of the patch (13.92 KB, patch)
2009-09-17 20:30 UTC, Karl-Heinz Schneider
none Details | Review

Description Karl-Heinz Schneider 2009-08-31 09:49:16 UTC
Created attachment 142113 [details] [review]
Folder support for MTP-Devices

I have added support for folders for the plugin mtpdevices.
1. It adds a folder for artist and album like this:
<music-folder>/<artist>/<album>.
2. If rhythmbox deletes files it checks if the folders are empty to
delete them as well.
Comment 1 Jonathan Matthew 2009-09-01 11:59:43 UTC
*** Bug 527840 has been marked as a duplicate of this bug. ***
Comment 2 Jonathan Matthew 2009-09-01 12:42:34 UTC
In general the approach looks good, but I have a few problems with how it's implemented.

@@ -292,7 +298,7 @@ rb_mtp_source_constructor (GType type, guint n_construct_properties,
 
 	g_signal_connect (G_OBJECT (source), "notify::name",
 			  (GCallback)rb_mtp_source_name_changed_cb, NULL);
-	
+
 	/* figure out supported file types */
 	if (LIBMTP_Get_Supported_Filetypes(priv->device, &types, &num_types) == 0) {
 		int i;


please don't include whitespace-only changes.

+/**
+ * Deletes a folder on the device if the folder is empty.
+ * Returns TRUE if successful otherwise FALSE
+ */
+
+static gboolean
+remove_folder_if_empty (LIBMTP_mtpdevice_t * device, guint32 folder_id) {

We don't generate API documentation for plugins, and static functions don't get included in API documentation anyway, so this shouldn't be a gtkdoc comment.
Also, the opening brace for function bodies goes on a new line, and pointer parameters should look like 'type *name', not 'type * name'.

+	// Don't delete default folders

No C++-style comments, please

+		rb_debug ("Didn'd delete default folder %i", folder_id);

"didn't" is misspelled here and in a few other places

+	file_list = LIBMTP_Get_Filelisting_With_Callback (device,NULL,NULL);

I really don't like the idea of fetching a full file list every time a track is deleted.  This is slow and it blocks the UI.  Doesn't the device itself stop you deleting folders if they're not empty?  At the very least, this should only be done if after check for subfolders.

+	// get folder list
+	folders = LIBMTP_Get_Folder_List (device);
+
+	// locate default music folder
+	if (device->default_music_folder > 0) {
+		music_folder = LIBMTP_Find_Folder(folders, device->default_music_folder);
+	}

These comments are useless, they don't add any useful information.

+	// search artist folder
+	folder_id = find_folder_by_name (music_folder->child, trackmeta->artist);
+	if (folder_id == 0) {
+		folder_id = LIBMTP_Create_Folder(device, trackmeta->artist,
+										device->default_music_folder,
+										trackmeta->storage_id);
+
+		rb_debug ("Artist folder %s with id %i created", trackmeta->artist, folder_id);
+
+		folder_id = LIBMTP_Create_Folder(device,
+							trackmeta->album,
+							folder_id,
+							trackmeta->storage_id);
+
+		rb_debug ("Album folder %s with id %i created", trackmeta->album, folder_id);
+
+		trackmeta->parent_id = folder_id;
+		ret = TRUE;

What should happen here when the first LIBMTP_Create_Folder() fails?
Also, it looks like you're formatting for 4-space tabs; we use 8.
Comment 3 Karl-Heinz Schneider 2009-09-01 16:18:46 UTC
Thank you for responding.

At first I'm sorry for not following the coding guidlines and my bad english at all.

Second: I think it makes no difference to the performance if you fetch every time a complete list of files or folders. That are commands running just under a second. The bigger deal is, this plugin is in this state unusable, in my opinion. If you try to put some GB of music to your device at once, rhythmbox has a bocked UI for hours (in my case). And at longer therm I want to remove that issue. But I wanted to become more familiar with the code and gObject at all. That's new for me, I'm used to program plain C or C++...
But I think you are right, this information should be hold in an internal structure.

Third comments: I think nearly every comment is use full. Especially at the top of functions. I didn't know that this is one was a API-doc comment. But look to the code, I see more than thousand lines, but very few comments wish explain whats going on...

Anyway I will work this code over when I find time. Rhythmbox is a very good player and I want help to make it a better peace of software :-)

Out of the libmtp doku:

	
int LIBMTP_Delete_Object 	( 	LIBMTP_mtpdevice_t *  	device,
		uint32_t  	object_id	 
	) 			

This function deletes a single file, track, playlist, folder or any other object off the MTP device, identified by the object ID.

If you delete a folder, there is no guarantee that the device will really delete all the files that were in that folder, rather it is expected that they will not be deleted, and will turn up in object listings with parent set to a non-existant object ID. The safe way to do this is to recursively delete all files (and folders) contained in the folder, then the folder itself.
Comment 4 Jonathan Matthew 2009-09-06 07:22:17 UTC
(In reply to comment #3)
> Thank you for responding.
> 
> At first I'm sorry for not following the coding guidlines and my bad english at
> all.
> 
> Second: I think it makes no difference to the performance if you fetch every
> time a complete list of files or folders. That are commands running just under
> a second. 

Blocking the UI for 'just under a second' is not OK.  Adding extra steps that take just under a second per track isn't good either.

> The bigger deal is, this plugin is in this state unusable, in my
> opinion. If you try to put some GB of music to your device at once, rhythmbox
> has a bocked UI for hours (in my case).

I'm actually mostly done with fixing this.  Anyway, the existence of this issue doesn't make it OK to make it worse.

> 
> Third comments: I think nearly every comment is use full. Especially at the top
> of functions. I didn't know that this is one was a API-doc comment. But look to
> the code, I see more than thousand lines, but very few comments wish explain
> whats going on...

I was specifically talking about comments like "// get folder list" above a call to LIBMTP_Get_Folder_List().  That comment doesn't add any words that aren't already in the code, and if you're looking for comments that explain important issues, it only gets in your way.

You're right that the existing code could do with more comments, but overcommenting new code doesn't fix that.

> Anyway I will work this code over when I find time. Rhythmbox is a very good
> player and I want help to make it a better peace of software :-)
> 
> Out of the libmtp doku:
> 
> 
> int LIBMTP_Delete_Object     (     LIBMTP_mtpdevice_t *      device,
>         uint32_t      object_id     
>     )             
> 
> This function deletes a single file, track, playlist, folder or any other
> object off the MTP device, identified by the object ID.
> 
> If you delete a folder, there is no guarantee that the device will really
> delete all the files that were in that folder, rather it is expected that they
> will not be deleted, and will turn up in object listings with parent set to a
> non-existant object ID. The safe way to do this is to recursively delete all
> files (and folders) contained in the folder, then the folder itself.

OK, it sounds like we do need to check that a folder is empty before trying to remove it.

Perhaps rather than checking each folder as we delete each file, we should use a timeout to do the check after some delay, so if you delete multiple tracks from the same folder we only check once.  It'd probably be a good idea to scan for empty folders on newly added devices, too.
Comment 5 Karl-Heinz Schneider 2009-09-17 20:30:37 UTC
Created attachment 143402 [details] [review]
Version 2 of the patch

The reworked version of the last patch.

I hope it meets all requirements.
Comment 6 Jonathan Matthew 2010-06-16 07:54:01 UTC
This patch didn't work with the thread model used in the MTP plugin.

Commits 8681fbf through c8a2377 implement folder support for MTP devices.