Record global page history to disk.

We currently don't do anything with it yet, but people could use it in scripts
already and we have the history later when completion or other stuff will be
added based on it.

See #33.
This commit is contained in:
Florian Bruhin 2015-02-01 17:34:16 +01:00
parent 933151abd7
commit 33a2181e31
3 changed files with 124 additions and 7 deletions

View File

@ -25,7 +25,8 @@ disable=no-self-use,
unnecessary-lambda,
blacklisted-name,
too-many-lines,
logging-format-interpolation
logging-format-interpolation,
interface-not-implemented
[BASIC]
module-rgx=(__)?[a-z][a-z0-9_]*(__)?$

View File

@ -40,7 +40,7 @@ import qutebrowser
import qutebrowser.resources # pylint: disable=unused-import
from qutebrowser.commands import cmdutils, runners
from qutebrowser.config import style, config, websettings
from qutebrowser.browser import quickmarks, cookies, cache, adblock
from qutebrowser.browser import quickmarks, cookies, cache, adblock, history
from qutebrowser.browser.network import qutescheme, proxy
from qutebrowser.mainwindow import mainwindow
from qutebrowser.misc import crashdialog, readline, ipc, earlyinit, savemanager
@ -197,6 +197,8 @@ class Application(QApplication):
log.init.debug("Initializing cache...")
diskcache = cache.DiskCache(self)
objreg.register('cache', diskcache)
log.init.debug("Initializing web history...")
history.init()
log.init.debug("Initializing main window...")
win_id = mainwindow.MainWindow.spawn(
False if self._args.nowindow else True)
@ -540,10 +542,10 @@ class Application(QApplication):
pages = []
try:
history = objreg.get('command-history')[-5:]
cmd_history = objreg.get('command-history')[-5:]
except Exception:
log.destroy.exception("Error while getting history: {}")
history = []
cmd_history = []
try:
objects = self.get_all_objects()
@ -562,7 +564,7 @@ class Application(QApplication):
log.destroy.exception("Error while preventing shutdown")
QApplication.closeAllWindows()
self._crashdlg = crashdialog.ExceptionCrashDialog(
self._args.debug, pages, history, exc, objects)
self._args.debug, pages, cmd_history, exc, objects)
ret = self._crashdlg.exec_()
if ret == QDialog.Accepted: # restore
self.restart(shutdown=False, pages=pages)
@ -668,9 +670,9 @@ class Application(QApplication):
def report(self):
"""Report a bug in qutebrowser."""
pages = self._recover_pages()
history = objreg.get('command-history')[-5:]
cmd_history = objreg.get('command-history')[-5:]
objects = self.get_all_objects()
self._crashdlg = crashdialog.ReportDialog(pages, history, objects)
self._crashdlg = crashdialog.ReportDialog(pages, cmd_history, objects)
self._crashdlg.show()
def interrupt(self, signum, _frame):

View File

@ -0,0 +1,114 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014-2015 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
# qutebrowser is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# qutebrowser is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
"""Simple history which gets written to disk."""
import time
import functools
from PyQt5.QtCore import pyqtSignal, QStandardPaths
from PyQt5.QtWebKit import QWebHistoryInterface
from qutebrowser.utils import utils, objreg, standarddir
from qutebrowser.config import config
from qutebrowser.config.parsers import line as lineparser
class HistoryEntry:
"""A single entry in the web history.
Attributes:
atime: The time the page was accessed.
url: The URL which was accessed as string
"""
def __init__(self, atime, url):
self.atime = atime
self.url = url
def __repr__(self):
return utils.get_repr(self, constructor=True, atime=self.atime,
url=self.url)
def __str__(self):
return '{} {}'.format(int(self.atime), self.url)
@classmethod
def from_str(cls, s):
"""Get a history based on a 'TIME URL' string."""
splitted = s.split(' ')
if len(splitted) != 2:
raise OSError("Invalid history entry '{}'".format(s))
return cls(*splitted)
class WebHistory(QWebHistoryInterface):
"""A QWebHistoryInterface which supports being written to disk."""
changed = pyqtSignal()
def __init__(self, parent=None):
super().__init__(parent)
datadir = standarddir.get(QStandardPaths.DataLocation)
self._linecp = lineparser.LineConfigParser(datadir, 'history',
parent=self)
self._history = [HistoryEntry.from_str(e) for e in self._linecp.data]
objreg.get('save-manager').add_saveable('history', self.save,
self.changed)
def __repr__(self):
return utils.get_repr(self, length=len(self._history))
def save(self):
"""Save the history to disk."""
self._linecp.data = (str(e) for e in self._history)
self._linecp.save()
def addHistoryEntry(self, url_string):
"""Called by WebKit when an URL should be added to the history.
Args:
url_string: An url as string to add to the history.
"""
if not config.get('general', 'private-browsing'):
entry = HistoryEntry(time.time(), url_string)
self._history.append(entry)
self.historyContains.cache_clear()
self.changed.emit()
@functools.lru_cache()
def historyContains(self, url_string):
"""Called by WebKit to determine if an URL is contained in the history.
Args:
url_string: The URL (as string) to check for.
Return:
True if the url is in the history, False otherwise.
"""
return url_string in (entry.url for entry in self._history)
def init():
"""Initialize the web history."""
history = WebHistory()
objreg.register('web-history', history)
QWebHistoryInterface.setDefaultInterface(history)