[Sandbox Paths] Automatically clean up old paths

Clean up redundant paths automatically, and on startup. Also refresh the
preferences dialog path list every time it is opened.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
main
Christopher Snowhill 2022-07-24 23:14:52 -07:00
parent 7e06aef932
commit 77b3d74948
9 changed files with 68 additions and 0 deletions

View File

@ -206,6 +206,7 @@ static AppController *kAppController = nil;
if(!sandboxBroker) {
ALog(@"Sandbox broker init failed.");
}
[SandboxBroker cleanupFolderAccess];
[[playlistController undoManager] enableUndoRegistration];

View File

@ -18,6 +18,7 @@
@property(readonly) NSImage *icon;
@optional
- (IBAction)refreshPathList:(id)sender;
- (IBAction)showPathSuggester:(id)sender;
@end

View File

@ -21,6 +21,7 @@ NS_ASSUME_NONNULL_BEGIN
- (IBAction)deleteSelectedPaths:(id)sender;
- (IBAction)removeStaleEntries:(id)sender;
- (IBAction)showPathSuggester:(id)sender;
- (IBAction)refreshPathList:(id)sender;
@end

View File

@ -105,4 +105,8 @@
[pathSuggester beginSuggestion:sender];
}
- (IBAction)refreshPathList:(id)sender {
[sandboxPathBehaviorController refresh];
}
@end

View File

@ -11,6 +11,8 @@ NS_ASSUME_NONNULL_BEGIN
@interface SandboxPathBehaviorController : NSArrayController
- (void)refresh;
- (void)addUrl:(NSURL *)url;
- (void)removeToken:(id)token;
- (void)removeStaleEntries;

View File

@ -27,6 +27,10 @@
@implementation SandboxPathBehaviorController
- (void)awakeFromNib {
[self refresh];
}
- (void)refresh {
[self removeObjects:[self arrangedObjects]];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"path" ascending:YES];
@ -77,6 +81,8 @@
ALog(@"Error saving bookmark: %@", [err localizedDescription]);
} else {
[self addObject:@{ @"path": [url path], @"valid": NSLocalizedPrefString(@"ValidYes"), @"isFolder": @(token.folder), @"token": token }];
[NSClassFromString(@"SandboxBroker") cleanupFolderAccess];
[self refresh];
}
}
}

View File

@ -89,6 +89,9 @@
}
[self setContentView:paneView animate:display];
if([paneController respondsToSelector:@selector(refreshPathList:)]) {
[paneController refreshPathList:self];
}
// Update defaults
[[NSUserDefaults standardUserDefaults] setObject:name forKey:[self lastPaneDefaultsKey]];

View File

@ -18,6 +18,8 @@ NS_ASSUME_NONNULL_BEGIN
+ (NSURL *)urlWithoutFragment:(NSURL *)url;
+ (BOOL)isPath:(NSURL *)path aSubdirectoryOf:(NSURL *)directory;
+ (void)cleanupFolderAccess;
- (id)init;
- (void)shutdown;

View File

@ -258,6 +258,7 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
if(token) {
token.path = [folderUrl path];
token.bookmark = bookmark;
[SandboxBroker cleanupFolderAccess];
}
});
}
@ -373,6 +374,7 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
if(token) {
token.path = [folderUrl path];
token.bookmark = bookmark;
[SandboxBroker cleanupFolderAccess];
}
}
});
@ -380,6 +382,52 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
}
}
+ (void)cleanupFolderAccess {
NSLock *lock = [SandboxBroker sharedPersistentContainerLock];
NSPersistentContainer *pc = [SandboxBroker sharedPersistentContainer];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"path.length" ascending:YES];
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"SandboxToken"];
request.sortDescriptors = @[sortDescriptor];
NSError *error = nil;
[lock lock];
NSArray *results = [pc.viewContext executeFetchRequest:request error:&error];
[lock unlock];
BOOL isUpdated = NO;
if(results && [results count]) {
NSMutableArray *resultsCopy = [results mutableCopy];
for(NSUInteger i = 0; i < [resultsCopy count] - 1; ++i) {
SandboxToken *token = resultsCopy[i];
NSURL *url = [NSURL fileURLWithPath:token.path];
for(NSUInteger j = i + 1; j < [resultsCopy count];) {
SandboxToken *compareToken = resultsCopy[j];
if([SandboxBroker isPath:[NSURL fileURLWithPath:compareToken.path] aSubdirectoryOf:url]) {
[lock lock];
[pc.viewContext deleteObject:compareToken];
[lock unlock];
isUpdated = YES;
[resultsCopy removeObjectAtIndex:j];
} else {
++j;
}
}
}
}
if(isUpdated) {
NSError *error;
[lock lock];
[pc.viewContext save:&error];
[lock unlock];
if(error) {
ALog(@"Error saving data: %@", [error localizedDescription]);
}
}
}
- (const void *)beginFolderAccess:(NSURL *)fileUrl {
NSURL *folderUrl = [SandboxBroker urlWithoutFragment:fileUrl];
if(![folderUrl isFileURL]) return NULL;