Hello Everyone,
I am working on a plugin that will organize my ebook files links like how calibre would do it which is to rename the ebook file to the same name as the entry plus the author name and then move it and the cover image into a folder under the main library folder. I have run into two case snags in the code:
1. When the link is moved using the UI move button, when I use link valueForKey:@"url" the URL is [DATA Folder]/rest_of_path. How do I get the full expanded URL, or the path to the data folder.
2. Is there a way once images are moved to update that in the database?
That should cover it for now. Thanks for the help.
Plugin development API questions
Re: Plugin development API questions
Sorry about the delay over the weekend to get to your two question.
1. Use the following method in your code to update the folder path, you can run it for ever URL so that it's automatically fixed if necessary.
To avoid warnings add the following to the header file for MyControllerForPlugins
2. The program always uses the covers located inside the data folder to display in the main image location. I would create a copy of the cover for the folder of the ebook and leave the original cover in "Covers/uid.jpg". You could also write a check as part of your plug-in that if the covers in these two location differ (modification date or size) then one or the other would be updated automatically depending if you would prefer Bookpedia to update the cover of the ebook or the ebook to update Bookpedia.
1. Use the following method in your code to update the folder path, you can run it for ever URL so that it's automatically fixed if necessary.
Code: Select all
- (NSMutableString *)fixLinkedFiledPath:(NSString *)aPath {
NSMutableString *fixedPathOfFile = [NSMutableString stringWithString:aPath];
NSString *dataFolderPath = [[NSApp delegate] dataFolderPath];
[fixedPathOfFile replaceOccurrencesOfString:@"[Data Folder]" withString:dataFolderPath options:NSLiteralSearch range:NSMakeRange(0,[fixedPathOfFile length])];
}
...
NSString *pathURL = [self fixLinkedFiledPath:[link valueForKey:@"url"]]; //Somewhere in your code
Code: Select all
@interface MyControllerForPlugins : NSObject
- (NSString *)dataFolderPath;
@end
Re: Plugin development API questions
Thank you very much for the reply works like a charm.
Re: Plugin development API questions
OK another question,
Is there a way to programmatically issue the move command found under the links menu? Thanks.
Is there a way to programmatically issue the move command found under the links menu? Thanks.
Re: Plugin development API questions
The move method is tied to the selection in the link table view so it's not as modular that you would be able to use it directly from the plugin for any arbitrary link. Luckily the code for moving a link is not too long. Here is a version with the irrelevant code stripped out that should work directly in your plugin (most of it is written directly here in the forum, so it might need some tweaking after copy/pasting and getting a few Xcode errors).
Code: Select all
[self moveToDownloadFolderWithName:nil link:aLink];
- (void)moveToDownloadFolderWithName:(NSString *)aName link(NSManagedEntry *)aLink {
NSFileManager *manager = [NSFileManager defaultManager];
NSString *directory = [NSString stringWithFormat:@"%@/Downloads", [[NSApp delegate] dataFolderPath]];
if (![manager fileExistsAtPath:directory]) {
NSError *anError = nil;
if (![manager createDirectoryAtPath:directory withIntermediateDirectories:YES attributes:nil error:&anError])
MyLog(@"Error creating downloads directory at: %@\nError: %@", directory, anError);
}
NSString *sourcePath = [aLink valueForKey:@"url"];
// Here you might want to check the link is not already in the data folder (has [Data Folder] prefix) or needs to be normalized, like removing the "file://" from the beginning done below.
if ([sourcePath rangeOfString:@"file://" options:NSCaseInsensitiveSearch | NSAnchoredSearch].location != NSNotFound])
sourcePath = [sourcePath substringFromIndex:6];
if (!aName)
aName = [aPath lastPathComponent];
directory = [NSString stringWithFormat:@"%@/%@", directory, aName];
if (![manager fileExistsAtPath:directory]) {
NSError *anError;
if ([manager moveItemAtPath:sourcePath toPath:directory error:&anError]) {
NSString *directory = [NSString stringWithFormat:@"[Data Folder]/Downloads/%@", aName];
//[aLink setValue:directory forKey:@"url"]; // You can choose to not add the [Data Folder] and leave the full path, less flexible
NSString *withDataFolder = [NSString stringWithFormat:@"[Data Folder]/Downloads/%@", aName];
[aLink setValue:withDataFolder forKey:@"url"];
}
else {
MyLog(@"Error moving %@ into downloads folder %@\n%@", sourcePath, directory, anError);
}
}
else {
//A file with the same name exists, ask for a new name from the user or make up a name by adding a number
NSString *fileExtension = [directory pathExtension];
NSSavePanel *savePanel = [NSSavePanel savePanel];
[savePanel setCanCreateDirectories:NO];
[savePanel setAllowedFileTypes:[NSArray arrayWithObject:fileExtension]];
[savePanel setPrompt:@"Move"];
[savePanel setDirectory:[directory stringByDeletingLastPathComponent]];
[savePanel setDelegate:self];
[savePanel setTitle:@"Choose a new name"];
[savePanel setMessage:@"A file by that name already exists in the downloads folder."];
if ([savePanel runModalForDirectory:[directory stringByDeletingLastPathComponent] file:[directory lastPathComponent]] == NSOKButton) {
NSString *newName = [[savePanel filename] lastPathComponent];
[self moveToDownloadFolderWithName:newName link:aLink];
}
}
}
Re: Plugin development API questions
Thanks again for your help, very much appreciated.