Brion VIBBER has uploaded a new change for review. https://gerrit.wikimedia.org/r/185548
Change subject: (Work in progress) MWKImageMetadata object interface ...................................................................... (Work in progress) MWKImageMetadata object interface Feed with a 'pageinfo' API result dict, it'll fetch out the 'imageinfo' list. Convenience getters provide a few particular bits of metadata as strings, or you can grab everything as MWKImageMetadataItems from a dictionary. Untested currently. :) Change-Id: If3781a6e514e142a05b07a4ccddfe3c52222dbdc --- M MediaWikiKit/MediaWikiKit.xcodeproj/project.pbxproj M MediaWikiKit/MediaWikiKit/MWKDataStore.h M MediaWikiKit/MediaWikiKit/MWKDataStore.m A MediaWikiKit/MediaWikiKit/MWKImageMetadata.h A MediaWikiKit/MediaWikiKit/MWKImageMetadata.m A MediaWikiKit/MediaWikiKit/MWKImageMetadataItem.h A MediaWikiKit/MediaWikiKit/MWKImageMetadataItem.m M MediaWikiKit/MediaWikiKit/MediaWikiKit.h 8 files changed, 275 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/apps/ios/wikipedia refs/changes/48/185548/1 diff --git a/MediaWikiKit/MediaWikiKit.xcodeproj/project.pbxproj b/MediaWikiKit/MediaWikiKit.xcodeproj/project.pbxproj index 249fa67..5b9f41c 100644 --- a/MediaWikiKit/MediaWikiKit.xcodeproj/project.pbxproj +++ b/MediaWikiKit/MediaWikiKit.xcodeproj/project.pbxproj @@ -67,6 +67,10 @@ D4DDF46119F055C800C6BC10 /* MWKUserTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D4DDF46019F055C800C6BC10 /* MWKUserTests.m */; }; D4DDF46319F0560400C6BC10 /* user-loggedin.json in Resources */ = {isa = PBXBuildFile; fileRef = D4DDF46219F0560400C6BC10 /* user-loggedin.json */; }; D4DDF46519F0561500C6BC10 /* user-anon.json in Resources */ = {isa = PBXBuildFile; fileRef = D4DDF46419F0561500C6BC10 /* user-anon.json */; }; + D4F9560D1A69B2AC00E9A2C4 /* MWKImageMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = D4F9560C1A69B2AC00E9A2C4 /* MWKImageMetadata.m */; }; + D4F9560E1A69B2AC00E9A2C4 /* MWKImageMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = D4F9560C1A69B2AC00E9A2C4 /* MWKImageMetadata.m */; }; + D4F956111A69B7BE00E9A2C4 /* MWKImageMetadataItem.m in Sources */ = {isa = PBXBuildFile; fileRef = D4F956101A69B7BE00E9A2C4 /* MWKImageMetadataItem.m */; }; + D4F956121A69B7BE00E9A2C4 /* MWKImageMetadataItem.m in Sources */ = {isa = PBXBuildFile; fileRef = D4F956101A69B7BE00E9A2C4 /* MWKImageMetadataItem.m */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -148,6 +152,10 @@ D4DDF46019F055C800C6BC10 /* MWKUserTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MWKUserTests.m; sourceTree = "<group>"; }; D4DDF46219F0560400C6BC10 /* user-loggedin.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "user-loggedin.json"; sourceTree = "<group>"; }; D4DDF46419F0561500C6BC10 /* user-anon.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "user-anon.json"; sourceTree = "<group>"; }; + D4F9560B1A69B2AC00E9A2C4 /* MWKImageMetadata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWKImageMetadata.h; sourceTree = "<group>"; }; + D4F9560C1A69B2AC00E9A2C4 /* MWKImageMetadata.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MWKImageMetadata.m; sourceTree = "<group>"; }; + D4F9560F1A69B7BE00E9A2C4 /* MWKImageMetadataItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWKImageMetadataItem.h; sourceTree = "<group>"; }; + D4F956101A69B7BE00E9A2C4 /* MWKImageMetadataItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MWKImageMetadataItem.m; sourceTree = "<group>"; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -271,6 +279,8 @@ D44EA7881A1BCD1400631A1D /* MWKRecentSearchEntry.m */, D44EA78B1A1BCD2600631A1D /* MWKRecentSearchList.h */, D44EA78C1A1BCD2600631A1D /* MWKRecentSearchList.m */, + D4F9560F1A69B7BE00E9A2C4 /* MWKImageMetadataItem.h */, + D4F956101A69B7BE00E9A2C4 /* MWKImageMetadataItem.m */, ); name = "Data classes"; sourceTree = "<group>"; @@ -299,6 +309,8 @@ D4B94B1E1A2FE975007FC79B /* MWKImageList.m */, D4209C9C1A3A50C9000E1A60 /* MWKSectionList.h */, D4209C9D1A3A50C9000E1A60 /* MWKSectionList.m */, + D4F9560B1A69B2AC00E9A2C4 /* MWKImageMetadata.h */, + D4F9560C1A69B2AC00E9A2C4 /* MWKImageMetadata.m */, ); name = "Data i/o"; sourceTree = "<group>"; @@ -415,7 +427,9 @@ D47F56281A1A89B4004D9856 /* MWKHistoryList.m in Sources */, D4612CED1A116E97008945A5 /* MWKSavedPageEntry.m in Sources */, D4B94B1F1A2FE975007FC79B /* MWKImageList.m in Sources */, + D4F9560D1A69B2AC00E9A2C4 /* MWKImageMetadata.m in Sources */, D4209C9E1A3A50C9000E1A60 /* MWKSectionList.m in Sources */, + D4F956111A69B7BE00E9A2C4 /* MWKImageMetadataItem.m in Sources */, D497FCE71A08013F004A36A5 /* MWKSavedPageList.m in Sources */, D4DDF45A19EDD22200C6BC10 /* MWKUser.m in Sources */, D48405C719E47542006F4139 /* MWKImage.m in Sources */, @@ -434,11 +448,13 @@ D494A6FF19F6C7C30098AA18 /* MWKProtectionStatus.m in Sources */, D47F56291A1A89B4004D9856 /* MWKHistoryList.m in Sources */, D44EA78E1A1BCD2600631A1D /* MWKRecentSearchList.m in Sources */, + D4F956121A69B7BE00E9A2C4 /* MWKImageMetadataItem.m in Sources */, D48405C019E47526006F4139 /* MWKSection.m in Sources */, D48405C819E47542006F4139 /* MWKImage.m in Sources */, D49ADCCA1A0028A70010F839 /* MWKImageStorageTests.m in Sources */, D4DDF46119F055C800C6BC10 /* MWKUserTests.m in Sources */, D4C3FA5D19E47D4700EB08CC /* MWKTitleTests.m in Sources */, + D4F9560E1A69B2AC00E9A2C4 /* MWKImageMetadata.m in Sources */, D497FCE81A08013F004A36A5 /* MWKSavedPageList.m in Sources */, D494A71119F6ECC10098AA18 /* MWKDataStorePathTests.m in Sources */, D4B94B201A2FE975007FC79B /* MWKImageList.m in Sources */, diff --git a/MediaWikiKit/MediaWikiKit/MWKDataStore.h b/MediaWikiKit/MediaWikiKit/MWKDataStore.h index f4ce2de..a948348 100644 --- a/MediaWikiKit/MediaWikiKit/MWKDataStore.h +++ b/MediaWikiKit/MediaWikiKit/MWKDataStore.h @@ -16,6 +16,7 @@ @class MWKHistoryList; @class MWKSavedPageList; @class MWKUserDataStore; +@class MWKImageMetadata; @interface MWKDataStore : NSObject @@ -36,6 +37,7 @@ -(NSString *)pathForImagesWithTitle:(MWKTitle *)title; -(NSString *)pathForImageURL:(NSString *)url title:(MWKTitle *)title; -(NSString *)pathForImage:(MWKImage *)image; +-(NSString *)pathForImageMetadata:(MWKImageMetadata *)imageMetadata; // Raw save methods -(void)saveArticle:(MWKArticle *)article; @@ -47,6 +49,8 @@ -(void)saveSavedPageList:(MWKSavedPageList *)list; -(void)saveRecentSearchList:(MWKRecentSearchList *)list; -(void)saveImageList:(MWKImageList *)imageList; +-(void)saveImageMetadata:(MWKImageMetadata *)imageMetadata; + // Raw load methods -(MWKArticle *)articleWithTitle:(MWKTitle *)title; @@ -57,6 +61,7 @@ -(MWKHistoryList *)historyList; -(MWKSavedPageList *)savedPageList; -(MWKRecentSearchList *)recentSearchList; +-(MWKImageMetadata *)imageMetadataWithName:(NSString *)name article:(MWKArticle *)article; // Storage helper methods -(MWKUserDataStore *)userDataStore; diff --git a/MediaWikiKit/MediaWikiKit/MWKDataStore.m b/MediaWikiKit/MediaWikiKit/MWKDataStore.m index 1573c36..c12680e 100644 --- a/MediaWikiKit/MediaWikiKit/MWKDataStore.m +++ b/MediaWikiKit/MediaWikiKit/MWKDataStore.m @@ -92,6 +92,15 @@ return [self pathForImageURL:image.sourceURL title:image.article.title]; } +-(NSString *)pathForImageMetadata:(MWKImageMetadata *)imageMetadata +{ + NSString *safeName = [self safeFilenameWithString:imageMetadata.name]; + + NSString *articlePath = [self pathForArticle:imageMetadata.article]; + NSString *metadataPath = [articlePath stringByAppendingPathComponent:@"ImageMetadata"]; + return [metadataPath stringByAppendingPathComponent:safeName]; +} + -(NSString *)safeFilenameWithString:(NSString *)str { // Escape only % and / with percent style for readability @@ -276,6 +285,14 @@ [self saveDictionary:export path:path name:@"Images.plist"]; } +-(void)saveImageMetadata:(MWKImageMetadata *)imageMetadata +{ + NSString *path = [self pathForImageMetadata:imageMetadata]; + NSDictionary *export = [imageMetadata dataExport]; + [self saveDictionary:export path:path name:@"ImageMetadata.plist"]; +} + + #pragma mark - load methods /// May return nil if no article data available. @@ -390,6 +407,19 @@ } } +-(MWKImageMetadata *)imageMetadataWithName:(NSString *)name article:(MWKArticle *)article +{ + MWKImageMetadata *stub = [[MWKImageMetadata alloc] initWithArticle:article name:name]; + NSString *path = [self pathForImageMetadata:stub]; + NSString *filePath = [path stringByAppendingPathComponent:@"ImageMetadata.plist"]; + NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:filePath]; + if (dict) { + return [[MWKImageMetadata alloc] initWithArticle:article name:name dict:dict]; + } else { + return nil; + } +} + #pragma mark - helper methods diff --git a/MediaWikiKit/MediaWikiKit/MWKImageMetadata.h b/MediaWikiKit/MediaWikiKit/MWKImageMetadata.h new file mode 100644 index 0000000..ad54286 --- /dev/null +++ b/MediaWikiKit/MediaWikiKit/MWKImageMetadata.h @@ -0,0 +1,36 @@ +// +// MWKImageMetadata.h +// MediaWikiKit +// +// Created by Brion on 1/16/15. +// Copyright (c) 2015 Wikimedia Foundation. All rights reserved. +// + +#import "MWKSiteDataObject.h" + +@class MWKArticle; +@class MWKImage; + +@interface MWKImageMetadata : MWKSiteDataObject + +@property (readonly) MWKArticle *article; +@property (readonly) NSString *name; + +// Everything as MWKImageMetadataItem objects +@property (readonly) NSDictionary *extmetadata; + +// Some handy props +@property (readonly) NSString *license; // text +@property (readonly) NSString *licenseShortName; // text? +@property (readonly) NSString *licenseUrl; // link +@property (readonly) NSString *artist; // HTML + +-(instancetype)initWithArticle:(MWKArticle *)article name:(NSString *)name; +-(instancetype)initWithArticle:(MWKArticle *)article name:(NSString *)name dict:(NSDictionary *)dict; + +-(MWKImage *)largestImageVariant; + +-(void)save; +-(void)remove; + +@end diff --git a/MediaWikiKit/MediaWikiKit/MWKImageMetadata.m b/MediaWikiKit/MediaWikiKit/MWKImageMetadata.m new file mode 100644 index 0000000..e98f06d --- /dev/null +++ b/MediaWikiKit/MediaWikiKit/MWKImageMetadata.m @@ -0,0 +1,121 @@ +// +// MWKImageMetadata.m +// MediaWikiKit +// +// Created by Brion on 1/16/15. +// Copyright (c) 2015 Wikimedia Foundation. All rights reserved. +// + +#import "MediaWikiKit.h" + +@implementation MWKImageMetadata { + NSDictionary *_extmetadata; +} + +-(instancetype)initWithArticle:(MWKArticle *)article name:(NSString *)name +{ + self = [self initWithSite:article.site]; + if (self) { + _article = article; + _name = name; + _extmetadata = @{}; + } + return self; +} + +-(instancetype)initWithArticle:(MWKArticle *)article name:(NSString *)name dict:(NSDictionary *)dict +{ + self = [self initWithArticle:article name:name]; + if (self) { + _extmetadata = [self parseImageMetadata:dict]; + } + return self; +} + +-(NSDictionary *)parseImageMetadata:(NSDictionary *)dict +{ + NSArray *imageinfos = dict[@"imageinfo"]; + if (imageinfos == nil || [imageinfos count] == 0) { + return @{}; + } + + NSDictionary *imageinfo = imageinfos[0]; + NSMutableDictionary *outdict = [[NSMutableDictionary alloc] init]; + for (NSString *key in [imageinfo keyEnumerator]) { + outdict[key] = [[MWKImageMetadataItem alloc] initWithDict:imageinfo[key]]; + } + return [NSDictionary dictionaryWithDictionary:outdict]; +} + +-(NSDictionary *)dataExport +{ + NSMutableDictionary *fields = [[NSMutableDictionary alloc] init]; + for (NSString *key in [self.extmetadata keyEnumerator]) { + MWKImageMetadataItem *item = self.extmetadata[key]; + fields[key] = [item dataExport]; + } + return @{@"imageinfo": @[fields]}; +} + +#pragma mark - fetch methods + +-(MWKImage *)largestImageVariant +{ + return nil; +} + +#pragma mark - io methods + +-(void)save +{ + [self.article.dataStore saveImageMetadata:self]; +} + +-(NSString *)basePath +{ + NSString *articlePath = [self.article.dataStore pathForArticle:self.article]; + NSString *metaPath = [articlePath stringByAppendingPathComponent:@"ImageMetadata"]; + + // note: names are validated server-side. scary! + return [metaPath stringByAppendingPathComponent:self.name]; +} + +-(void)remove +{ + NSString *path = [self.article.dataStore pathForImageMetadata:self]; + + NSError *err = nil; + [[NSFileManager defaultManager] removeItemAtPath:path error:&err]; + + if (err) { + NSLog(@"err deleting image metadata: %@", err); + } +} + +#pragma mark - convenience properties + +-(NSString *)license +{ + MWKImageMetadataItem *item = self.extmetadata[@"License"]; + return item ? item.value : @""; +} + +-(NSString *)licenseShortName +{ + MWKImageMetadataItem *item = self.extmetadata[@"LicenseShortName"]; + return item ? item.value : @""; +} + +-(NSString *)licenseUrl +{ + MWKImageMetadataItem *item = self.extmetadata[@"LicenseUrl"]; + return item ? item.value : @""; +} + +-(NSString *)artist +{ + MWKImageMetadataItem *item = self.extmetadata[@"Artist"]; + return item ? item.value : @""; +} + +@end diff --git a/MediaWikiKit/MediaWikiKit/MWKImageMetadataItem.h b/MediaWikiKit/MediaWikiKit/MWKImageMetadataItem.h new file mode 100644 index 0000000..abde451 --- /dev/null +++ b/MediaWikiKit/MediaWikiKit/MWKImageMetadataItem.h @@ -0,0 +1,19 @@ +// +// MWKImageMetadataItem.h +// MediaWikiKit +// +// Created by Brion on 1/16/15. +// Copyright (c) 2015 Wikimedia Foundation. All rights reserved. +// + +#import "MWKDataObject.h" + +@interface MWKImageMetadataItem : MWKDataObject + +@property (readonly) NSString *value; +@property (readonly) NSString *source; +@property (readonly) BOOL hidden; + +-(instancetype)initWithDict:(NSDictionary *)dict; + +@end diff --git a/MediaWikiKit/MediaWikiKit/MWKImageMetadataItem.m b/MediaWikiKit/MediaWikiKit/MWKImageMetadataItem.m new file mode 100644 index 0000000..dc8f187 --- /dev/null +++ b/MediaWikiKit/MediaWikiKit/MWKImageMetadataItem.m @@ -0,0 +1,45 @@ +// +// MWKImageMetadataItem.m +// MediaWikiKit +// +// Created by Brion on 1/16/15. +// Copyright (c) 2015 Wikimedia Foundation. All rights reserved. +// + +#import "MWKImageMetadataItem.h" + +@implementation MWKImageMetadataItem + +-(instancetype)initWithDict:(NSDictionary *)dict +{ + self = [super init]; + if (self) { + if (dict[@"value"] != nil) { + _value = dict[@"value"]; + } else { + _value = @""; + } + + if (dict[@"source"] != nil) { + _source = dict[@"source"]; + } else { + _source = @""; + } + + _hidden = (dict[@"hidden"] != nil); + } + return self; +} + +-(NSDictionary *)dataExport +{ + NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; + dict[@"value"] = self.value; + dict[@"source"] = self.source; + if (self.hidden) { + dict[@"hidden"] = @""; + } + return [NSDictionary dictionaryWithDictionary:dict]; +} + +@end diff --git a/MediaWikiKit/MediaWikiKit/MediaWikiKit.h b/MediaWikiKit/MediaWikiKit/MediaWikiKit.h index cadd7f4..cde54e8 100644 --- a/MediaWikiKit/MediaWikiKit/MediaWikiKit.h +++ b/MediaWikiKit/MediaWikiKit/MediaWikiKit.h @@ -40,6 +40,9 @@ #import "MWKUserDataStore.h" +#import "MWKImageMetadataItem.h" +#import "MWKImageMetadata.h" + @interface MediaWikiKit : NSObject @end -- To view, visit https://gerrit.wikimedia.org/r/185548 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: If3781a6e514e142a05b07a4ccddfe3c52222dbdc Gerrit-PatchSet: 1 Gerrit-Project: apps/ios/wikipedia Gerrit-Branch: master Gerrit-Owner: Brion VIBBER <br...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits