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 all 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
35 changes: 30 additions & 5 deletions Sources/Controllers/TargetMenu/OATargetInfoViewController.mm
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@

@interface OATargetInfoViewController() <OACollapsableCardViewDelegate, OAEditDescriptionViewControllerDelegate>

@property (nonatomic) BOOL wikiCardsReady;

@end

@implementation OATargetInfoViewController
Expand All @@ -74,7 +76,6 @@ @implementation OATargetInfoViewController

OARowInfo *_nearbyImagesRowInfo;
BOOL _otherCardsReady;
BOOL _wikiCardsReady;
}

- (void) setRows:(NSMutableArray<OARowInfo *> *)rows
Expand Down Expand Up @@ -499,7 +500,22 @@ - (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"];

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)
Expand Down Expand Up @@ -988,10 +1004,19 @@ - (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])
{
__weak OATargetInfoViewController *selfWeak = self;
[[OAWikiImageHelper sharedInstance] sendNearbyWikiImagesRequest:_nearbyImagesRowInfo targetObj:self.getTargetObj addOtherImagesOnComplete:^(NSMutableArray <OAAbstractCard *> *cards) {
selfWeak.wikiCardsReady = YES;
[selfWeak 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
5 changes: 5 additions & 0 deletions Sources/Helpers/OAWikiImageHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,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;

Expand Down
214 changes: 157 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,121 @@ - (OAWikiImage *)getWikiImage:(NSString *)imageFileName
return [[OAWikiImage alloc] initWithWikiMediaTag:urlSafeFileName imageName:imageName imageStubUrl:imageStubUrl imageHiResUrl:imageHiResUrl];
}

- (void)addWikidataCards:(NSString *)wikidataTagContent cards:(NSMutableArray<OAAbstractCard *> *)cards rowInfo:(OARowInfo *)nearbyImagesRowInfo
- (void)addOsmandAPIWikidataImageListByCategory:(NSString *)categoryName
cards:(NSMutableArray<OAAbstractCard *> *)cards
{
if (wikidataTagContent && [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)
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 *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
[[session 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)
{
if (data && !error)
NSError *error;
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
NSArray<NSString *> *images = jsonDict[@"features"];
if (!error && images)
{
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
if (jsonDict)
for (NSString *image in images)
{
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)
{
NSLog(@"Wikidata image json serialising error");
}
OAWikiImageCard *card = [[OAWikiImageCard alloc] initWithWikiImage:[self getOsmandApiWikiImage:image] type:@"wikimedia-photo" wikimediaCategory:NO];
if (card)
[resultCards addObject:card];
}
}
}
dispatch_async(dispatch_get_main_queue(), ^{
if (resultCard)
[cards addObject:resultCard];
}
else
{
NSLog(@"Error retrieving Wikimedia photos (OsmandApi): %@", error);
}
dispatch_async(dispatch_get_main_queue(), ^{
[cards addObjectsFromArray:resultCards];
if (byCategory)
{
_wikimediaCardsReady = YES;
if (_wikidataCardsReady)
_addOtherImagesFunction(cards);
}
else
{
_wikidataCardsReady = YES;
if (_wikimediaCardsReady)
_addOtherImagesFunction(cards);
});
}] resume];
}
});
}] resume];
}


- (void)addWikidataCards:(NSString *)wikidataTagContent cards:(NSMutableArray<OAAbstractCard *> *)cards rowInfo:(OARowInfo *)nearbyImagesRowInfo
{
if (wikidataTagContent)
{
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 *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
[[session dataTaskWithURL:urlObj completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
OAWikiImageCard *resultCard = nil;
if (((NSHTTPURLResponse *)response).statusCode == 200)
{
if (data && !error)
{
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)
{
NSLog(@"Wikidata image json serialising error");
}
}
}
}
else
{
NSLog(@"Error retrieving Wikidata photos: %@", error);
}
dispatch_async(dispatch_get_main_queue(), ^{
if (resultCard)
[cards addObject:resultCard];
_wikidataCardsReady = YES;
if (_wikimediaCardsReady)
_addOtherImagesFunction(cards);
});
}] resume];
}
}
else
{
Expand All @@ -143,41 +231,53 @@ - (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 *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
[[session 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];
else
{
NSLog(@"Error retrieving Wikimedia photos: %@", error);
}
dispatch_async(dispatch_get_main_queue(), ^{
[cards addObjectsFromArray:resultCards];
_wikimediaCardsReady = YES;
if (_wikidataCardsReady)
_addOtherImagesFunction(cards);
});
}] resume];
}
}
else
{
Expand Down