Revert "Use SQL for quickmark/bookmark storage."

This reverts commit fa1ebb03b70dfff4ac64038e67d9bab04b984de5.
This commit is contained in:
Ryan Roden-Corrent 2017-02-28 08:43:11 -05:00
parent e3a33ca427
commit 80619c88b3
2 changed files with 81 additions and 41 deletions

View File

@ -1260,15 +1260,13 @@ class CommandDispatcher:
if name is None:
url = self._current_url()
try:
quickmark_manager.delete_by_qurl(url)
name = quickmark_manager.get_by_qurl(url)
except urlmarks.DoesNotExistError as e:
raise cmdexc.CommandError(str(e))
else:
try:
quickmark_manager.delete(name)
except KeyError:
raise cmdexc.CommandError(
"Quickmark '{}' not found!".format(name))
try:
quickmark_manager.delete(name)
except KeyError:
raise cmdexc.CommandError("Quickmark '{}' not found!".format(name))
@cmdutils.register(instance='command-dispatcher', scope='window')
def bookmark_add(self, url=None, title=None, toggle=False):

View File

@ -29,13 +29,14 @@ import os
import html
import os.path
import functools
import collections
from PyQt5.QtCore import QUrl
from PyQt5.QtCore import pyqtSignal, QUrl, QObject
from qutebrowser.utils import (message, usertypes, qtutils, urlutils,
standarddir, objreg, log)
from qutebrowser.commands import cmdutils
from qutebrowser.misc import lineparser, sql
from qutebrowser.misc import lineparser
class Error(Exception):
@ -66,18 +67,29 @@ class AlreadyExistsError(Error):
pass
class UrlMarkManager(sql.SqlTable):
class UrlMarkManager(QObject):
"""Base class for BookmarkManager and QuickmarkManager.
Attributes:
marks: An OrderedDict of all quickmarks/bookmarks.
_lineparser: The LineParser used for the marks
Signals:
changed: Emitted when anything changed.
added: Emitted when a new quickmark/bookmark was added.
removed: Emitted when an existing quickmark/bookmark was removed.
"""
def __init__(self, name, fields, primary_key, parent=None):
"""Initialize and read marks."""
super().__init__(name, fields, primary_key, parent)
changed = pyqtSignal()
added = pyqtSignal(str, str)
removed = pyqtSignal(str)
def __init__(self, parent=None):
"""Initialize and read quickmarks."""
super().__init__(parent)
self.marks = collections.OrderedDict()
self._init_lineparser()
for line in self._lineparser:
@ -98,17 +110,31 @@ class UrlMarkManager(sql.SqlTable):
def save(self):
"""Save the marks to disk."""
self._lineparser.data = [' '.join(tpl) for tpl in self]
self._lineparser.data = [' '.join(tpl) for tpl in self.marks.items()]
self._lineparser.save()
def delete(self, key):
"""Delete a quickmark/bookmark.
Args:
key: The key to delete (name for quickmarks, URL for bookmarks.)
"""
del self.marks[key]
self.changed.emit()
self.removed.emit(key)
class QuickmarkManager(UrlMarkManager):
"""Manager for quickmarks."""
"""Manager for quickmarks.
def __init__(self, parent=None):
super().__init__('Quickmarks', ['name', 'url'], primary_key='name',
parent=parent)
The primary key for quickmarks is their *name*, this means:
- self.marks maps names to URLs.
- changed gets emitted with the name as first argument and the URL as
second argument.
- removed gets emitted with the name as argument.
"""
def _init_lineparser(self):
self._lineparser = lineparser.LineParser(
@ -125,7 +151,7 @@ class QuickmarkManager(UrlMarkManager):
except ValueError:
message.error("Invalid quickmark '{}'".format(line))
else:
self.insert([key, url])
self.marks[key] = url
def prompt_save(self, url):
"""Prompt for a new quickmark name to be added and add it.
@ -165,32 +191,41 @@ class QuickmarkManager(UrlMarkManager):
def set_mark():
"""Really set the quickmark."""
self.insert([name, url], replace=True)
self.marks[name] = url
self.changed.emit()
self.added.emit(name, url)
log.misc.debug("Added quickmark {} for {}".format(name, url))
if name in self:
if name in self.marks:
message.confirm_async(
title="Override existing quickmark?",
yes_action=set_mark, default=True)
else:
set_mark()
def delete_by_qurl(self, url):
"""Delete a quickmark by QUrl (as opposed to by name)."""
def get_by_qurl(self, url):
"""Look up a quickmark by QUrl, returning its name.
Takes O(n) time, where n is the number of quickmarks.
Use a name instead where possible.
"""
qtutils.ensure_valid(url)
urlstr = url.toString(QUrl.RemovePassword | QUrl.FullyEncoded)
try:
self.delete(urlstr, field='url')
except KeyError:
raise DoesNotExistError("Quickmark for '{}' not found!"
.format(urlstr))
index = list(self.marks.values()).index(urlstr)
key = list(self.marks.keys())[index]
except ValueError:
raise DoesNotExistError(
"Quickmark for '{}' not found!".format(urlstr))
return key
def get(self, name):
"""Get the URL of the quickmark named name as a QUrl."""
if name not in self:
raise DoesNotExistError("Quickmark '{}' does not exist!"
.format(name))
urlstr = self[name].url
if name not in self.marks:
raise DoesNotExistError(
"Quickmark '{}' does not exist!".format(name))
urlstr = self.marks[name]
try:
url = urlutils.fuzzy_url(urlstr, do_search=False)
except urlutils.InvalidUrlError as e:
@ -201,11 +236,15 @@ class QuickmarkManager(UrlMarkManager):
class BookmarkManager(UrlMarkManager):
"""Manager for bookmarks."""
"""Manager for bookmarks.
def __init__(self, parent=None):
super().__init__('Bookmarks', ['url', 'title'], primary_key='url',
parent=parent)
The primary key for bookmarks is their *url*, this means:
- self.marks maps URLs to titles.
- changed gets emitted with the URL as first argument and the title as
second argument.
- removed gets emitted with the URL as argument.
"""
def _init_lineparser(self):
bookmarks_directory = os.path.join(standarddir.config(), 'bookmarks')
@ -223,9 +262,10 @@ class BookmarkManager(UrlMarkManager):
def _parse_line(self, line):
parts = line.split(maxsplit=1)
urlstr = parts[0]
title = parts[1] if len(parts) == 2 else ''
self.insert([urlstr, title])
if len(parts) == 2:
self.marks[parts[0]] = parts[1]
elif len(parts) == 1:
self.marks[parts[0]] = ''
def add(self, url, title, *, toggle=False):
"""Add a new bookmark.
@ -246,12 +286,14 @@ class BookmarkManager(UrlMarkManager):
urlstr = url.toString(QUrl.RemovePassword | QUrl.FullyEncoded)
if urlstr in self:
if urlstr in self.marks:
if toggle:
self.delete(urlstr)
del self.marks[urlstr]
return False
else:
raise AlreadyExistsError("Bookmark already exists!")
else:
self.insert([urlstr, title])
self.marks[urlstr] = title
self.changed.emit()
self.added.emit(title, urlstr)
return True