Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix wikimedia photos #3278

Merged
merged 4 commits into from
Dec 11, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 23 additions & 4 deletions Sources/Controllers/TargetMenu/OATargetInfoViewController.mm
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,18 @@ - (void)getCard:(NSDictionary *)feature

- (void)addOtherCards:(NSString *)imageTagContent mapillary:(NSString *)mapillaryTagContent cards:(NSMutableArray<OAAbstractCard *> *)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] : @""),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's better not to use two ternary operators in one condition

(myLocation ? [NSString stringWithFormat:@"&mloc=%f,%f", myLocation.coordinate.latitude, myLocation.coordinate.longitude] : @"")];
if (imageTagContent)
urlString = [urlString stringByAppendingString:[NSString stringWithFormat:@"&osm_image=%@", imageTagContent]];
if (mapillaryTagContent)
Expand Down Expand Up @@ -988,10 +999,18 @@ - (void)onViewExpanded
[cardsView setCards:@[[[OAImageCard alloc] initWithData:@{@"key": @"loading"}]]];
}

[[OAWikiImageHelper sharedInstance] sendNearbyWikiImagesRequest:_nearbyImagesRowInfo targetObj:self.getTargetObj addOtherImagesOnComplete:^(NSMutableArray <OAAbstractCard *> *cards) {
if ([OAPlugin isEnabled:OAWikipediaPlugin.class])
{
[[OAWikiImageHelper sharedInstance] sendNearbyWikiImagesRequest:_nearbyImagesRowInfo targetObj:self.getTargetObj addOtherImagesOnComplete:^(NSMutableArray <OAAbstractCard *> *cards) {
_wikiCardsReady = YES;
[self sendNearbyOtherImagesRequest:cards];
}];
}
else
{
_wikiCardsReady = YES;
[self sendNearbyOtherImagesRequest:cards];
}];
[self sendNearbyOtherImagesRequest:[NSMutableArray array]];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

retain cycle ?

}
}

#pragma mark - OAEditDescriptionViewControllerDelegate
Expand Down
4 changes: 4 additions & 0 deletions Sources/Helpers/OAWikiImageHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -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/"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't use #define. it is not type-safe. static NSString* const 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:"
Expand Down
193 changes: 136 additions & 57 deletions Sources/Helpers/OAWikiImageHelper.mm
Original file line number Diff line number Diff line change
Expand Up @@ -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:@"_"];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

imageHiResUrl - Interesting name:)

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];
Expand All @@ -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<OAAbstractCard *> *)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<OAAbstractCard *> *)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<OAAbstractCard *> *)cards
byCategory:(BOOL)byCategory
{
url = [url stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
NSURL *urlObj = [[NSURL alloc] initWithString:url];
NSURLSession *aSession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*session

[[aSession dataTaskWithURL:urlObj completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSMutableArray<OAAbstractCard *> *resultCards = [NSMutableArray array];
if (((NSHTTPURLResponse *)response).statusCode == 200)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should add error logging to the log output?

{
if (data)
{
NSError *error;
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
NSArray<NSString *> *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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace duplicate checks with 'if byCategory'.

if (byCategory ? _wikidataCardsReady : _wikimediaCardsReady)
_addOtherImagesFunction(cards);
});
}] resume];
}


- (void)addWikidataCards:(NSString *)wikidataTagContent cards:(NSMutableArray<OAAbstractCard *> *)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]];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*session

[[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
{
Expand All @@ -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<OAAbstractCard *> *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]];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*session

[[aSession dataTaskWithURL:urlObj completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSMutableArray<OAAbstractCard *> *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
{
Expand Down