Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

Migrating tabs and bookmarks from Ghostery

  • Loading branch information
mahmoud-adam85 committed May 9, 2018
1 parent 6c62acb commit f0c3411170c52028faaa2286f31c29e07ef49c15
@@ -47,9 +47,14 @@
1E3CBC152057D83700898B05 /* CliqzAppSettingsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E3CBC142057D83700898B05 /* CliqzAppSettingsTableViewController.swift */; };
1E3CBC1D205806F000898B05 /* DateExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E3CBC1C205806F000898B05 /* DateExtension.swift */; };
1E3FBF59207763FE00FAE3FD /* BrowserViewController+Connect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E3FBF58207763FE00FAE3FD /* BrowserViewController+Connect.swift */; };
1E4C0DBC20A1A27E00D5941B /* BookmarkMirrorItemExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E4C0DAA20A1A27D00D5941B /* BookmarkMirrorItemExtension.swift */; };
1E4C0DBD20A1A27E00D5941B /* GhosteryMigrationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E4C0DAB20A1A27D00D5941B /* GhosteryMigrationManager.swift */; };
1E4C0DBE20A1A27E00D5941B /* GhosterySQLiteFactories.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E4C0DAC20A1A27D00D5941B /* GhosterySQLiteFactories.swift */; };
1E4C0DBF20A1A27E00D5941B /* GhosteryTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E4C0DAD20A1A27D00D5941B /* GhosteryTab.swift */; };
1E4CFBE7207380AD00B26E85 /* ConnectTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E4CFBE6207380AD00B26E85 /* ConnectTableViewController.swift */; };
1E4CFBF92073A5BD00B26E85 /* AddConnectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E4CFBF82073A5BD00B26E85 /* AddConnectionViewController.swift */; };
1E4CFBFB2073A5CC00B26E85 /* EditConnectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E4CFBFA2073A5CC00B26E85 /* EditConnectionViewController.swift */; };
1E650C9C2091E35D0070C670 /* BrowserViewController+GhosteryMigration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E650C9A2091E3220070C670 /* BrowserViewController+GhosteryMigration.swift */; };
1E7A3DC22085FCCA00F53E90 /* assets in Resources */ = {isa = PBXBuildFile; fileRef = 1E7A3DC12085FCCA00F53E90 /* assets */; };
1E7B7688206A8AC000FD0BA5 /* CliqzTabToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E7B7687206A8AC000FD0BA5 /* CliqzTabToolbar.swift */; };
1E7B76AF206B9CB500FD0BA5 /* ConnectDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E7B76AE206B9CB500FD0BA5 /* ConnectDataSource.swift */; };
@@ -1519,9 +1524,14 @@
1E3CBC162058057700898B05 /* CliqzAppSettingsOptions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CliqzAppSettingsOptions.swift; sourceTree = "<group>"; };
1E3CBC1C205806F000898B05 /* DateExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateExtension.swift; sourceTree = "<group>"; };
1E3FBF58207763FE00FAE3FD /* BrowserViewController+Connect.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BrowserViewController+Connect.swift"; sourceTree = "<group>"; };
1E4C0DAA20A1A27D00D5941B /* BookmarkMirrorItemExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BookmarkMirrorItemExtension.swift; sourceTree = "<group>"; };
1E4C0DAB20A1A27D00D5941B /* GhosteryMigrationManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GhosteryMigrationManager.swift; sourceTree = "<group>"; };
1E4C0DAC20A1A27D00D5941B /* GhosterySQLiteFactories.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GhosterySQLiteFactories.swift; sourceTree = "<group>"; };
1E4C0DAD20A1A27D00D5941B /* GhosteryTab.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GhosteryTab.swift; sourceTree = "<group>"; };
1E4CFBE6207380AD00B26E85 /* ConnectTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectTableViewController.swift; sourceTree = "<group>"; };
1E4CFBF82073A5BD00B26E85 /* AddConnectionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddConnectionViewController.swift; sourceTree = "<group>"; };
1E4CFBFA2073A5CC00B26E85 /* EditConnectionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditConnectionViewController.swift; sourceTree = "<group>"; };
1E650C9A2091E3220070C670 /* BrowserViewController+GhosteryMigration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BrowserViewController+GhosteryMigration.swift"; sourceTree = "<group>"; };
1E7A3DC12085FCCA00F53E90 /* assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = assets; path = Cliqz/JSEngine/assets; sourceTree = SOURCE_ROOT; };
1E7B7687206A8AC000FD0BA5 /* CliqzTabToolbar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CliqzTabToolbar.swift; sourceTree = "<group>"; };
1E7B76AE206B9CB500FD0BA5 /* ConnectDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectDataSource.swift; sourceTree = "<group>"; };
@@ -2613,6 +2623,25 @@
path = Settings;
sourceTree = "<group>";
};
1E4C0DA820A1A27D00D5941B /* Storage */ = {
isa = PBXGroup;
children = (
1E4C0DA920A1A27D00D5941B /* GhosteryMigration */,
);
path = Storage;
sourceTree = "<group>";
};
1E4C0DA920A1A27D00D5941B /* GhosteryMigration */ = {
isa = PBXGroup;
children = (
1E4C0DAA20A1A27D00D5941B /* BookmarkMirrorItemExtension.swift */,
1E4C0DAB20A1A27D00D5941B /* GhosteryMigrationManager.swift */,
1E4C0DAC20A1A27D00D5941B /* GhosterySQLiteFactories.swift */,
1E4C0DAD20A1A27D00D5941B /* GhosteryTab.swift */,
);
path = GhosteryMigration;
sourceTree = "<group>";
};
1E7B769F206B9C4900FD0BA5 /* Connect */ = {
isa = PBXGroup;
children = (
@@ -3312,6 +3341,7 @@
4FD19FC4205A9F7700547DD5 /* NativeContextMenu.swift */,
1EEA36EC2067DD6F003B6AD5 /* VideoDownloader.swift */,
1E3FBF58207763FE00FAE3FD /* BrowserViewController+Connect.swift */,
1E650C9A2091E3220070C670 /* BrowserViewController+GhosteryMigration.swift */,
);
path = BrowserViewController;
sourceTree = "<group>";
@@ -3321,6 +3351,7 @@
children = (
1EDF91B5208A339800200100 /* Tab Tray */,
1EDF91722087445600200100 /* Share Menu */,
1E4C0DA820A1A27D00D5941B /* Storage */,
1E7B769F206B9C4900FD0BA5 /* Connect */,
1EDF0B20207B868000856493 /* QuerySuggestions */,
4FF07D712063C754001385A8 /* MyOffrz */,
@@ -5988,12 +6019,15 @@
2829D3A01C2F0AD400DCF931 /* Sharing.swift in Sources */,
2FCAE2751ABB531100877008 /* SQLiteRemoteClientsAndTabs.swift in Sources */,
285F2DC11AF80B4600211843 /* SQLiteBookmarksSyncing.swift in Sources */,
1E4C0DBC20A1A27E00D5941B /* BookmarkMirrorItemExtension.swift in Sources */,
28C4AB721AD42D4300D9ACE3 /* Clients.swift in Sources */,
D0131B4D1F3CF7D8000CDE86 /* SQLiteFavicons.swift in Sources */,
28126F741C2F96F1006466CC /* SQLiteBookmarksResetting.swift in Sources */,
28B62ACE1BC745E7004A585A /* Syncable.swift in Sources */,
1E4C0DBD20A1A27E00D5941B /* GhosteryMigrationManager.swift in Sources */,
74B195441CF503FC007F36EF /* RecentlyClosedTabs.swift in Sources */,
E65075C21E37F956006961AC /* ExtensionUtils.swift in Sources */,
1E4C0DBE20A1A27E00D5941B /* GhosterySQLiteFactories.swift in Sources */,
7BF5A1EA1B41640500EA9DD8 /* SyncQueue.swift in Sources */,
2852B8441C51996B00591EAC /* Trees.swift in Sources */,
E677F0541D94247300ECF1FB /* Metadata.swift in Sources */,
@@ -6015,6 +6049,7 @@
0B54BD191B698B7C004C822C /* SuggestedSites.swift in Sources */,
318FB6EB1DB5600D0004E40F /* SQLiteHistoryFactories.swift in Sources */,
285D3B681B4380B70035FD22 /* Queue.swift in Sources */,
1E4C0DBF20A1A27E00D5941B /* GhosteryTab.swift in Sources */,
28E08C9A1AF44F00009BA2FA /* BrowserSchema.swift in Sources */,
2FCAE2681ABB531100877008 /* BrowserDB.swift in Sources */,
283586FD1C73F18E00A55435 /* CachingItemSource.swift in Sources */,
@@ -6556,6 +6591,7 @@
C8F457AA1F1FDD9B000CB895 /* BrowserViewController+KeyCommands.swift in Sources */,
E69DB0BD1E97E301008A67E6 /* ActivityStreamTopics.swift in Sources */,
1EAFE56D205FFE82006A36B4 /* AboutSettingsTableViewController.swift in Sources */,
1E650C9C2091E35D0070C670 /* BrowserViewController+GhosteryMigration.swift in Sources */,
59A68FD5260B8D520F890F4A /* ReaderPanel.swift in Sources */,
E40FAB0C1A7ABB77009CB80D /* WebServer.swift in Sources */,
59A68D66379CFA85C4EAF00B /* TwoLineCell.swift in Sources */,
@@ -156,6 +156,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UIViewControllerRestorati

//Cliqz: Cards Subscription
SubscriptionsHandler.sharedInstance.delegate = browserViewController

//Cliqz: start Ghostery Migration
if let profile = self.profile as? BrowserProfile {
GhosteryMigrationManager.shared.startMigration(profile.mirrorBookmarks, migrationDelegate: browserViewController)
}

let navigationController = UINavigationController(rootViewController: browserViewController)
navigationController.delegate = self
@@ -0,0 +1,19 @@
//
// BrowserViewController+GhosteryMigration.swift
// Storage
//
// Created by Mahmoud Adam on 4/26/18.
// Copyright © 2018 Cliqz. All rights reserved.
//
import UIKit
import Storage

extension BrowserViewController : GhosteryMigrationDelegate {

func openMigratedGhosteryTab(_ url: URL) {
DispatchQueue.main.async {
self.openURLInNewTab(url, isPrivileged: false)
}
}
}
@@ -11,7 +11,8 @@ import Shared

class CliqzAppSettingsTableViewController: AppSettingsTableViewController {

override func generateSettings() -> [SettingSection] {
// override func generateSettings() -> [SettingSection] {
func generateSettings_() -> [SettingSection] {
var settings = [SettingSection]()
let prefs = profile.prefs

@@ -0,0 +1,38 @@
//
// BookmarkMirrorItemExtension.swift
// Client
//
// Created by Mahmoud Adam on 4/30/18.
// Copyright © 2018 Cliqz. All rights reserved.
//
import UIKit
import Shared

extension BookmarkMirrorItem {
public func copyWithChildrenn(_ children: [GUID]) -> BookmarkMirrorItem {
return BookmarkMirrorItem(
guid: self.guid,
type: self.type,
dateAdded: self.dateAdded,
serverModified: self.serverModified,
isDeleted: self.isDeleted,
hasDupe: self.hasDupe,
parentID: self.parentID,
parentName: self.parentName,
feedURI: self.feedURI,
siteURI: self.siteURI,
pos: self.pos,
title: self.title,
description: self.description,
bookmarkURI: self.bookmarkURI,
tags: self.tags,
keyword: self.keyword,
folderName: self.folderName,
queryID: self.queryID,
children: children,
faviconID: self.faviconID,
localModified: self.localModified,
syncStatus: self.syncStatus)
}
}
@@ -0,0 +1,136 @@
//
// GhosteryMigrationManager.swift
// Client
//
// Created by Mahmoud Adam on 4/24/18.
// Copyright © 2018 Cliqz. All rights reserved.
//
import UIKit
import Shared
import Deferred

public protocol GhosteryMigrationDelegate: class {
func openMigratedGhosteryTab(_ url: URL)
}

public class GhosteryMigrationManager {

open static var shared = GhosteryMigrationManager()
open weak var delegate: GhosteryMigrationDelegate?

private static let migrationKey = "GhosteryMigrationKey"
private static let databaseFilename = "Ghostery.sqlite"

private var ghosteryDB: BrowserDB?
private var bookmarkBuffer: BookmarkBufferStorage?
private var bookmarkFolders: [BookmarkMirrorItem]?
private var bookmarks: [BookmarkMirrorItem]?

init() {
guard UserDefaults.standard.object(forKey: GhosteryMigrationManager.migrationKey) == nil else {
return
}

let rootPath = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0])
let files = FileAccessor(rootPath: rootPath)
let file = URL(fileURLWithPath: (try! files.getAndEnsureDirectory())).appendingPathComponent(GhosteryMigrationManager.databaseFilename).path
if FileManager.default.fileExists(atPath: file) {
self.ghosteryDB = BrowserDB(filename: GhosteryMigrationManager.databaseFilename, schema: BrowserSchema(), files: files)
}
}

public func startMigration(_ bookmarkBuffer: BookmarkBufferStorage, migrationDelegate : GhosteryMigrationDelegate) {
self.bookmarkBuffer = bookmarkBuffer
self.delegate = migrationDelegate

guard self.ghosteryDB != nil else {
return
}

DispatchQueue.global().async { [weak self] in
self?.migrateOpenTabs()
self?.migrateFoldersAndBookmarks()
}
}

private func migrateFoldersAndBookmarks() {
let folders = self.fetchBookmarkFolders()
if folders.value.isSuccess {
let bookmarks = self.fetchBookmarks()
if bookmarks.value.isSuccess {
self.performBookmarkMigration()
self.cleanup()
}
}
}

private func migrateOpenTabs() {
let sql = "SELECT * from \(TableGhosteryTabs) order by ZORDER"
ghosteryDB!.runQuery(sql, args: [], factory: GhosterySQLiteFactories.tabFactory) >>== { [weak self] tabs in
for tab in tabs.asArray() {
if let url = URL(string: tab.url) {
self?.delegate?.openMigratedGhosteryTab(url)
}
}
}
}

private func fetchBookmarkFolders() -> Deferred<Maybe<Cursor<BookmarkMirrorItem>>> {
let sql = "SELECT * from \(TableGhosteryBookmarkFolders)"
return ghosteryDB!.runQuery(sql, args: [], factory: GhosterySQLiteFactories.bookmarkFolderFactory) >>== { [weak self] bookmarkFolders in
self?.bookmarkFolders = bookmarkFolders.asArray()
return deferMaybe(bookmarkFolders)
}
}

private func fetchBookmarks() -> Deferred<Maybe<Cursor<BookmarkMirrorItem>>> {
let sql = "SELECT * from \(TableGhosteryBookmarks)"
return ghosteryDB!.runQuery(sql, args: [], factory: GhosterySQLiteFactories.bookmarkFactory) >>== { [weak self] bookmarks in
self?.bookmarks = bookmarks.asArray()
return deferMaybe(bookmarks)
}
}

private func performBookmarkMigration() {

var records = [BookmarkMirrorItem]()
// Add mobile record at the start of the array
let mobileRecord = BookmarkMirrorItem.folder(BookmarkRoots.MobileFolderGUID, dateAdded: Date.now(), modified: Date.now(), hasDupe: false, parentID: BookmarkRoots.RootGUID, parentName: "<Root>", title: "Mobile Bookmarks", description: nil, children: [])
records.append(mobileRecord)

// Append bookmark folders
if let bookmarkFolders = self.bookmarkFolders {
records.append(contentsOf: bookmarkFolders)
}

// Append bookmarks
if let bookmarks = bookmarks {
records.append(contentsOf: bookmarks)
}

// Fill in the childern attribute
let fixedRecords = self.fixupChildern(records)

// Insert the bookmarks into the database
_ = self.bookmarkBuffer?.applyRecords(fixedRecords)
}

private func fixupChildern(_ bookmarks: [BookmarkMirrorItem]) -> [BookmarkMirrorItem] {
var records = [BookmarkMirrorItem]()
for bookmark in bookmarks {
let childern = bookmarks.filter { bookmark.guid == $0.parentID }
let childernGUIDs = childern.map { $0.guid }
let fixedBookmark = bookmark.copyWithChildrenn(childernGUIDs)
records.append(fixedBookmark)
}
return records
}

private func cleanup() {
DispatchQueue.main.async { [weak self] in
self?.ghosteryDB?.forceClose()
UserDefaults.standard.set(true, forKey: GhosteryMigrationManager.migrationKey)
}
}
}
@@ -0,0 +1,49 @@
//
// GhosterySQLiteFactories.swift
// Client
//
// Created by Mahmoud Adam on 4/26/18.
// Copyright © 2018 Cliqz. All rights reserved.
//
import UIKit
import Shared

let TableGhosteryBookmarkFolders = "zfolder"
let TableGhosteryBookmarks = "zbookmark"
let TableGhosteryTabs = "ztab"

class GhosterySQLiteFactories {

class func bookmarkFolderFactory(_ row: SDRow) -> BookmarkMirrorItem {
let id = row["Z_PK"] as! Int
let parentId = row["ZPARENT"] as? Int
let name = row["ZNAME"] as! String

let parentGUID = parentId != nil ? String("GhosteryFolder-\(parentId!)") : BookmarkRoots.MobileFolderGUID

let bookmarkFolder = BookmarkMirrorItem.folder(String("GhosteryFolder-\(id)"), dateAdded: Date.now(), modified: Date.now(), hasDupe: false, parentID: parentGUID, parentName: nil, title: name, description: name, children: [])
return bookmarkFolder
}

class func bookmarkFactory(_ row: SDRow) -> BookmarkMirrorItem {
let id = row["Z_PK"] as! Int
let name = row["ZNAME"] as! String
let url = row["ZURL"] as! String
let folderId = row["ZFOLDER"] as? Int

let parentId = folderId != nil ? String("GhosteryFolder-\(folderId!)") : BookmarkRoots.MobileFolderGUID

let bookmark = BookmarkMirrorItem.bookmark(String("GhosteryBookmark-\(id)"), dateAdded: Date.now(), modified: Date.now(), hasDupe: false, parentID: parentId, parentName: nil, title: name, description: name, URI: url, tags: "", keyword: nil)
return bookmark
}


class func tabFactory(_ row: SDRow) -> GhosteryTab {
let id = row["Z_PK"] as! Int
let order = row["ZORDER"] as! Int
let url = row["ZURL"] as! String
let tab = GhosteryTab(id, order: order, url: url)
return tab
}
}
@@ -0,0 +1,21 @@
//
// GhosteryTab.swift
// Storage
//
// Created by Mahmoud Adam on 4/26/18.
// Copyright © 2018 Cliqz. All rights reserved.
//
import UIKit

class GhosteryTab {
let id: Int
let order: Int
let url: String

init(_ id: Int, order: Int, url: String) {
self.id = id
self.order = order
self.url = url
}
}

0 comments on commit f0c3411

Please sign in to comment.