Browse Source

Safari bookmarks (#22)

* Safari bookmarks report: add support for iOS 7.0+
Alberto Güerere 7 năm trước cách đây
mục cha
commit
236c68ac03
3 tập tin đã thay đổi với 185 bổ sung2 xóa
  1. 2 1
      tools/index.js
  2. 82 0
      tools/reports/safari_bookmarks.js
  3. 101 1
      tools/util/iphone_backup.js

+ 2 - 1
tools/index.js

@@ -26,7 +26,8 @@ var reportTypes = {
   'webhistory': require('./reports/webhistory'),
   'calls_statistics': require('./reports/calls_statistics'),
   'wifi': require('./reports/wifi'),
-  'address_book': require('./reports/address_book')
+  'address_book': require('./reports/address_book'),
+  'safari_bookmarks': require('./reports/safari_bookmarks')
 }
 
 var formatters = {

+ 82 - 0
tools/reports/safari_bookmarks.js

@@ -0,0 +1,82 @@
+module.exports.name = 'safari_bookmarks'
+module.exports.description = 'List all Safari bookmarks'
+
+// Specify this reporter requires a backup.
+// The second parameter to func() is now a backup instead of the path to one.
+module.exports.requiresBackup = true
+
+// Specify this reporter supports the promises API for allowing chaining of reports.
+module.exports.usesPromises = true
+
+// Specify this only works for iOS 7+
+module.exports.supportedVersions = '>=7.0'
+
+// You can also provide an array of functions instead of using `module.exports.func`.
+// These functions *should* be independent ranges to ensure reliable execution
+module.exports.functions = {
+  '>=11.0': function (program, backup, resolve, reject) {
+    // This function would be called for iOS 10+
+    backup.getSafariBookmarks()
+      .then((items) => {
+        var result = program.formatter.format(items, {
+          program: program,
+          // Columns to be displayed in human-readable printouts.
+          // Some formatters, like raw or CSV, ignore these.
+          columns: {
+            'id': el => el.id,
+            'title': el => el.title ? el.title.trim() : '',
+            'url': el => el.url ? el.url.trim() : '',
+            'parent': el => el.parent_title
+          }
+        })
+
+        resolve(result)
+      })
+      .catch(reject)
+  },
+  '>=7.0,<11.0': function (program, backup, resolve, reject) {
+    // This function would be called for all iOS 7+.
+    backup.getSafariBookmarksiOS7()
+      .then((items) => {
+        var result = program.formatter.format(items, {
+          program: program,
+          // Columns to be displayed in human-readable printouts.
+          // Some formatters, like raw or CSV, ignore these.
+          columns: {
+            'id': el => el.id,
+            'title': el => el.title ? el.title.trim() : '',
+            'url': el => el.url ? el.url.trim() : '',
+            'parent': el => el.parent_title
+          }
+        })
+
+        resolve(result)
+      })
+      .catch(reject)
+  }
+}
+
+/*
+module.exports.func = function (program, backup, resolve, reject) {
+  backup.getSafariBookmarks()
+    .then((items) => {
+    // Use the configured formatter to print the rows.
+      const result = program.formatter.format(items, {
+      // Color formatting?
+        program: program,
+
+        // Columns to be displayed in human-readable printouts.
+        // Some formatters, like raw or CSV, ignore these.
+        columns: {
+          'id': el => el.id,
+          'title': el => el.title ? el.title.trim() : '',
+          'url': el => el.url ? el.url.trim() : '',
+          'parent': el => el.parent_title
+        }
+      })
+
+      resolve(result)
+    })
+    .catch(reject)
+}
+*/

+ 101 - 1
tools/util/iphone_backup.js

@@ -32,7 +32,8 @@ const databases = {
   WebHistory: fileHash('Library/Safari/History.db', 'AppDomain-com.apple.mobilesafari'),
   Photos: fileHash('Media/PhotoData/Photos.sqlite', 'CameraRollDomain'),
   WiFi: fileHash('SystemConfiguration/com.apple.wifi.plist', 'SystemPreferencesDomain'),
-  Voicemail: fileHash('Library/Voicemail/voicemail.db')
+  Voicemail: fileHash('Library/Voicemail/voicemail.db'),
+  SafariBookmarks: fileHash('Library/Safari/Bookmarks.db')
 }
 
 var cache = {}
@@ -625,6 +626,105 @@ class IPhoneBackup {
       }
     })
   }
+
+  getSafariBookmarks () {
+    return new Promise((resolve, reject) => {
+      var bookmarksdb = this.getDatabase(databases.SafariBookmarks)
+      try {
+        const query = `
+          select bookmarks.id
+            , bookmarks.title
+            , bookmarks.url
+            , bookmarks.parent as parent_id
+            , bookmarks.special_id
+            , bookmarks.type
+            , bookmarks.num_children
+            , bookmarks.editable
+            , bookmarks.deletable
+            , bookmarks.hidden
+            , bookmarks.hidden_ancestor_count
+            , bookmarks.order_index
+            , bookmarks.external_uuid
+            , bookmarks.read
+            , bookmarks.last_modified
+            , bookmarks.server_id
+            , bookmarks.sync_key
+            , bookmarks.added
+            , bookmarks.deleted
+            , bookmarks.fetched_icon
+            , bookmarks.dav_generation
+            , bookmarks.locally_added
+            , bookmarks.archive_status
+            , bookmarks.syncable
+            , bookmarks.web_filter_status
+            , bookmarks.modified_attributes
+            , parent_bookmarks.title as parent_title
+          from bookmarks
+          left join bookmarks as parent_bookmarks on parent_bookmarks.id = bookmarks.parent
+          where bookmarks.type = 0
+          order by bookmarks.id
+        `
+        bookmarksdb.all(query, async function (err, rows) {
+          if (err) reject(err)
+
+          resolve(rows)
+        })
+      } catch (e) {
+        reject(e)
+      }
+    })
+  }
+
+  getSafariBookmarksiOS7 () {
+    return new Promise((resolve, reject) => {
+      var bookmarksdb = this.getDatabase(databases.SafariBookmarks)
+      try {
+        const query = `
+          select bookmarks.id
+            , bookmarks.special_id
+            , bookmarks.parent as parent_id
+            , bookmarks.type
+            , bookmarks.title
+            , bookmarks.url
+            , bookmarks.num_children
+            , bookmarks.editable
+            , bookmarks.deletable
+            , bookmarks.hidden
+            , bookmarks.hidden_ancestor_count
+            , bookmarks.order_index
+            , bookmarks.external_uuid
+            , bookmarks.read
+            , bookmarks.last_modified
+            , bookmarks.server_id
+            , bookmarks.sync_key
+            , bookmarks.sync_data
+            , bookmarks.added
+            , bookmarks.deleted
+            , bookmarks.extra_attributes
+            , bookmarks.local_attributes
+            , bookmarks.fetched_icon
+            , bookmarks.icon
+            , bookmarks.dav_generation
+            , bookmarks.locally_added
+            , bookmarks.archive_status
+            , bookmarks.syncable
+            , bookmarks.web_filter_status
+            , parent_bookmarks.title as parent_title
+          from bookmarks
+          left join bookmarks as parent_bookmarks on parent_bookmarks.id = bookmarks.parent
+          where bookmarks.type = 0
+          order by bookmarks.id
+        `
+        bookmarksdb.all(query, async function (err, rows) {
+          if (err) reject(err)
+
+          resolve(rows)
+        })
+      } catch (e) {
+        reject(e)
+      }
+    })
+  }
 }
 
 module.exports.availableBackups = function () {