Browse Source

Feature/viber (#43)

* Viber contacts report
* Viber calls report
* Viber messages report
Alberto Güerere 7 years ago
parent
commit
d60e6eebb9
4 changed files with 184 additions and 1 deletions
  1. 4 1
      tools/index.js
  2. 60 0
      tools/reports/viber_calls.js
  3. 58 0
      tools/reports/viber_contacts.js
  4. 62 0
      tools/reports/viber_messages.js

+ 4 - 1
tools/index.js

@@ -47,7 +47,10 @@ var reportTypes = {
   'waze_places': require('./reports/waze_places'),
   'waze_recents': require('./reports/waze_recents'),
   'skype_accounts': require('./reports/skype_accounts'),
-  'skype_calls': require('./reports/skype_calls')
+  'skype_calls': require('./reports/skype_calls'),
+  'viber_contacts': require('./reports/viber_contacts'),
+  'viber_calls': require('./reports/viber_calls'),
+  'viber_messages': require('./reports/viber_messages')
 }
 
 var formatters = {

+ 60 - 0
tools/reports/viber_calls.js

@@ -0,0 +1,60 @@
+const log = require('../util/log')
+const path = require('path')
+const sqlite3 = require('sqlite3')
+const bplist = require('bplist-parser')
+const fs = require('fs')
+const plist = require('plist')
+
+// Derive filenames based on domain + file path
+const fileHash = require('../util/backup_filehash')
+
+const database = fileHash('com.viber/database/Contacts.data', 'AppDomainGroup-group.viber.share.container')
+
+module.exports.name = 'viber_calls'
+module.exports.description = 'List Viber calls'
+
+// 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
+
+module.exports.func = function (program, backup, resolve, reject) {
+  viberCallsReport(backup)
+    .then((items) => {
+      var result = program.formatter.format(items, {
+        program: program,
+        columns: {
+          'PK': el => el.Z_PK,
+          'Date': el => (new Date((el.ZDATE + 978307200) * 1000).toDateString()) + ' ' + (new Date((el.ZDATE + 978307200) * 1000).toTimeString()),
+          'Name': el => el.ZMAINNAME + ' ' + el.ZSUFFIXNAME,
+          'Phone': el => el.ZPHONENUMBER,
+          'Call Type': el => el.ZCALLTYPE
+        }
+      })
+      resolve(result)
+    })
+    .catch(reject)
+}
+
+const viberCallsReport = (backup) => {
+  return new Promise((resolve, reject) => {
+    var vibercallsdb = backup.getDatabase(database)
+      try {
+        const query = `
+        SELECT * FROM ZRECENTSLINE
+        INNER JOIN ZABCONTACT
+        ON ZABCONTACT.Z_PK = ZRECENTSLINE.ZCONTACT
+        ORDER BY ZABCONTACT.Z_PK;
+        `
+        vibercallsdb.all(query, async function (err, rows) {
+          if (err) reject(err)
+          
+          resolve(rows)
+        })
+      } catch (e) {
+        reject(e)
+      }
+  })
+}

+ 58 - 0
tools/reports/viber_contacts.js

@@ -0,0 +1,58 @@
+const log = require('../util/log')
+const path = require('path')
+const sqlite3 = require('sqlite3')
+const bplist = require('bplist-parser')
+const fs = require('fs')
+const plist = require('plist')
+
+// Derive filenames based on domain + file path
+const fileHash = require('../util/backup_filehash')
+
+const database = fileHash('com.viber/database/Contacts.data', 'AppDomainGroup-group.viber.share.container')
+
+module.exports.name = 'viber_contacts'
+module.exports.description = 'List Viber contacts'
+
+// 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
+
+module.exports.func = function (program, backup, resolve, reject) {
+  viberContactsReport(backup)
+    .then((items) => {
+      var result = program.formatter.format(items, {
+        program: program,
+        columns: {
+          'PK': el => el.Z_PK,
+          'Name': el => el.ZDISPLAYFULLNAME,
+          'Phone': el => el.ZPHONE
+        }
+      })
+      resolve(result)
+    })
+    .catch(reject)
+}
+
+const viberContactsReport = (backup) => {
+  return new Promise((resolve, reject) => {
+    var vibercontactsdb = backup.getDatabase(database)
+      try {
+        const query = `
+        SELECT * FROM ZMEMBER
+        INNER JOIN ZPHONENUMBER
+        ON ZPHONENUMBER.ZMEMBER = ZMEMBER.Z_PK
+        ORDER BY ZMEMBER.Z_PK;
+        `
+        vibercontactsdb.all(query, async function (err, rows) {
+          if (err) reject(err)
+          
+          resolve(rows)
+        })
+      } catch (e) {
+        reject(e)
+      }
+  })
+}

+ 62 - 0
tools/reports/viber_messages.js

@@ -0,0 +1,62 @@
+const log = require('../util/log')
+const path = require('path')
+const sqlite3 = require('sqlite3')
+const bplist = require('bplist-parser')
+const fs = require('fs')
+const plist = require('plist')
+
+// Derive filenames based on domain + file path
+const fileHash = require('../util/backup_filehash')
+
+const database = fileHash('com.viber/database/Contacts.data', 'AppDomainGroup-group.viber.share.container')
+
+module.exports.name = 'viber_messages'
+module.exports.description = 'List Viber messages'
+
+// 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
+
+module.exports.func = function (program, backup, resolve, reject) {
+  viberMessagesReport(backup)
+    .then((items) => {
+      var result = program.formatter.format(items, {
+        program: program,
+        columns: {
+          'PK': el => el.Z_PK,
+          'Date': el => (new Date((el.ZDATE + 978307200) * 1000).toDateString()) + ' ' + (new Date((el.ZDATE + 978307200) * 1000).toTimeString()),
+          'Name': el => el.ZDISPLAYFULLNAME,
+          'Text': el => el.ZTEXT,
+          'State': el => el.ZSTATE
+        }
+      })
+      resolve(result)
+    })
+    .catch(reject)
+}
+
+const viberMessagesReport = (backup) => {
+  return new Promise((resolve, reject) => {
+    var vibermessagesdb = backup.getDatabase(database)
+      try {
+        const query = `
+        SELECT * FROM ZVIBERMESSAGE
+        INNER JOIN ZCONVERSATION
+        ON ZCONVERSATION.Z_PK = ZVIBERMESSAGE.ZCONVERSATION
+        INNER JOIN ZMEMBER
+        ON ZCONVERSATION.ZINTERLOCUTOR = ZMEMBER.Z_PK
+        ORDER BY ZVIBERMESSAGE.Z_PK DESC;
+        `
+        vibermessagesdb.all(query, async function (err, rows) {
+          if (err) reject(err)
+          
+          resolve(rows)
+        })
+      } catch (e) {
+        reject(e)
+      }
+  })
+}