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)
예제 #13
0
	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()
예제 #14
0
    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()
예제 #15
0
    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()
예제 #23
0
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)
예제 #24
0
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))
예제 #33
0
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)
예제 #34
0
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)
예제 #35
0
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()
예제 #37
0
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)
예제 #38
0
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)
예제 #43
0
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)
예제 #44
0
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)
예제 #47
0
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)