From ef8c490e4377327a2cb8b8252cdf019c8f78bb05 Mon Sep 17 00:00:00 2001 From: Skalii Date: Thu, 7 Dec 2023 22:17:07 +0200 Subject: [PATCH 1/3] fix wikimedia photos; --- Sources/Helpers/OAWikiImageHelper.h | 4 + Sources/Helpers/OAWikiImageHelper.mm | 193 +++++++++++++++++++-------- 2 files changed, 140 insertions(+), 57 deletions(-) diff --git a/Sources/Helpers/OAWikiImageHelper.h b/Sources/Helpers/OAWikiImageHelper.h index b407fccbae..26d048893f 100644 --- a/Sources/Helpers/OAWikiImageHelper.h +++ b/Sources/Helpers/OAWikiImageHelper.h @@ -15,6 +15,10 @@ #define CM_LIMIT @"&cmlimit=500" #define FORMAT_JSON @"&format=json" #define IMAGE_BASE_URL @"https://commons.wikimedia.org/wiki/Special:FilePath/" +#define USE_OSMAND_WIKI_API YES +#define OSMAND_API_ENDPOINT @"https://osmand.net/api/" +#define OSMAND_API_WIKIDATA_ARTICLE_ACTION @"wiki_place?article=" +#define OSMAND_API_WIKIDATA_CATEGORY_ACTION @"wiki_place?category=" #define WIKIDATA_PREFIX @"Q" #define WIKIMEDIA_FILE @"File:" diff --git a/Sources/Helpers/OAWikiImageHelper.mm b/Sources/Helpers/OAWikiImageHelper.mm index 6608229dfc..33f1ed2f1f 100644 --- a/Sources/Helpers/OAWikiImageHelper.mm +++ b/Sources/Helpers/OAWikiImageHelper.mm @@ -60,6 +60,19 @@ - (void)sendNearbyWikiImagesRequest:(OARowInfo *)nearbyImagesRowInfo targetObj:( [self addWikidataCards:wikidataTagContent cards:cards rowInfo:nearbyImagesRowInfo]; } +- (OAWikiImage *)getOsmandApiWikiImage:(NSString *)imageUrl +{ + NSString *url = [imageUrl stringByRemovingPercentEncoding]; + NSString *imageHiResUrl = [url stringByReplacingOccurrencesOfString:@" " withString:@"_"]; + NSString *imageFileName = url.lastPathComponent; + NSString *imageName = imageFileName.stringByDeletingPathExtension; + NSString *imageStubUrl = [NSString stringWithFormat:@"%@%@%i", imageHiResUrl, @"?width=", THUMB_SIZE]; + return [[OAWikiImage alloc] initWithWikiMediaTag:imageFileName + imageName:imageName + imageStubUrl:imageStubUrl + imageHiResUrl:imageHiResUrl]; +} + - (OAWikiImage *)getWikiImage:(NSString *)imageFileName { NSString *imageName = [imageFileName stringByRemovingPercentEncoding]; @@ -78,46 +91,104 @@ - (OAWikiImage *)getWikiImage:(NSString *)imageFileName return [[OAWikiImage alloc] initWithWikiMediaTag:urlSafeFileName imageName:imageName imageStubUrl:imageStubUrl imageHiResUrl:imageHiResUrl]; } +- (void)addOsmandAPIWikidataImageListByCategory:(NSString *)categoryName + cards:(NSMutableArray *)cards +{ + NSString *url = [NSString stringWithFormat:@"%@%@%@", OSMAND_API_ENDPOINT, OSMAND_API_WIKIDATA_CATEGORY_ACTION, categoryName]; + [self addOsmandAPIImageList:url cards:cards byCategory:YES]; +} + +- (void)addOsmandAPIWikidataImageList:(NSString *)wikidataTagContent + cards:(NSMutableArray *)cards +{ + NSString *url = [NSString stringWithFormat:@"%@%@%@", OSMAND_API_ENDPOINT, OSMAND_API_WIKIDATA_ARTICLE_ACTION, wikidataTagContent]; + [self addOsmandAPIImageList:url cards:cards byCategory:NO]; +} + +- (void)addOsmandAPIImageList:(NSString *)url + cards:(NSMutableArray *)cards + byCategory:(BOOL)byCategory +{ + url = [url stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; + NSURL *urlObj = [[NSURL alloc] initWithString:url]; + NSURLSession *aSession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; + [[aSession dataTaskWithURL:urlObj completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { + NSMutableArray *resultCards = [NSMutableArray array]; + if (((NSHTTPURLResponse *)response).statusCode == 200) + { + if (data) + { + NSError *error; + NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error]; + NSArray *images = jsonDict[@"features"]; + if (!error && images) + { + for (NSString *image in images) + { + OAWikiImageCard *card = [[OAWikiImageCard alloc] initWithWikiImage:[self getOsmandApiWikiImage:image] type:@"wikimedia-photo" wikimediaCategory:NO]; + if (card) + [resultCards addObject:card]; + } + } + } + } + dispatch_async(dispatch_get_main_queue(), ^{ + [cards addObjectsFromArray:resultCards]; + (byCategory ? _wikimediaCardsReady : _wikidataCardsReady) = YES; + if (byCategory ? _wikidataCardsReady : _wikimediaCardsReady) + _addOtherImagesFunction(cards); + }); + }] resume]; +} + + - (void)addWikidataCards:(NSString *)wikidataTagContent cards:(NSMutableArray *)cards rowInfo:(OARowInfo *)nearbyImagesRowInfo { - if (wikidataTagContent && [wikidataTagContent hasPrefix:WIKIDATA_PREFIX]) + if (wikidataTagContent) { - NSString *safeWikidataTagContent = [wikidataTagContent stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; - NSURL *urlObj = [[NSURL alloc] initWithString: [NSString stringWithFormat:@"%@%@%@%@", WIKIDATA_API_ENDPOINT, WIKIDATA_ACTION, safeWikidataTagContent, FORMAT_JSON]]; - NSURLSession *aSession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; - [[aSession dataTaskWithURL:urlObj completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { - OAWikiImageCard *resultCard = nil; - if (((NSHTTPURLResponse *)response).statusCode == 200) - { - if (data && !error) + if (USE_OSMAND_WIKI_API) + { + [self addOsmandAPIWikidataImageList:wikidataTagContent cards:cards]; + } + else if ([wikidataTagContent hasPrefix:WIKIDATA_PREFIX]) + { + NSString *safeWikidataTagContent = [wikidataTagContent stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; + NSURL *urlObj = [[NSURL alloc] initWithString: [NSString stringWithFormat:@"%@%@%@%@", WIKIDATA_API_ENDPOINT, WIKIDATA_ACTION, safeWikidataTagContent, FORMAT_JSON]]; + NSURLSession *aSession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; + [[aSession dataTaskWithURL:urlObj completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { + OAWikiImageCard *resultCard = nil; + if (((NSHTTPURLResponse *)response).statusCode == 200) { - NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error]; - if (jsonDict) + if (data && !error) { - try { - NSArray *records = jsonDict[@"claims"][@"P18"]; - if (records && records.count > 0) + NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error]; + if (jsonDict) + { + try { + NSArray *records = jsonDict[@"claims"][@"P18"]; + if (records && records.count > 0) + { + NSString *imageName = records.firstObject[@"mainsnak"][@"datavalue"][@"value"]; + if (imageName) + resultCard = [[OAWikiImageCard alloc] initWithWikiImage:[self getWikiImage:imageName] type:@"wikidata-photo"]; + } + } + catch(NSException *e) { - NSString *imageName = records.firstObject[@"mainsnak"][@"datavalue"][@"value"]; - if (imageName) - resultCard = [[OAWikiImageCard alloc] initWithWikiImage:[self getWikiImage:imageName] type:@"wikidata-photo"]; + NSLog(@"Wikidata image json serialising error"); } } - catch(NSException *e) - { - NSLog(@"Wikidata image json serialising error"); - } } } - } - dispatch_async(dispatch_get_main_queue(), ^{ - if (resultCard) - [cards addObject:resultCard]; - _wikidataCardsReady = YES; - if (_wikimediaCardsReady) - _addOtherImagesFunction(cards); - }); - }] resume]; + dispatch_async(dispatch_get_main_queue(), ^{ + if (resultCard) + [cards addObject:resultCard]; + _wikidataCardsReady = YES; + if (_wikimediaCardsReady) + _addOtherImagesFunction(cards); + }); + }] resume]; + } } else { @@ -143,41 +214,49 @@ - (void)addWikimediaCards:(NSString *)wikiMediaTagContent cards:(NSMutableArray< } else if (wikiMediaTagContent && [wikiMediaTagContent hasPrefix:WIKIMEDIA_CATEGORY]) { - NSString *url = [NSString stringWithFormat:@"%@%@%@%@%@", WIKIMEDIA_API_ENDPOINT, WIKIMEDIA_ACTION, wikiMediaTagContent, CM_LIMIT, FORMAT_JSON]; - url = [url stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; - NSURL *urlObj = [[NSURL alloc] initWithString:url]; - NSURLSession *aSession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; - [[aSession dataTaskWithURL:urlObj completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { - NSMutableArray *resultCards = [NSMutableArray array]; - if (((NSHTTPURLResponse *)response).statusCode == 200) - { - if (data) + if (USE_OSMAND_WIKI_API) + { + NSString *categoryName = [wikiMediaTagContent stringByReplacingOccurrencesOfString:WIKIMEDIA_CATEGORY withString:@""]; + [self addOsmandAPIWikidataImageListByCategory:categoryName cards:cards]; + } + else + { + NSString *url = [NSString stringWithFormat:@"%@%@%@%@%@", WIKIMEDIA_API_ENDPOINT, WIKIMEDIA_ACTION, wikiMediaTagContent, CM_LIMIT, FORMAT_JSON]; + url = [url stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; + NSURL *urlObj = [[NSURL alloc] initWithString:url]; + NSURLSession *aSession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; + [[aSession dataTaskWithURL:urlObj completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { + NSMutableArray *resultCards = [NSMutableArray array]; + if (((NSHTTPURLResponse *)response).statusCode == 200) { - NSError *error; - NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error]; - NSDictionary *imagesDict = jsonDict[@"query"][@"categorymembers"]; - if (!error && imagesDict) + if (data) { - for (NSDictionary *imageDict in imagesDict) + NSError *error; + NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error]; + NSDictionary *imagesDict = jsonDict[@"query"][@"categorymembers"]; + if (!error && imagesDict) { - NSString *imageName = imageDict[@"title"]; - if (imageName) + for (NSDictionary *imageDict in imagesDict) { - OAWikiImageCard *card = [[OAWikiImageCard alloc] initWithWikiImage:[self getWikiImage:imageName] type:@"wikimedia-photo" wikimediaCategory:YES]; - if (card) - [resultCards addObject:card]; + NSString *imageName = imageDict[@"title"]; + if (imageName) + { + OAWikiImageCard *card = [[OAWikiImageCard alloc] initWithWikiImage:[self getWikiImage:imageName] type:@"wikimedia-photo" wikimediaCategory:YES]; + if (card) + [resultCards addObject:card]; + } } } } } - } - dispatch_async(dispatch_get_main_queue(), ^{ - [cards addObjectsFromArray:resultCards]; - _wikimediaCardsReady = YES; - if (_wikidataCardsReady) - _addOtherImagesFunction(cards); - }); - }] resume]; + dispatch_async(dispatch_get_main_queue(), ^{ + [cards addObjectsFromArray:resultCards]; + _wikimediaCardsReady = YES; + if (_wikidataCardsReady) + _addOtherImagesFunction(cards); + }); + }] resume]; + } } else { From 4c32f9a8c176875ed504ec948e961ef48edd59b1 Mon Sep 17 00:00:00 2001 From: Skalii Date: Fri, 8 Dec 2023 12:27:23 +0200 Subject: [PATCH 2/3] hide wikimedia photos if the wikipedia plugin is disabled; sync cm_place url with android; --- .../TargetMenu/OATargetInfoViewController.mm | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/Sources/Controllers/TargetMenu/OATargetInfoViewController.mm b/Sources/Controllers/TargetMenu/OATargetInfoViewController.mm index 2c67f3c7e5..88970579ff 100644 --- a/Sources/Controllers/TargetMenu/OATargetInfoViewController.mm +++ b/Sources/Controllers/TargetMenu/OATargetInfoViewController.mm @@ -499,7 +499,18 @@ - (void)getCard:(NSDictionary *)feature - (void)addOtherCards:(NSString *)imageTagContent mapillary:(NSString *)mapillaryTagContent cards:(NSMutableArray *)cards rowInfo:(OARowInfo *)nearbyImagesRowInfo { - NSString *urlString = [NSString stringWithFormat:@"https://osmand.net/api/cm_place?lat=%f&lon=%f", self.location.latitude, self.location.longitude]; + CLLocation *myLocation = [OsmAndApp instance].locationServices.lastKnownLocation; + OAAppSettings *settings = [OAAppSettings sharedManager]; + NSString *preferredLang = [settings.settingPrefMapLanguage get]; + if (!preferredLang) + preferredLang = [OAUtilities currentLang]; + + NSString *urlString = [NSString stringWithFormat:@"https://osmand.net/api/cm_place?lat=%f&lon=%f&app=%@%@%@", + self.location.latitude, + self.location.longitude, + [OAIAPHelper isPaidVersion] ? @"paid" : @"free", + (preferredLang && preferredLang.length > 0 ? [@"&lang=" stringByAppendingString:preferredLang] : @""), + (myLocation ? [NSString stringWithFormat:@"&mloc=%f,%f", myLocation.coordinate.latitude, myLocation.coordinate.longitude] : @"")]; if (imageTagContent) urlString = [urlString stringByAppendingString:[NSString stringWithFormat:@"&osm_image=%@", imageTagContent]]; if (mapillaryTagContent) @@ -988,10 +999,18 @@ - (void)onViewExpanded [cardsView setCards:@[[[OAImageCard alloc] initWithData:@{@"key": @"loading"}]]]; } - [[OAWikiImageHelper sharedInstance] sendNearbyWikiImagesRequest:_nearbyImagesRowInfo targetObj:self.getTargetObj addOtherImagesOnComplete:^(NSMutableArray *cards) { + if ([OAPlugin isEnabled:OAWikipediaPlugin.class]) + { + [[OAWikiImageHelper sharedInstance] sendNearbyWikiImagesRequest:_nearbyImagesRowInfo targetObj:self.getTargetObj addOtherImagesOnComplete:^(NSMutableArray *cards) { + _wikiCardsReady = YES; + [self sendNearbyOtherImagesRequest:cards]; + }]; + } + else + { _wikiCardsReady = YES; - [self sendNearbyOtherImagesRequest:cards]; - }]; + [self sendNearbyOtherImagesRequest:[NSMutableArray array]]; + } } #pragma mark - OAEditDescriptionViewControllerDelegate From e96bc147fa924efd94004a4fabd2398577ba5327 Mon Sep 17 00:00:00 2001 From: Skalii Date: Sat, 9 Dec 2023 18:24:50 +0200 Subject: [PATCH 3/3] review fixes; --- .../TargetMenu/OATargetInfoViewController.mm | 20 ++++++---- Sources/Helpers/OAWikiImageHelper.h | 9 +++-- Sources/Helpers/OAWikiImageHelper.mm | 39 ++++++++++++++----- 3 files changed, 48 insertions(+), 20 deletions(-) diff --git a/Sources/Controllers/TargetMenu/OATargetInfoViewController.mm b/Sources/Controllers/TargetMenu/OATargetInfoViewController.mm index 88970579ff..4dbb6dc052 100644 --- a/Sources/Controllers/TargetMenu/OATargetInfoViewController.mm +++ b/Sources/Controllers/TargetMenu/OATargetInfoViewController.mm @@ -60,6 +60,8 @@ @interface OATargetInfoViewController() +@property (nonatomic) BOOL wikiCardsReady; + @end @implementation OATargetInfoViewController @@ -74,7 +76,6 @@ @implementation OATargetInfoViewController OARowInfo *_nearbyImagesRowInfo; BOOL _otherCardsReady; - BOOL _wikiCardsReady; } - (void) setRows:(NSMutableArray *)rows @@ -505,12 +506,16 @@ - (void)addOtherCards:(NSString *)imageTagContent mapillary:(NSString *)mapillar if (!preferredLang) preferredLang = [OAUtilities currentLang]; - NSString *urlString = [NSString stringWithFormat:@"https://osmand.net/api/cm_place?lat=%f&lon=%f&app=%@%@%@", + NSString *urlString = [NSString stringWithFormat:@"https://osmand.net/api/cm_place?lat=%f&lon=%f&app=%@", self.location.latitude, self.location.longitude, - [OAIAPHelper isPaidVersion] ? @"paid" : @"free", - (preferredLang && preferredLang.length > 0 ? [@"&lang=" stringByAppendingString:preferredLang] : @""), - (myLocation ? [NSString stringWithFormat:@"&mloc=%f,%f", myLocation.coordinate.latitude, myLocation.coordinate.longitude] : @"")]; + [OAIAPHelper isPaidVersion] ? @"paid" : @"free"]; + + if (preferredLang && preferredLang.length > 0) + urlString = [urlString stringByAppendingFormat:@"&lang=%@", preferredLang]; + if (myLocation) + urlString = [urlString stringByAppendingFormat:@"&mloc=%f,%f", myLocation.coordinate.latitude, myLocation.coordinate.longitude]; + if (imageTagContent) urlString = [urlString stringByAppendingString:[NSString stringWithFormat:@"&osm_image=%@", imageTagContent]]; if (mapillaryTagContent) @@ -1001,9 +1006,10 @@ - (void)onViewExpanded if ([OAPlugin isEnabled:OAWikipediaPlugin.class]) { + __weak OATargetInfoViewController *selfWeak = self; [[OAWikiImageHelper sharedInstance] sendNearbyWikiImagesRequest:_nearbyImagesRowInfo targetObj:self.getTargetObj addOtherImagesOnComplete:^(NSMutableArray *cards) { - _wikiCardsReady = YES; - [self sendNearbyOtherImagesRequest:cards]; + selfWeak.wikiCardsReady = YES; + [selfWeak sendNearbyOtherImagesRequest:cards]; }]; } else diff --git a/Sources/Helpers/OAWikiImageHelper.h b/Sources/Helpers/OAWikiImageHelper.h index 26d048893f..75fc6525a7 100644 --- a/Sources/Helpers/OAWikiImageHelper.h +++ b/Sources/Helpers/OAWikiImageHelper.h @@ -15,10 +15,6 @@ #define CM_LIMIT @"&cmlimit=500" #define FORMAT_JSON @"&format=json" #define IMAGE_BASE_URL @"https://commons.wikimedia.org/wiki/Special:FilePath/" -#define USE_OSMAND_WIKI_API YES -#define OSMAND_API_ENDPOINT @"https://osmand.net/api/" -#define OSMAND_API_WIKIDATA_ARTICLE_ACTION @"wiki_place?article=" -#define OSMAND_API_WIKIDATA_CATEGORY_ACTION @"wiki_place?category=" #define WIKIDATA_PREFIX @"Q" #define WIKIMEDIA_FILE @"File:" @@ -27,6 +23,11 @@ #define THUMB_SIZE 500 +static const NSString *OSMAND_API_ENDPOINT = @"https://osmand.net/api/"; +static const NSString *OSMAND_API_WIKIDATA_ARTICLE_ACTION = @"wiki_place?article="; +static const NSString *OSMAND_API_WIKIDATA_CATEGORY_ACTION = @"wiki_place?category="; +static const BOOL USE_OSMAND_WIKI_API = YES; + @class OARowInfo; @class OAAbstractCard; diff --git a/Sources/Helpers/OAWikiImageHelper.mm b/Sources/Helpers/OAWikiImageHelper.mm index 33f1ed2f1f..5faf0a4afd 100644 --- a/Sources/Helpers/OAWikiImageHelper.mm +++ b/Sources/Helpers/OAWikiImageHelper.mm @@ -111,8 +111,8 @@ - (void)addOsmandAPIImageList:(NSString *)url { url = [url stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; NSURL *urlObj = [[NSURL alloc] initWithString:url]; - NSURLSession *aSession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; - [[aSession dataTaskWithURL:urlObj completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { + NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; + [[session dataTaskWithURL:urlObj completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { NSMutableArray *resultCards = [NSMutableArray array]; if (((NSHTTPURLResponse *)response).statusCode == 200) { @@ -132,11 +132,24 @@ - (void)addOsmandAPIImageList:(NSString *)url } } } + else + { + NSLog(@"Error retrieving Wikimedia photos (OsmandApi): %@", error); + } dispatch_async(dispatch_get_main_queue(), ^{ [cards addObjectsFromArray:resultCards]; - (byCategory ? _wikimediaCardsReady : _wikidataCardsReady) = YES; - if (byCategory ? _wikidataCardsReady : _wikimediaCardsReady) - _addOtherImagesFunction(cards); + if (byCategory) + { + _wikimediaCardsReady = YES; + if (_wikidataCardsReady) + _addOtherImagesFunction(cards); + } + else + { + _wikidataCardsReady = YES; + if (_wikimediaCardsReady) + _addOtherImagesFunction(cards); + } }); }] resume]; } @@ -154,8 +167,8 @@ - (void)addWikidataCards:(NSString *)wikidataTagContent cards:(NSMutableArray *resultCards = [NSMutableArray array]; if (((NSHTTPURLResponse *)response).statusCode == 200) { @@ -249,6 +266,10 @@ - (void)addWikimediaCards:(NSString *)wikiMediaTagContent cards:(NSMutableArray< } } } + else + { + NSLog(@"Error retrieving Wikimedia photos: %@", error); + } dispatch_async(dispatch_get_main_queue(), ^{ [cards addObjectsFromArray:resultCards]; _wikimediaCardsReady = YES;