diff --git a/Playlist/PlaylistLoader.m b/Playlist/PlaylistLoader.m index 130f55846..cd47294f4 100644 --- a/Playlist/PlaylistLoader.m +++ b/Playlist/PlaylistLoader.m @@ -441,6 +441,8 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc // Make sure the container isn't added twice. [uniqueURLs addObject:url]; + + [[SandboxBroker sharedSandboxBroker] requestFolderForFile:url]; } else { /* Fall back on adding the raw file if all container parsers have failed. */ [fileURLs addObject:url]; diff --git a/Utils/SandboxBroker.h b/Utils/SandboxBroker.h index d46bfb419..08470d517 100644 --- a/Utils/SandboxBroker.h +++ b/Utils/SandboxBroker.h @@ -24,6 +24,8 @@ NS_ASSUME_NONNULL_BEGIN - (void)addFolderIfMissing:(NSURL *)folderUrl; - (void)addFileIfMissing:(NSURL *)fileUrl; +- (void)requestFolderForFile:(NSURL *)fileUrl; + - (const void *)beginFolderAccess:(NSURL *)fileUrl; - (void)endFolderAccess:(const void *)handle; diff --git a/Utils/SandboxBroker.m b/Utils/SandboxBroker.m index fa72692d4..928d8afb2 100644 --- a/Utils/SandboxBroker.m +++ b/Utils/SandboxBroker.m @@ -304,6 +304,57 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc } } +- (void)requestFolderForFile:(NSURL *)fileUrl { + if(![fileUrl isFileURL]) return; + NSURL *folderUrl = [fileUrl URLByDeletingLastPathComponent]; + + @synchronized(self) { + SandboxEntry *_entry = nil; + + for(SandboxEntry *entry in storage) { + if(entry.path && entry.isFolder && [SandboxBroker isPath:folderUrl aSubdirectoryOf:[NSURL fileURLWithPath:entry.path]]) { + _entry = entry; + break; + } + } + + if(!_entry) { + _entry = [self recursivePathTest:folderUrl]; + } + + if(!_entry) { + dispatch_sync_reentrant(dispatch_get_main_queue(), ^{ + NSOpenPanel *panel = [NSOpenPanel openPanel]; + [panel setAllowsMultipleSelection:NO]; + [panel setCanChooseDirectories:YES]; + [panel setCanChooseFiles:NO]; + [panel setFloatingPanel:YES]; + [panel setDirectoryURL:folderUrl]; + [panel setTitle:@"Open to grant access to container folder"]; + NSInteger result = [panel runModal]; + if(result == NSModalResponseOK) { + NSURL *folderUrl = [panel URL]; + NSError *err = nil; + NSData *bookmark = [folderUrl bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope includingResourceValuesForKeys:nil relativeToURL:nil error:&err]; + if(!bookmark && err) { + ALog(@"Failed to add bookmark for URL: %@, with error: %@", folderUrl, [err localizedDescription]); + return; + } + + NSPersistentContainer *pc = [NSClassFromString(@"PlaylistController") sharedPersistentContainer]; + + SandboxToken *token = [NSEntityDescription insertNewObjectForEntityForName:@"SandboxToken" inManagedObjectContext:pc.viewContext]; + + if(token) { + token.path = [folderUrl path]; + token.bookmark = bookmark; + } + } + }); + } + } +} + - (const void *)beginFolderAccess:(NSURL *)fileUrl { NSURL *folderUrl = [SandboxBroker urlWithoutFragment:fileUrl]; if(![folderUrl isFileURL]) return NULL;