--- a/WebBrowser/History/HistoryManager.py Mon Apr 17 18:38:58 2017 +0200 +++ b/WebBrowser/History/HistoryManager.py Tue Apr 18 19:22:54 2017 +0200 @@ -21,24 +21,28 @@ import Utilities import Preferences -HISTORY_VERSION = 42 +HISTORY_VERSION_42 = 42 +HISTORY_VERSION_60 = 60 +HISTORY_VERSIONS = [HISTORY_VERSION_60, HISTORY_VERSION_42] class HistoryEntry(object): """ Class implementing a history entry. """ - def __init__(self, url=None, dateTime=None, title=None): + def __init__(self, url=None, dateTime=None, title=None, visitCount=None): """ Constructor @param url URL of the history entry (string) @param dateTime date and time this entry was created (QDateTime) @param title title string for the history entry (string) + @param visitCount number of visits of this URL (int) """ self.url = url and url or "" self.dateTime = dateTime and dateTime or QDateTime() self.title = title and title or "" + self.visitCount = visitCount and visitCount or 0 def __eq__(self, other): """ @@ -76,6 +80,15 @@ return page return self.url return self.title + + def isValid(self): + """ + Public method to determine validity. + + @return flag indicating validity + @rtype bool + """ + return bool(self.url) and self.dateTime.isValid() class HistoryManager(QObject): @@ -178,6 +191,36 @@ self.__saveTimer.changeOccurred() self.historyReset.emit() + def __findFirstHistoryEntry(self, url): + """ + Private method to find the first entry for the given URL. + + @param url URL to search for + @type str + @return first entry for the given URL + @rtype HistoryEntry + """ + for index in range(len(self.__history)): + if url == self.__history[index].url: + return self.__history[index] + + # not found, return an empty entry + return HistoryEntry() + + def __updateVisitCount(self, url, count): + """ + Private method to update the visit count for all entries of the + given URL. + + @param url URL to be updated + @type str + @param count new visit count + @type int + """ + for index in range(len(self.__history)): + if url == self.__history[index].url: + self.__history[index].visitCount = count + def addHistoryEntry(self, view): """ Public method to add a history entry. @@ -192,15 +235,18 @@ url = view.url() title = view.title() - if url.scheme() not in ["eric", "about", "data"]: - if url.password(): - # don't save the password in the history - url.setPassword("") - if url.host(): - url.setHost(url.host().lower()) - itm = HistoryEntry(url.toString(), + if url.scheme() not in ["eric", "about", "data", "chrome"]: + cleanUrlStr = self.__cleanUrlStr(url) + firstEntry = self.__findFirstHistoryEntry(cleanUrlStr) + if firstEntry.isValid(): + visitCount = firstEntry.visitCount + 1 + self.__updateVisitCount(cleanUrlStr, visitCount) + else: + visitCount = 1 + itm = HistoryEntry(cleanUrlStr, QDateTime.currentDateTime(), - title) + title, + visitCount) self.__history.insert(0, itm) self.entryAdded.emit(itm) if len(self.__history) == 1: @@ -213,10 +259,10 @@ @param url URL of the entry to update (string) @param title title of the entry to update (string) """ - cleanurl = QUrl(url) - if cleanurl.scheme() not in ["eric", "about"]: + if QUrl(url).scheme() not in ["eric", "about", "data", "chrome"]: + cleanUrlStr = self.__cleanUrlStr(QUrl(url)) for index in range(len(self.__history)): - if url == self.__history[index].url: + if cleanUrlStr == self.__history[index].url: self.__history[index].title = title self.__saveTimer.changeOccurred() if not self.__lastSavedUrl: @@ -231,14 +277,47 @@ @param url URL of the entry to remove (QUrl) @param title title of the entry to remove (string) """ - for index in range(len(self.__history)): - if url == QUrl(self.__history[index].url) and \ - (not title or title == self.__history[index].title): - itm = self.__history[index] - self.__lastSavedUrl = "" - self.__history.remove(itm) - self.entryRemoved.emit(itm) - break + if url.scheme() not in ["eric", "about", "data", "chrome"]: + cleanUrlStr = self.__cleanUrlStr(url) + for index in range(len(self.__history)): + if cleanUrlStr == self.__history[index].url and \ + (not title or title == self.__history[index].title): + itm = self.__history[index] + self.__lastSavedUrl = "" + self.__history.remove(itm) + self.entryRemoved.emit(itm) + break + + def __cleanUrl(self, url): + """ + Private method to generate a clean URL usable for the history entry. + + @param url original URL + @type QUrl + @return cleaned URL + @rtype QUrl + """ + cleanurl = QUrl(url) + if cleanurl.password(): + # don't save the password in the history + cleanurl.setPassword("") + if cleanurl.host(): + # convert host to lower case + cleanurl.setHost(url.host().lower()) + + return cleanurl + + def __cleanUrlStr(self, url): + """ + Private method to generate a clean URL usable for the history entry. + + @param url original URL + @type QUrl + @return cleaned URL + @rtype str + """ + cleanurl = self.__cleanUrl(url) + return cleanurl.toString() def historyModel(self): """ @@ -383,12 +462,14 @@ stream.setVersion(QDataStream.Qt_4_6) while not stream.atEnd(): ver = stream.readUInt32() - if ver != HISTORY_VERSION: + if ver not in HISTORY_VERSIONS: continue itm = HistoryEntry() itm.url = Utilities.readStringFromStream(stream) stream >> itm.dateTime itm.title = Utilities.readStringFromStream(stream) + if ver == HISTORY_VERSION_60: + itm.visitCount = stream.readUInt32() if not itm.dateTime.isValid(): continue @@ -398,6 +479,15 @@ history[0].title = itm.title continue + if ver == HISTORY_VERSION_42: + firstEntry = self.__findFirstHistoryEntry(itm.url) + if firstEntry.isValid(): + visitCount = firstEntry.visitCount + 1 + self.__updateVisitCount(itm.url, visitCount) + else: + visitCount = 1 + itm.visitCount = visitCount + if not needToSort and history and lastInsertedItem < itm: needToSort = True @@ -458,10 +548,11 @@ stream = QDataStream(data, QIODevice.WriteOnly) stream.setVersion(QDataStream.Qt_4_6) itm = self.__history[index] - stream.writeUInt32(HISTORY_VERSION) + stream.writeUInt32(HISTORY_VERSION_60) stream.writeString(itm.url.encode("utf-8")) stream << itm.dateTime stream.writeString(itm.title.encode('utf-8')) + stream.writeUInt32(itm.visitCount) f.write(data) f.close()