summaryrefslogtreecommitdiff
path: root/Providers/QSLinkdingProvider.m
diff options
context:
space:
mode:
authorRuben Beltran del Rio <git@r.bdr.sh>2025-09-08 21:49:49 +0200
committerRuben Beltran del Rio <git@r.bdr.sh>2025-09-08 21:49:49 +0200
commit2d247ab64b84cf80d1beedb9521d7488bcb99f18 (patch)
tree6cfb3ec812446133d439a19a0fa07939f4d16648 /Providers/QSLinkdingProvider.m
parent848982f156a86038438918e3a51cc0f04be9c78c (diff)
Apply formatting
Diffstat (limited to 'Providers/QSLinkdingProvider.m')
-rw-r--r--Providers/QSLinkdingProvider.m348
1 files changed, 200 insertions, 148 deletions
diff --git a/Providers/QSLinkdingProvider.m b/Providers/QSLinkdingProvider.m
index c7bf33f..378ae6f 100644
--- a/Providers/QSLinkdingProvider.m
+++ b/Providers/QSLinkdingProvider.m
@@ -4,178 +4,230 @@
//
#import "QSLinkdingProvider.h"
-#import "SocialSite.h"
#import "Constants.h"
+#import "SocialSite.h"
#import <QSCore/QSCore.h>
@implementation QSLinkdingProvider
-- (BOOL)canHandleSite:(SocialSite)site username:(NSString *)username password:(NSString *)password host:(NSString *)host {
- return (site == SocialSiteLinkding) &&
- username.length > 0 &&
- password.length > 0 && // password is API token for Linkding
- host.length > 0;
+- (BOOL)canHandleSite:(SocialSite)site
+ username:(NSString *)username
+ password:(NSString *)password
+ host:(NSString *)host {
+ return (site == SocialSiteLinkding) && username.length > 0 &&
+ password.length > 0 && // password is API token for Linkding
+ host.length > 0;
}
-- (NSData *)cachedBookmarkDataForHost:(NSString *)host username:(NSString *)username {
- // Create a safe filename from host
- NSString *safeHost = [[host componentsSeparatedByCharactersInSet:[[NSCharacterSet alphanumericCharacterSet] invertedSet]] componentsJoinedByString:@"-"];
- NSString *cachePath = [QSApplicationSupportSubPath([NSString stringWithFormat:@"Caches/linkding/"], NO) stringByAppendingPathComponent:[NSString stringWithFormat:@"%@-%@.json", safeHost, username]];
- return [NSData dataWithContentsOfFile:cachePath];
+- (NSData *)cachedBookmarkDataForHost:(NSString *)host
+ username:(NSString *)username {
+ // Create a safe filename from host
+ NSString *safeHost =
+ [[host componentsSeparatedByCharactersInSet:[[NSCharacterSet
+ alphanumericCharacterSet]
+ invertedSet]]
+ componentsJoinedByString:@"-"];
+ NSString *cachePath = [QSApplicationSupportSubPath(
+ [NSString stringWithFormat:@"Caches/linkding/"], NO)
+ stringByAppendingPathComponent:[NSString stringWithFormat:@"%@-%@.json",
+ safeHost,
+ username]];
+ return [NSData dataWithContentsOfFile:cachePath];
}
-- (void)cacheBookmarkData:(NSData *)data forHost:(NSString *)host username:(NSString *)username {
- // Create a safe filename from host
- NSString *safeHost = [[host componentsSeparatedByCharactersInSet:[[NSCharacterSet alphanumericCharacterSet] invertedSet]] componentsJoinedByString:@"-"];
- NSString *cachePath = [QSApplicationSupportSubPath([NSString stringWithFormat:@"Caches/linkding/"], YES) stringByAppendingPathComponent:[NSString stringWithFormat:@"%@-%@.json", safeHost, username]];
- [data writeToFile:cachePath atomically:NO];
+- (void)cacheBookmarkData:(NSData *)data
+ forHost:(NSString *)host
+ username:(NSString *)username {
+ // Create a safe filename from host
+ NSString *safeHost =
+ [[host componentsSeparatedByCharactersInSet:[[NSCharacterSet
+ alphanumericCharacterSet]
+ invertedSet]]
+ componentsJoinedByString:@"-"];
+ NSString *cachePath = [QSApplicationSupportSubPath(
+ [NSString stringWithFormat:@"Caches/linkding/"], YES)
+ stringByAppendingPathComponent:[NSString stringWithFormat:@"%@-%@.json",
+ safeHost,
+ username]];
+ [data writeToFile:cachePath atomically:NO];
}
-- (NSArray *)fetchBookmarksForSite:(SocialSite)site username:(NSString *)username password:(NSString *)password identifier:(NSString *)identifier host:(NSString *)host includeTags:(BOOL)includeTags {
-
- if (![self canHandleSite:site username:username password:password host:host]) {
- return @[];
+- (NSArray *)fetchBookmarksForSite:(SocialSite)site
+ username:(NSString *)username
+ password:(NSString *)password
+ identifier:(NSString *)identifier
+ host:(NSString *)host
+ includeTags:(BOOL)includeTags {
+
+ if (![self canHandleSite:site
+ username:username
+ password:password
+ host:host]) {
+ return @[];
+ }
+
+ // Try cached data first
+ NSData *data = [self cachedBookmarkDataForHost:host username:username];
+
+ // If no cached data, fetch from API
+ if (![data length]) {
+ // Construct Linkding API URL
+ NSString *baseURL = host;
+ if (![baseURL hasPrefix:@"http://"] && ![baseURL hasPrefix:@"https://"]) {
+ baseURL = [NSString stringWithFormat:@"https://%@", baseURL];
}
-
- // Try cached data first
- NSData *data = [self cachedBookmarkDataForHost:host username:username];
-
- // If no cached data, fetch from API
- if (![data length]) {
- // Construct Linkding API URL
- NSString *baseURL = host;
- if (![baseURL hasPrefix:@"http://"] && ![baseURL hasPrefix:@"https://"]) {
- baseURL = [NSString stringWithFormat:@"https://%@", baseURL];
- }
- if ([baseURL hasSuffix:@"/"]) {
- baseURL = [baseURL substringToIndex:[baseURL length] - 1];
- }
-
- NSString *urlString = [NSString stringWithFormat:@"%@/api/bookmarks/", baseURL];
- NSURL *requestURL = [NSURL URLWithString:urlString];
-
- if (!requestURL) {
- NSLog(@"Invalid Linkding host URL: %@", host);
- return @[];
- }
-
- NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:requestURL
- cachePolicy:NSURLRequestUseProtocolCachePolicy
- timeoutInterval:60.0];
- [theRequest setHTTPMethod:@"GET"];
- [theRequest setValue:@"application/json" forHTTPHeaderField:@"Accept"];
- [theRequest setValue:[NSString stringWithFormat:@"Token %@", password] forHTTPHeaderField:@"Authorization"];
- [theRequest setValue:@"Quicksilver (Blacktree,MacOSX)" forHTTPHeaderField:@"User-Agent"];
-
- NSError *error = nil;
- data = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:nil error:&error];
-
- if (error) {
- NSLog(@"Error fetching Linkding bookmarks: %@", error.localizedDescription);
- return @[];
- }
-
- // Cache the data
- [self cacheBookmarkData:data forHost:host username:username];
+ if ([baseURL hasSuffix:@"/"]) {
+ baseURL = [baseURL substringToIndex:[baseURL length] - 1];
}
-
- // Parse JSON data
- NSError *jsonError = nil;
- NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];
-
- if (jsonError) {
- NSLog(@"Error parsing Linkding JSON: %@", jsonError.localizedDescription);
- return @[];
+
+ NSString *urlString =
+ [NSString stringWithFormat:@"%@/api/bookmarks/", baseURL];
+ NSURL *requestURL = [NSURL URLWithString:urlString];
+
+ if (!requestURL) {
+ NSLog(@"Invalid Linkding host URL: %@", host);
+ return @[];
}
-
- NSArray *results = [jsonResponse objectForKey:@"results"];
- if (!results || ![results isKindOfClass:[NSArray class]]) {
- NSLog(@"Invalid Linkding response format");
- return @[];
+
+ NSMutableURLRequest *theRequest =
+ [NSMutableURLRequest requestWithURL:requestURL
+ cachePolicy:NSURLRequestUseProtocolCachePolicy
+ timeoutInterval:60.0];
+ [theRequest setHTTPMethod:@"GET"];
+ [theRequest setValue:@"application/json" forHTTPHeaderField:@"Accept"];
+ [theRequest setValue:[NSString stringWithFormat:@"Token %@", password]
+ forHTTPHeaderField:@"Authorization"];
+ [theRequest setValue:@"Quicksilver (Blacktree,MacOSX)"
+ forHTTPHeaderField:@"User-Agent"];
+
+ NSError *error = nil;
+ data = [NSURLConnection sendSynchronousRequest:theRequest
+ returningResponse:nil
+ error:&error];
+
+ if (error) {
+ NSLog(@"Error fetching Linkding bookmarks: %@",
+ error.localizedDescription);
+ return @[];
}
-
- NSMutableArray *objects = [NSMutableArray arrayWithCapacity:1];
- NSMutableSet *tagSet = [NSMutableSet set];
-
- // Create bookmark objects
- for (NSDictionary *bookmark in results) {
- QSObject *newObject = [self objectForLinkdingBookmark:bookmark];
- if (newObject) {
- [objects addObject:newObject];
-
- // Collect tags if requested
- if (includeTags) {
- NSArray *tags = [bookmark objectForKey:@"tag_names"];
- if (tags && [tags isKindOfClass:[NSArray class]]) {
- [tagSet addObjectsFromArray:tags];
- }
- }
+
+ // Cache the data
+ [self cacheBookmarkData:data forHost:host username:username];
+ }
+
+ // Parse JSON data
+ NSError *jsonError = nil;
+ NSDictionary *jsonResponse =
+ [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];
+
+ if (jsonError) {
+ NSLog(@"Error parsing Linkding JSON: %@", jsonError.localizedDescription);
+ return @[];
+ }
+
+ NSArray *results = [jsonResponse objectForKey:@"results"];
+ if (!results || ![results isKindOfClass:[NSArray class]]) {
+ NSLog(@"Invalid Linkding response format");
+ return @[];
+ }
+
+ NSMutableArray *objects = [NSMutableArray arrayWithCapacity:1];
+ NSMutableSet *tagSet = [NSMutableSet set];
+
+ // Create bookmark objects
+ for (NSDictionary *bookmark in results) {
+ QSObject *newObject = [self objectForLinkdingBookmark:bookmark];
+ if (newObject) {
+ [objects addObject:newObject];
+
+ // Collect tags if requested
+ if (includeTags) {
+ NSArray *tags = [bookmark objectForKey:@"tag_names"];
+ if (tags && [tags isKindOfClass:[NSArray class]]) {
+ [tagSet addObjectsFromArray:tags];
}
+ }
}
-
- // Create tag objects if requested
- if (includeTags) {
- for (NSString *tag in tagSet) {
- if (tag.length > 0) {
- QSObject *tagObject = [QSObject makeObjectWithIdentifier:[NSString stringWithFormat:@"[Linkding tag]:%@", tag]];
- [tagObject setObject:tag forType:kTagType];
- [tagObject setObject:@(site) forMeta:kTagSiteField];
- [tagObject setObject:username forMeta:kTagUsernameField];
- [tagObject setObject:host forMeta:kTagHostField];
- // We need the identifier to be able to fetch the keychain password
- [tagObject setObject:identifier forMeta:kTagIdentifierField];
- [tagObject setName:tag];
- [tagObject setPrimaryType:kTagType];
- [objects addObject:tagObject];
- }
- }
+ }
+
+ // Create tag objects if requested
+ if (includeTags) {
+ for (NSString *tag in tagSet) {
+ if (tag.length > 0) {
+ QSObject *tagObject = [QSObject
+ makeObjectWithIdentifier:[NSString
+ stringWithFormat:@"[Linkding tag]:%@",
+ tag]];
+ [tagObject setObject:tag forType:kTagType];
+ [tagObject setObject:@(site) forMeta:kTagSiteField];
+ [tagObject setObject:username forMeta:kTagUsernameField];
+ [tagObject setObject:host forMeta:kTagHostField];
+ // We need the identifier to be able to fetch the keychain password
+ [tagObject setObject:identifier forMeta:kTagIdentifierField];
+ [tagObject setName:tag];
+ [tagObject setPrimaryType:kTagType];
+ [objects addObject:tagObject];
+ }
}
-
- return objects;
+ }
+
+ return objects;
}
-- (NSArray *)fetchBookmarksForTag:(NSString *)tag site:(SocialSite)site username:(NSString *)username password:(NSString *)password host:(NSString *)host {
- NSData *data = [self cachedBookmarkDataForHost:host username:username];
- if (!data) return @[];
-
- NSError *jsonError;
- NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];
-
- if (jsonError) return @[];
-
- NSArray *results = [jsonResponse objectForKey:@"results"];
- if (!results || ![results isKindOfClass:[NSArray class]]) return @[];
-
- NSMutableArray *objects = [NSMutableArray arrayWithCapacity:1];
-
- for (NSDictionary *bookmark in results) {
- NSArray *tags = [bookmark objectForKey:@"tag_names"];
- if (tags && [tags isKindOfClass:[NSArray class]] && [tags containsObject:tag]) {
- QSObject *newObject = [self objectForLinkdingBookmark:bookmark];
- if (newObject) {
- [objects addObject:newObject];
- }
- }
+- (NSArray *)fetchBookmarksForTag:(NSString *)tag
+ site:(SocialSite)site
+ username:(NSString *)username
+ password:(NSString *)password
+ host:(NSString *)host {
+ NSData *data = [self cachedBookmarkDataForHost:host username:username];
+ if (!data)
+ return @[];
+
+ NSError *jsonError;
+ NSDictionary *jsonResponse =
+ [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];
+
+ if (jsonError)
+ return @[];
+
+ NSArray *results = [jsonResponse objectForKey:@"results"];
+ if (!results || ![results isKindOfClass:[NSArray class]])
+ return @[];
+
+ NSMutableArray *objects = [NSMutableArray arrayWithCapacity:1];
+
+ for (NSDictionary *bookmark in results) {
+ NSArray *tags = [bookmark objectForKey:@"tag_names"];
+ if (tags && [tags isKindOfClass:[NSArray class]] &&
+ [tags containsObject:tag]) {
+ QSObject *newObject = [self objectForLinkdingBookmark:bookmark];
+ if (newObject) {
+ [objects addObject:newObject];
+ }
}
-
- return objects;
+ }
+
+ return objects;
}
- (QSObject *)objectForLinkdingBookmark:(NSDictionary *)bookmark {
- NSNumber *bookmarkId = [bookmark objectForKey:@"id"];
- NSString *url = [bookmark objectForKey:@"url"];
- NSString *title = [bookmark objectForKey:@"title"];
- NSString *description = [bookmark objectForKey:@"description"];
-
- if (!bookmarkId || !url) return nil;
-
- QSObject *newObject = [QSObject makeObjectWithIdentifier:[NSString stringWithFormat:@"linkding-%@", bookmarkId]];
- [newObject setObject:url forType:QSURLType];
- [newObject setName:title.length > 0 ? title : url];
- [newObject setDetails:description.length > 0 ? description : @""];
- [newObject setPrimaryType:QSURLType];
-
- return newObject;
+ NSNumber *bookmarkId = [bookmark objectForKey:@"id"];
+ NSString *url = [bookmark objectForKey:@"url"];
+ NSString *title = [bookmark objectForKey:@"title"];
+ NSString *description = [bookmark objectForKey:@"description"];
+
+ if (!bookmarkId || !url)
+ return nil;
+
+ QSObject *newObject = [QSObject
+ makeObjectWithIdentifier:[NSString stringWithFormat:@"linkding-%@",
+ bookmarkId]];
+ [newObject setObject:url forType:QSURLType];
+ [newObject setName:title.length > 0 ? title : url];
+ [newObject setDetails:description.length > 0 ? description : @""];
+ [newObject setPrimaryType:QSURLType];
+
+ return newObject;
}
@end