Mhurd has submitted this change and it was merged.
Change subject: Old->new data importer
......................................................................
Old->new data importer
Notes on OldDataSchema:
* need -ObjC link option to not filter out 'unused' classes :P
this can probably be removed if classes are marked used other ways
* separate OldDataSchemaBundle.bundle used to get the Core Data object
definition
into the app, this can be removed if switch to a framework bundle in iOS
8-only
future?
Still left to do in future:
* progress indicator
* fix or remove broken code for conversion from PhoneGap app
Change-Id: I7234f714b7c368da09b8a63295c623394dfbc70a
---
M MediaWikiKit/MediaWikiKit/MWKUserDataStore.h
M MediaWikiKit/MediaWikiKit/MWKUserDataStore.m
M OldDataSchema/Categories/Article+Convenience.h
M OldDataSchema/Data/ArticleDataContextSingleton.m
M OldDataSchema/Data/Model/ArticleCoreDataObjects.h
M OldDataSchema/OldDataSchema.xcodeproj/project.pbxproj
M OldDataSchema/OldDataSchema/OldDataSchema.h
M OldDataSchema/OldDataSchema/OldDataSchema.m
A OldDataSchema/OldDataSchemaBundle/Info.plist
M Wikipedia.xcodeproj/project.pbxproj
M Wikipedia.xcodeproj/xcshareddata/xcschemes/Wikipedia-iOS.xcscheme
R wikipedia/Data/DataMigrator.h
R wikipedia/Data/DataMigrator.m
R wikipedia/Data/SQLiteHelper.h
R wikipedia/Data/SQLiteHelper.m
A wikipedia/Data/SchemaConverter.h
A wikipedia/Data/SchemaConverter.m
M wikipedia/View Controllers/WebView/WebViewController.m
18 files changed, 642 insertions(+), 15 deletions(-)
Approvals:
Mhurd: Verified; Looks good to me, approved
diff --git a/MediaWikiKit/MediaWikiKit/MWKUserDataStore.h
b/MediaWikiKit/MediaWikiKit/MWKUserDataStore.h
index b245b04..eccae62 100644
--- a/MediaWikiKit/MediaWikiKit/MWKUserDataStore.h
+++ b/MediaWikiKit/MediaWikiKit/MWKUserDataStore.h
@@ -23,6 +23,7 @@
-(instancetype)initWithDataStore:(MWKDataStore *)dataStore;
-(void)save;
+-(void)reset;
-(void)updateHistory:(MWKTitle *)title
discoveryMethod:(MWKHistoryDiscoveryMethod)discoveryMethod;
-(void)savePage:(MWKTitle *)title;
diff --git a/MediaWikiKit/MediaWikiKit/MWKUserDataStore.m
b/MediaWikiKit/MediaWikiKit/MWKUserDataStore.m
index 7e0e440..85eb80b 100644
--- a/MediaWikiKit/MediaWikiKit/MWKUserDataStore.m
+++ b/MediaWikiKit/MediaWikiKit/MWKUserDataStore.m
@@ -27,6 +27,14 @@
}
}
+/// Clear out any currently loaded data and force it to be reloaded on next use
+-(void)reset
+{
+ _historyList = nil;
+ _savedPageList = nil;
+ _recentSearchList = nil;
+}
+
-(instancetype)initWithDataStore:(MWKDataStore *)dataStore
{
self = [self init];
diff --git a/OldDataSchema/Categories/Article+Convenience.h
b/OldDataSchema/Categories/Article+Convenience.h
index 4c6a86f..2f732af 100644
--- a/OldDataSchema/Categories/Article+Convenience.h
+++ b/OldDataSchema/Categories/Article+Convenience.h
@@ -1,6 +1,8 @@
// Created by Monte Hurd on 12/23/13.
// Copyright (c) 2013 Wikimedia Foundation. Provided under MIT-style license;
please copy and modify!
+#import "UIKit/UIKit.h"
+
#import "Article.h"
@interface Article (Convenience)
diff --git a/OldDataSchema/Data/ArticleDataContextSingleton.m
b/OldDataSchema/Data/ArticleDataContextSingleton.m
index de5091d..ca49ef0 100644
--- a/OldDataSchema/Data/ArticleDataContextSingleton.m
+++ b/OldDataSchema/Data/ArticleDataContextSingleton.m
@@ -49,7 +49,9 @@
// Setup the masterContext and attach the persistant store to it.
self.masterContext = [[NSManagedObjectContext alloc]
initWithConcurrencyType:NSPrivateQueueConcurrencyType];
- NSManagedObjectModel *managedObjectModel = [NSManagedObjectModel
mergedModelFromBundles:nil];
+ NSString *bundlePath = [[NSBundle mainBundle]
pathForResource:@"OldDataSchemaBundle" ofType:@"bundle"];
+ NSBundle *bundle = [NSBundle bundleWithPath:bundlePath];
+ NSManagedObjectModel *managedObjectModel = [NSManagedObjectModel
mergedModelFromBundles:@[bundle]];
NSPersistentStoreCoordinator *persistentStoreCoordinator =
[[NSPersistentStoreCoordinator alloc]
initWithManagedObjectModel:managedObjectModel];
NSString *articlesDBPath = [[self documentRootPath]
stringByAppendingString:@"/articleData6.sqlite"];
diff --git a/OldDataSchema/Data/Model/ArticleCoreDataObjects.h
b/OldDataSchema/Data/Model/ArticleCoreDataObjects.h
index 7ae506b..c7cda9b 100644
--- a/OldDataSchema/Data/Model/ArticleCoreDataObjects.h
+++ b/OldDataSchema/Data/Model/ArticleCoreDataObjects.h
@@ -1,6 +1,6 @@
#import <CoreData/CoreData.h>
-//#import "Article+Convenience.h"
+#import "Article+Convenience.h"
#import "DiscoveryContext.h"
#import "Section.h"
#import "History.h"
diff --git a/OldDataSchema/OldDataSchema.xcodeproj/project.pbxproj
b/OldDataSchema/OldDataSchema.xcodeproj/project.pbxproj
index a663d97..2562281 100644
--- a/OldDataSchema/OldDataSchema.xcodeproj/project.pbxproj
+++ b/OldDataSchema/OldDataSchema.xcodeproj/project.pbxproj
@@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
+ D4E6D9111A5C65C0004916C1 /* ArticleData.xcdatamodeld in Sources
*/ = {isa = PBXBuildFile; fileRef = D4F478531A48CE0100D8043C /*
ArticleData.xcdatamodeld */; };
D4F4782E1A48CD8500D8043C /* OldDataSchema.h in CopyFiles */ =
{isa = PBXBuildFile; fileRef = D4F4782D1A48CD8500D8043C /* OldDataSchema.h */;
};
D4F478301A48CD8500D8043C /* OldDataSchema.m in Sources */ =
{isa = PBXBuildFile; fileRef = D4F4782F1A48CD8500D8043C /* OldDataSchema.m */;
};
D4F478661A48CE0200D8043C /* ArticleDataContextSingleton.m in
Sources */ = {isa = PBXBuildFile; fileRef = D4F4784E1A48CE0100D8043C /*
ArticleDataContextSingleton.m */; };
@@ -36,6 +37,8 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
+ D4E6D90A1A5C65B5004916C1 /* OldDataSchemaBundle.bundle */ =
{isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex =
0; path = OldDataSchemaBundle.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
+ D4E6D90D1A5C65B5004916C1 /* Info.plist */ = {isa =
PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist;
sourceTree = "<group>"; };
D4F4782A1A48CD8500D8043C /* libOldDataSchema.a */ = {isa =
PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path =
libOldDataSchema.a; sourceTree = BUILT_PRODUCTS_DIR; };
D4F4782D1A48CD8500D8043C /* OldDataSchema.h */ = {isa =
PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OldDataSchema.h;
sourceTree = "<group>"; };
D4F4782F1A48CD8500D8043C /* OldDataSchema.m */ = {isa =
PBXFileReference; lastKnownFileType = sourcecode.c.objc; path =
OldDataSchema.m; sourceTree = "<group>"; };
@@ -69,6 +72,13 @@
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
+ D4E6D9071A5C65B5004916C1 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
D4F478271A48CD8500D8043C /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@@ -79,10 +89,27 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
+ D4E6D90B1A5C65B5004916C1 /* OldDataSchemaBundle */ = {
+ isa = PBXGroup;
+ children = (
+ D4E6D90C1A5C65B5004916C1 /* Supporting Files */,
+ );
+ path = OldDataSchemaBundle;
+ sourceTree = "<group>";
+ };
+ D4E6D90C1A5C65B5004916C1 /* Supporting Files */ = {
+ isa = PBXGroup;
+ children = (
+ D4E6D90D1A5C65B5004916C1 /* Info.plist */,
+ );
+ name = "Supporting Files";
+ sourceTree = "<group>";
+ };
D4F478211A48CD8500D8043C = {
isa = PBXGroup;
children = (
D4F4782C1A48CD8500D8043C /* OldDataSchema */,
+ D4E6D90B1A5C65B5004916C1 /* OldDataSchemaBundle
*/,
D4F4782B1A48CD8500D8043C /* Products */,
);
sourceTree = "<group>";
@@ -91,6 +118,7 @@
isa = PBXGroup;
children = (
D4F4782A1A48CD8500D8043C /* libOldDataSchema.a
*/,
+ D4E6D90A1A5C65B5004916C1 /*
OldDataSchemaBundle.bundle */,
);
name = Products;
sourceTree = "<group>";
@@ -150,6 +178,23 @@
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
+ D4E6D9091A5C65B5004916C1 /* OldDataSchemaBundle */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = D4E6D9101A5C65B5004916C1 /*
Build configuration list for PBXNativeTarget "OldDataSchemaBundle" */;
+ buildPhases = (
+ D4E6D9061A5C65B5004916C1 /* Sources */,
+ D4E6D9071A5C65B5004916C1 /* Frameworks */,
+ D4E6D9081A5C65B5004916C1 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = OldDataSchemaBundle;
+ productName = OldDataSchemaBundle;
+ productReference = D4E6D90A1A5C65B5004916C1 /*
OldDataSchemaBundle.bundle */;
+ productType = "com.apple.product-type.bundle";
+ };
D4F478291A48CD8500D8043C /* OldDataSchema */ = {
isa = PBXNativeTarget;
buildConfigurationList = D4F4783E1A48CD8500D8043C /*
Build configuration list for PBXNativeTarget "OldDataSchema" */;
@@ -176,6 +221,9 @@
LastUpgradeCheck = 0610;
ORGANIZATIONNAME = "Wikimedia Foundation";
TargetAttributes = {
+ D4E6D9091A5C65B5004916C1 = {
+ CreatedOnToolsVersion = 6.1.1;
+ };
D4F478291A48CD8500D8043C = {
CreatedOnToolsVersion = 6.1.1;
};
@@ -194,11 +242,30 @@
projectRoot = "";
targets = (
D4F478291A48CD8500D8043C /* OldDataSchema */,
+ D4E6D9091A5C65B5004916C1 /* OldDataSchemaBundle
*/,
);
};
/* End PBXProject section */
+/* Begin PBXResourcesBuildPhase section */
+ D4E6D9081A5C65B5004916C1 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
/* Begin PBXSourcesBuildPhase section */
+ D4E6D9061A5C65B5004916C1 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D4E6D9111A5C65C0004916C1 /*
ArticleData.xcdatamodeld in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
D4F478261A48CD8500D8043C /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@@ -221,6 +288,39 @@
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
+ D4E6D90E1A5C65B5004916C1 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ INFOPLIST_FILE = OldDataSchemaBundle/Info.plist;
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles";
+ MACOSX_DEPLOYMENT_TARGET = 10.10;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = iphoneos;
+ SKIP_INSTALL = YES;
+ WRAPPER_EXTENSION = bundle;
+ };
+ name = Debug;
+ };
+ D4E6D90F1A5C65B5004916C1 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ INFOPLIST_FILE = OldDataSchemaBundle/Info.plist;
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles";
+ MACOSX_DEPLOYMENT_TARGET = 10.10;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = iphoneos;
+ SKIP_INSTALL = YES;
+ WRAPPER_EXTENSION = bundle;
+ };
+ name = Release;
+ };
D4F4783C1A48CD8500D8043C /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -254,6 +354,10 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = (
+ "$(inherited)",
+
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
+ );
IPHONEOS_DEPLOYMENT_TARGET = 8.1;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
@@ -288,6 +392,10 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = (
+ "$(inherited)",
+
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
+ );
IPHONEOS_DEPLOYMENT_TARGET = 8.1;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
@@ -316,6 +424,14 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
+ D4E6D9101A5C65B5004916C1 /* Build configuration list for
PBXNativeTarget "OldDataSchemaBundle" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ D4E6D90E1A5C65B5004916C1 /* Debug */,
+ D4E6D90F1A5C65B5004916C1 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ };
D4F478251A48CD8500D8043C /* Build configuration list for
PBXProject "OldDataSchema" */ = {
isa = XCConfigurationList;
buildConfigurations = (
diff --git a/OldDataSchema/OldDataSchema/OldDataSchema.h
b/OldDataSchema/OldDataSchema/OldDataSchema.h
index 77b5aa2..c74a4aa 100644
--- a/OldDataSchema/OldDataSchema/OldDataSchema.h
+++ b/OldDataSchema/OldDataSchema/OldDataSchema.h
@@ -14,6 +14,7 @@
@protocol OldDataSchemaDelegate
-(void)oldDataSchema:(OldDataSchema *)schema migrateArticle:(NSDictionary
*)articleDict;
+-(void)oldDataSchema:(OldDataSchema *)schema migrateImage:(NSDictionary
*)imageDict;
-(void)oldDataSchema:(OldDataSchema *)schema migrateHistoryEntry:(NSDictionary
*)historyDict;
-(void)oldDataSchema:(OldDataSchema *)schema migrateSavedEntry:(NSDictionary
*)savedDict;
@@ -26,5 +27,6 @@
-(BOOL)exists;
-(void)migrateData;
+-(void)removeOldData;
@end
diff --git a/OldDataSchema/OldDataSchema/OldDataSchema.m
b/OldDataSchema/OldDataSchema/OldDataSchema.m
index 8ad8d57..4190e04 100644
--- a/OldDataSchema/OldDataSchema/OldDataSchema.m
+++ b/OldDataSchema/OldDataSchema/OldDataSchema.m
@@ -14,19 +14,301 @@
@implementation OldDataSchema {
ArticleDataContextSingleton *context;
+ NSMutableSet *savedTitles;
}
--(BOOL)exists
+-(instancetype)init
+{
+ self = [super init];
+ if (self) {
+ savedTitles = [[NSMutableSet alloc] init];
+ if (self.exists) {
+ context = [ArticleDataContextSingleton sharedInstance];
+ } else {
+ context = nil;
+ }
+ }
+ return self;
+}
+
+-(NSString *)sqlitePath
{
NSArray *documentPaths =
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentRootPath = [documentPaths objectAtIndex:0];
NSString *filePath = [documentRootPath
stringByAppendingPathComponent:@"articleData6.sqlite"];
+ return filePath;
+}
+
+-(BOOL)exists
+{
+ NSString *filePath = [self sqlitePath];
return [[NSFileManager defaultManager] fileExistsAtPath:filePath];
}
+
+-(void)removeOldData
+{
+ NSString *filePath = [self sqlitePath];
+ NSString *backupPath = [filePath stringByAppendingString:@".bak"];
+ NSError *err = nil;
+ [[NSFileManager defaultManager] moveItemAtPath:filePath
+ toPath:backupPath
+ error:&err];
+ if (err) {
+ NSLog(@"Error backing up %@: %@", filePath, err);
+ }
+}
+
-(void)migrateData
{
// TODO
+ // 1) Go through saved article list, saving entries and (articles and
images)
+ // 2) Go through page reading history, saving entries and (articles and
images) when not already transferred
+
+ NSFetchRequest *req = [NSFetchRequest fetchRequestWithEntityName:@"Saved"];
+ req.sortDescriptors = @[[[NSSortDescriptor alloc] initWithKey:@"dateSaved"
ascending:YES]];
+ NSError *err;
+ NSArray *savedEntries = [context.mainContext executeFetchRequest:req
error:&err];
+ if (err) {
+ NSLog(@"Error reading old Saved entries: %@", err);
+ }
+ for (Saved *saved in savedEntries) {
+ [self migrateSaved:saved];
+ [self migrateArticle:saved.article];
+ }
+
+ NSFetchRequest *req2 = [NSFetchRequest
fetchRequestWithEntityName:@"History"];
+ req2.sortDescriptors = @[[[NSSortDescriptor alloc]
initWithKey:@"dateVisited" ascending:YES]];
+ NSError *err2;
+ NSArray *historyEntries = [context.mainContext executeFetchRequest:req2
error:&err2];
+ if (err2) {
+ NSLog(@"Error reading old History entries: %@", err2);
+ }
+ for (History *history in historyEntries) {
+ [self migrateHistory:history];
+ [self migrateArticle:history.article];
+ }
+}
+
+-(void)migrateSaved:(Saved *)saved
+{
+ NSDictionary *dict = [self exportSaved:saved];
+ [self.delegate oldDataSchema:self migrateSavedEntry:dict];
+}
+
+-(void)migrateHistory:(History *)history
+{
+ NSDictionary *dict = [self exportHistory:history];
+ [self.delegate oldDataSchema:self migrateHistoryEntry:dict];
+}
+
+-(void)migrateArticle:(Article *)article
+{
+ NSString *key = [NSString stringWithFormat:@"%@:%@", article.domain,
article.title];
+ if ([savedTitles containsObject:key]) {
+ // already imported this article
+ } else {
+ // Record for later to avoid dupe imports
+ [savedTitles addObject:key];
+
+ NSDictionary *dict = [self exportArticle:article];
+ [self.delegate oldDataSchema:self migrateArticle:dict];
+
+ Image *thumbnail = article.thumbnailImage;
+ if (thumbnail) {
+ [self migrateThumbnailImage:thumbnail article:article];
+ }
+
+ // Find its images...
+ for (Section *section in article.section) {
+ for (SectionImage *sectionImage in section.sectionImage) {
+ [self migrateImage:sectionImage];
+ }
+ }
+ }
+}
+
+-(void)migrateThumbnailImage:(Image *)thumbnailImage article:(Article *)article
+{
+ NSDictionary *dict = [self exportThumbnailImage:thumbnailImage
article:article];
+ [self.delegate oldDataSchema:self migrateImage:dict];
+}
+
+-(void)migrateImage:(SectionImage *)sectionImage
+{
+ NSDictionary *dict = [self exportImage:sectionImage];
+ [self.delegate oldDataSchema:self migrateImage:dict];
+}
+
+-(NSDictionary *)exportSaved:(Saved *)saved
+{
+ return @{
+ @"domain": @"wikipedia.org",
+ @"language": saved.article.domain,
+ @"title": saved.article.title,
+ @"date": [self stringWithDate:saved.dateSaved]
+ };
+}
+
+-(NSDictionary *)exportHistory:(History *)history
+{
+ return @{
+ @"domain": @"wikipedia.org",
+ @"language": history.article.domain,
+ @"title": history.article.title,
+ @"date": [self stringWithDate:history.dateVisited],
+ @"discoveryMethod": history.discoveryMethod,
+ @"scrollPosition": history.article.lastScrollY
+ };
+}
+
+-(NSDictionary *)exportArticle:(Article *)article
+{
+ NSMutableDictionary *dict = [@{} mutableCopy];
+
+ if (article.redirected) {
+ dict[@"redirected"] = article.redirected;
+ }
+ if (article.lastmodified) {
+ dict[@"lastmodified"] = [self stringWithDate:article.lastmodified];
+ }
+ if (article.lastmodifiedby) {
+ dict[@"lastmodifiedby"] = @{
+ @"name": article.lastmodifiedby,
+ @"gender": @"unknown"
+ };
+ }
+ if (article.articleId) {
+ dict[@"id"] = article.articleId;
+ }
+ if (article.languagecount) {
+ dict[@"languagecount"] = article.languagecount;
+ }
+ if (article.displayTitle) {
+ dict[@"displaytitle"] = article.displayTitle;
+ }
+ if (article.protectionStatus) {
+ dict[@"protection"] = @{
+ @"edit": article.protectionStatus
+ };
+ }
+ if (article.editable) {
+ dict[@"editable"] = @"";
+ }
+
+ if (article.thumbnailImage) {
+ dict[@"thumbnailURL"] = article.thumbnailImage.sourceUrl;
+ }
+
+ // sections!
+ NSUInteger numSections = [article.section count];
+ if (numSections) {
+ dict[@"sections"] = [[NSMutableArray alloc]
initWithCapacity:numSections];
+ for (int i = 0; i < numSections; i++) {
+ dict[@"sections"][i] = [NSNull null]; // stub out
+ }
+ for (Section *section in article.section) {
+ int sectionId = [section.sectionId intValue];
+ dict[@"sections"][sectionId] = [self exportSection:section];
+ }
+ }
+
+ return @{
+ @"language": article.domain,
+ @"title": article.title,
+ @"dict": dict
+ };
+}
+
+-(NSDictionary *)exportSection:(Section *)section
+{
+ NSMutableDictionary *dict = [@{} mutableCopy];
+
+ if (section.tocLevel) {
+ dict[@"toclevel"] = section.tocLevel;
+ }
+ if (section.level) {
+ dict[@"level"] = section.level;
+ }
+ if (section.title) {
+ dict[@"line"] = section.title;
+ }
+ if (section.fromTitle) {
+ dict[@"fromtitle"] = section.fromTitle;
+ }
+ if (section.anchor) {
+ dict[@"anchor"] = section.anchor;
+ }
+ dict[@"id"] = section.sectionId;
+ if (section.html) {
+ dict[@"text"] = section.html;
+ }
+
+ return dict;
+}
+
+-(NSDictionary *)exportThumbnailImage:(Image *)image article:(Article *)article
+{
+ ImageData *imageData = image.imageData;
+
+ NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
+
+ dict[@"domain"] = @"wikipedia.org";
+ dict[@"language"] = article.domain;
+ dict[@"title"] = article.title;
+
+ dict[@"sectionId"] = @(-1);
+
+ dict[@"sourceURL"] = image.sourceUrl;
+ if (imageData.data) {
+ dict[@"data"] = imageData.data;
+ }
+
+ return dict;
+}
+
+-(NSDictionary *)exportImage:(SectionImage *)sectionImage
+{
+ Section *section = sectionImage.section;
+ Article *article = section.article;
+ Image *image = sectionImage.image;
+ ImageData *imageData = image.imageData;
+
+ NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
+
+ dict[@"domain"] = @"wikipedia.org";
+ dict[@"language"] = article.domain;
+ dict[@"title"] = article.title;
+
+ dict[@"sectionId"] = section.sectionId;
+
+ dict[@"sourceURL"] = image.sourceUrl;
+ if (imageData.data) {
+ dict[@"data"] = imageData.data;
+ }
+
+ return dict;
+}
+
+#pragma mark - date methods
+
+- (NSDateFormatter *)iso8601Formatter
+{
+ // See: https://www.mediawiki.org/wiki/Manual:WfTimestamp
+ NSDateFormatter * formatter = [[NSDateFormatter alloc] init];
+ [formatter setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]];
+ [formatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"];
+ return formatter;
+}
+
+- (NSDate *)dateWithString:(NSString *)string
+{
+ return [[self iso8601Formatter] dateFromString:string];
+}
+
+- (NSString *)stringWithDate:(NSDate *)date
+{
+ return [[self iso8601Formatter] stringFromDate:date];
}
@end
diff --git a/OldDataSchema/OldDataSchemaBundle/Info.plist
b/OldDataSchema/OldDataSchemaBundle/Info.plist
new file mode 100644
index 0000000..6011a73
--- /dev/null
+++ b/OldDataSchema/OldDataSchemaBundle/Info.plist
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleExecutable</key>
+ <string>$(EXECUTABLE_NAME)</string>
+ <key>CFBundleIdentifier</key>
+ <string>org.wikimedia.$(PRODUCT_NAME:rfc1034identifier)</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>$(PRODUCT_NAME)</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+ <key>NSHumanReadableCopyright</key>
+ <string>Copyright © 2015 Wikimedia Foundation. All rights
reserved.</string>
+ <key>NSPrincipalClass</key>
+ <string></string>
+</dict>
+</plist>
diff --git a/Wikipedia.xcodeproj/project.pbxproj
b/Wikipedia.xcodeproj/project.pbxproj
index 426cc7e..11098ab 100644
--- a/Wikipedia.xcodeproj/project.pbxproj
+++ b/Wikipedia.xcodeproj/project.pbxproj
@@ -180,6 +180,7 @@
04F27B7818FE0F2E00EDD838 /* PageHistoryViewController.m in
Sources */ = {isa = PBXBuildFile; fileRef = 04F27B7418FE0F2E00EDD838 /*
PageHistoryViewController.m */; };
04F39590186CF80100B0D6FC /* TOCViewController.m in Sources */ =
{isa = PBXBuildFile; fileRef = 04F3958F186CF80100B0D6FC /* TOCViewController.m
*/; };
C9180EC418AED30C006C1DCA /* WikipediaAppUtils.m in Sources */ =
{isa = PBXBuildFile; fileRef = C9180EC318AED30C006C1DCA /* WikipediaAppUtils.m
*/; };
+ D407E6411A51DBDA00CCC8B1 /* SchemaConverter.m in Sources */ =
{isa = PBXBuildFile; fileRef = D407E6401A51DBDA00CCC8B1 /* SchemaConverter.m
*/; };
D42E75EB18D11237002EA7E5 /* MWLanguageInfo.m in Sources */ =
{isa = PBXBuildFile; fileRef = D42E75EA18D11237002EA7E5 /* MWLanguageInfo.m */;
};
D46CD8C418A1AC4F0042959E /* InfoPlist.strings in Resources */ =
{isa = PBXBuildFile; fileRef = D46CD8C018A1AC4F0042959E /* InfoPlist.strings
*/; };
D46CD8C518A1AC4F0042959E /* Localizable.strings in Resources */
= {isa = PBXBuildFile; fileRef = D46CD8C218A1AC4F0042959E /*
Localizable.strings */; };
@@ -201,8 +202,10 @@
D4B0AE0819366A0A00F0AC90 /* CreateAccountFunnel.m in Sources */
= {isa = PBXBuildFile; fileRef = D4B0AE0719366A0A00F0AC90 /*
CreateAccountFunnel.m */; };
D4B0AE0B19366A2C00F0AC90 /* ReadingActionFunnel.m in Sources */
= {isa = PBXBuildFile; fileRef = D4B0AE0A19366A2C00F0AC90 /*
ReadingActionFunnel.m */; };
D4B0AE0E19366A5400F0AC90 /* LoginFunnel.m in Sources */ = {isa
= PBXBuildFile; fileRef = D4B0AE0D19366A5400F0AC90 /* LoginFunnel.m */; };
+ D4B7794D1A5F36F700D06E00 /* OldDataSchemaBundle.bundle in
Resources */ = {isa = PBXBuildFile; fileRef = D4E6D9161A5C65FA004916C1 /*
OldDataSchemaBundle.bundle */; };
D4BC22B4181E9E6300CAC673 /* empty.png in Resources */ = {isa =
PBXBuildFile; fileRef = D4BC22B3181E9E6300CAC673 /* empty.png */; };
D4C16A6819709CDF00CD91AD /* (null) in Resources */ = {isa =
PBXBuildFile; };
+ D4E6D9121A5C65F9004916C1 /* CoreData.framework in Frameworks */
= {isa = PBXBuildFile; fileRef = 040E5C4E184566F4007AFE6F /* CoreData.framework
*/; };
D4E8A8A4190835C100DA4765 /* DataMigrator.m in Sources */ = {isa
= PBXBuildFile; fileRef = D4E8A8A3190835C100DA4765 /* DataMigrator.m */; };
D4E8A8A719084F1300DA4765 /* SQLiteHelper.m in Sources */ = {isa
= PBXBuildFile; fileRef = D4E8A8A619084F1300DA4765 /* SQLiteHelper.m */; };
D4E8A8A919085CEA00DA4765 /* libsqlite3.dylib in Frameworks */ =
{isa = PBXBuildFile; fileRef = D4E8A8A819085CEA00DA4765 /* libsqlite3.dylib */;
};
@@ -267,6 +270,13 @@
proxyType = 1;
remoteGlobalIDString = C73D7690357B1F8585BBD225;
remoteInfo = "Pods-hpple";
+ };
+ D4E6D9151A5C65FA004916C1 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = D4F478441A48CD8500D8043C /*
OldDataSchema.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = D4E6D90A1A5C65B5004916C1;
+ remoteInfo = OldDataSchemaBundle;
};
D4F478491A48CD8700D8043C /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
@@ -496,8 +506,8 @@
04AE1C6F1891B302002D5487 /* NSObject+Extras.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path
= "NSObject+Extras.m"; sourceTree = "<group>"; };
04AE520319DB5E0900F89B92 /* NSObject+ConstraintsScale.h */ =
{isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h;
path = "NSObject+ConstraintsScale.h"; sourceTree = "<group>"; };
04AE520419DB5E0900F89B92 /* NSObject+ConstraintsScale.m */ =
{isa = PBXFileReference; fileEncoding = 4; lastKnownFileType =
sourcecode.c.objc; path = "NSObject+ConstraintsScale.m"; sourceTree =
"<group>"; };
- 04B0EA43190AFDD8007458AF /* ArticleImporter.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path =
ArticleImporter.h; sourceTree = "<group>"; };
- 04B0EA44190AFDD8007458AF /* ArticleImporter.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path
= ArticleImporter.m; sourceTree = "<group>"; };
+ 04B0EA43190AFDD8007458AF /* ArticleImporter.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name =
ArticleImporter.h; path = wikipedia/Importer/ArticleImporter.h; sourceTree =
SOURCE_ROOT; };
+ 04B0EA44190AFDD8007458AF /* ArticleImporter.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name
= ArticleImporter.m; path = wikipedia/Importer/ArticleImporter.m; sourceTree =
SOURCE_ROOT; };
04B0EA46190B2319007458AF /* PreviewLicenseView.xib */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path =
PreviewLicenseView.xib; sourceTree = "<group>"; };
04B0EA48190B2348007458AF /* PreviewLicenseView.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path =
PreviewLicenseView.h; sourceTree = "<group>"; };
04B0EA49190B2348007458AF /* PreviewLicenseView.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path
= PreviewLicenseView.m; sourceTree = "<group>"; };
@@ -604,6 +614,8 @@
04F3958F186CF80100B0D6FC /* TOCViewController.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path
= TOCViewController.m; sourceTree = "<group>"; };
C9180EC218AED30C006C1DCA /* WikipediaAppUtils.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path =
WikipediaAppUtils.h; sourceTree = "<group>"; };
C9180EC318AED30C006C1DCA /* WikipediaAppUtils.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path
= WikipediaAppUtils.m; sourceTree = "<group>"; };
+ D407E63F1A51DBDA00CCC8B1 /* SchemaConverter.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name =
SchemaConverter.h; path = wikipedia/Data/SchemaConverter.h; sourceTree =
SOURCE_ROOT; };
+ D407E6401A51DBDA00CCC8B1 /* SchemaConverter.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name
= SchemaConverter.m; path = wikipedia/Data/SchemaConverter.m; sourceTree =
SOURCE_ROOT; };
D42E75E918D11237002EA7E5 /* MWLanguageInfo.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name =
MWLanguageInfo.h; path = "mw-support/MWLanguageInfo.h"; sourceTree = "<group>";
};
D42E75EA18D11237002EA7E5 /* MWLanguageInfo.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name
= MWLanguageInfo.m; path = "mw-support/MWLanguageInfo.m"; sourceTree =
"<group>"; };
D442F58619709E540013A2CA /* qqq */ = {isa = PBXFileReference;
lastKnownFileType = text.plist.strings; name = qqq; path =
qqq.lproj/Main_iPhone.strings; sourceTree = "<group>"; };
@@ -820,10 +832,10 @@
D4C16A6119708B0E00CD91AD /* krc */ = {isa = PBXFileReference;
lastKnownFileType = text.plist.strings; name = krc; path =
krc.lproj/Main_iPhone.strings; sourceTree = "<group>"; };
D4C16A6419709CDF00CD91AD /* qqq */ = {isa = PBXFileReference;
lastKnownFileType = text.plist.strings; name = qqq; path =
qqq.lproj/InfoPlist.strings; sourceTree = "<group>"; };
D4C16A6519709CDF00CD91AD /* qqq */ = {isa = PBXFileReference;
lastKnownFileType = text.plist.strings; name = qqq; path =
qqq.lproj/Localizable.strings; sourceTree = "<group>"; };
- D4E8A8A2190835C100DA4765 /* DataMigrator.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name =
DataMigrator.h; path = wikipedia/DataMigrator.h; sourceTree = SOURCE_ROOT; };
- D4E8A8A3190835C100DA4765 /* DataMigrator.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name
= DataMigrator.m; path = wikipedia/DataMigrator.m; sourceTree = SOURCE_ROOT; };
- D4E8A8A519084F1300DA4765 /* SQLiteHelper.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path =
SQLiteHelper.h; sourceTree = "<group>"; };
- D4E8A8A619084F1300DA4765 /* SQLiteHelper.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path
= SQLiteHelper.m; sourceTree = "<group>"; };
+ D4E8A8A2190835C100DA4765 /* DataMigrator.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name =
DataMigrator.h; path = wikipedia/Data/DataMigrator.h; sourceTree = SOURCE_ROOT;
};
+ D4E8A8A3190835C100DA4765 /* DataMigrator.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name
= DataMigrator.m; path = wikipedia/Data/DataMigrator.m; sourceTree =
SOURCE_ROOT; };
+ D4E8A8A519084F1300DA4765 /* SQLiteHelper.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name =
SQLiteHelper.h; path = wikipedia/Data/SQLiteHelper.h; sourceTree = SOURCE_ROOT;
};
+ D4E8A8A619084F1300DA4765 /* SQLiteHelper.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name
= SQLiteHelper.m; path = wikipedia/Data/SQLiteHelper.m; sourceTree =
SOURCE_ROOT; };
D4E8A8A819085CEA00DA4765 /* libsqlite3.dylib */ = {isa =
PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name =
libsqlite3.dylib; path = usr/lib/libsqlite3.dylib; sourceTree = SDKROOT; };
D4F277F9194235A00032BA38 /* ProtectedEditAttemptFunnel.h */ =
{isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h;
name = ProtectedEditAttemptFunnel.h; path =
EventLogging/ProtectedEditAttemptFunnel.h; sourceTree = "<group>"; };
D4F277FA194235A00032BA38 /* ProtectedEditAttemptFunnel.m */ =
{isa = PBXFileReference; fileEncoding = 4; lastKnownFileType =
sourcecode.c.objc; name = ProtectedEditAttemptFunnel.m; path =
EventLogging/ProtectedEditAttemptFunnel.m; sourceTree = "<group>"; };
@@ -838,6 +850,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ D4E6D9121A5C65F9004916C1 /* CoreData.framework
in Frameworks */,
D4F478741A48D1B100D8043C /* libOldDataSchema.a
in Frameworks */,
D497FCFB1A080810004A36A5 /* libMediaWikiKit.a
in Frameworks */,
D4AD975019F99E9000957451 /* libPods-hpple.a in
Frameworks */,
@@ -860,8 +873,9 @@
D4E8A8A11908357600DA4765 /* Data Migration */,
04B0EA42190AFDBA007458AF /* Importer */,
);
- path = Data;
- sourceTree = "<group>";
+ name = Data;
+ path = wikipedia/Data;
+ sourceTree = SOURCE_ROOT;
};
0412CC5F192536580010E616 /* Root */ = {
isa = PBXGroup;
@@ -1289,7 +1303,7 @@
);
name = Importer;
path = ../Importer;
- sourceTree = "<group>";
+ sourceTree = SOURCE_ROOT;
};
04B60509193522650007185A /* MenuButton */ = {
isa = PBXGroup;
@@ -1743,10 +1757,12 @@
D4E8A8A3190835C100DA4765 /* DataMigrator.m */,
D4E8A8A519084F1300DA4765 /* SQLiteHelper.h */,
D4E8A8A619084F1300DA4765 /* SQLiteHelper.m */,
+ D407E63F1A51DBDA00CCC8B1 /* SchemaConverter.h
*/,
+ D407E6401A51DBDA00CCC8B1 /* SchemaConverter.m
*/,
);
name = "Data Migration";
path = ..;
- sourceTree = "<group>";
+ sourceTree = SOURCE_ROOT;
};
D4EE00BB182445670090790F /* mw-support */ = {
isa = PBXGroup;
@@ -1762,6 +1778,7 @@
isa = PBXGroup;
children = (
D4F4784A1A48CD8700D8043C /* libOldDataSchema.a
*/,
+ D4E6D9161A5C65FA004916C1 /*
OldDataSchemaBundle.bundle */,
);
name = Products;
sourceTree = "<group>";
@@ -1952,6 +1969,13 @@
remoteRef = D4AD974819F99CD700957451 /*
PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
+ D4E6D9161A5C65FA004916C1 /* OldDataSchemaBundle.bundle */ = {
+ isa = PBXReferenceProxy;
+ fileType = wrapper.cfbundle;
+ path = OldDataSchemaBundle.bundle;
+ remoteRef = D4E6D9151A5C65FA004916C1 /*
PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
D4F4784A1A48CD8700D8043C /* libOldDataSchema.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
@@ -1966,6 +1990,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ D4B7794D1A5F36F700D06E00 /*
OldDataSchemaBundle.bundle in Resources */,
04D3082C19991CB60034F106 /*
[email protected] in Resources */,
D46CD8C418A1AC4F0042959E /* InfoPlist.strings
in Resources */,
045EFF1B19A25FEB00D0EDBB /*
[email protected] in Resources */,
@@ -2184,6 +2209,7 @@
047801BE18AE987900DBB747 /*
UIButton+ColorMask.m in Sources */,
0429300A18604898002A13FC /*
SavedPagesResultCell.m in Sources */,
0487048419F8262600B7D307 /* CaptchaResetter.m
in Sources */,
+ D407E6411A51DBDA00CCC8B1 /* SchemaConverter.m
in Sources */,
04821CD119895EDC007558F6 /*
ReferenceGradientView.m in Sources */,
0460F8DC19B0F932001BC59B /* CenteredPathView.m
in Sources */,
0472BC18193AD88C00C40BDA /*
MWKSection+DisplayHtml.m in Sources */,
@@ -2551,10 +2577,12 @@
"$(PROJECT_DIR)/cocoapods/Pods/Headers/Public/AFNetworking",
"$(PROJECT_DIR)/cocoapods/Pods/Headers/Public/hpple",
"$(PROJECT_DIR)/MediaWikiKit/MediaWikiKit",
+ "$(PROJECT_DIR)/OldDataSchema/**",
);
INFOPLIST_FILE =
"Wikipedia/Wikipedia-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
LIBRARY_SEARCH_PATHS = "$(inherited)";
+ OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = Wikipedia;
PROVISIONING_PROFILE = "";
WRAPPER_EXTENSION = app;
@@ -2648,10 +2676,12 @@
"$(PROJECT_DIR)/cocoapods/Pods/Headers/Public/AFNetworking",
"$(PROJECT_DIR)/cocoapods/Pods/Headers/Public/hpple",
"$(PROJECT_DIR)/MediaWikiKit/MediaWikiKit",
+ "$(PROJECT_DIR)/OldDataSchema/**",
);
INFOPLIST_FILE =
"Wikipedia/Wikipedia-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
LIBRARY_SEARCH_PATHS = "$(inherited)";
+ OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = Wikipedia;
PROVISIONING_PROFILE = "";
WRAPPER_EXTENSION = app;
@@ -2674,10 +2704,12 @@
"$(PROJECT_DIR)/cocoapods/Pods/Headers/Public/AFNetworking",
"$(PROJECT_DIR)/cocoapods/Pods/Headers/Public/hpple",
"$(PROJECT_DIR)/MediaWikiKit/MediaWikiKit",
+ "$(PROJECT_DIR)/OldDataSchema/**",
);
INFOPLIST_FILE =
"Wikipedia/Wikipedia-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
LIBRARY_SEARCH_PATHS = "$(inherited)";
+ OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = Wikipedia;
PROVISIONING_PROFILE = "";
WRAPPER_EXTENSION = app;
diff --git a/Wikipedia.xcodeproj/xcshareddata/xcschemes/Wikipedia-iOS.xcscheme
b/Wikipedia.xcodeproj/xcshareddata/xcschemes/Wikipedia-iOS.xcscheme
index 2ddce9c..3bbc795 100644
--- a/Wikipedia.xcodeproj/xcshareddata/xcschemes/Wikipedia-iOS.xcscheme
+++ b/Wikipedia.xcodeproj/xcshareddata/xcschemes/Wikipedia-iOS.xcscheme
@@ -34,6 +34,20 @@
ReferencedContainer = "container:Wikipedia.xcodeproj">
</BuildableReference>
</BuildActionEntry>
+ <BuildActionEntry
+ buildForTesting = "YES"
+ buildForRunning = "YES"
+ buildForProfiling = "YES"
+ buildForArchiving = "YES"
+ buildForAnalyzing = "YES">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "D4E6D9091A5C65B5004916C1"
+ BuildableName = "OldDataSchemaBundle.bundle"
+ BlueprintName = "OldDataSchemaBundle"
+ ReferencedContainer =
"container:OldDataSchema/OldDataSchema.xcodeproj">
+ </BuildableReference>
+ </BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
diff --git a/wikipedia/DataMigrator.h b/wikipedia/Data/DataMigrator.h
similarity index 100%
rename from wikipedia/DataMigrator.h
rename to wikipedia/Data/DataMigrator.h
diff --git a/wikipedia/DataMigrator.m b/wikipedia/Data/DataMigrator.m
similarity index 100%
rename from wikipedia/DataMigrator.m
rename to wikipedia/Data/DataMigrator.m
diff --git a/wikipedia/SQLiteHelper.h b/wikipedia/Data/SQLiteHelper.h
similarity index 100%
rename from wikipedia/SQLiteHelper.h
rename to wikipedia/Data/SQLiteHelper.h
diff --git a/wikipedia/SQLiteHelper.m b/wikipedia/Data/SQLiteHelper.m
similarity index 100%
rename from wikipedia/SQLiteHelper.m
rename to wikipedia/Data/SQLiteHelper.m
diff --git a/wikipedia/Data/SchemaConverter.h b/wikipedia/Data/SchemaConverter.h
new file mode 100644
index 0000000..25e854f
--- /dev/null
+++ b/wikipedia/Data/SchemaConverter.h
@@ -0,0 +1,23 @@
+//
+// SchemaConverter.h
+// Wikipedia
+//
+// Created by Brion on 12/29/14.
+// Copyright (c) 2014 Wikimedia Foundation. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+#import "OldDataSchema.h"
+
+#import "MediaWikiKit.h"
+
+@interface SchemaConverter : NSObject <OldDataSchemaDelegate>
+
+@property OldDataSchema *schema;
+@property MWKDataStore *dataStore;
+@property MWKUserDataStore *userDataStore;
+
+-(instancetype)initWithDataStore:(MWKDataStore *)dataStore;
+
+@end
diff --git a/wikipedia/Data/SchemaConverter.m b/wikipedia/Data/SchemaConverter.m
new file mode 100644
index 0000000..45bda53
--- /dev/null
+++ b/wikipedia/Data/SchemaConverter.m
@@ -0,0 +1,92 @@
+//
+// SchemaConverter.m
+// Wikipedia
+//
+// Created by Brion on 12/29/14.
+// Copyright (c) 2014 Wikimedia Foundation. All rights reserved.
+//
+
+#import "SchemaConverter.h"
+
+@implementation SchemaConverter
+
+-(instancetype)initWithDataStore:(MWKDataStore *)dataStore
+{
+ self = [super init];
+ if (self) {
+ self.dataStore = dataStore;
+ self.userDataStore = [self.dataStore userDataStore];
+ }
+ return self;
+}
+
+-(void)oldDataSchema:(OldDataSchema *)schema migrateArticle:(NSDictionary
*)articleDict
+{
+ NSString *language = articleDict[@"language"];
+ NSString *titleStr = articleDict[@"title"];
+ NSDictionary *mobileview = articleDict[@"dict"];
+
+ MWKSite *site = [[MWKSite alloc] initWithDomain:@"wikipedia.org"
language:language];
+ MWKTitle *title = [site titleWithString:titleStr];
+ MWKArticle *article = [self.dataStore articleWithTitle:title];
+ [article importMobileViewJSON:mobileview];
+ [article save];
+}
+
+-(void)oldDataSchema:(OldDataSchema *)schema migrateImage:(NSDictionary
*)imageDict
+{
+ NSString *language = imageDict[@"language"];
+ NSString *titleStr = imageDict[@"title"];
+ NSString *sourceURL = imageDict[@"sourceURL"];
+ int sectionId = [imageDict[@"sectionId"] intValue];
+ NSData *imageData = imageDict[@"data"];
+
+ // @todo cache the article object?
+ MWKSite *site = [[MWKSite alloc] initWithDomain:@"wikipedia.org"
language:language];
+ MWKTitle *title = [site titleWithString:titleStr];
+ MWKArticle *article = [self.dataStore articleWithTitle:title];
+
+ MWKImage *image = [article importImageURL:sourceURL sectionId:sectionId];
+ [image importImageData:imageData];
+}
+
+-(void)oldDataSchema:(OldDataSchema *)schema migrateHistoryEntry:(NSDictionary
*)historyDict
+{
+ NSString *language = historyDict[@"language"];
+ NSString *titleStr = historyDict[@"title"];
+ NSString *date = historyDict[@"date"];
+ NSString *discoveryMethod = historyDict[@"discoveryMethod"];
+
+ NSMutableDictionary *dict = [@{} mutableCopy];
+ dict[@"domain"] = @"wikipedia.org";
+ dict[@"language"] = language;
+ dict[@"title"] = titleStr;
+ dict[@"date"] = date;
+ dict[@"discoveryMethod"] = discoveryMethod;
+ dict[@"scrollPosition"] = @(0); // @fixme extract from article?
+
+ MWKHistoryEntry *entry = [[MWKHistoryEntry alloc] initWithDict:dict];
+
+ MWKHistoryList *historyList = self.userDataStore.historyList;
+ [historyList addEntry:entry];
+ [self.userDataStore save];
+}
+
+-(void)oldDataSchema:(OldDataSchema *)schema migrateSavedEntry:(NSDictionary
*)savedDict
+{
+ NSString *language = savedDict[@"language"];
+ NSString *titleStr = savedDict[@"title"];
+
+ NSMutableDictionary *dict = [@{} mutableCopy];
+ dict[@"domain"] = @"wikipedia.org";
+ dict[@"language"] = language;
+ dict[@"title"] = titleStr;
+
+ MWKSavedPageEntry *entry = [[MWKSavedPageEntry alloc] initWithDict:dict];
+
+ MWKSavedPageList *savedPageList = self.userDataStore.savedPageList;
+ [savedPageList addEntry:entry];
+ [self.userDataStore save];
+}
+
+@end
diff --git a/wikipedia/View Controllers/WebView/WebViewController.m
b/wikipedia/View Controllers/WebView/WebViewController.m
index 61fe777..cadcd34 100644
--- a/wikipedia/View Controllers/WebView/WebViewController.m
+++ b/wikipedia/View Controllers/WebView/WebViewController.m
@@ -54,6 +54,8 @@
#import "AssetsFileFetcher.h"
#import "LeadImageContainer.h"
+#import "OldDataSchema.h"
+#import "SchemaConverter.h"
//#import "UIView+Debugging.h"
@@ -1849,6 +1851,28 @@
- (void)migrateDataIfNecessary
{
+ // Middle-Ages Converter
+ // From the native app's initial CoreData-based implementation,
+ // which now lives in OldDataSchema subproject.
+ OldDataSchema *oldDataSchema = [[OldDataSchema alloc] init];
+ if ([oldDataSchema exists]) {
+ SchemaConverter *schemaConverter = [[SchemaConverter alloc]
initWithDataStore:session.dataStore];
+ oldDataSchema.delegate = schemaConverter;
+ NSLog(@"begin migration");
+ [oldDataSchema migrateData];
+ NSLog(@"end migration");
+
+ [oldDataSchema removeOldData];
+
+ // hack for history fix
+ [session.userDataStore reset];
+
+ return;
+ }
+
+ // Ye Ancient Converter
+ // From the old PhoneGap app
+ // @fixme: fix this to work again
DataMigrator *dataMigrator = [[DataMigrator alloc] init];
if ([dataMigrator hasData]) {
NSLog(@"Old data to migrate found!");
@@ -1862,10 +1886,11 @@
[importer importArticles:titles];
[dataMigrator removeOldData];
- } else {
- NSLog(@"No old data to migrate.");
+
+ return;
}
+ NSLog(@"No old data to migrate.");
}
#pragma mark Bottom menu bar
--
To view, visit https://gerrit.wikimedia.org/r/183091
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I7234f714b7c368da09b8a63295c623394dfbc70a
Gerrit-PatchSet: 9
Gerrit-Project: apps/ios/wikipedia
Gerrit-Branch: master
Gerrit-Owner: Brion VIBBER <[email protected]>
Gerrit-Reviewer: Brion VIBBER <[email protected]>
Gerrit-Reviewer: Dr0ptp4kt <[email protected]>
Gerrit-Reviewer: Mhurd <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits