def __init__(self, cursor, path, daemon = False): QtGui.QWidget.__init__(self) self.ui = Ui_SafariState() self.ui.setupUi(self) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.cursor = cursor self.backup_path = path filename = plugins_utils.realFileName(self.cursor, filename="SuspendState.plist", domaintype="HomeDomain", path="Library/Safari") if filename == '': filename = plugins_utils.realFileName(self.cursor, filename="SuspendState.plist", domaintype="AppDomain", path="Library/Safari", domain = "com.apple.mobilesafari") self.filename = os.path.join(self.backup_path, filename) if (not os.path.isfile(self.filename)): raise Exception("Safari State file not found: \"%s\""%self.filename) QtCore.QObject.connect(self.ui.documentsTree, QtCore.SIGNAL("itemSelectionChanged()"), self.onTreeClick) self.ui.listTree.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) QtCore.QObject.connect(self.ui.listTree, QtCore.SIGNAL('customContextMenuRequested(QPoint)'), self.ctxMenu) self.ui.documentsTree.setColumnHidden(0,True) self.ui.documentsTree.setColumnWidth(1,150) self.ui.thumbLabel.hide() if (daemon == False): self.populateUI()
def __init__(self, cursor, path, daemon = False): QtGui.QWidget.__init__(self) self.ui = Ui_WhatsAppBrowser() self.ui.setupUi(self) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.cursor = cursor self.backup_path = path self.fname_contacts = os.path.join(self.backup_path, plugins_utils.realFileName(self.cursor, filename="Contacts.sqlite", domaintype="AppDomain")) self.fname_chatstorage = os.path.join(self.backup_path, plugins_utils.realFileName(self.cursor, filename="ChatStorage.sqlite", domaintype="AppDomain")) # check if files exist if (not os.path.isfile(self.fname_chatstorage)): raise Exception("WhatsApp database not found: \"%s\""%self.fname_chatstorage) if (daemon == False): self.populateUI() # signal-slot chats/msgs connection QtCore.QObject.connect(self.ui.chatsWidget, QtCore.SIGNAL("itemSelectionChanged()"), self.onChatsClick) self.ui.chatsWidget.setColumnHidden(0,True) self.ui.msgsWidget.setColumnHidden(0,True) # signal-slot connection: right click context menu on contacts table self.ui.contactsWidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.connect(self.ui.contactsWidget, QtCore.SIGNAL('customContextMenuRequested(QPoint)'), self.ctxMenuContacts) # signal-slot connection: right click context menu on chats table self.ui.chatsWidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.connect(self.ui.chatsWidget, QtCore.SIGNAL('customContextMenuRequested(QPoint)'), self.ctxMenuChats) # signal-slot connection: right click context menu on messages table self.ui.msgsWidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.connect(self.ui.msgsWidget, QtCore.SIGNAL('customContextMenuRequested(QPoint)'), self.ctxMenuMsgs)
def __init__(self, cursor, path, daemon = False): QtGui.QWidget.__init__(self) self.ui = Ui_WhatsAppBrowser() self.ui.setupUi(self) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.cursor = cursor self.backup_path = path self.fname_contacts = os.path.join(self.backup_path, plugins_utils.realFileName(self.cursor, filename="Contacts.sqlite", domaintype="AppDomain")) self.fname_chatstorage = os.path.join(self.backup_path, plugins_utils.realFileName(self.cursor, filename="ChatStorage.sqlite", domaintype="AppDomain")) # check if files exist if (not os.path.isfile(self.fname_chatstorage)): raise Exception("WhatsApp database not found: \"%s\""%self.fname_chatstorage) if (daemon == False): self.populateUI() # signal-slot chats/msgs connection QtCore.QObject.connect(self.ui.chatsWidget, QtCore.SIGNAL("itemSelectionChanged()"), self.onChatsClick) self.ui.chatsWidget.setColumnHidden(0,True) self.ui.msgsWidget.setColumnHidden(0,True) # signal-slot connection: right click context menu on contacts table self.ui.contactsWidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.connect(self.ui.contactsWidget, QtCore.SIGNAL('customContextMenuRequested(QPoint)'), self.ctxMenuContacts) # signal-slot connection: right click context menu on chats table self.ui.chatsWidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.connect(self.ui.chatsWidget, QtCore.SIGNAL('customContextMenuRequested(QPoint)'), self.ctxMenuChats) # signal-slot connection: right click context menu on messages table self.ui.msgsWidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.connect(self.ui.msgsWidget, QtCore.SIGNAL('customContextMenuRequested(QPoint)'), self.ctxMenuMsgs)
def __init__(self, cursor, path, daemon=False): QtGui.QWidget.__init__(self) self.ui = Ui_AddressBook() self.ui.setupUi(self) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.cursor = cursor self.backup_path = path self.filename = os.path.join( self.backup_path, plugins_utils.realFileName(cursor, filename="AddressBook.sqlitedb", domaintype="HomeDomain")) self.thumbsfilename = os.path.join( self.backup_path, plugins_utils.realFileName(cursor, filename="AddressBookImages.sqlitedb", domaintype="HomeDomain")) # check if files exist if (not os.path.isfile(self.filename)): raise Exception("Contacts database not found: \"%s\"" % self.filename) if (not os.path.isfile(self.thumbsfilename)): self.thumbsfilename = None if (daemon == False): self.populateUI()
def __init__(self, cursor, path, daemon = False): QtGui.QWidget.__init__(self) self.ui = Ui_SMS() self.ui.setupUi(self) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.cursor = cursor self.backup_path = path self.cursor = cursor self.filename = os.path.join(self.backup_path, plugins_utils.realFileName(cursor, filename="sms.db", domaintype="HomeDomain")) # check if files exist if (not os.path.isfile(self.filename)): raise Exception("Messages database not found: \"%s\""%self.filename) if (daemon == False): self.populateUI() QtCore.QObject.connect(self.ui.threadsTree, QtCore.SIGNAL("itemSelectionChanged()"), self.onTreeClick) self.ui.threadsTree.setColumnHidden(0,True) # attach context menu to rightclick on message attachment self.ui.messageTable.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.connect(self.ui.messageTable, QtCore.SIGNAL('customContextMenuRequested(QPoint)'), self.ctxMenu) # search label self.connect(self.ui.searchLabel, QtCore.SIGNAL('textChanged(QString)'), self.search)
def __init__(self, cursor, path, daemon = False): QtGui.QWidget.__init__(self) self.ui = Ui_KnownNetworks() self.ui.setupUi(self) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.cursor = cursor self.backup_path = path self.filename = os.path.join(self.backup_path, plugins_utils.realFileName(self.cursor, filename="com.apple.wifi.plist", domaintype="SystemPreferencesDomain")) if (not os.path.isfile(self.filename)): raise Exception("Known networks file not found: \"%s\""%self.filename) #self.ui.listTree.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) #QtCore.QObject.connect(self.ui.listTree, QtCore.SIGNAL('customContextMenuRequested(QPoint)'), self.ctxMenu) if (daemon == False): self.ui.networksTree.setColumnHidden(0,True) QtCore.QObject.connect(self.ui.networksTree, QtCore.SIGNAL("itemSelectionChanged()"), self.onTreeClick) self.populateUI()
def __init__(self, cursor, path, daemon=False): QtGui.QWidget.__init__(self) self.ui = Ui_KnownNetworks() self.ui.setupUi(self) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.cursor = cursor self.backup_path = path self.filename = os.path.join( self.backup_path, plugins_utils.realFileName(self.cursor, filename="com.apple.wifi.plist", domaintype="SystemPreferencesDomain")) if (not os.path.isfile(self.filename)): raise Exception("Known networks file not found: \"%s\"" % self.filename) #self.ui.listTree.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) #QtCore.QObject.connect(self.ui.listTree, QtCore.SIGNAL('customContextMenuRequested(QPoint)'), self.ctxMenu) if (daemon == False): self.ui.networksTree.setColumnHidden(0, True) QtCore.QObject.connect(self.ui.networksTree, QtCore.SIGNAL("itemSelectionChanged()"), self.onTreeClick) self.populateUI()
def populateUI(self): thumbFiles = [ ["120x120.ithmb", 120, 120, 28], ["158x158.ithmb", 160, 158, 28] ] self.availableThumbFiles = [] for file in thumbFiles: fileName = file[0] width = file[1] height = file[2] padding = file[3] searchFile = os.path.join(self.backup_path, plugins_utils.realFileName(self.cursor, filename=fileName)) if (os.path.isfile(searchFile)): file.append(searchFile) self.availableThumbFiles.append(file) index = 0 for file in self.availableThumbFiles: self.ui.thumbsFilesList.insertItem(index, file[0]) index = index + 1 if (len(self.availableThumbFiles) > 0): element = self.availableThumbFiles[0] self.frame_width = element[1] self.frame_height = element[2] self.frame_padding = element[3] self.filename = element[4] self.drawThumbs(self.start, self.number)
def __init__(self, cursor, path, daemon=False): QtGui.QWidget.__init__(self) self.ui = Ui_NetworkIdent() self.ui.setupUi(self) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.cursor = cursor self.backup_path = path self.filename = os.path.join( self.backup_path, plugins_utils.realFileName( self.cursor, filename="com.apple.network.identification.plist", domaintype="SystemPreferencesDomain")) if (not os.path.isfile(self.filename)): raise Exception("Network Identification file not found: \"%s\"" % self.filename) QtCore.QObject.connect(self.ui.networksTree, QtCore.SIGNAL("itemSelectionChanged()"), self.onTreeClick) self.ui.networksTree.setColumnHidden(0, True) if (daemon == False): self.populateUI()
def __init__(self, cursor, path, daemon=False): QtGui.QWidget.__init__(self) self.ui = Ui_SafariHistory() self.ui.setupUi(self) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.cursor = cursor self.backup_path = path self.filename = os.path.join( self.backup_path, plugins_utils.realFileName( self.cursor, filename="History.plist", domaintype="HomeDomain", path="Library/Safari" ), ) if not os.path.isfile(self.filename): raise Exception('Safari history file not found: "%s"' % self.filename) self.ui.historyTree.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) QtCore.QObject.connect(self.ui.historyTree, QtCore.SIGNAL("customContextMenuRequested(QPoint)"), self.ctxMenu) if daemon == False: self.ui.historyTree.setColumnHidden(0, True) self.ui.historyTree.setColumnWidth(1, 150) QtCore.QObject.connect(self.ui.historyTree, QtCore.SIGNAL("itemSelectionChanged()"), self.onTreeClick) self.populateUI()
def __init__(self, cursor, path, daemon=False): QtGui.QWidget.__init__(self) self.ui = Ui_SafBookmarks() self.ui.setupUi(self) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.cursor = cursor self.backup_path = path self.filename = os.path.join( self.backup_path, plugins_utils.realFileName(self.cursor, filename="Bookmarks.db", domaintype="HomeDomain")) if (not os.path.isfile(self.filename)): raise Exception("Safari Bookmarks Database not found: \"%s\"" % self.filename) self.ui.bookmarksTree.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) QtCore.QObject.connect( self.ui.bookmarksTree, QtCore.SIGNAL('customContextMenuRequested(QPoint)'), self.ctxMenu) if (daemon == False): self.populateUI()
def populateUI(self): thumbFiles = [["120x120.ithmb", 120, 120, 28], ["158x158.ithmb", 160, 158, 28]] self.availableThumbFiles = [] for file in thumbFiles: fileName = file[0] width = file[1] height = file[2] padding = file[3] searchFile = os.path.join( self.backup_path, plugins_utils.realFileName(self.cursor, filename=fileName)) if (os.path.isfile(searchFile)): file.append(searchFile) self.availableThumbFiles.append(file) index = 0 for file in self.availableThumbFiles: self.ui.thumbsFilesList.insertItem(index, file[0]) index = index + 1 if (len(self.availableThumbFiles) > 0): element = self.availableThumbFiles[0] self.frame_width = element[1] self.frame_height = element[2] self.frame_padding = element[3] self.filename = element[4] self.drawThumbs(self.start, self.number)
def __init__(self, cursor, path, daemon = False): QtGui.QWidget.__init__(self) self.ui = Ui_SafariHistory() self.ui.setupUi(self) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.cursor = cursor self.backup_path = path self.filename = os.path.join(self.backup_path, plugins_utils.realFileName(self.cursor, filename="History.plist", domaintype="HomeDomain", path="Library/Safari")) if (not os.path.isfile(self.filename)): raise Exception("Safari history file not found: \"%s\""%self.filename) self.ui.historyTree.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) QtCore.QObject.connect(self.ui.historyTree, QtCore.SIGNAL('customContextMenuRequested(QPoint)'), self.ctxMenu) if (daemon == False): self.ui.historyTree.setColumnHidden(0,True) self.ui.historyTree.setColumnWidth(1,150) QtCore.QObject.connect(self.ui.historyTree, QtCore.SIGNAL("itemSelectionChanged()"), self.onTreeClick) self.populateUI()
def __init__(self, cursor, path, daemon=False): QtGui.QWidget.__init__(self) self.ui = Ui_SafariState() self.ui.setupUi(self) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.cursor = cursor self.backup_path = path filename = plugins_utils.realFileName(self.cursor, filename="SuspendState.plist", domaintype="HomeDomain", path="Library/Safari") if filename == '': filename = plugins_utils.realFileName( self.cursor, filename="SuspendState.plist", domaintype="AppDomain", path="Library/Safari", domain="com.apple.mobilesafari") self.filename = os.path.join(self.backup_path, filename) if (not os.path.isfile(self.filename)): raise Exception("Safari State file not found: \"%s\"" % self.filename) QtCore.QObject.connect(self.ui.documentsTree, QtCore.SIGNAL("itemSelectionChanged()"), self.onTreeClick) self.ui.listTree.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) QtCore.QObject.connect( self.ui.listTree, QtCore.SIGNAL('customContextMenuRequested(QPoint)'), self.ctxMenu) self.ui.documentsTree.setColumnHidden(0, True) self.ui.documentsTree.setColumnWidth(1, 150) self.ui.thumbLabel.hide() if (daemon == False): self.populateUI()
def onTreeClick(self): # retrieving selected network currentSelectedElement = self.ui.documentsTree.currentItem() if (currentSelectedElement): pass else: return documents = plistutils.readPlist(self.filename)['SafariStateDocuments'] currentTabIndex = int(currentSelectedElement.text(0)) currentTab = documents[currentTabIndex] currentList = currentTab['SafariStateDocumentBackForwardList'] currentOpenElement = currentTab['SafariStateDocumentBackForwardList'][ 'current'] self.ui.listTree.clear() index = 0 for element in currentList['entries']: try: title = element['title'] except: title = "<non title>" titleElement = QtGui.QTreeWidgetItem(None) titleElement.setText(0, title) titleElement.setText(1, element['']) self.ui.listTree.addTopLevelItem(titleElement) urlElement = QtGui.QTreeWidgetItem(titleElement) urlElement.setText(0, element['']) self.ui.listTree.addTopLevelItem(urlElement) if (index == currentOpenElement): titleElement.setBackground(0, QtCore.Qt.yellow) index = index + 1 # look for page appearance cache cacheFileName = "%s.png" % currentTab['SafariStateDocumentUUID'] cacheFile = os.path.join( self.backup_path, plugins_utils.realFileName(self.cursor, filename=cacheFileName, domaintype="HomeDomain")) if (os.path.isfile(cacheFile)): pic = QtGui.QPixmap(cacheFile).scaled(200, 200, QtCore.Qt.KeepAspectRatio) self.ui.thumbLabel.setPixmap(pic) self.ui.thumbLabel.show() else: self.ui.thumbLabel.hide()
def __init__(self, cursor, path, daemon = False): QtGui.QWidget.__init__(self) self.ui = Ui_CallHistory() self.ui.setupUi(self) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.cursor = cursor self.backup_path = path self.filename = os.path.join(self.backup_path, plugins_utils.realFileName(self.cursor, filename="call_history.db", domaintype="WirelessDomain")) self.addressbookfilename = os.path.join(self.backup_path, plugins_utils.realFileName(cursor, filename="AddressBook.sqlitedb", domaintype="HomeDomain")) # check if files exist if (not os.path.isfile(self.filename)): raise Exception("Call History database not found: \"%s\""%self.filename) if (not os.path.isfile(self.addressbookfilename)): self.addressbookfilename = None if (daemon == False): self.populateUI()
def onTreeClick(self): # retrieving selected network currentSelectedElement = self.ui.documentsTree.currentItem() if (currentSelectedElement): pass else: return documents = plistutils.readPlist(self.filename)['SafariStateDocuments'] currentTabIndex = int(currentSelectedElement.text(0)) currentTab = documents[currentTabIndex] currentList = currentTab['SafariStateDocumentBackForwardList'] currentOpenElement = currentTab['SafariStateDocumentBackForwardList']['current'] self.ui.listTree.clear() index = 0 for element in currentList['entries']: try: title = element['title'] except: title = "<non title>" titleElement = QtGui.QTreeWidgetItem(None) titleElement.setText(0, title) titleElement.setText(1, element['']) self.ui.listTree.addTopLevelItem(titleElement) urlElement = QtGui.QTreeWidgetItem(titleElement) urlElement.setText(0, element['']) self.ui.listTree.addTopLevelItem(urlElement) if (index == currentOpenElement): titleElement.setBackground(0, QtCore.Qt.yellow) index = index + 1 # look for page appearance cache cacheFileName = "%s.png"%currentTab['SafariStateDocumentUUID'] cacheFile = os.path.join(self.backup_path, plugins_utils.realFileName(self.cursor, filename=cacheFileName, domaintype="HomeDomain")) if (os.path.isfile(cacheFile)): pic = QtGui.QPixmap(cacheFile).scaled(200, 200, QtCore.Qt.KeepAspectRatio) self.ui.thumbLabel.setPixmap(pic) self.ui.thumbLabel.show() else: self.ui.thumbLabel.hide()
def __init__(self, cursor, path, daemon = False): QtGui.QWidget.__init__(self) self.ui = Ui_Note() self.ui.setupUi(self) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.cursor = cursor self.backup_path = path self.filename = os.path.join(self.backup_path, plugins_utils.realFileName(cursor, filename="notes.sqlite", domaintype="HomeDomain")) # check if files exist if (not os.path.isfile(self.filename)): raise Exception("Note database not found: \"%s\""%self.filename) if (daemon == False): self.populateUI()
def __init__(self, cursor, path, daemon=False): QtGui.QWidget.__init__(self) self.ui = Ui_SMS() self.ui.setupUi(self) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.cursor = cursor self.backup_path = path self.cursor = cursor self.filename = os.path.join( self.backup_path, plugins_utils.realFileName(cursor, filename="sms.db", domaintype="HomeDomain")) # check if files exist if (not os.path.isfile(self.filename)): raise Exception("Messages database not found: \"%s\"" % self.filename) if (daemon == False): self.populateUI() QtCore.QObject.connect(self.ui.threadsTree, QtCore.SIGNAL("itemSelectionChanged()"), self.onTreeClick) self.ui.threadsTree.setColumnHidden(0, True) # attach context menu to rightclick on message attachment self.ui.messageTable.setContextMenuPolicy( QtCore.Qt.CustomContextMenu) self.connect(self.ui.messageTable, QtCore.SIGNAL('customContextMenuRequested(QPoint)'), self.ctxMenu) # search label self.connect(self.ui.searchLabel, QtCore.SIGNAL('textChanged(QString)'), self.search)
def __init__(self, cursor, path, daemon = False): QtGui.QWidget.__init__(self) self.ui = Ui_NetworkIdent() self.ui.setupUi(self) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.cursor = cursor self.backup_path = path self.filename = os.path.join(self.backup_path, plugins_utils.realFileName(self.cursor, filename="com.apple.network.identification.plist", domaintype="SystemPreferencesDomain")) if (not os.path.isfile(self.filename)): raise Exception("Network Identification file not found: \"%s\""%self.filename) QtCore.QObject.connect(self.ui.networksTree, QtCore.SIGNAL("itemSelectionChanged()"), self.onTreeClick) self.ui.networksTree.setColumnHidden(0,True) if (daemon == False): self.populateUI()
def __init__(self, cursor, path, daemon = False): QtGui.QWidget.__init__(self) self.ui = Ui_SafBookmarks() self.ui.setupUi(self) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.cursor = cursor self.backup_path = path self.filename = os.path.join(self.backup_path, plugins_utils.realFileName(self.cursor, filename="Bookmarks.db", domaintype="HomeDomain")) if (not os.path.isfile(self.filename)): raise Exception("Safari Bookmarks Database not found: \"%s\""%self.filename) self.ui.bookmarksTree.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) QtCore.QObject.connect(self.ui.bookmarksTree, QtCore.SIGNAL('customContextMenuRequested(QPoint)'), self.ctxMenu) if (daemon == False): self.populateUI()
def onChatsClick(self): # disable chats table (to disable click events while processing) self.ui.chatsWidget.setEnabled(False) # retrieving selected row self.ui.chatsWidget.setCurrentCell(self.ui.chatsWidget.currentRow(), 0) currentSelectedItem = self.ui.chatsWidget.currentItem() if (currentSelectedItem): pass else: return ###################################################### # MESSAGES SECTION # ###################################################### zpk = int(currentSelectedItem.text()) #msgs = self.getMsgs(zpk) # <--- single thread msgs = self.getMsgsThreaded(zpk) # <--- multithreaded # re-select a visible column to allow the keyboard selection self.ui.chatsWidget.setCurrentCell(self.ui.chatsWidget.currentRow(), 1) # erase previous messages and set new table lenght #self.ui.msgsWidget.clearContents() self.ui.msgsWidget.setSortingEnabled(False) self.ui.msgsWidget.setRowCount(len(msgs)) row = 0 for msg in msgs: from_me = False # var to remember from whom is the msg if hasattr(msg, 'Z_PK'): newItem = QtGui.QTableWidgetItem() newItem.setData(QtCore.Qt.DisplayRole, msg.Z_PK) self.ui.msgsWidget.setItem(row, 0, newItem) if hasattr(msg, 'ZPHONENUMINDEX'): newItem = QtGui.QTableWidgetItem() fromstring = "" if msg.ZPHONENUMINDEX is not None: msgcontact = self.getMsgContact(msg.ZPHONENUMINDEX) if msgcontact is not None: if msgcontact.ZPREFIXNAME is not None: fromstring += msgcontact.ZPREFIXNAME + " " if msgcontact.ZMAINNAME is not None: fromstring += msgcontact.ZMAINNAME + " " if msgcontact.ZCANONIZEDPHONENUM is not None: fromstring += msgcontact.ZCANONIZEDPHONENUM else: fromstring = "N/A" else: fromstring = "Me" from_me = True newItem.setData(QtCore.Qt.DisplayRole, fromstring) self.ui.msgsWidget.setItem(row, 1, newItem) if hasattr(msg, 'ZDATE'): newItem = QtGui.QTableWidgetItem( str(self.formatDate(msg.ZDATE))) self.ui.msgsWidget.setItem(row, 2, newItem) if hasattr(msg, 'ZTEXT'): newItem = QtGui.QTableWidgetItem(msg.ZTEXT) self.ui.msgsWidget.setItem(row, 3, newItem) if hasattr(msg, 'ZSTATE'): newItem = QtGui.QTableWidgetItem(msg.ZSTATE) self.ui.msgsWidget.setItem(row, 5, newItem) if hasattr(msg, 'ZSTATEDATE'): newItem = QtGui.QTableWidgetItem( str(self.formatDate(msg.ZSTATEDATE))) self.ui.msgsWidget.setItem(row, 6, newItem) # ATTACHMENTS SECTION if hasattr(msg, 'ZATTACHMENT') and hasattr(msg, 'ZLOCATION'): mediaItem = QtGui.QTableWidgetItem("") msgcontent = "" # case 1: msg contains a location if msg.ZLOCATION is not None: location = self.getLocation(msg.ZLOCATION) msgcontent += "GPS\n" + "lat: " + str( location.ZLATITUDE) + "\nlong: " + str( location.ZLONGITUDE) + "\naddress: " + unicode( location.ZADDRESS) + "\n" # re-set message content (3rd column) newItem = QtGui.QTableWidgetItem(msgcontent) self.ui.msgsWidget.setItem(row, 3, newItem) # compose location thumbnail filename (guess) # example: if LAT = 41.796141 and LONG = 12.481714 # the filename is 41.796141_12.jpg strlat = str(location.ZLATITUDE) strlong = str(location.ZLONGITUDE) strlat_s = strlat.split('.') strlong_s = strlong.split('.') filename = strlat_s[0] + "." + ( strlat_s[1])[:6] + "_" + strlong_s[0] + ".jpg" locationlocalfile = filename locationRealFilename = os.path.join( self.backup_path, plugins_utils.realFileName(self.cursor, filename=locationlocalfile, domaintype="AppDomain")) # add a thumbnail to the table view icon = QtGui.QIcon(locationRealFilename) mediaItem.setIcon(icon) # add info for attachment export (ctx menu) mediaItem.setData(QtCore.Qt.UserRole + 2, location.ZLATITUDE) mediaItem.setData(QtCore.Qt.UserRole + 3, location.ZLONGITUDE) # case 2: msg contains an attachment elif msg.ZATTACHMENT is not None: media = self.getMediaItem(msg.ZATTACHMENT) msgcontent += "ATTACHMENT\n" + "type: " + str( media.ZTYPE) + "\nstate: " + str( media.ZSTATE) + "\nsize: " + str( media.ZFILESIZE) + "B\n" if 'sticker' in media.ZTYPE: msgcontent += "id: " + media.ZID + "\n" # re-set message content (3rd column) newItem = QtGui.QTableWidgetItem(msgcontent) self.ui.msgsWidget.setItem(row, 3, newItem) if media.ZNAME: medialocalfile = media.ZNAME mediaRealFilename = os.path.join( self.backup_path, plugins_utils.realFileName(self.cursor, filename=medialocalfile, domaintype="AppDomain")) # add a thumbnail to the table view icon = QtGui.QIcon(mediaRealFilename) mediaItem.setIcon(icon) # add info for attachment export (ctx menu) mediaItem.setData(QtCore.Qt.UserRole, mediaRealFilename) mediaItem.setData(QtCore.Qt.UserRole + 1, medialocalfile) self.ui.msgsWidget.setItem(row, 4, mediaItem) if from_me: for i in range(7): self.ui.msgsWidget.item(row, i).setBackground(QtCore.Qt.green) row = row + 1 self.ui.msgsWidget.setSortingEnabled(True) self.ui.msgsWidget.setIconSize(QtCore.QSize(150, 150)) self.ui.msgsWidget.resizeColumnsToContents() self.ui.msgsWidget.setColumnWidth(6, 150) self.ui.msgsWidget.resizeRowsToContents() # signal-slot connection: preserve row height when sorting messages self.ui.msgsWidget.horizontalHeader().sortIndicatorChanged.connect( self.ui.msgsWidget.resizeRowsToContents) # re-enable chats table self.ui.chatsWidget.setEnabled(True) self.ui.chatsWidget.setFocus()
def main(cursor, backup_path): global filename global datetree, textarea, cellstree filename = os.path.join( backup_path, plugins_utils.realFileName(cursor, filename="consolidated.db", domaintype="RootDomain")) if (not os.path.isfile(filename)): print("Invalid file name for Cell Location database") return # main window cellwindow = Toplevel() cellwindow.title('Cell Location data') cellwindow.focus_set() cellwindow.grid_columnconfigure(2, weight=1) cellwindow.grid_rowconfigure(1, weight=1) # header label celltitle = Label(cellwindow, text="Cell Location data from: " + filename, relief=RIDGE) celltitle.grid(column=0, row=0, sticky="ew", columnspan=4, padx=5, pady=5) # tree of distinct timestamps datetree = ttk.Treeview(cellwindow, columns=("timestamp"), displaycolumns=(), yscrollcommand=lambda f, l: autoscroll(mvsb, f, l)) datetree.heading("#0", text="Timestamp", anchor='w') datetree.column("#0", width=200) datetree.grid(column=0, row=1, sticky="ns") # scrollbars for tree mvsb = ttk.Scrollbar(cellwindow, orient="vertical") mvsb.grid(column=1, row=1, sticky='ns') mvsb['command'] = datetree.yview # main block mainblock = Frame(cellwindow, bd=2, relief=RAISED) mainblock.grid(column=2, row=1, sticky="nsew") mainblock.grid_columnconfigure(0, weight=1) mainblock.grid_rowconfigure(2, weight=1) # main block label mainblocklabel = Label( mainblock, text= "Click on the list to show description, double click to show location in browser", relief=RIDGE) mainblocklabel.grid(column=0, row=0, sticky="nsew") # tree cellstree = ttk.Treeview(mainblock, columns=("mnc", "lac", "ci", "lat", "lon", "alt", "hacc", "vacc", "speed", "course", "confidence"), displaycolumns=("mnc", "lac", "ci", "lat", "lon", "alt")) cellstree.heading("#0", text="MCC", anchor='w') cellstree.column("#0", width=30) cellstree.heading("mnc", text="MNC", anchor='w') cellstree.column("mnc", width=30) cellstree.heading("lac", text="LAC", anchor='w') cellstree.column("lac", width=30) cellstree.heading("ci", text="CI", anchor='w') cellstree.column("ci", width=50) cellstree.heading("lat", text="LAT", anchor='w') cellstree.column("lat", width=60) cellstree.heading("lon", text="LON", anchor='w') cellstree.column("lon", width=60) cellstree.heading("alt", text="ALT", anchor='w') cellstree.column("alt", width=50) cellstree.grid(column=0, row=1, sticky="nsew") # textarea textarea = Text(mainblock, bd=2, relief=SUNKEN, yscrollcommand=lambda f, l: autoscroll(tvsb, f, l)) textarea.grid(column=0, row=2, sticky="nsew") # scrollbars for main textarea tvsb = ttk.Scrollbar(mainblock, orient="vertical") tvsb.grid(column=1, row=2, sticky='ns') tvsb['command'] = textarea.yview # footer label footerlabel = StringVar() cellfooter = Label(cellwindow, textvariable=footerlabel, relief=RIDGE) cellfooter.grid(column=0, row=2, sticky="ew", columnspan=4, padx=5, pady=5) # destroy window when closed cellwindow.protocol("WM_DELETE_WINDOW", cellwindow.destroy) # opening database tempdb = sqlite3.connect(filename) tempcur = tempdb.cursor() # footer statistics query = "SELECT count(*) FROM CellLocation" tempcur.execute(query) cellsnumber = tempcur.fetchall()[0][0] query = "SELECT DISTINCT(timestamp) FROM CellLocation ORDER BY timestamp" tempcur.execute(query) disttimestamps = tempcur.fetchall() footerlabel.set("Found %s cell locations in %s distinct timestamps." % (cellsnumber, len(disttimestamps))) # populating tree with distinct timestamps for timestamp in disttimestamps: raw = timestamp[0] converted = raw + 978307200 #JAN 1 1970 converted = datetime.fromtimestamp(int(converted)) datetree.insert('', 'end', text=converted, values=(raw)) datetree.bind("<ButtonRelease-1>", OnClick) cellstree.bind("<Double-Button-1>", OnCellDoubleClick) cellstree.bind("<ButtonRelease-1>", OnCellClick)
def main(cursor, backup_path): global filename global netidenttree, textarea, netidentwindow global dict_nodes filename = os.path.join( backup_path, plugins_utils.realFileName( cursor, filename="com.apple.network.identification.plist", domaintype="SystemPreferencesDomain")) if (not os.path.isfile(filename)): print("Invalid file name for network identification data: %s" % filename) return # main window netidentwindow = Toplevel() netidentwindow.title('Network Identification') netidentwindow.focus_set() netidentwindow.grid_columnconfigure(1, weight=1) netidentwindow.grid_rowconfigure(1, weight=1) # header label netidenttitle = Label(netidentwindow, text="Network Identification data from: %s (%s) " % (filename, "com.apple.network.identification.plist"), relief=RIDGE, width=100, height=3, wraplength=800, justify=LEFT) netidenttitle.grid(column=0, row=0, sticky="ew", columnspan=4, padx=5, pady=5) # tree netidenttree = ttk.Treeview( netidentwindow, columns=("id", "timestamp", "node"), displaycolumns=("id", "timestamp"), yscrollcommand=lambda f, l: autoscroll(mvsb, f, l)) netidenttree.heading("#0", text="", anchor='w') netidenttree.heading("id", text="ID", anchor='w') netidenttree.heading("timestamp", text="Time", anchor='w') netidenttree.column("#0", width=40) netidenttree.column("id", width=250) netidenttree.column("timestamp", width=150) netidenttree.grid(column=0, row=1, sticky="ns") # textarea textarea = Text(netidentwindow, bd=2, relief=SUNKEN, yscrollcommand=lambda f, l: autoscroll(tvsb, f, l)) textarea.grid(column=2, row=1, sticky="nsew") # scrollbars for tree mvsb = ttk.Scrollbar(netidentwindow, orient="vertical") mvsb.grid(column=1, row=1, sticky='ns') mvsb['command'] = netidenttree.yview # scrollbars for main textarea tvsb = ttk.Scrollbar(netidentwindow, orient="vertical") tvsb.grid(column=3, row=1, sticky='ns') tvsb['command'] = textarea.yview # footer label footerlabel = StringVar() netidentfooter = Label(netidentwindow, textvariable=footerlabel, relief=RIDGE) netidentfooter.grid(column=0, row=2, sticky="ew", columnspan=4, padx=5, pady=5) # destroy window when closed netidentwindow.protocol("WM_DELETE_WINDOW", netidentwindow.destroy) # convert binary plist file into plain plist file netidentxml = plistutils.readPlistToXml(filename) if (netidentxml == None): print("Error while parsing binary plist data") return # main dictionary (contains anything else) maindicts = netidentxml.getElementsByTagName('dict') if (len(maindicts) <= 0): print("no main dict found in file") return maindict = maindicts[0] # extract Signatures array maindictelements = plistutils.readDict(maindict) try: signatures = maindictelements['Signatures'] except: print("No Signatures array found in main dict") return signatures_array = plistutils.readArray(signatures) # footer statistics footerlabel.set("Found %i identified networks." % (len(signatures_array))) id_number = 0 for signature in signatures_array: sig_dict = plistutils.readDict(signature) id_string = sig_dict['Identifier'].firstChild.toxml() #2011-12-27T17:35:53.290510Z timestamp_string = sig_dict['Timestamp'].firstChild.toxml() if ("." in timestamp_string): timestamp_string = timestamp_string.split(".")[0] timestamp = datetime.datetime.strptime(timestamp_string, "%Y-%m-%dT%H:%M:%S") elem_id = "" # parse identification for IPv4 routers if (id_string.startswith('IPv4')): [ip, mac] = parseipv4(id_string) elem_id = "%s (%s)" % (ip, mac) else: elem_id = id_string netidenttree.insert('', 'end', text=id_number, values=(elem_id, timestamp, sig_dict)) dict_nodes.append([id_number, sig_dict]) id_number = id_number + 1 netidenttree.bind("<ButtonRelease-1>", OnClick)
def populateUI(self): ###################################################### # CONTACTS SECTION # ###################################################### contacts = self.getContacts() self.ui.contactsWidget.setRowCount(len(contacts)) self.ui.contactsWidget.setSortingEnabled(False) row = 0 for contact in contacts: if hasattr(contact, 'ZMAINNAME') and hasattr(contact, 'ZPREFIXNAME'): newItem = QtGui.QTableWidgetItem() nameStr = "" if contact.ZPREFIXNAME is not None: nameStr += contact.ZPREFIXNAME + " " if contact.ZMAINNAME is not None: nameStr += contact.ZMAINNAME newItem.setData(QtCore.Qt.DisplayRole,nameStr) self.ui.contactsWidget.setItem(row, 0, newItem) if hasattr(contact, 'ZCANONIZEDPHONENUM'): newItem = QtGui.QTableWidgetItem(str(contact.ZCANONIZEDPHONENUM)) self.ui.contactsWidget.setItem(row, 1, newItem) if hasattr(contact, 'ZREGISTRATIONDATE'): newItem = QtGui.QTableWidgetItem() if contact.ZREGISTRATIONDATE is not None: newItem.setData(QtCore.Qt.DisplayRole,str(self.formatDate(contact.ZREGISTRATIONDATE))) self.ui.contactsWidget.setItem(row, 2, newItem) if hasattr(contact, 'ZMODIFCATIONDATE'): newItem = QtGui.QTableWidgetItem() if contact.ZMODIFCATIONDATE is not None: newItem.setData(QtCore.Qt.DisplayRole,str(self.formatDate(contact.ZMODIFCATIONDATE))) self.ui.contactsWidget.setItem(row, 3, newItem) if hasattr(contact, 'ZISVIBERICON') and hasattr(contact, 'ZICONID'): newItem = QtGui.QTableWidgetItem() iconRealFilename = "" iconlocalfile = "" if contact.ZISVIBERICON is 1 and contact.ZICONID is not None: iconlocalfile = contact.ZICONID + ".jpg" iconRealFilename = os.path.join(self.backup_path, plugins_utils.realFileName(self.cursor, filename=iconlocalfile, domaintype="AppDomain")) # add a thumnail to the table view icon = QtGui.QIcon(iconRealFilename) newItem.setIcon(icon) # add info for attachment export (ctx menu) newItem.setData(QtCore.Qt.UserRole, iconRealFilename) newItem.setData(QtCore.Qt.UserRole+1, iconlocalfile) self.ui.contactsWidget.setItem(row, 4, newItem) self.ui.contactsWidget.setRowHeight(row, 80) row = row + 1 self.ui.contactsWidget.setSortingEnabled(True) self.ui.contactsWidget.setIconSize(QtCore.QSize(80,80)) self.ui.contactsWidget.resizeColumnsToContents() self.ui.contactsWidget.setColumnWidth(4, 80) ###################################################### # RECENT CALLS SECTION # ###################################################### calls = self.getCalls() self.ui.callsWidget.setRowCount(len(calls)) self.ui.callsWidget.setSortingEnabled(False) row = 0 for call in calls: if hasattr(call, 'ZMAINNAME') and hasattr(call, 'ZPREFIXNAME'): newItem = QtGui.QTableWidgetItem() nameStr = "" if call.ZPREFIXNAME is not None: nameStr += call.ZPREFIXNAME + " " if call.ZMAINNAME is not None: nameStr += call.ZMAINNAME newItem.setData(QtCore.Qt.DisplayRole,nameStr) self.ui.callsWidget.setItem(row, 0, newItem) if hasattr(call, 'ZDATE'): newItem = QtGui.QTableWidgetItem() if call.ZDATE is not None: newItem.setData(QtCore.Qt.DisplayRole,str(self.formatDate(call.ZDATE))) self.ui.callsWidget.setItem(row, 1, newItem) if hasattr(call, 'ZDURATION'): newItem = QtGui.QTableWidgetItem() newItem.setData(QtCore.Qt.DisplayRole,call.ZDURATION) self.ui.callsWidget.setItem(row, 2, newItem) if hasattr(call, 'ZCALLTYPE'): newItem = QtGui.QTableWidgetItem(str(call.ZCALLTYPE)) self.ui.callsWidget.setItem(row, 3, newItem) if 'missed' in str(call.ZCALLTYPE): for i in range(4): self.ui.callsWidget.item(row,i).setBackground(QtCore.Qt.red) elif 'incoming' in str(call.ZCALLTYPE): for i in range(4): self.ui.callsWidget.item(row,i).setBackground(QtCore.Qt.cyan) else: for i in range(4): self.ui.callsWidget.item(row,i).setBackground(QtCore.Qt.green) row = row + 1 self.ui.callsWidget.setSortingEnabled(True) self.ui.callsWidget.resizeColumnsToContents() self.ui.callsWidget.resizeRowsToContents() ###################################################### # CHATS SECTION # ###################################################### chats = self.getChats() self.ui.chatsWidget.setRowCount(len(chats)) row = 0 for chat in chats: if hasattr(chat, 'Z_PK'): newItem = QtGui.QTableWidgetItem() newItem.setData(QtCore.Qt.DisplayRole,chat.Z_PK) self.ui.chatsWidget.setItem(row, 0, newItem) if hasattr(chat, 'ZMAINNAME') and hasattr(chat, 'ZPREFIXNAME'): newItem = QtGui.QTableWidgetItem() nameStr = "" if chat.ZPREFIXNAME is not None: nameStr += chat.ZPREFIXNAME + " " if chat.ZMAINNAME is not None: nameStr += chat.ZMAINNAME newItem.setData(QtCore.Qt.DisplayRole,nameStr) self.ui.chatsWidget.setItem(row, 1, newItem) if hasattr(chat, 'ZNAME'): newItem = QtGui.QTableWidgetItem(chat.ZNAME) self.ui.chatsWidget.setItem(row, 2, newItem) if hasattr(chat, 'ZGROUPID'): newItem = QtGui.QTableWidgetItem(chat.ZGROUPID) self.ui.chatsWidget.setItem(row, 3, newItem) if hasattr(chat, 'ZDATE'): newItem = QtGui.QTableWidgetItem(str(self.formatDate(chat.ZDATE))) self.ui.chatsWidget.setItem(row, 4, newItem) if hasattr(chat, 'ZUNREADCOUNT'): newItem = QtGui.QTableWidgetItem() newItem.setData(QtCore.Qt.DisplayRole,chat.ZUNREADCOUNT) self.ui.chatsWidget.setItem(row, 5, newItem) if hasattr(chat, 'ZGROUPID'): if chat.ZGROUPID is not None: for i in range(6): self.ui.chatsWidget.item(row,i).setBackground(QtCore.Qt.yellow) row = row + 1 self.ui.chatsWidget.resizeColumnsToContents() self.ui.chatsWidget.resizeRowsToContents()
def onTreeClick(self): # retrieving selected network currentSelectedElement = self.ui.threadsTree.currentItem() if (currentSelectedElement): pass else: return currentChat = int(currentSelectedElement.text(0)) self.ui.threadLabel.setText(currentSelectedElement.text(1)) # opening database tempdb = sqlite3.connect(self.filename) tempdb.row_factory = sqlite3.Row tempcur = tempdb.cursor() query = 'SELECT ROWID, text, date, is_from_me, cache_has_attachments, service FROM message INNER JOIN chat_message_join ON message.ROWID = chat_message_join.message_id WHERE chat_id = ?;' tempcur.execute(query, (currentChat,)) messages = tempcur.fetchall() self.ui.messageTable.clear() # prepare table with enough rows # each message is a row, but each attachment also counts as one # so, we make an educated guess maxRows = len(messages) * 3 if (maxRows < 100): maxRows += 300 self.ui.messageTable.setRowCount(maxRows) self.ui.messageTable.setColumnCount(2) self.ui.messageTable.setHorizontalHeaderLabels(["Date", "Text"]) row = 0 lastDate = "" for message in messages: documentTimestampUnix = message['date'] + 978307200 #JAN 1 1970 documentTimestamp = datetime.fromtimestamp(documentTimestampUnix).strftime('%Y-%m-%d %H:%M:%S') # separator on date change actualDate = datetime.fromtimestamp(documentTimestampUnix).strftime("%Y-%m-%d") if (actualDate != lastDate): lastDate = actualDate newItem = QtGui.QTableWidgetItem(actualDate) newItem.setBackground(QtCore.Qt.yellow) self.ui.messageTable.setItem(row, 0, newItem) newItem = QtGui.QTableWidgetItem() #newItem.setBackground(QtCore.Qt.yellow) self.ui.messageTable.setItem(row, 1, newItem) row += 1 if (message['is_from_me'] == 1): documentTimestamp = "Sent on:\n" + documentTimestamp else: documentTimestamp = "Received on:\n" + documentTimestamp newItem = QtGui.QTableWidgetItem(documentTimestamp) self.ui.messageTable.setItem(row, 0, newItem) newItem = QtGui.QTableWidgetItem(message['text']) if (message['is_from_me'] == 1): if (message['service'] == "SMS"): newItem.setBackground(QtCore.Qt.green) else: newItem.setBackground(QtCore.Qt.cyan) else: newItem.setBackground(QtCore.Qt.gray) self.ui.messageTable.setItem(row, 1, newItem) row += 1 if (message['cache_has_attachments'] == 1): query = 'SELECT ROWID, filename, mime_type FROM attachment INNER JOIN message_attachment_join ON message_attachment_join.attachment_id = attachment.ROWID WHERE message_attachment_join.message_id = ?;' tempcur.execute(query, (message['ROWID'], )) for attachment in tempcur.fetchall(): attachmentFileName = attachment['filename'] attachmentType = attachment['mime_type'] # seems paths have changed from iOS 5 to iOS 6, must find # path from "Library" onwards attachmentPathParts = os.path.dirname(attachmentFileName).split("/") libraryPosition = 0 index = 0 for element in attachmentPathParts: if (element == "Library"): libraryPosition = index break else: index += 1 attachmentPath = "/".join(os.path.dirname(attachmentFileName).split("/")[libraryPosition:]) attachmentName = os.path.basename(attachmentFileName) attachmentRealFilename = os.path.join(self.backup_path, plugins_utils.realFileName(self.cursor, filename=attachmentName, path=attachmentPath, domaintype="MediaDomain")) if (not os.path.isfile(attachmentRealFilename)): newItem = QtGui.QTableWidgetItem("Attached file %s (id: %i) not found."%(attachmentFileName, attachment['ROWID'])) else: if (attachmentType.split("/")[0] == "image"): newItem = QtGui.QTableWidgetItem() icon = QtGui.QIcon(attachmentRealFilename) newItem.setIcon(icon) else: newItem = QtGui.QTableWidgetItem("Right click to open attached file\n%s (%s)"%(attachmentName, attachment['mime_type'])) newItem.setForeground(QtCore.Qt.red) newItem.setData(QtCore.Qt.UserRole, attachmentRealFilename) newItem.setData(QtCore.Qt.UserRole + 1, attachmentName) if (message['is_from_me'] == 1): if (message['service'] == "SMS"): newItem.setBackground(QtCore.Qt.green) else: newItem.setBackground(QtCore.Qt.cyan) else: newItem.setBackground(QtCore.Qt.gray) self.ui.messageTable.setItem(row, 1, newItem) row += 1 self.ui.messageTable.setRowCount(row) self.ui.messageTable.setIconSize(QtCore.QSize(200,200)) self.ui.messageTable.resizeColumnsToContents() self.ui.messageTable.setColumnWidth(1, 200) self.ui.messageTable.horizontalHeader().setStretchLastSection(True) self.ui.messageTable.resizeRowsToContents() # closing database tempdb.close()
def main(cursor, backup_path, commandLineFilename=None): global filename global thumbstree, textarea, prevarea, thumbswindow global photoImagesList global framelen_image, framelen_padding, thumbs_filename if (commandLineFilename): filename = commandLineFilename else: filename = os.path.join( backup_path, plugins_utils.realFileName(cursor, filename=thumbs_filename)) if (not os.path.isfile(filename)): import tkMessageBox tkMessageBox.showwarning( "File not found", "Seems like this backup doesn't contain \"%s\" thumbnail data. Each iDevice has its set of thumbnails, maybe the device you are working on doesn't have this kind of thumbnails." % thumbs_filename) return # main window thumbswindow = Toplevel() thumbswindow.title('Thumbnails') thumbswindow.focus_set() thumbswindow.grid_columnconfigure(2, weight=1) thumbswindow.grid_rowconfigure(1, weight=1) # header label thumbstitle = Label(thumbswindow, text="Thumbnails data from: %s (%s)" % (filename, thumbs_filename), relief=RIDGE, width=100, height=2, wraplength=800, justify=LEFT) thumbstitle.grid(column=0, row=0, sticky="ew", columnspan=6, padx=5, pady=5) # tree thumbstree = ttk.Treeview( thumbswindow, columns=(), displaycolumns=(), yscrollcommand=lambda f, l: autoscroll(mvsb, f, l)) thumbstree.heading("#0", text="ID", anchor='w') #thumbstree.heading("pos", text="Address", anchor='w') thumbstree.column("#0", width=130) #thumbstree.column("pos", width=200) thumbstree.grid(column=0, row=1, sticky="ns", rowspan=2) # upper textarea #uppertextarea = Text(thumbswindow, bd=2, relief=SUNKEN, height=5) #uppertextarea.grid(column = 2, row = 1, sticky="nsew") # textarea textarea = Text(thumbswindow, bd=2, relief=SUNKEN, yscrollcommand=lambda f, l: autoscroll(tvsb, f, l), width=60) textarea.grid(column=2, row=1, rowspan=2, sticky="nsew") # preview area prevarea = Text(thumbswindow, bd=2, relief=SUNKEN, width=50) prevarea.grid(column=5, row=1, rowspan=2, sticky="nsew") # scrollbars for tree mvsb = ttk.Scrollbar(thumbswindow, orient="vertical") mvsb.grid(column=1, row=1, sticky='ns', rowspan=2) mvsb['command'] = thumbstree.yview # scrollbars for main textarea tvsb = ttk.Scrollbar(thumbswindow, orient="vertical") tvsb.grid(column=3, row=2, sticky='ns') tvsb['command'] = textarea.yview # footer label footerlabel = StringVar() thumbsfooter = Label(thumbswindow, textvariable=footerlabel, relief=RIDGE) thumbsfooter.grid(column=0, row=3, sticky="ew", columnspan=6, padx=5, pady=5) # destroy window when closed thumbswindow.protocol("WM_DELETE_WINDOW", thumbswindow.destroy) # populating list f = open(filename, 'r') wholefile = f.read() f.close() framelen = framelen_image + framelen_padding numframes = len(wholefile) / framelen #print("Number of frames found: ", numframes) del photoImagesList[:] for i in range(numframes): string = wholefile[framelen * i:framelen * (i + 1) - 1] im = Image.frombuffer('RGB', (frame_width, frame_height), string, 'raw', 'BGR;15', 0, 1) im = im.resize((15, 15), Image.ANTIALIAS) tkim = ImageTk.PhotoImage(im) photoImagesList.append(tkim) thumbstree.insert('', 'end', text=i, image=tkim) textarea.insert(END, "Thumbnail file viewer\n") textarea.insert(END, "\n") textarea.insert(END, "Thumbnail file name: %s\n" % thumbs_filename) textarea.insert(END, "Thumbnail file real name: %s\n" % filename) textarea.insert(END, "\n") textarea.insert(END, "Thumbnail width: %i\n" % frame_width) textarea.insert(END, "Thumbnail height: %i\n" % frame_height) textarea.insert( END, "Thumbnail size in bytes: %i + %i padding for each\n" % (frame_width * frame_height * 2, framelen_padding)) thumbstree.bind("<ButtonRelease-1>", OnClick)
def onChatsClick(self): # disable chats table (to disable click events while processing) self.ui.chatsWidget.setEnabled(False) # retrieving selected row self.ui.chatsWidget.setCurrentCell(self.ui.chatsWidget.currentRow(),0) currentSelectedItem = self.ui.chatsWidget.currentItem() if (currentSelectedItem): pass else: return ###################################################### # MESSAGES SECTION # ###################################################### zpk = int(currentSelectedItem.text()) #msgs = self.getMsgs(zpk) # <--- single thread msgs = self.getMsgsThreaded(zpk) # <--- multithreaded # re-select a visible column to allow the keyboard selection self.ui.chatsWidget.setCurrentCell(self.ui.chatsWidget.currentRow(),1) # erase previous messages and set new table lenght #self.ui.msgsWidget.clearContents() self.ui.msgsWidget.setSortingEnabled(False) self.ui.msgsWidget.setRowCount(len(msgs)) row = 0 for msg in msgs: from_me = False # var to remember from whom is the msg if hasattr(msg, 'Z_PK'): newItem = QtGui.QTableWidgetItem() newItem.setData(QtCore.Qt.DisplayRole,msg.Z_PK) self.ui.msgsWidget.setItem(row, 0, newItem) if hasattr(msg, 'ZPHONENUMINDEX'): newItem = QtGui.QTableWidgetItem() fromstring = "" if msg.ZPHONENUMINDEX is not None: msgcontact = self.getMsgContact(msg.ZPHONENUMINDEX) if msgcontact is not None: if msgcontact.ZPREFIXNAME is not None: fromstring += msgcontact.ZPREFIXNAME + " " if msgcontact.ZMAINNAME is not None: fromstring += msgcontact.ZMAINNAME + " " if msgcontact.ZCANONIZEDPHONENUM is not None: fromstring += msgcontact.ZCANONIZEDPHONENUM else: fromstring = "N/A" else: fromstring = "Me" from_me = True newItem.setData(QtCore.Qt.DisplayRole,fromstring) self.ui.msgsWidget.setItem(row, 1, newItem) if hasattr(msg, 'ZDATE'): newItem = QtGui.QTableWidgetItem(str(self.formatDate(msg.ZDATE))) self.ui.msgsWidget.setItem(row, 2, newItem) if hasattr(msg, 'ZTEXT'): newItem = QtGui.QTableWidgetItem(msg.ZTEXT) self.ui.msgsWidget.setItem(row, 3, newItem) if hasattr(msg, 'ZSTATE'): newItem = QtGui.QTableWidgetItem(msg.ZSTATE) self.ui.msgsWidget.setItem(row, 5, newItem) if hasattr(msg, 'ZSTATEDATE'): newItem = QtGui.QTableWidgetItem(str(self.formatDate(msg.ZSTATEDATE))) self.ui.msgsWidget.setItem(row, 6, newItem) # ATTACHMENTS SECTION if hasattr(msg, 'ZATTACHMENT') and hasattr(msg, 'ZLOCATION'): mediaItem = QtGui.QTableWidgetItem("") msgcontent = "" # case 1: msg contains a location if msg.ZLOCATION is not None: location = self.getLocation(msg.ZLOCATION) msgcontent += "GPS\n" + "lat: " + str(location.ZLATITUDE) + "\nlong: " + str(location.ZLONGITUDE) + "\naddress: " + unicode(location.ZADDRESS) + "\n" # re-set message content (3rd column) newItem = QtGui.QTableWidgetItem(msgcontent) self.ui.msgsWidget.setItem(row, 3, newItem) # compose location thumbnail filename (guess) # example: if LAT = 41.796141 and LONG = 12.481714 # the filename is 41.796141_12.jpg strlat = str(location.ZLATITUDE) strlong = str(location.ZLONGITUDE) strlat_s = strlat.split('.') strlong_s = strlong.split('.') filename = strlat_s[0] + "." + (strlat_s[1])[:6] + "_" + strlong_s[0] + ".jpg" locationlocalfile = filename locationRealFilename = os.path.join(self.backup_path, plugins_utils.realFileName(self.cursor, filename=locationlocalfile, domaintype="AppDomain")) # add a thumbnail to the table view icon = QtGui.QIcon(locationRealFilename) mediaItem.setIcon(icon) # add info for attachment export (ctx menu) mediaItem.setData(QtCore.Qt.UserRole+2, location.ZLATITUDE) mediaItem.setData(QtCore.Qt.UserRole+3, location.ZLONGITUDE) # case 2: msg contains an attachment elif msg.ZATTACHMENT is not None: media = self.getMediaItem(msg.ZATTACHMENT) msgcontent += "ATTACHMENT\n" + "type: " + str(media.ZTYPE) + "\nstate: " + str(media.ZSTATE) + "\nsize: " + str(media.ZFILESIZE) + "B\n" if 'sticker' in media.ZTYPE: msgcontent += "id: " + media.ZID + "\n" # re-set message content (3rd column) newItem = QtGui.QTableWidgetItem(msgcontent) self.ui.msgsWidget.setItem(row, 3, newItem) if media.ZNAME: medialocalfile = media.ZNAME mediaRealFilename = os.path.join(self.backup_path, plugins_utils.realFileName(self.cursor, filename=medialocalfile, domaintype="AppDomain")) # add a thumbnail to the table view icon = QtGui.QIcon(mediaRealFilename) mediaItem.setIcon(icon) # add info for attachment export (ctx menu) mediaItem.setData(QtCore.Qt.UserRole, mediaRealFilename) mediaItem.setData(QtCore.Qt.UserRole+1, medialocalfile) self.ui.msgsWidget.setItem(row, 4, mediaItem) if from_me: for i in range(7): self.ui.msgsWidget.item(row,i).setBackground(QtCore.Qt.green) row = row + 1 self.ui.msgsWidget.setSortingEnabled(True) self.ui.msgsWidget.setIconSize(QtCore.QSize(150,150)) self.ui.msgsWidget.resizeColumnsToContents() self.ui.msgsWidget.setColumnWidth(6, 150) self.ui.msgsWidget.resizeRowsToContents() # signal-slot connection: preserve row height when sorting messages self.ui.msgsWidget.horizontalHeader().sortIndicatorChanged.connect(self.ui.msgsWidget.resizeRowsToContents) # re-enable chats table self.ui.chatsWidget.setEnabled(True) self.ui.chatsWidget.setFocus()
def onChatsClick(self): # disable chats table (to disable click events while processing) self.ui.chatsWidget.setEnabled(False) # retrieving selected row self.ui.chatsWidget.setCurrentCell(self.ui.chatsWidget.currentRow(),0) currentSelectedItem = self.ui.chatsWidget.currentItem() if (currentSelectedItem): pass else: return ###################################################### # MESSAGES SECTION # ###################################################### zpk = int(currentSelectedItem.text()) #msgs = self.getMsgs(zpk) # <--- msgs = self.getMsgsThreaded(zpk) # <--- # re-select a visible column to allow the keyboard selection self.ui.chatsWidget.setCurrentCell(self.ui.chatsWidget.currentRow(),1) # erase previous messages and set new table lenght #self.ui.msgsWidget.clearContents() self.ui.msgsWidget.setSortingEnabled(False) self.ui.msgsWidget.setRowCount(len(msgs)) row = 0 for msg in msgs: if hasattr(msg, 'Z_PK'): newItem = QtGui.QTableWidgetItem() newItem.setData(QtCore.Qt.DisplayRole,msg.Z_PK) self.ui.msgsWidget.setItem(row, 0, newItem) if hasattr(msg, 'ZFROMJID'): fromstring = "Me" if msg.ZFROMJID is not None: fromstring = msg.ZFROMJID newItem = QtGui.QTableWidgetItem() newItem.setData(QtCore.Qt.DisplayRole,fromstring) self.ui.msgsWidget.setItem(row, 1, newItem) if hasattr(msg, 'ZMESSAGEDATE'): newItem = QtGui.QTableWidgetItem(str(self.formatDate(msg.ZMESSAGEDATE))) self.ui.msgsWidget.setItem(row, 2, newItem) if hasattr(msg, 'ZTEXT'): newItem = QtGui.QTableWidgetItem(msg.ZTEXT) self.ui.msgsWidget.setItem(row, 3, newItem) if hasattr(msg, 'ZMESSAGESTATUS'): newItem = QtGui.QTableWidgetItem() newItem.setData(QtCore.Qt.DisplayRole,msg.ZMESSAGESTATUS) self.ui.msgsWidget.setItem(row, 5, newItem) if hasattr(msg, 'ZGROUPMEMBER'): if msg.ZGROUPMEMBER is not None: gmember = self.getGroupInfo(msg.ZGROUPMEMBER) fromstring = "" if gmember is not None: fromstring = gmember.ZCONTACTNAME + " - " + gmember.ZMEMBERJID else: fromstring = "N/A" newItem = QtGui.QTableWidgetItem(fromstring) self.ui.msgsWidget.setItem(row, 1, newItem) if hasattr(msg, 'ZMEDIAITEM'): mediaItem = QtGui.QTableWidgetItem("") if msg.ZMEDIAITEM is not None: media = self.getMediaItem(msg.ZMEDIAITEM) msgcontent = "" # VCARD info if (media.ZVCARDNAME and media.ZVCARDSTRING) is not None: msgcontent += ("VCARD\n" + media.ZVCARDNAME + "\n" + media.ZVCARDSTRING + "\n") # GPS info if media.ZLATITUDE != 0. or media.ZLONGITUDE != 0.: msgcontent += ("GPS\n" + "lat: " + str(media.ZLATITUDE) + "\nlong: " + str(media.ZLONGITUDE) + "\n") # VIDEO info if media.ZMOVIEDURATION != 0: msgcontent += ("VIDEO\n" + "duration: " + str(media.ZMOVIEDURATION) + " sec\n") # FILE info if media.ZFILESIZE != 0: msgcontent += ("FILE\n" + "size: " + str(media.ZFILESIZE) + " B\n") # set message content (3rd column) newItem = QtGui.QTableWidgetItem(msgcontent) self.ui.msgsWidget.setItem(row, 3, newItem) thumbRealFilename = "" mediaRealFilename = "" mediallocalfile = "" # THUMBNAIL if media.ZTHUMBNAILLOCALPATH is not None: thumblocalfilepath = media.ZTHUMBNAILLOCALPATH thumblocalpath = os.path.dirname(thumblocalfilepath) thumbllocalfile = os.path.basename(thumblocalfilepath) thumbRealFilename = os.path.join(self.backup_path, plugins_utils.realFileName(self.cursor, filename=thumbllocalfile, path='Library/'+thumblocalpath, domaintype="AppDomain")) # ATTACHMENT if media.ZMEDIALOCALPATH is not None: medialocalfilepath = media.ZMEDIALOCALPATH mediallocalpath = os.path.dirname(medialocalfilepath) mediallocalfile = os.path.basename(medialocalfilepath) mediaRealFilename = os.path.join(self.backup_path, plugins_utils.realFileName(self.cursor, filename=mediallocalfile, path='Library/'+mediallocalpath, domaintype="AppDomain")) # add a thumnail to the table view icon = None if thumbRealFilename != "": icon = QtGui.QIcon(thumbRealFilename) else: icon = QtGui.QIcon(mediaRealFilename) mediaItem = QtGui.QTableWidgetItem() mediaItem.setIcon(icon) # add info for attachment export (ctx menu) if mediallocalfile != "": mediaItem.setData(QtCore.Qt.UserRole, mediaRealFilename) mediaItem.setData(QtCore.Qt.UserRole+1, mediallocalfile) if media.ZLATITUDE != 0. or media.ZLONGITUDE != 0.: mediaItem.setData(QtCore.Qt.UserRole+2, media.ZLATITUDE) mediaItem.setData(QtCore.Qt.UserRole+3, media.ZLONGITUDE) self.ui.msgsWidget.setItem(row, 4, mediaItem) if hasattr(msg, 'ZISFROMME'): if msg.ZISFROMME is 1: for i in range(6): self.ui.msgsWidget.item(row,i).setBackground(QtCore.Qt.green) row = row + 1 self.ui.msgsWidget.setSortingEnabled(True) self.ui.msgsWidget.setIconSize(QtCore.QSize(150,150)) self.ui.msgsWidget.resizeColumnsToContents() self.ui.msgsWidget.setColumnWidth(4, 150) self.ui.msgsWidget.resizeRowsToContents() # re-enable chats table self.ui.chatsWidget.setEnabled(True) self.ui.chatsWidget.setFocus()
def main(cursor, backup_path): global filename global historytree, textarea, historywindow global titlefootertext, urlfootertext filename = os.path.join(backup_path, plugins_utils.realFileName(cursor, filename="History.plist", domaintype="HomeDomain", path="Library/Safari")) if (not os.path.isfile(filename)): print("Invalid file name for Safari History database: %s"%filename) return # main window historywindow = Toplevel() historywindow.title('Safari History data') historywindow.focus_set() historywindow.grid_columnconfigure(0, weight=1) historywindow.grid_rowconfigure(1, weight=1) # header label contactstitle = Label(historywindow, text = "Safari History data from: " + filename, relief = RIDGE) contactstitle.grid(column = 0, row = 0, sticky="ew", padx=5, pady=5) # convert binary plist file into plain plist file historyxml = plistutils.readPlistToXml(filename) if (historyxml == None): print("Error while parsing Safari History Data") return # main dictionary (contains anything else) maindicts = historyxml.getElementsByTagName('dict') if (len(maindicts) <= 0): print("no main dict found in file") return maindict = maindicts[0] # read WebHistoryDates array of dicts (one dict for each bookmark) from plistutils import readDict, readArray outerDict = readDict(maindict) bookmarksArray = readArray(outerDict['WebHistoryDates']) bookmarks = [] # decode each bookmark dict for element in bookmarksArray: bookmark = {} elementDict = readDict(element) bookmark['title'] = "" if ('title' in elementDict.keys()): bookmark['title'] = elementDict['title'].firstChild.toxml() bookmark['url'] = "" if ('-' in elementDict.keys()): bookmark['url'] = elementDict['-'].firstChild.toxml() bookmark['date'] = "" if ('lastVisitedDate' in elementDict.keys()): bookmark['date'] = elementDict['lastVisitedDate'].firstChild.toxml() bookmarks.append(bookmark) # tree historytree = ttk.Treeview(historywindow, columns=("title", "url"), displaycolumns=("title", "url")) historytree.heading("#0", text="Date", anchor='w') historytree.heading("title", text="Title", anchor='w') historytree.heading("url", text="Url", anchor='w') historytree.column("#0", width=25) historytree.column("title", width=250) historytree.column("url", width=300) historytree.grid(column = 0, row = 1, sticky="ewns") # details box detailsbox = Frame(historywindow, bd=2, relief=RAISED); detailsbox.grid(column = 0, row = 2, sticky="ew", padx=5, pady=5) detailsbox.grid_columnconfigure(1, weight=1) titlefooterlabel = Label(detailsbox, text = 'Title:', relief = RIDGE, width=10) titlefooterlabel.grid(column = 0, row = 0, sticky="ew", padx=2, pady=2) titlefootertext = StringVar() titlefooter = Label(detailsbox, textvariable = titlefootertext, relief = RIDGE, anchor = 'w') titlefooter.grid(column = 1, row = 0, sticky="ew", padx=2, pady=2) titlefootertext.set("mille") urlfooterlabel = Label(detailsbox, text = 'URL:', relief = RIDGE, width=10) urlfooterlabel.grid(column = 0, row = 1, sticky="ew", padx=2, pady=2) urlfootertext = StringVar() urlfooter = Label(detailsbox, textvariable = urlfootertext, relief = RIDGE, anchor = 'w') urlfooter.grid(column = 1, row = 1, sticky="ew", padx=2, pady=2) urlfootertext.set("mille") # footer label footerlabel = StringVar() contactsfooter = Label(historywindow, textvariable = footerlabel, relief = RIDGE) contactsfooter.grid(column = 0, row = 3, sticky="ew", padx=5, pady=5) # destroy window when closed historywindow.protocol("WM_DELETE_WINDOW", historywindow.destroy) # footer statistics footerlabel.set("Found %s Safari history records"%(len(bookmarks))) # populating bookmarks tree for bookmark in bookmarks: timestamp = float(bookmark['date']) + 978307200 #JAN 1 1970 convtimestamp = datetime.fromtimestamp(int(timestamp)) historytree.insert( '', 'end', text = convtimestamp, values = ( bookmark['title'], bookmark['url'] ) ) historytree.bind("<ButtonRelease-1>", OnClick) historytree.bind("<Double-Button-1>", OnDoubleClick)
def onTreeClick(self): # retrieving selected network currentSelectedElement = self.ui.threadsTree.currentItem() if (currentSelectedElement): pass else: return currentChat = int(currentSelectedElement.text(0)) self.ui.threadLabel.setText(currentSelectedElement.text(1)) # opening database tempdb = sqlite3.connect(self.filename) tempdb.row_factory = sqlite3.Row tempcur = tempdb.cursor() query = 'SELECT ROWID, text, date, is_from_me, cache_has_attachments, service FROM message INNER JOIN chat_message_join ON message.ROWID = chat_message_join.message_id WHERE chat_id = ?;' tempcur.execute(query, (currentChat, )) messages = tempcur.fetchall() self.ui.messageTable.clear() # prepare table with enough rows # each message is a row, but each attachment also counts as one # so, we make an educated guess maxRows = len(messages) * 3 if (maxRows < 100): maxRows += 300 self.ui.messageTable.setRowCount(maxRows) self.ui.messageTable.setColumnCount(2) self.ui.messageTable.setHorizontalHeaderLabels(["Date", "Text"]) row = 0 lastDate = "" for message in messages: documentTimestampUnix = message['date'] + 978307200 #JAN 1 1970 documentTimestamp = datetime.fromtimestamp( documentTimestampUnix).strftime('%Y-%m-%d %H:%M:%S') # separator on date change actualDate = datetime.fromtimestamp( documentTimestampUnix).strftime("%Y-%m-%d") if (actualDate != lastDate): lastDate = actualDate newItem = QtGui.QTableWidgetItem(actualDate) newItem.setBackground(QtCore.Qt.yellow) self.ui.messageTable.setItem(row, 0, newItem) newItem = QtGui.QTableWidgetItem() #newItem.setBackground(QtCore.Qt.yellow) self.ui.messageTable.setItem(row, 1, newItem) row += 1 if (message['is_from_me'] == 1): documentTimestamp = "Sent on:\n" + documentTimestamp else: documentTimestamp = "Received on:\n" + documentTimestamp newItem = QtGui.QTableWidgetItem(documentTimestamp) self.ui.messageTable.setItem(row, 0, newItem) newItem = QtGui.QTableWidgetItem(message['text']) if (message['is_from_me'] == 1): if (message['service'] == "SMS"): newItem.setBackground(QtCore.Qt.green) else: newItem.setBackground(QtCore.Qt.cyan) else: newItem.setBackground(QtCore.Qt.gray) self.ui.messageTable.setItem(row, 1, newItem) row += 1 if (message['cache_has_attachments'] == 1): query = 'SELECT ROWID, filename, mime_type FROM attachment INNER JOIN message_attachment_join ON message_attachment_join.attachment_id = attachment.ROWID WHERE message_attachment_join.message_id = ?;' tempcur.execute(query, (message['ROWID'], )) for attachment in tempcur.fetchall(): attachmentFileName = attachment['filename'] attachmentType = attachment['mime_type'] # seems paths have changed from iOS 5 to iOS 6, must find # path from "Library" onwards attachmentPathParts = os.path.dirname( attachmentFileName).split("/") libraryPosition = 0 index = 0 for element in attachmentPathParts: if (element == "Library"): libraryPosition = index break else: index += 1 attachmentPath = "/".join( os.path.dirname(attachmentFileName).split("/") [libraryPosition:]) attachmentName = os.path.basename(attachmentFileName) attachmentRealFilename = os.path.join( self.backup_path, plugins_utils.realFileName(self.cursor, filename=attachmentName, path=attachmentPath, domaintype="MediaDomain")) if (not os.path.isfile(attachmentRealFilename)): newItem = QtGui.QTableWidgetItem( "Attached file %s (id: %i) not found." % (attachmentFileName, attachment['ROWID'])) else: if (attachmentType.split("/")[0] == "image"): newItem = QtGui.QTableWidgetItem() icon = QtGui.QIcon(attachmentRealFilename) newItem.setIcon(icon) else: newItem = QtGui.QTableWidgetItem( "Right click to open attached file\n%s (%s)" % (attachmentName, attachment['mime_type'])) newItem.setForeground(QtCore.Qt.red) newItem.setData(QtCore.Qt.UserRole, attachmentRealFilename) newItem.setData(QtCore.Qt.UserRole + 1, attachmentName) if (message['is_from_me'] == 1): if (message['service'] == "SMS"): newItem.setBackground(QtCore.Qt.green) else: newItem.setBackground(QtCore.Qt.cyan) else: newItem.setBackground(QtCore.Qt.gray) self.ui.messageTable.setItem(row, 1, newItem) row += 1 self.ui.messageTable.setRowCount(row) self.ui.messageTable.setIconSize(QtCore.QSize(200, 200)) self.ui.messageTable.resizeColumnsToContents() self.ui.messageTable.setColumnWidth(1, 200) self.ui.messageTable.horizontalHeader().setStretchLastSection(True) self.ui.messageTable.resizeRowsToContents() # closing database tempdb.close()
def main(cursor, backup_path): global filename global callstree, textarea filename = os.path.join(backup_path, plugins_utils.realFileName(cursor, filename="call_history.db", domaintype="WirelessDomain")) if (not os.path.isfile(filename)): print("Invalid file name for SMS database") return # main window callswindow = Toplevel() callswindow.title('Call History data') callswindow.focus_set() callswindow.grid_columnconfigure(2, weight=1) callswindow.grid_rowconfigure(1, weight=1) # header label callstitle = Label(callswindow, text = "Calls history data from: " + filename, relief = RIDGE) callstitle.grid(column = 0, row = 0, sticky="ew", columnspan=4, padx=5, pady=5) # tree callstree = ttk.Treeview(callswindow, columns=("address", "date", "duration", "flags", "id", "name", "countrycode"), displaycolumns=("address", "date", "duration", "flags"), yscrollcommand=lambda f, l: autoscroll(mvsb, f, l)) callstree.heading("#0", text="ID", anchor='w') callstree.heading("date", text="Date", anchor='w') callstree.heading("address", text="Address", anchor='w') callstree.heading("duration", text="Duration", anchor='w') callstree.heading("flags", text="Flags", anchor='w') callstree.column("#0", width=50) callstree.column("date", width=200) callstree.column("address", width=150) callstree.column("duration", width=100) callstree.column("flags", width=100) callstree.grid(column = 0, row = 1, sticky="ns") # textarea textarea = Text(callswindow, bd=2, relief=SUNKEN, width=50, yscrollcommand=lambda f, l: autoscroll(tvsb, f, l)) textarea.grid(column = 2, row = 1, sticky="nsew") # scrollbars for tree mvsb = ttk.Scrollbar(callswindow, orient="vertical") mvsb.grid(column=1, row=1, sticky='ns') mvsb['command'] = callstree.yview # scrollbars for main textarea tvsb = ttk.Scrollbar(callswindow, orient="vertical") tvsb.grid(column=3, row=1, sticky='ns') tvsb['command'] = textarea.yview # footer label footerlabel = StringVar() callsfooter = Label(callswindow, textvariable = footerlabel, relief = RIDGE) callsfooter.grid(column = 0, row = 2, sticky="ew", columnspan=4, padx=5, pady=5) # destroy window when closed callswindow.protocol("WM_DELETE_WINDOW", callswindow.destroy) # opening database tempdb = sqlite3.connect(filename) tempcur = tempdb.cursor() # footer statistics query = "SELECT count(ROWID) FROM call" tempcur.execute(query) callsnumber = tempcur.fetchall()[0][0] footerlabel.set("Found %s calls."%callsnumber) def readKey(key): query = "SELECT value FROM _SqliteDatabaseProperties WHERE key = \"%s\""%key tempcur.execute(query) data = tempcur.fetchall() if (len(data) > 0): value = data[0][0] else: value = 0 return value def formatTime(seconds): durationtot = int(seconds) durationmin = int(durationtot / 60) durationhh = int(durationmin / 60) durationmin = durationmin - (durationhh * 60) durationsec = durationtot - (durationmin * 60) - (durationhh * 3600) duration = "%i:%.2i:%.2i"%(durationhh, durationmin, durationsec) return duration # populating textarea with data from _SqliteDatabaseProperties textarea.insert(END, "Call history limit: %s\n"%(readKey("call_history_limit"))) textarea.insert(END, "Last call duration: %s\n"%(formatTime(readKey("timer_last")))) textarea.insert(END, "Incoming calls duration: %s\n"%(formatTime(readKey("timer_incoming")))) textarea.insert(END, "Outgoing calls duration: %s\n"%(formatTime(readKey("timer_outgoing")))) textarea.insert(END, "Total call duration: %s\n"%(formatTime(readKey("timer_all")))) textarea.insert(END, "Total lifetime call duration: %s\n"%(formatTime(readKey("timer_lifetime")))) # populating tree with calls query = "SELECT ROWID, address, date, duration, flags, id, name, country_code FROM call ORDER BY date" tempcur.execute(query) calls = tempcur.fetchall() tempdb.close() for call in calls: rowid = call[0] address = call[1] date = datetime.fromtimestamp(int(call[2])) duration = formatTime(call[3]) flagval = call[4] if (flagval == 5): flags = "Outgoing" elif (flagval == 4): flags = "Incoming" else: flags = "Cancelled" id = call[5] name = call[6] country_code = call[7] callstree.insert('', 'end', text=rowid, values=(address, date, duration, flags))
def main(cursor, backup_path): global filename global safstatetree, textarea, safstatewindow global dict_nodes filename = os.path.join( backup_path, plugins_utils.realFileName(cursor, filename="SuspendState.plist", domaintype="HomeDomain")) if (not os.path.isfile(filename)): print("Invalid file name for Safari state data: %s" % filename) return # main window safstatewindow = Toplevel() safstatewindow.title('Safari State') safstatewindow.focus_set() safstatewindow.grid_columnconfigure(1, weight=1) safstatewindow.grid_rowconfigure(1, weight=1) # header label safstatetitle = Label(safstatewindow, text="Safari State data from: %s (%s) " % (filename, "SuspendState.plist"), relief=RIDGE, width=100, height=3, wraplength=800, justify=LEFT) safstatetitle.grid(column=0, row=0, sticky="ew", columnspan=4, padx=5, pady=5) # tree safstatetree = ttk.Treeview( safstatewindow, columns=("active", "title", "timestamp"), displaycolumns=("active", "title", "timestamp"), yscrollcommand=lambda f, l: autoscroll(mvsb, f, l)) safstatetree.heading("#0", text="", anchor='w') safstatetree.heading("active", text="A", anchor='w') safstatetree.heading("title", text="Title", anchor='w') safstatetree.heading("timestamp", text="Timestamp", anchor='w') safstatetree.column("#0", width=30) safstatetree.column("active", width=20) safstatetree.column("title", width=250) safstatetree.column("timestamp", width=160) safstatetree.grid(column=0, row=1, sticky="ns") # textarea textarea = Text(safstatewindow, bd=2, relief=SUNKEN, yscrollcommand=lambda f, l: autoscroll(tvsb, f, l)) textarea.grid(column=2, row=1, sticky="nsew") # scrollbars for tree mvsb = ttk.Scrollbar(safstatewindow, orient="vertical") mvsb.grid(column=1, row=1, sticky='ns') mvsb['command'] = safstatetree.yview # scrollbars for main textarea tvsb = ttk.Scrollbar(safstatewindow, orient="vertical") tvsb.grid(column=3, row=1, sticky='ns') tvsb['command'] = textarea.yview # footer label footerlabel = StringVar() safstatefooter = Label(safstatewindow, textvariable=footerlabel, relief=RIDGE) safstatefooter.grid(column=0, row=2, sticky="ew", columnspan=4, padx=5, pady=5) # destroy window when closed safstatewindow.protocol("WM_DELETE_WINDOW", safstatewindow.destroy) # convert binary plist file into plain plist file safstatexml = plistutils.readPlistToXml(filename) if (safstatexml == None): print("Error while parsing binary plist data") return # main dictionary (contains anything else) maindicts = safstatexml.getElementsByTagName('dict') if (len(maindicts) <= 0): print("no main dict found in file") return maindict = maindicts[0] # extract SafariStateDocuments array maindictelements = plistutils.readDict(maindict) try: safstatedocs = maindictelements['SafariStateDocuments'] except: print("No SafariStateDocuments array found in main dict") return active_tab = int( maindictelements['SafariStateActiveDocumentIndex'].firstChild.toxml()) safstatedocs_array = plistutils.readArray(safstatedocs) # footer statistics footerlabel.set("Found %i open tabs." % (len(safstatedocs_array))) id_number = 0 for safstatedoc in safstatedocs_array: safstatedoc_dict = plistutils.readDict(safstatedoc) try: title = safstatedoc_dict[ 'SafariStateDocumentTitle'].firstChild.toxml() except: title = "" timestamp_val = float( safstatedoc_dict['SafariStateDocumentLastViewedTime'].firstChild. toxml()) timestamp_val = timestamp_val + 978307200 #JAN 1 1970 timestamp = datetime.datetime.fromtimestamp(timestamp_val) timestamp = timestamp.strftime("%Y-%m-%d %H:%M") active_status = "" if (active_tab == id_number): active_status = "*" safstatetree.insert('', 'end', text=id_number, values=(active_status, title, timestamp)) dict_nodes.append([id_number, safstatedoc_dict]) id_number = id_number + 1 safstatetree.bind("<ButtonRelease-1>", OnClick)
def main(cursor, backup_path): global filename global historytree, textarea, historywindow global titlefootertext, urlfootertext filename = os.path.join( backup_path, plugins_utils.realFileName(cursor, filename="History.plist", domaintype="HomeDomain", path="Library/Safari")) if (not os.path.isfile(filename)): print("Invalid file name for Safari History database: %s" % filename) return # main window historywindow = Toplevel() historywindow.title('Safari History data') historywindow.focus_set() historywindow.grid_columnconfigure(0, weight=1) historywindow.grid_rowconfigure(1, weight=1) # header label contactstitle = Label(historywindow, text="Safari History data from: " + filename, relief=RIDGE) contactstitle.grid(column=0, row=0, sticky="ew", padx=5, pady=5) # convert binary plist file into plain plist file historyxml = plistutils.readPlistToXml(filename) if (historyxml == None): print("Error while parsing Safari History Data") return # main dictionary (contains anything else) maindicts = historyxml.getElementsByTagName('dict') if (len(maindicts) <= 0): print("no main dict found in file") return maindict = maindicts[0] # read WebHistoryDates array of dicts (one dict for each bookmark) from plistutils import readDict, readArray outerDict = readDict(maindict) bookmarksArray = readArray(outerDict['WebHistoryDates']) bookmarks = [] # decode each bookmark dict for element in bookmarksArray: bookmark = {} elementDict = readDict(element) bookmark['title'] = "" if ('title' in elementDict.keys()): bookmark['title'] = elementDict['title'].firstChild.toxml() bookmark['url'] = "" if ('-' in elementDict.keys()): bookmark['url'] = elementDict['-'].firstChild.toxml() bookmark['date'] = "" if ('lastVisitedDate' in elementDict.keys()): bookmark['date'] = elementDict['lastVisitedDate'].firstChild.toxml( ) bookmarks.append(bookmark) # tree historytree = ttk.Treeview(historywindow, columns=("title", "url"), displaycolumns=("title", "url")) historytree.heading("#0", text="Date", anchor='w') historytree.heading("title", text="Title", anchor='w') historytree.heading("url", text="Url", anchor='w') historytree.column("#0", width=25) historytree.column("title", width=250) historytree.column("url", width=300) historytree.grid(column=0, row=1, sticky="ewns") # details box detailsbox = Frame(historywindow, bd=2, relief=RAISED) detailsbox.grid(column=0, row=2, sticky="ew", padx=5, pady=5) detailsbox.grid_columnconfigure(1, weight=1) titlefooterlabel = Label(detailsbox, text='Title:', relief=RIDGE, width=10) titlefooterlabel.grid(column=0, row=0, sticky="ew", padx=2, pady=2) titlefootertext = StringVar() titlefooter = Label(detailsbox, textvariable=titlefootertext, relief=RIDGE, anchor='w') titlefooter.grid(column=1, row=0, sticky="ew", padx=2, pady=2) titlefootertext.set("mille") urlfooterlabel = Label(detailsbox, text='URL:', relief=RIDGE, width=10) urlfooterlabel.grid(column=0, row=1, sticky="ew", padx=2, pady=2) urlfootertext = StringVar() urlfooter = Label(detailsbox, textvariable=urlfootertext, relief=RIDGE, anchor='w') urlfooter.grid(column=1, row=1, sticky="ew", padx=2, pady=2) urlfootertext.set("mille") # footer label footerlabel = StringVar() contactsfooter = Label(historywindow, textvariable=footerlabel, relief=RIDGE) contactsfooter.grid(column=0, row=3, sticky="ew", padx=5, pady=5) # destroy window when closed historywindow.protocol("WM_DELETE_WINDOW", historywindow.destroy) # footer statistics footerlabel.set("Found %s Safari history records" % (len(bookmarks))) # populating bookmarks tree for bookmark in bookmarks: timestamp = float(bookmark['date']) + 978307200 #JAN 1 1970 convtimestamp = datetime.fromtimestamp(int(timestamp)) historytree.insert('', 'end', text=convtimestamp, values=(bookmark['title'], bookmark['url'])) historytree.bind("<ButtonRelease-1>", OnClick) historytree.bind("<Double-Button-1>", OnDoubleClick)
def main(cursor, backup_path): global filename global youtubetree, textarea, youtubewindow global bookmarksArray, historyArray, lastSearch, lastViewedVideo filename = os.path.join( backup_path, plugins_utils.realFileName(cursor, filename="com.apple.youtube.dp.plist", domaintype="HomeDomain")) if (not os.path.isfile(filename)): print("Invalid file name for Contacts database: %s" % filename) return # main window youtubewindow = Toplevel() youtubewindow.title('YouTube data') youtubewindow.focus_set() youtubewindow.grid_columnconfigure(1, weight=1) youtubewindow.grid_rowconfigure(1, weight=1) # header label youtubetitle = Label(youtubewindow, text="YouTube data from: %s (%s) " % (filename, "com.apple.youtube.dp.list"), relief=RIDGE, width=100, height=3, wraplength=800, justify=LEFT) youtubetitle.grid(column=0, row=0, sticky="ew", columnspan=2, padx=5, pady=5) # tree # Column type: G for groups, C for contacts youtubetree = ttk.Treeview(youtubewindow, columns=("name", "code"), displaycolumns=("name")) youtubetree.heading("#0", text="", anchor='w') youtubetree.heading("name", text="Name", anchor='w') youtubetree.column("#0", width=20) youtubetree.column("name", width=200) youtubetree.grid(column=0, row=1, sticky="ns") # textarea textarea = Text(youtubewindow, bd=2, relief=SUNKEN) textarea.grid(column=1, row=1, sticky="nsew") textarea.tag_configure('dynamic_link', foreground="blue", underline=True) textarea.tag_bind('dynamic_link', '<Enter>', lambda event: textarea.configure(cursor='hand2')) textarea.tag_bind('dynamic_link', '<Leave>', lambda event: textarea.configure(cursor='arrow')) # footer label footerlabel = StringVar() youtubefooter = Label(youtubewindow, textvariable=footerlabel, relief=RIDGE) youtubefooter.grid(column=0, row=2, sticky="ew", columnspan=2, padx=5, pady=5) # destroy window when closed youtubewindow.protocol("WM_DELETE_WINDOW", youtubewindow.destroy) # reading plist from xml.dom.minidom import parse try: xmldata = parse(filename) except: print "Unexpected error while parsing XML data:", sys.exc_info()[1] return None # main dictionary (contains anything else) maindicts = xmldata.getElementsByTagName('dict') if (len(maindicts) <= 0): print("no main dict found in file") return maindict = maindicts[0] # read data from main dict outerDict = plugins_utils.readDict(maindict) if ("Bookmarks" in outerDict.keys()): bookmarksArray = plugins_utils.readArray(outerDict['Bookmarks']) else: bookmarksArray = [] if ("History" in outerDict.keys()): historyArray = plugins_utils.readArray(outerDict['History']) else: historyArray = [] if ("lastSearch" in outerDict.keys()): lastSearch = outerDict['lastSearch'].firstChild.toxml() else: lastSearch = "Not available" if ("lastViewedVideo" in outerDict.keys()): lastViewedVideo = outerDict['lastViewedVideo'].firstChild.toxml() else: lastViewedVideo = None # footer statistics footerlabel.set("Found %i history elements and %i bookmarks." % (len(historyArray), len(bookmarksArray))) # populating tree youtubetree.insert('', 'end', text="", values=("Last use data", "L")) # bookmarks in the main tree bookmarksnode = youtubetree.insert('', 'end', text="", values=("Bookmarks", "B")) for element in bookmarksArray: element_string = element.firstChild.toxml() youtubetree.insert(bookmarksnode, 'end', text="", values=(element_string, element_string)) # history in the main tree historynode = youtubetree.insert('', 'end', text="", values=("History", "H")) for element in historyArray: element_string = element.firstChild.toxml() youtubetree.insert(historynode, 'end', text="", values=(element_string, element_string)) youtubetree.bind("<ButtonRelease-1>", OnClick)
def populateUI(self): ###################################################### # CONTACTS SECTION # ###################################################### contacts = self.getContacts() self.ui.contactsWidget.setRowCount(len(contacts)) self.ui.contactsWidget.setSortingEnabled(False) row = 0 for contact in contacts: if hasattr(contact, 'ZMAINNAME') and hasattr( contact, 'ZPREFIXNAME'): newItem = QtGui.QTableWidgetItem() nameStr = "" if contact.ZPREFIXNAME is not None: nameStr += contact.ZPREFIXNAME + " " if contact.ZMAINNAME is not None: nameStr += contact.ZMAINNAME newItem.setData(QtCore.Qt.DisplayRole, nameStr) self.ui.contactsWidget.setItem(row, 0, newItem) if hasattr(contact, 'ZCANONIZEDPHONENUM'): newItem = QtGui.QTableWidgetItem( str(contact.ZCANONIZEDPHONENUM)) self.ui.contactsWidget.setItem(row, 1, newItem) if hasattr(contact, 'ZREGISTRATIONDATE'): newItem = QtGui.QTableWidgetItem() if contact.ZREGISTRATIONDATE is not None: newItem.setData( QtCore.Qt.DisplayRole, str(self.formatDate(contact.ZREGISTRATIONDATE))) self.ui.contactsWidget.setItem(row, 2, newItem) if hasattr(contact, 'ZMODIFCATIONDATE'): newItem = QtGui.QTableWidgetItem() if contact.ZMODIFCATIONDATE is not None: newItem.setData( QtCore.Qt.DisplayRole, str(self.formatDate(contact.ZMODIFCATIONDATE))) self.ui.contactsWidget.setItem(row, 3, newItem) if hasattr(contact, 'ZISVIBERICON') and hasattr( contact, 'ZICONID'): newItem = QtGui.QTableWidgetItem() iconRealFilename = "" iconlocalfile = "" if contact.ZISVIBERICON is 1 and contact.ZICONID is not None: iconlocalfile = contact.ZICONID + ".jpg" iconRealFilename = os.path.join( self.backup_path, plugins_utils.realFileName(self.cursor, filename=iconlocalfile, domaintype="AppDomain")) # add a thumnail to the table view icon = QtGui.QIcon(iconRealFilename) newItem.setIcon(icon) # add info for attachment export (ctx menu) newItem.setData(QtCore.Qt.UserRole, iconRealFilename) newItem.setData(QtCore.Qt.UserRole + 1, iconlocalfile) self.ui.contactsWidget.setItem(row, 4, newItem) self.ui.contactsWidget.setRowHeight(row, 80) row = row + 1 self.ui.contactsWidget.setSortingEnabled(True) self.ui.contactsWidget.setIconSize(QtCore.QSize(80, 80)) self.ui.contactsWidget.resizeColumnsToContents() self.ui.contactsWidget.setColumnWidth(4, 80) ###################################################### # RECENT CALLS SECTION # ###################################################### calls = self.getCalls() self.ui.callsWidget.setRowCount(len(calls)) self.ui.callsWidget.setSortingEnabled(False) row = 0 for call in calls: if hasattr(call, 'ZMAINNAME') and hasattr(call, 'ZPREFIXNAME'): newItem = QtGui.QTableWidgetItem() nameStr = "" if call.ZPREFIXNAME is not None: nameStr += call.ZPREFIXNAME + " " if call.ZMAINNAME is not None: nameStr += call.ZMAINNAME newItem.setData(QtCore.Qt.DisplayRole, nameStr) self.ui.callsWidget.setItem(row, 0, newItem) if hasattr(call, 'ZDATE'): newItem = QtGui.QTableWidgetItem() if call.ZDATE is not None: newItem.setData(QtCore.Qt.DisplayRole, str(self.formatDate(call.ZDATE))) self.ui.callsWidget.setItem(row, 1, newItem) if hasattr(call, 'ZDURATION'): newItem = QtGui.QTableWidgetItem() newItem.setData(QtCore.Qt.DisplayRole, call.ZDURATION) self.ui.callsWidget.setItem(row, 2, newItem) if hasattr(call, 'ZCALLTYPE'): newItem = QtGui.QTableWidgetItem(str(call.ZCALLTYPE)) self.ui.callsWidget.setItem(row, 3, newItem) if 'missed' in str(call.ZCALLTYPE): for i in range(4): self.ui.callsWidget.item(row, i).setBackground( QtCore.Qt.red) elif 'incoming' in str(call.ZCALLTYPE): for i in range(4): self.ui.callsWidget.item(row, i).setBackground( QtCore.Qt.cyan) else: for i in range(4): self.ui.callsWidget.item(row, i).setBackground( QtCore.Qt.green) row = row + 1 self.ui.callsWidget.setSortingEnabled(True) self.ui.callsWidget.resizeColumnsToContents() self.ui.callsWidget.resizeRowsToContents() ###################################################### # CHATS SECTION # ###################################################### chats = self.getChats() self.ui.chatsWidget.setRowCount(len(chats)) row = 0 for chat in chats: if hasattr(chat, 'Z_PK'): newItem = QtGui.QTableWidgetItem() newItem.setData(QtCore.Qt.DisplayRole, chat.Z_PK) self.ui.chatsWidget.setItem(row, 0, newItem) if hasattr(chat, 'ZMAINNAME') and hasattr(chat, 'ZPREFIXNAME'): newItem = QtGui.QTableWidgetItem() nameStr = "" if chat.ZPREFIXNAME is not None: nameStr += chat.ZPREFIXNAME + " " if chat.ZMAINNAME is not None: nameStr += chat.ZMAINNAME newItem.setData(QtCore.Qt.DisplayRole, nameStr) self.ui.chatsWidget.setItem(row, 1, newItem) if hasattr(chat, 'ZNAME'): newItem = QtGui.QTableWidgetItem(chat.ZNAME) self.ui.chatsWidget.setItem(row, 2, newItem) if hasattr(chat, 'ZGROUPID'): newItem = QtGui.QTableWidgetItem(chat.ZGROUPID) self.ui.chatsWidget.setItem(row, 3, newItem) if hasattr(chat, 'ZDATE'): newItem = QtGui.QTableWidgetItem( str(self.formatDate(chat.ZDATE))) self.ui.chatsWidget.setItem(row, 4, newItem) if hasattr(chat, 'ZUNREADCOUNT'): newItem = QtGui.QTableWidgetItem() newItem.setData(QtCore.Qt.DisplayRole, chat.ZUNREADCOUNT) self.ui.chatsWidget.setItem(row, 5, newItem) if hasattr(chat, 'ZGROUPID'): if chat.ZGROUPID is not None: for i in range(6): self.ui.chatsWidget.item(row, i).setBackground( QtCore.Qt.yellow) row = row + 1 self.ui.chatsWidget.resizeColumnsToContents() self.ui.chatsWidget.resizeRowsToContents()
def main(cursor, backup_path): global filename global youtubetree, textarea, youtubewindow global bookmarksArray, historyArray, lastSearch, lastViewedVideo filename = os.path.join(backup_path, plugins_utils.realFileName(cursor, filename="com.apple.youtube.dp.plist", domaintype="HomeDomain")) if (not os.path.isfile(filename)): print("Invalid file name for Contacts database: %s"%filename) return # main window youtubewindow = Toplevel() youtubewindow.title('YouTube data') youtubewindow.focus_set() youtubewindow.grid_columnconfigure(1, weight=1) youtubewindow.grid_rowconfigure(1, weight=1) # header label youtubetitle = Label( youtubewindow, text = "YouTube data from: %s (%s) "%(filename, "com.apple.youtube.dp.list"), relief = RIDGE, width=100, height=3, wraplength=800, justify=LEFT ) youtubetitle.grid(column = 0, row = 0, sticky="ew", columnspan=2, padx=5, pady=5) # tree # Column type: G for groups, C for contacts youtubetree = ttk.Treeview(youtubewindow, columns=("name", "code"), displaycolumns=("name")) youtubetree.heading("#0", text="", anchor='w') youtubetree.heading("name", text="Name", anchor='w') youtubetree.column("#0", width=20) youtubetree.column("name", width=200) youtubetree.grid(column = 0, row = 1, sticky="ns") # textarea textarea = Text(youtubewindow, bd=2, relief=SUNKEN) textarea.grid(column = 1, row = 1, sticky="nsew") textarea.tag_configure('dynamic_link', foreground="blue", underline=True) textarea.tag_bind('dynamic_link', '<Enter>', lambda event: textarea.configure(cursor='hand2')) textarea.tag_bind('dynamic_link', '<Leave>', lambda event: textarea.configure(cursor='arrow')) # footer label footerlabel = StringVar() youtubefooter = Label(youtubewindow, textvariable = footerlabel, relief = RIDGE) youtubefooter.grid(column = 0, row = 2, sticky="ew", columnspan=2, padx=5, pady=5) # destroy window when closed youtubewindow.protocol("WM_DELETE_WINDOW", youtubewindow.destroy) # reading plist from xml.dom.minidom import parse try: xmldata = parse(filename) except: print "Unexpected error while parsing XML data:", sys.exc_info()[1] return None # main dictionary (contains anything else) maindicts = xmldata.getElementsByTagName('dict') if (len(maindicts) <= 0): print("no main dict found in file") return maindict = maindicts[0] # read data from main dict outerDict = plugins_utils.readDict(maindict) if ("Bookmarks" in outerDict.keys()): bookmarksArray = plugins_utils.readArray(outerDict['Bookmarks']) else: bookmarksArray = [] if ("History" in outerDict.keys()): historyArray = plugins_utils.readArray(outerDict['History']) else: historyArray = [] if ("lastSearch" in outerDict.keys()): lastSearch = outerDict['lastSearch'].firstChild.toxml() else: lastSearch = "Not available" if ("lastViewedVideo" in outerDict.keys()): lastViewedVideo = outerDict['lastViewedVideo'].firstChild.toxml() else: lastViewedVideo = None # footer statistics footerlabel.set("Found %i history elements and %i bookmarks."%(len(historyArray), len(bookmarksArray))) # populating tree youtubetree.insert('', 'end', text="", values=("Last use data", "L")) # bookmarks in the main tree bookmarksnode = youtubetree.insert('', 'end', text="", values=("Bookmarks", "B")) for element in bookmarksArray: element_string = element.firstChild.toxml() youtubetree.insert(bookmarksnode, 'end', text="", values=(element_string, element_string)) # history in the main tree historynode = youtubetree.insert('', 'end', text="", values=("History", "H")) for element in historyArray: element_string = element.firstChild.toxml() youtubetree.insert(historynode, 'end', text="", values=(element_string, element_string)) youtubetree.bind("<ButtonRelease-1>", OnClick)
def main(cursor, backup_path): global filename global callstree, textarea filename = os.path.join( backup_path, plugins_utils.realFileName(cursor, filename="call_history.db", domaintype="WirelessDomain")) if (not os.path.isfile(filename)): print("Invalid file name for SMS database") return # main window callswindow = Toplevel() callswindow.title('Call History data') callswindow.focus_set() callswindow.grid_columnconfigure(2, weight=1) callswindow.grid_rowconfigure(1, weight=1) # header label callstitle = Label(callswindow, text="Calls history data from: " + filename, relief=RIDGE) callstitle.grid(column=0, row=0, sticky="ew", columnspan=4, padx=5, pady=5) # tree callstree = ttk.Treeview( callswindow, columns=("address", "date", "duration", "flags", "id", "name", "countrycode"), displaycolumns=("address", "date", "duration", "flags"), yscrollcommand=lambda f, l: autoscroll(mvsb, f, l)) callstree.heading("#0", text="ID", anchor='w') callstree.heading("date", text="Date", anchor='w') callstree.heading("address", text="Address", anchor='w') callstree.heading("duration", text="Duration", anchor='w') callstree.heading("flags", text="Flags", anchor='w') callstree.column("#0", width=50) callstree.column("date", width=200) callstree.column("address", width=150) callstree.column("duration", width=100) callstree.column("flags", width=100) callstree.grid(column=0, row=1, sticky="ns") # textarea textarea = Text(callswindow, bd=2, relief=SUNKEN, width=50, yscrollcommand=lambda f, l: autoscroll(tvsb, f, l)) textarea.grid(column=2, row=1, sticky="nsew") # scrollbars for tree mvsb = ttk.Scrollbar(callswindow, orient="vertical") mvsb.grid(column=1, row=1, sticky='ns') mvsb['command'] = callstree.yview # scrollbars for main textarea tvsb = ttk.Scrollbar(callswindow, orient="vertical") tvsb.grid(column=3, row=1, sticky='ns') tvsb['command'] = textarea.yview # footer label footerlabel = StringVar() callsfooter = Label(callswindow, textvariable=footerlabel, relief=RIDGE) callsfooter.grid(column=0, row=2, sticky="ew", columnspan=4, padx=5, pady=5) # destroy window when closed callswindow.protocol("WM_DELETE_WINDOW", callswindow.destroy) # opening database tempdb = sqlite3.connect(filename) tempcur = tempdb.cursor() # footer statistics query = "SELECT count(ROWID) FROM call" tempcur.execute(query) callsnumber = tempcur.fetchall()[0][0] footerlabel.set("Found %s calls." % callsnumber) def readKey(key): query = "SELECT value FROM _SqliteDatabaseProperties WHERE key = \"%s\"" % key tempcur.execute(query) data = tempcur.fetchall() if (len(data) > 0): value = data[0][0] else: value = 0 return value def formatTime(seconds): durationtot = int(seconds) durationmin = int(durationtot / 60) durationhh = int(durationmin / 60) durationmin = durationmin - (durationhh * 60) durationsec = durationtot - (durationmin * 60) - (durationhh * 3600) duration = "%i:%.2i:%.2i" % (durationhh, durationmin, durationsec) return duration # populating textarea with data from _SqliteDatabaseProperties textarea.insert( END, "Call history limit: %s\n" % (readKey("call_history_limit"))) textarea.insert( END, "Last call duration: %s\n" % (formatTime(readKey("timer_last")))) textarea.insert( END, "Incoming calls duration: %s\n" % (formatTime(readKey("timer_incoming")))) textarea.insert( END, "Outgoing calls duration: %s\n" % (formatTime(readKey("timer_outgoing")))) textarea.insert( END, "Total call duration: %s\n" % (formatTime(readKey("timer_all")))) textarea.insert( END, "Total lifetime call duration: %s\n" % (formatTime(readKey("timer_lifetime")))) # populating tree with calls query = "SELECT ROWID, address, date, duration, flags, id, name, country_code FROM call ORDER BY date" tempcur.execute(query) calls = tempcur.fetchall() tempdb.close() for call in calls: rowid = call[0] address = call[1] date = datetime.fromtimestamp(int(call[2])) duration = formatTime(call[3]) flagval = call[4] if (flagval == 5): flags = "Outgoing" elif (flagval == 4): flags = "Incoming" else: flags = "Cancelled" id = call[5] name = call[6] country_code = call[7] callstree.insert('', 'end', text=rowid, values=(address, date, duration, flags))
def main(cursor, backup_path): global filename global datetree, textarea, cellstree filename = os.path.join(backup_path, plugins_utils.realFileName(cursor, filename="consolidated.db", domaintype="RootDomain")) if (not os.path.isfile(filename)): print("Invalid file name for Cell Location database") return # main window cellwindow = Toplevel() cellwindow.title('Cell Location data') cellwindow.focus_set() cellwindow.grid_columnconfigure(2, weight=1) cellwindow.grid_rowconfigure(1, weight=1) # header label celltitle = Label(cellwindow, text = "Cell Location data from: " + filename, relief = RIDGE) celltitle.grid(column = 0, row = 0, sticky="ew", columnspan=4, padx=5, pady=5) # tree of distinct timestamps datetree = ttk.Treeview(cellwindow, columns=("timestamp"), displaycolumns=(), yscrollcommand=lambda f, l: autoscroll(mvsb, f, l)) datetree.heading("#0", text="Timestamp", anchor='w') datetree.column("#0", width=200) datetree.grid(column = 0, row = 1, sticky="ns") # scrollbars for tree mvsb = ttk.Scrollbar(cellwindow, orient="vertical") mvsb.grid(column=1, row=1, sticky='ns') mvsb['command'] = datetree.yview # main block mainblock = Frame(cellwindow, bd=2, relief=RAISED); mainblock.grid(column=2, row=1, sticky="nsew") mainblock.grid_columnconfigure(0, weight=1) mainblock.grid_rowconfigure(2, weight=1) # main block label mainblocklabel = Label(mainblock, text="Click on the list to show description, double click to show location in browser", relief=RIDGE) mainblocklabel.grid(column = 0, row = 0, sticky="nsew") # tree cellstree = ttk.Treeview(mainblock, columns=("mnc", "lac", "ci", "lat", "lon", "alt", "hacc", "vacc", "speed", "course", "confidence"), displaycolumns=("mnc", "lac", "ci", "lat", "lon", "alt")) cellstree.heading("#0", text="MCC", anchor='w') cellstree.column("#0", width=30) cellstree.heading("mnc", text="MNC", anchor='w') cellstree.column("mnc", width=30) cellstree.heading("lac", text="LAC", anchor='w') cellstree.column("lac", width=30) cellstree.heading("ci", text="CI", anchor='w') cellstree.column("ci", width=50) cellstree.heading("lat", text="LAT", anchor='w') cellstree.column("lat", width=60) cellstree.heading("lon", text="LON", anchor='w') cellstree.column("lon", width=60) cellstree.heading("alt", text="ALT", anchor='w') cellstree.column("alt", width=50) cellstree.grid(column = 0, row = 1, sticky="nsew") # textarea textarea = Text(mainblock, bd=2, relief=SUNKEN, yscrollcommand=lambda f, l: autoscroll(tvsb, f, l)) textarea.grid(column = 0, row = 2, sticky="nsew") # scrollbars for main textarea tvsb = ttk.Scrollbar(mainblock, orient="vertical") tvsb.grid(column=1, row=2, sticky='ns') tvsb['command'] = textarea.yview # footer label footerlabel = StringVar() cellfooter = Label(cellwindow, textvariable = footerlabel, relief = RIDGE) cellfooter.grid(column = 0, row = 2, sticky="ew", columnspan=4, padx=5, pady=5) # destroy window when closed cellwindow.protocol("WM_DELETE_WINDOW", cellwindow.destroy) # opening database tempdb = sqlite3.connect(filename) tempcur = tempdb.cursor() # footer statistics query = "SELECT count(*) FROM CellLocation" tempcur.execute(query) cellsnumber = tempcur.fetchall()[0][0] query = "SELECT DISTINCT(timestamp) FROM CellLocation ORDER BY timestamp" tempcur.execute(query) disttimestamps = tempcur.fetchall() footerlabel.set("Found %s cell locations in %s distinct timestamps."%(cellsnumber, len(disttimestamps))) # populating tree with distinct timestamps for timestamp in disttimestamps: raw = timestamp[0] converted = raw + 978307200 #JAN 1 1970 converted = datetime.fromtimestamp(int(converted)) datetree.insert('', 'end', text=converted, values=(raw)) datetree.bind("<ButtonRelease-1>", OnClick) cellstree.bind("<Double-Button-1>", OnCellDoubleClick) cellstree.bind("<ButtonRelease-1>", OnCellClick)
def onChatsClick(self): # disable chats table (to disable click events while processing) self.ui.chatsWidget.setEnabled(False) # retrieving selected row self.ui.chatsWidget.setCurrentCell(self.ui.chatsWidget.currentRow(),0) currentSelectedItem = self.ui.chatsWidget.currentItem() if (currentSelectedItem): pass else: return ###################################################### # MESSAGES SECTION # ###################################################### zpk = int(currentSelectedItem.text()) #msgs = self.getMsgs(zpk) # <--- msgs = self.getMsgsThreaded(zpk) # <--- # re-select a visible column to allow the keyboard selection self.ui.chatsWidget.setCurrentCell(self.ui.chatsWidget.currentRow(),1) # erase previous messages and set new table lenght #self.ui.msgsWidget.clearContents() self.ui.msgsWidget.setSortingEnabled(False) self.ui.msgsWidget.setRowCount(len(msgs)) row = 0 for msg in msgs: fields = set(msg.keys()) if 'Z_PK' in fields: newItem = QtGui.QTableWidgetItem() newItem.setData(QtCore.Qt.DisplayRole, msg['Z_PK']) self.ui.msgsWidget.setItem(row, 0, newItem) if 'ZFROMJID' in fields: fromstring = "Me" if msg['ZFROMJID'] is not None: fromstring = msg['ZFROMJID'] newItem = QtGui.QTableWidgetItem() newItem.setData(QtCore.Qt.DisplayRole,fromstring) self.ui.msgsWidget.setItem(row, 1, newItem) if 'ZMESSAGEDATE' in fields: newItem = QtGui.QTableWidgetItem(str(self.formatDate(msg['ZMESSAGEDATE']))) self.ui.msgsWidget.setItem(row, 2, newItem) if 'ZTEXT' in fields: newItem = QtGui.QTableWidgetItem(msg['ZTEXT']) self.ui.msgsWidget.setItem(row, 3, newItem) if 'ZMESSAGESTATUS' in fields: newItem = QtGui.QTableWidgetItem() newItem.setData(QtCore.Qt.DisplayRole,msg['ZMESSAGESTATUS']) self.ui.msgsWidget.setItem(row, 5, newItem) if 'ZGROUPMEMBER' in fields and msg['ZGROUPMEMBER'] is not None: if msg['ZCONTACTNAME'] is not None: fromstring = msg['ZCONTACTNAME'] + " - " + msg['ZMEMBERJID'] else: fromstring = "N/A" newItem = QtGui.QTableWidgetItem(fromstring) self.ui.msgsWidget.setItem(row, 1, newItem) if 'ZMEDIAITEM' in fields: mediaItem = QtGui.QTableWidgetItem("") if msg['ZMEDIAITEM'] is not None: media = self.getMediaItem(msg['ZMEDIAITEM']) msgcontent = "" # VCARD info if (media.ZVCARDNAME and media.ZVCARDSTRING) is not None: msgcontent += ("VCARD\n" + media.ZVCARDNAME + "\n" + media.ZVCARDSTRING + "\n") # GPS info if media.ZLATITUDE != 0. or media.ZLONGITUDE != 0.: msgcontent += ("GPS\n" + "lat: " + str(media.ZLATITUDE) + "\nlong: " + str(media.ZLONGITUDE) + "\n") # VIDEO info if media.ZMOVIEDURATION != 0: msgcontent += ("VIDEO\n" + "duration: " + str(media.ZMOVIEDURATION) + " sec\n") # FILE info if media.ZFILESIZE != 0: msgcontent += ("FILE\n" + "size: " + str(media.ZFILESIZE) + " B\n") # set message content (3rd column) newItem = QtGui.QTableWidgetItem(msgcontent) self.ui.msgsWidget.setItem(row, 3, newItem) thumbRealFilename = "" mediaRealFilename = "" mediallocalfile = "" # THUMBNAIL if media.ZTHUMBNAILLOCALPATH is not None: thumblocalfilepath = media.ZTHUMBNAILLOCALPATH thumblocalpath = os.path.dirname(thumblocalfilepath) thumbllocalfile = os.path.basename(thumblocalfilepath) thumbRealFilename = os.path.join(self.backup_path, plugins_utils.realFileName(self.cursor, filename=thumbllocalfile, path='Library/'+thumblocalpath, domaintype="AppDomain")) # ATTACHMENT if media.ZMEDIALOCALPATH is not None: medialocalfilepath = media.ZMEDIALOCALPATH mediallocalpath = os.path.dirname(medialocalfilepath) mediallocalfile = os.path.basename(medialocalfilepath) mediaRealFilename = os.path.join(self.backup_path, plugins_utils.realFileName(self.cursor, filename=mediallocalfile, path='Library/'+mediallocalpath, domaintype="AppDomain")) # add a thumnail to the table view icon = None if thumbRealFilename != "": icon = QtGui.QIcon(thumbRealFilename) else: icon = QtGui.QIcon(mediaRealFilename) mediaItem = QtGui.QTableWidgetItem() mediaItem.setIcon(icon) # add info for attachment export (ctx menu) if mediallocalfile != "": mediaItem.setData(QtCore.Qt.UserRole, mediaRealFilename) mediaItem.setData(QtCore.Qt.UserRole+1, mediallocalfile) if media.ZLATITUDE != 0. or media.ZLONGITUDE != 0.: mediaItem.setData(QtCore.Qt.UserRole+2, media.ZLATITUDE) mediaItem.setData(QtCore.Qt.UserRole+3, media.ZLONGITUDE) self.ui.msgsWidget.setItem(row, 4, mediaItem) if 'ZISFROMME' in fields and msg['ZISFROMME'] is 1: for i in range(6): self.ui.msgsWidget.item(row,i).setBackground(QtCore.Qt.green) row = row + 1 self.ui.msgsWidget.setSortingEnabled(True) self.ui.msgsWidget.setIconSize(QtCore.QSize(150,150)) self.ui.msgsWidget.resizeColumnsToContents() self.ui.msgsWidget.setColumnWidth(4, 150) self.ui.msgsWidget.resizeRowsToContents() # re-enable chats table self.ui.chatsWidget.setEnabled(True) self.ui.chatsWidget.setFocus()
def main(cursor, backup_path): global filename global bookmarkstree, textarea global namelabel, urllabel, url filename = os.path.join(backup_path, plugins_utils.realFileName(cursor, filename="Bookmarks.db", domaintype="HomeDomain")) if (not os.path.isfile(filename)): print("Invalid file name for Safari Bookmarks database") return # main window bookmarkswindow = Toplevel() bookmarkswindow.title('Bookmarks data') bookmarkswindow.focus_set() bookmarkswindow.grid_columnconfigure(2, weight=1) bookmarkswindow.grid_rowconfigure(1, weight=1) # header label bookmarkstitle = Label(bookmarkswindow, text = "Bookmarks data from: " + filename, relief = RIDGE) bookmarkstitle.grid(column = 0, row = 0, sticky="ew", columnspan=4, padx=5, pady=5) # tree bookmarkstree = ttk.Treeview(bookmarkswindow, columns=("id"), displaycolumns=(), yscrollcommand=lambda f, l: autoscroll(mvsb, f, l)) bookmarkstree.heading("#0", text="title", anchor='w') #bookmarkstree.heading("id", text="id", anchor='w') bookmarkstree.column("#0", width=250) #bookmarkstree.column("id", width=30) bookmarkstree.grid(column = 0, row = 1, sticky="ns") # center column centercolumn = Frame(bookmarkswindow, bd=2, relief=RAISED); centercolumn.grid(column=2, row=1, sticky="nswe") centercolumn.grid_columnconfigure(1, weight=1) centercolumn.grid_rowconfigure(2, weight=1) # Bookmark name bookmarknamefix = Label(centercolumn, text = "Title:", relief = RIDGE) bookmarknamefix.grid(column = 0, row = 0, sticky="ew") namelabel = StringVar() bookmarkname = Label(centercolumn, textvariable = namelabel, relief = RIDGE) bookmarkname.grid(column = 1, row = 0, sticky="ew", columnspan=2) # Bookmark URL bookmarkurlfix = Label(centercolumn, text = "URL:", relief = RIDGE) bookmarkurlfix.grid(column = 0, row = 1, sticky="ew") urllabel = StringVar() bookmarkurl = Label(centercolumn, textvariable = urllabel, relief = RIDGE) bookmarkurl.grid(column = 1, row = 1, sticky="ew") bookmarkbutton = Button(centercolumn, text="GO!", width=10, default=ACTIVE) bookmarkbutton.grid(column = 2, row = 1, sticky="ew") bookmarkbutton.bind("<Button-1>", openurl) # textarea textarea = Text(centercolumn, bd=2, relief=SUNKEN, yscrollcommand=lambda f, l: autoscroll(tvsb, f, l)) textarea.grid(column = 0, row = 2, sticky="nsew", columnspan=3) # scrollbars for main textarea tvsb = ttk.Scrollbar(centercolumn, orient="vertical") tvsb.grid(column=3, row=2, sticky='ns') tvsb['command'] = textarea.yview # scrollbars for tree mvsb = ttk.Scrollbar(bookmarkswindow, orient="vertical") mvsb.grid(column=1, row=1, sticky='ns') mvsb['command'] = bookmarkstree.yview # footer label footerlabel = StringVar() bookmarksfooter = Label(bookmarkswindow, textvariable = footerlabel, relief = RIDGE) bookmarksfooter.grid(column = 0, row = 2, sticky="ew", columnspan=4, padx=5, pady=5) # destroy window when closed bookmarkswindow.protocol("WM_DELETE_WINDOW", bookmarkswindow.destroy) # opening database tempdb = sqlite3.connect(filename) tempcur = tempdb.cursor() # footer statistics query = "SELECT count(*) FROM bookmarks" tempcur.execute(query) bookmarksnumber = tempcur.fetchall()[0][0] footerlabel.set("Found %s bookmarks."%(bookmarksnumber)) def insertBookmark(parent_node, parent_id): query = "SELECT id, title, num_children FROM bookmarks WHERE parent = \"%s\" ORDER BY order_index"%parent_id tempcur.execute(query) bookmarks = tempcur.fetchall() for bookmark in bookmarks: id = bookmark[0] title = bookmark[1] num_children = bookmark[2] newnode = bookmarkstree.insert(parent_node, 'end', text=title, values=(id)) if (num_children != 0): insertBookmark(newnode, id) # populating tree with Safari Bookmarks insertBookmark('', 0) bookmarkstree.bind("<ButtonRelease-1>", OnClick)
def main(cursor, backup_path): global filename global thumbstree, textarea, prevarea global photoImagesList global framelen_image, framelen_padding, thumbs_filename filename = os.path.join(backup_path, plugins_utils.realFileName(cursor, filename=thumbs_filename)) if (not os.path.isfile(filename)): import tkMessageBox tkMessageBox.showwarning("File not found", "Seems like this backup doesn't contain \"%s\" thumbnail data. Each iDevice has its set of thumbnails, maybe the device you are working on doesn't have this kind of thumbnails."%thumbs_filename) return # main window thumbswindow = Toplevel() thumbswindow.title('Thumbnails') thumbswindow.focus_set() thumbswindow.grid_columnconfigure(2, weight=1) thumbswindow.grid_rowconfigure(1, weight=1) # header label thumbstitle = Label(thumbswindow, text = "Thumbnails data from: %s (%s)"%(filename, thumbs_filename), relief = RIDGE, width=100, height=2, wraplength=800, justify=LEFT) thumbstitle.grid(column = 0, row = 0, sticky="ew", columnspan=6, padx=5, pady=5) # tree thumbstree = ttk.Treeview(thumbswindow, columns=(), displaycolumns=(), yscrollcommand=lambda f, l: autoscroll(mvsb, f, l)) thumbstree.heading("#0", text="ID", anchor='w') #thumbstree.heading("pos", text="Address", anchor='w') thumbstree.column("#0", width=130) #thumbstree.column("pos", width=200) thumbstree.grid(column = 0, row = 1, sticky="ns", rowspan=2) # upper textarea #uppertextarea = Text(thumbswindow, bd=2, relief=SUNKEN, height=5) #uppertextarea.grid(column = 2, row = 1, sticky="nsew") # textarea textarea = Text(thumbswindow, bd=2, relief=SUNKEN, yscrollcommand=lambda f, l: autoscroll(tvsb, f, l), width=60) textarea.grid(column = 2, row = 1, rowspan=2, sticky="nsew") # preview area prevarea = Text(thumbswindow, bd=2, relief=SUNKEN, width=50) prevarea.grid(column = 5, row = 1, rowspan=2, sticky="nsew") # scrollbars for tree mvsb = ttk.Scrollbar(thumbswindow, orient="vertical") mvsb.grid(column=1, row=1, sticky='ns', rowspan=2) mvsb['command'] = thumbstree.yview # scrollbars for main textarea tvsb = ttk.Scrollbar(thumbswindow, orient="vertical") tvsb.grid(column=3, row=2, sticky='ns') tvsb['command'] = textarea.yview # footer label footerlabel = StringVar() thumbsfooter = Label(thumbswindow, textvariable = footerlabel, relief = RIDGE) thumbsfooter.grid(column = 0, row = 3, sticky="ew", columnspan=6, padx=5, pady=5) # destroy window when closed thumbswindow.protocol("WM_DELETE_WINDOW", thumbswindow.destroy) # populating list f = open(filename, 'r') wholefile = f.read() f.close() framelen = framelen_image + framelen_padding numframes = len(wholefile) / framelen #print("Number of frames found: ", numframes) del photoImagesList[:] for i in range(numframes) : string = wholefile[framelen*i:framelen*(i+1)-1] im = Image.frombuffer('RGB', (frame_width, frame_height), string, 'raw', 'BGR;15', 0, 1) im = im.resize((15,15), Image.ANTIALIAS) tkim = ImageTk.PhotoImage(im) photoImagesList.append(tkim) thumbstree.insert('', 'end', text=i, image=tkim) textarea.insert(END, "Thumbnail file viewer\n") textarea.insert(END, "\n") textarea.insert(END, "Thumbnail file name: %s\n"%thumbs_filename) textarea.insert(END, "Thumbnail file real name: %s\n"%filename) textarea.insert(END, "\n") textarea.insert(END, "Thumbnail width: %i\n"%frame_width) textarea.insert(END, "Thumbnail height: %i\n"%frame_height) textarea.insert(END, "Thumbnail size in bytes: %i + %i padding for each\n"%(frame_width * frame_height *2 , framelen_padding)) thumbstree.bind("<ButtonRelease-1>", OnClick)
def main(cursor, backup_path): global filename global groupstree, textarea filename = os.path.join(backup_path, plugins_utils.realFileName(cursor, filename="sms.db", domaintype="HomeDomain")) if (not os.path.isfile(filename)): print("Invalid file name for SMS database") return # main window smswindow = Toplevel() smswindow.title('SMS data') smswindow.focus_set() smswindow.grid_columnconfigure(2, weight=1) smswindow.grid_rowconfigure(1, weight=1) # header label smstitle = Label(smswindow, text = "SMS data from: " + filename, relief = RIDGE) smstitle.grid(column = 0, row = 0, sticky="ew", columnspan=4, padx=5, pady=5) # tree groupstree = ttk.Treeview(smswindow, columns=("address"), displaycolumns=("address"), yscrollcommand=lambda f, l: autoscroll(mvsb, f, l)) groupstree.heading("#0", text="ID", anchor='w') groupstree.heading("address", text="Address", anchor='w') groupstree.column("#0", width=30) groupstree.column("address", width=200) groupstree.grid(column = 0, row = 1, sticky="ns", rowspan=2) # upper textarea uppertextarea = Text(smswindow, bd=2, relief=SUNKEN, height=5) uppertextarea.grid(column = 2, row = 1, sticky="nsew") # textarea textarea = Text(smswindow, bd=2, relief=SUNKEN, yscrollcommand=lambda f, l: autoscroll(tvsb, f, l)) textarea.grid(column = 2, row = 2, sticky="nsew") # scrollbars for tree mvsb = ttk.Scrollbar(smswindow, orient="vertical") mvsb.grid(column=1, row=1, sticky='ns', rowspan=2) mvsb['command'] = groupstree.yview # scrollbars for main textarea tvsb = ttk.Scrollbar(smswindow, orient="vertical") tvsb.grid(column=3, row=2, sticky='ns') tvsb['command'] = textarea.yview # footer label footerlabel = StringVar() smsfooter = Label(smswindow, textvariable = footerlabel, relief = RIDGE) smsfooter.grid(column = 0, row = 3, sticky="ew", columnspan=4, padx=5, pady=5) # destroy window when closed smswindow.protocol("WM_DELETE_WINDOW", smswindow.destroy) # opening database tempdb = sqlite3.connect(filename) tempcur = tempdb.cursor() # footer statistics query = "SELECT count(ROWID) FROM msg_group" tempcur.execute(query) groupsnumber = tempcur.fetchall()[0][0] query = "SELECT count(ROWID) FROM message" tempcur.execute(query) smsnumber = tempcur.fetchall()[0][0] footerlabel.set("Found %s messages in %s groups."%(smsnumber, groupsnumber)) # uppertextarea statistics def readKey(key): query = "SELECT value FROM _SqliteDatabaseProperties WHERE key = \"%s\""%key tempcur.execute(query) data = tempcur.fetchall() if (len(data) > 0): value = data[0][0] else: value = 0 return value uppertextarea.insert(END, "Incoming messages (after last reset): %s\n"%(readKey("counter_in_all"))) uppertextarea.insert(END, "Lifetime incoming messages: %s\n"%(readKey("counter_in_lifetime"))) uppertextarea.insert(END, "Outgoing messages (after last reset): %s\n"%(readKey("counter_out_all"))) uppertextarea.insert(END, "Lifetime outgoing messages: %s\n"%(readKey("counter_out_lifetime"))) uppertextarea.insert(END, "Counter last reset: %s\n"%(readKey("counter_last_reset"))) # populating tree with SMS groups query = "SELECT DISTINCT(msg_group.rowid), address FROM msg_group INNER JOIN group_member ON msg_group.rowid = group_member.group_id" tempcur.execute(query) groups = tempcur.fetchall() tempdb.close() for group in groups: groupid = group[0] address = group[1].replace(' ', '') groupstree.insert('', 'end', text=groupid, values=(address)) groupstree.bind("<ButtonRelease-1>", OnClick)
def main(cursor, backup_path): global filename global bookmarkstree, textarea global namelabel, urllabel, url filename = os.path.join( backup_path, plugins_utils.realFileName(cursor, filename="Bookmarks.db", domaintype="HomeDomain")) if (not os.path.isfile(filename)): print("Invalid file name for Safari Bookmarks database") return # main window bookmarkswindow = Toplevel() bookmarkswindow.title('Bookmarks data') bookmarkswindow.focus_set() bookmarkswindow.grid_columnconfigure(2, weight=1) bookmarkswindow.grid_rowconfigure(1, weight=1) # header label bookmarkstitle = Label(bookmarkswindow, text="Bookmarks data from: " + filename, relief=RIDGE) bookmarkstitle.grid(column=0, row=0, sticky="ew", columnspan=4, padx=5, pady=5) # tree bookmarkstree = ttk.Treeview( bookmarkswindow, columns=("id"), displaycolumns=(), yscrollcommand=lambda f, l: autoscroll(mvsb, f, l)) bookmarkstree.heading("#0", text="title", anchor='w') #bookmarkstree.heading("id", text="id", anchor='w') bookmarkstree.column("#0", width=250) #bookmarkstree.column("id", width=30) bookmarkstree.grid(column=0, row=1, sticky="ns") # center column centercolumn = Frame(bookmarkswindow, bd=2, relief=RAISED) centercolumn.grid(column=2, row=1, sticky="nswe") centercolumn.grid_columnconfigure(1, weight=1) centercolumn.grid_rowconfigure(2, weight=1) # Bookmark name bookmarknamefix = Label(centercolumn, text="Title:", relief=RIDGE) bookmarknamefix.grid(column=0, row=0, sticky="ew") namelabel = StringVar() bookmarkname = Label(centercolumn, textvariable=namelabel, relief=RIDGE) bookmarkname.grid(column=1, row=0, sticky="ew", columnspan=2) # Bookmark URL bookmarkurlfix = Label(centercolumn, text="URL:", relief=RIDGE) bookmarkurlfix.grid(column=0, row=1, sticky="ew") urllabel = StringVar() bookmarkurl = Label(centercolumn, textvariable=urllabel, relief=RIDGE) bookmarkurl.grid(column=1, row=1, sticky="ew") bookmarkbutton = Button(centercolumn, text="GO!", width=10, default=ACTIVE) bookmarkbutton.grid(column=2, row=1, sticky="ew") bookmarkbutton.bind("<Button-1>", openurl) # textarea textarea = Text(centercolumn, bd=2, relief=SUNKEN, yscrollcommand=lambda f, l: autoscroll(tvsb, f, l)) textarea.grid(column=0, row=2, sticky="nsew", columnspan=3) # scrollbars for main textarea tvsb = ttk.Scrollbar(centercolumn, orient="vertical") tvsb.grid(column=3, row=2, sticky='ns') tvsb['command'] = textarea.yview # scrollbars for tree mvsb = ttk.Scrollbar(bookmarkswindow, orient="vertical") mvsb.grid(column=1, row=1, sticky='ns') mvsb['command'] = bookmarkstree.yview # footer label footerlabel = StringVar() bookmarksfooter = Label(bookmarkswindow, textvariable=footerlabel, relief=RIDGE) bookmarksfooter.grid(column=0, row=2, sticky="ew", columnspan=4, padx=5, pady=5) # destroy window when closed bookmarkswindow.protocol("WM_DELETE_WINDOW", bookmarkswindow.destroy) # opening database tempdb = sqlite3.connect(filename) tempcur = tempdb.cursor() # footer statistics query = "SELECT count(*) FROM bookmarks" tempcur.execute(query) bookmarksnumber = tempcur.fetchall()[0][0] footerlabel.set("Found %s bookmarks." % (bookmarksnumber)) def insertBookmark(parent_node, parent_id): query = "SELECT id, title, num_children FROM bookmarks WHERE parent = \"%s\" ORDER BY order_index" % parent_id tempcur.execute(query) bookmarks = tempcur.fetchall() for bookmark in bookmarks: id = bookmark[0] title = bookmark[1] num_children = bookmark[2] newnode = bookmarkstree.insert(parent_node, 'end', text=title, values=(id)) if (num_children != 0): insertBookmark(newnode, id) # populating tree with Safari Bookmarks insertBookmark('', 0) bookmarkstree.bind("<ButtonRelease-1>", OnClick)
def main(cursor, backup_path): global filename global netidenttree, textarea, netidentwindow global dict_nodes filename = os.path.join(backup_path, plugins_utils.realFileName(cursor, filename="com.apple.network.identification.plist", domaintype="SystemPreferencesDomain")) if (not os.path.isfile(filename)): print("Invalid file name for network identification data: %s"%filename) return # main window netidentwindow = Toplevel() netidentwindow.title('Network Identification') netidentwindow.focus_set() netidentwindow.grid_columnconfigure(1, weight=1) netidentwindow.grid_rowconfigure(1, weight=1) # header label netidenttitle = Label( netidentwindow, text = "Network Identification data from: %s (%s) "%(filename, "com.apple.network.identification.plist"), relief = RIDGE, width=100, height=3, wraplength=800, justify=LEFT ) netidenttitle.grid(column = 0, row = 0, sticky="ew", columnspan=4, padx=5, pady=5) # tree netidenttree = ttk.Treeview( netidentwindow, columns=("id", "timestamp", "node"), displaycolumns=("id", "timestamp"), yscrollcommand=lambda f, l: autoscroll(mvsb, f, l) ) netidenttree.heading("#0", text="", anchor='w') netidenttree.heading("id", text="ID", anchor='w') netidenttree.heading("timestamp", text="Time", anchor='w') netidenttree.column("#0", width=40) netidenttree.column("id", width=250) netidenttree.column("timestamp", width=150) netidenttree.grid(column = 0, row = 1, sticky="ns") # textarea textarea = Text( netidentwindow, bd=2, relief=SUNKEN, yscrollcommand=lambda f, l: autoscroll(tvsb, f, l) ) textarea.grid(column = 2, row = 1, sticky="nsew") # scrollbars for tree mvsb = ttk.Scrollbar(netidentwindow, orient="vertical") mvsb.grid(column=1, row=1, sticky='ns') mvsb['command'] = netidenttree.yview # scrollbars for main textarea tvsb = ttk.Scrollbar(netidentwindow, orient="vertical") tvsb.grid(column=3, row=1, sticky='ns') tvsb['command'] = textarea.yview # footer label footerlabel = StringVar() netidentfooter = Label(netidentwindow, textvariable = footerlabel, relief = RIDGE) netidentfooter.grid(column = 0, row = 2, sticky="ew", columnspan=4, padx=5, pady=5) # destroy window when closed netidentwindow.protocol("WM_DELETE_WINDOW", netidentwindow.destroy) # convert binary plist file into plain plist file netidentxml = plistutils.readPlistToXml(filename) if (netidentxml == None): print("Error while parsing binary plist data") return # main dictionary (contains anything else) maindicts = netidentxml.getElementsByTagName('dict') if (len(maindicts) <= 0): print("no main dict found in file") return maindict = maindicts[0] # extract Signatures array maindictelements = plistutils.readDict(maindict) try: signatures = maindictelements['Signatures'] except: print("No Signatures array found in main dict") return signatures_array = plistutils.readArray(signatures) # footer statistics footerlabel.set("Found %i identified networks."%(len(signatures_array))) id_number = 0 for signature in signatures_array: sig_dict = plistutils.readDict(signature) id_string = sig_dict['Identifier'].firstChild.toxml() #2011-12-27T17:35:53.290510Z timestamp_string = sig_dict['Timestamp'].firstChild.toxml() if ("." in timestamp_string): timestamp_string = timestamp_string.split(".")[0] timestamp = datetime.datetime.strptime( timestamp_string, "%Y-%m-%dT%H:%M:%S" ) elem_id = "" # parse identification for IPv4 routers if (id_string.startswith('IPv4')): [ip, mac] = parseipv4(id_string) elem_id = "%s (%s)"%(ip, mac) else: elem_id = id_string netidenttree.insert('', 'end', text=id_number, values=(elem_id, timestamp, sig_dict)) dict_nodes.append([id_number, sig_dict]) id_number = id_number + 1 netidenttree.bind("<ButtonRelease-1>", OnClick)
def main(cursor, backup_path): global filename global safstatetree, textarea, safstatewindow global dict_nodes filename = os.path.join(backup_path, plugins_utils.realFileName(cursor, filename="SuspendState.plist", domaintype="HomeDomain")) if (not os.path.isfile(filename)): print("Invalid file name for Safari state data: %s"%filename) return # main window safstatewindow = Toplevel() safstatewindow.title('Safari State') safstatewindow.focus_set() safstatewindow.grid_columnconfigure(1, weight=1) safstatewindow.grid_rowconfigure(1, weight=1) # header label safstatetitle = Label( safstatewindow, text = "Safari State data from: %s (%s) "%(filename, "SuspendState.plist"), relief = RIDGE, width=100, height=3, wraplength=800, justify=LEFT ) safstatetitle.grid(column = 0, row = 0, sticky="ew", columnspan=4, padx=5, pady=5) # tree safstatetree = ttk.Treeview( safstatewindow, columns=("active", "title", "timestamp"), displaycolumns=("active", "title", "timestamp"), yscrollcommand=lambda f, l: autoscroll(mvsb, f, l) ) safstatetree.heading("#0", text="", anchor='w') safstatetree.heading("active", text="A", anchor='w') safstatetree.heading("title", text="Title", anchor='w') safstatetree.heading("timestamp", text="Timestamp", anchor='w') safstatetree.column("#0", width=30) safstatetree.column("active", width=20) safstatetree.column("title", width=250) safstatetree.column("timestamp", width=160) safstatetree.grid(column = 0, row = 1, sticky="ns") # textarea textarea = Text( safstatewindow, bd=2, relief=SUNKEN, yscrollcommand=lambda f, l: autoscroll(tvsb, f, l) ) textarea.grid(column = 2, row = 1, sticky="nsew") # scrollbars for tree mvsb = ttk.Scrollbar(safstatewindow, orient="vertical") mvsb.grid(column=1, row=1, sticky='ns') mvsb['command'] = safstatetree.yview # scrollbars for main textarea tvsb = ttk.Scrollbar(safstatewindow, orient="vertical") tvsb.grid(column=3, row=1, sticky='ns') tvsb['command'] = textarea.yview # footer label footerlabel = StringVar() safstatefooter = Label(safstatewindow, textvariable = footerlabel, relief = RIDGE) safstatefooter.grid(column = 0, row = 2, sticky="ew", columnspan=4, padx=5, pady=5) # destroy window when closed safstatewindow.protocol("WM_DELETE_WINDOW", safstatewindow.destroy) # convert binary plist file into plain plist file safstatexml = plistutils.readPlistToXml(filename) if (safstatexml == None): print("Error while parsing binary plist data") return # main dictionary (contains anything else) maindicts = safstatexml.getElementsByTagName('dict') if (len(maindicts) <= 0): print("no main dict found in file") return maindict = maindicts[0] # extract SafariStateDocuments array maindictelements = plistutils.readDict(maindict) try: safstatedocs = maindictelements['SafariStateDocuments'] except: print("No SafariStateDocuments array found in main dict") return active_tab = int(maindictelements['SafariStateActiveDocumentIndex'].firstChild.toxml()) safstatedocs_array = plistutils.readArray(safstatedocs) # footer statistics footerlabel.set("Found %i open tabs."%(len(safstatedocs_array))) id_number = 0 for safstatedoc in safstatedocs_array: safstatedoc_dict = plistutils.readDict(safstatedoc) try: title = safstatedoc_dict['SafariStateDocumentTitle'].firstChild.toxml() except: title = "" timestamp_val = float(safstatedoc_dict['SafariStateDocumentLastViewedTime'].firstChild.toxml()) timestamp_val = timestamp_val + 978307200 #JAN 1 1970 timestamp = datetime.datetime.fromtimestamp(timestamp_val) timestamp = timestamp.strftime("%Y-%m-%d %H:%M") active_status = "" if (active_tab == id_number): active_status = "*" safstatetree.insert('', 'end', text=id_number, values=(active_status, title, timestamp)) dict_nodes.append([id_number, safstatedoc_dict]) id_number = id_number + 1 safstatetree.bind("<ButtonRelease-1>", OnClick)
def main(cursor, backup_path): global filename, thumbsfilename global contactstree, textarea, contactswindow filename = os.path.join(backup_path, plugins_utils.realFileName(cursor, filename="AddressBook.sqlitedb", domaintype="HomeDomain")) thumbsfilename = os.path.join(backup_path, plugins_utils.realFileName(cursor, filename="AddressBookImages.sqlitedb", domaintype="HomeDomain")) if (not os.path.isfile(filename)): print("Invalid file name for Contacts database: %s"%filename) return if (thumbsfilename != None): if (not os.path.isfile(thumbsfilename)): print("Invalid file name for Contacts Thumbnails database: %s"%thumbsfilename) return # main window contactswindow = Toplevel() contactswindow.title('SMS data') contactswindow.focus_set() contactswindow.grid_columnconfigure(1, weight=1) contactswindow.grid_rowconfigure(1, weight=1) # header label contactstitle = Label(contactswindow, text = "Contacts data from: " + filename, relief = RIDGE) contactstitle.grid(column = 0, row = 0, sticky="ew", columnspan=2, padx=5, pady=5) # tree # Column type: G for groups, C for contacts contactstree = ttk.Treeview(contactswindow, columns=("name", "type"), displaycolumns=("name")) contactstree.heading("#0", text="ID", anchor='w') contactstree.heading("name", text="Name", anchor='w') contactstree.column("#0", width=80) contactstree.column("name", width=250) contactstree.grid(column = 0, row = 1, sticky="ns") # textarea textarea = Text(contactswindow, bd=2, relief=SUNKEN) textarea.grid(column = 1, row = 1, sticky="nsew") # footer label footerlabel = StringVar() contactsfooter = Label(contactswindow, textvariable = footerlabel, relief = RIDGE) contactsfooter.grid(column = 0, row = 2, sticky="ew", columnspan=2, padx=5, pady=5) # destroy window when closed contactswindow.protocol("WM_DELETE_WINDOW", contactswindow.destroy) # opening database tempdb = sqlite3.connect(filename) tempcur = tempdb.cursor() # footer statistics query = "SELECT count(ROWID) from ABPerson" tempcur.execute(query) contactsnumber = tempcur.fetchall()[0][0] query = "SELECT count(ROWID) from ABGroup" tempcur.execute(query) groupsnumber = tempcur.fetchall()[0][0] footerlabel.set("Found %s contacts in %s groups."%(contactsnumber, groupsnumber)) # populating contacts tree # all contacts allnode = contactstree.insert('', 'end', text="", values=("All Contacts", "G")) query = "SELECT ROWID, First, Last, Organization FROM ABPerson ORDER BY Last, First, Organization" tempcur.execute(query) people = tempcur.fetchall() for person in people: personid = person[0] if (person[1] != None): name = person[1] if (person[2] != None): name = name + " " + person[2] if (person[1] == None and person[2] == None): name = person[3] contactstree.insert(allnode, 'end', text=personid, values=(cleanSpace(name), "C")) # groups contacts query = "SELECT ROWID, Name FROM ABGroup" tempcur.execute(query) groups = tempcur.fetchall() for group in groups: groupid = group[0] name = group[1] groupnode = contactstree.insert('', 'end', text=groupid, values=(cleanSpace(name), "G")) query = "SELECT ABPerson.ROWID, First, Last, Organization FROM ABGroupMembers INNER JOIN ABPerson ON ABGroupMembers.member_id = ABPerson.ROWID WHERE ABGroupMembers.group_id = \"%s\" ORDER BY Last, First, Organization"%groupid tempcur.execute(query) people = tempcur.fetchall() for person in people: personid = person[0] if (person[1] != None): name = person[1] if (person[2] != None): name = name + " " + person[2] if (person[1] == None and person[2] == None): name = person[3] contactstree.insert(groupnode, 'end', text=personid, values=(cleanSpace(name), "C")) tempdb.close() contactstree.bind("<ButtonRelease-1>", OnClick)