Support subdirectories in GetDirectoryContentsAsync()/FolderContentsResponse
First of all, thanks for the great library!
I'm a bit lost and I couldn't find what I was looking for in the example apps, so I'll ask here. How does one get the contents of a directory so that the paths of the files include the subdirectory they're in? When I run
var dir = await client.GetDirectoryContentsAsync(user, folder);
var filepaths = dir.Files.Select(x => x.Filename);
then filepaths contains the names of the files without their full paths. This is fine if they're all direct children of folder, but if they're in a subdirectory inside the folder, I'm unable to get the full path and therefore I can't download it. I'm probably missing something simple?
I chatted with @mathiascode about this and realized that this is probably an issue with the library.
The behavior of the Soulseek QT and Nicotine+ clients, as well as slskd, is to return only the files in the root of the requested directory (so, no traversal of subdirectories). This means that a response from these clients will only ever contain 1 directory. Soulseek.NET was written as if this would always be the case.
The Soulseek NS client does include subdirectories, and in that case Soulseek.NET is incompatible with those responses because it always assumes 1 directory.
Fixing this would require some adjustments to the FolderContentsResponse class and associated tests, and it would be a breaking change to the GetDirectoryContentsAsync method, as it will need to return a shape that supports multiple directories.
This is kind of a moot point because only Soulseek NS will support it, but I'm interested in supporting it in slskd so I'll probably make the necessary changes.
Thanks for raising this!
The behavior of the Soulseek QT and Nicotine+ clients, as well as slskd, is to return only the files in the root of the requested directory
This is kind of a moot point because only Soulseek NS will support it
I'm not sure I understand it correctly. Does this mean that there will be no way in general of retrieving all directory contents recursively so that I can download all of it (by calling this method one or multiple times)?
What I'm currently doing is browsing all user shares and then filtering them to include only the ones starting with that directory, but I'm sure GetDirectoryContentsAsync is a lot more efficient.
Right, you might get this method to work for some clients but not all, and therefore it wouldn't be a good approach.
Since you've already downloaded the browse response you'll have all of the necessary information on hand already. GetDirectoryContentsAsync() and the underlying protocol messages were, I'm 99% sure, introduced so that users could selectively expand search results, to support the download dialog that is present in the official clients.
Another way to approach this would be to perform a search of the target user's shares and include the root directory. This should return the recursive list, but may also return other unrelated files that overlap the search query. I you could overcome this by throwing out paths that aren't rooted in the search term, though.