From 748ec7e7a1d614e70c6cfdbb66cbc0e19700697f Mon Sep 17 00:00:00 2001 From: Imran Sobir Date: Tue, 7 Feb 2017 00:04:32 +0500 Subject: [PATCH 01/24] Add history page. --- qutebrowser/browser/qutescheme.py | 64 ++++++++++++++++++++++ qutebrowser/html/history.html | 89 +++++++++++++++++++++++++++++++ 2 files changed, 153 insertions(+) create mode 100644 qutebrowser/html/history.html diff --git a/qutebrowser/browser/qutescheme.py b/qutebrowser/browser/qutescheme.py index 4d27d694a..3853de02c 100644 --- a/qutebrowser/browser/qutescheme.py +++ b/qutebrowser/browser/qutescheme.py @@ -24,6 +24,7 @@ Module attributes: _HANDLERS: The handlers registered via decorators. """ +import datetime import urllib.parse import qutebrowser @@ -158,6 +159,69 @@ def qute_bookmarks(_url): return 'text/html', html +@add_handler('history') +def qute_history(url): + """Handler for qute:history. Display history.""" + + # Get current date from query parameter, if not given choose today. + curr_date = datetime.date.today() + try: + for query in url.query().split("&"): + kv = query.split("=", 2) + if kv[0] == "date": + curr_date = datetime.datetime.strptime(kv[1], "%Y-%m-%d") + break + except Exception: + log.misc.debug("Invalid query string passed to qute://history") + + ONE_DAY = datetime.timedelta(days=1) + next_date = curr_date + ONE_DAY + prev_date = curr_date - ONE_DAY + + def history_iter(): + for item in objreg.get('web-history').history_dict.values(): + # Convert timestamp + item_date = None + try: + item_date = datetime.datetime.fromtimestamp(item.atime) + except Exception: + log.misc.error("Invalid timestamp {}.".format(item.atime)) + continue + + display_url = item.url.toDisplayString() + + # Skip items not on curr_date + # Skip redirects and items without title + # Skip qute:// links + has_no_title = len(item.title) <= 0 + is_internal = display_url.startswith("qute://") + is_redirect = item.redirect + is_not_today = ( + item_date.year != curr_date.year or + item_date.month != curr_date.month or + item_date.day != curr_date.day + ) + if (is_redirect or is_internal or has_no_title or is_not_today): + continue + + display_atime = item_date.strftime("%X") + yield (display_url, item.title, display_atime) + + history = [item for item in history_iter()] + try: + history = reversed(history) + except TypeError: # Python < 3.5 + history = reversed(list(history)) + + html = jinja.render('history.html', + title='History', + history=history, + curr_date=curr_date.strftime("%a, %d %B %Y"), + next_date=next_date.strftime("%Y-%m-%d"), + prev_date=prev_date.strftime("%Y-%m-%d")) + return 'text/html', html + + @add_handler('pyeval') def qute_pyeval(_url): """Handler for qute:pyeval.""" diff --git a/qutebrowser/html/history.html b/qutebrowser/html/history.html new file mode 100644 index 000000000..35bb79b39 --- /dev/null +++ b/qutebrowser/html/history.html @@ -0,0 +1,89 @@ +{% extends "base.html" %} + +{% block style %} +body { + background: #fefefe; + font-family: sans-serif; + margin: 0 auto; + max-width: 1440px; + padding-left: 20px; + padding-right: 20px; +} + +h1 { + color: #444; + font-weight: normal; +} + +table { + border-collapse: collapse; + width: 100%; +} + +td { + max-width: 50%; + padding: 2px 5px; + text-align: left; +} + +td.title { + word-break: break-all; +} + +td.time { + color: #555; + white-space: nowrap; +} + +a { + text-decoration: none; + color: #2562dc +} + +a:hover { + text-decoration: underline; +} + +tr:nth-child(odd) { + background-color: #f8f8f8; +} + +.date { + color: #888; + font-size: 14pt; + padding-left: 25px; +} + +.pagination-link { + display: inline-block; + margin-bottom: 10px; + margin-top: 10px; + padding-right: 10px; +} + +.pagination-link > a { + color: #333; + font-weight: bold; +} + +{% endblock %} + +{% block content %} + +

Browsing history {{curr_date}}

+ + + + {% for url, title, time in history %} + + + + + {% endfor %} + +
{{title}}{{time}}
+ +Previous +Next + +{% endblock %} From 46a34a99f387f686f1c768d3283a78cc720afae6 Mon Sep 17 00:00:00 2001 From: Imran Sobir Date: Tue, 7 Feb 2017 11:22:04 +0500 Subject: [PATCH 02/24] Use QUrlQuery to parse qute://history queries. --- qutebrowser/browser/qutescheme.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/qutebrowser/browser/qutescheme.py b/qutebrowser/browser/qutescheme.py index 3853de02c..627ddb08a 100644 --- a/qutebrowser/browser/qutescheme.py +++ b/qutebrowser/browser/qutescheme.py @@ -27,6 +27,8 @@ Module attributes: import datetime import urllib.parse +from PyQt5.QtCore import QUrlQuery + import qutebrowser from qutebrowser.utils import (version, utils, jinja, log, message, docutils, objreg) @@ -162,17 +164,12 @@ def qute_bookmarks(_url): @add_handler('history') def qute_history(url): """Handler for qute:history. Display history.""" - # Get current date from query parameter, if not given choose today. - curr_date = datetime.date.today() - try: - for query in url.query().split("&"): - kv = query.split("=", 2) - if kv[0] == "date": - curr_date = datetime.datetime.strptime(kv[1], "%Y-%m-%d") - break - except Exception: - log.misc.debug("Invalid query string passed to qute://history") + url_query_date = QUrlQuery(url).queryItemValue("date") + if url_query_date: + curr_date = datetime.datetime.strptime(url_query_date, "%Y-%m-%d") + else: + curr_date = datetime.date.today() ONE_DAY = datetime.timedelta(days=1) next_date = curr_date + ONE_DAY From f5e75ff870a502b0fbe1fad5e4577fdf06ecdc34 Mon Sep 17 00:00:00 2001 From: Imran Sobir Date: Tue, 7 Feb 2017 11:56:51 +0500 Subject: [PATCH 03/24] Misc qute_history() fixes. --- qutebrowser/browser/qutescheme.py | 36 +++++++++++-------------------- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/qutebrowser/browser/qutescheme.py b/qutebrowser/browser/qutescheme.py index 627ddb08a..3c4874928 100644 --- a/qutebrowser/browser/qutescheme.py +++ b/qutebrowser/browser/qutescheme.py @@ -167,48 +167,38 @@ def qute_history(url): # Get current date from query parameter, if not given choose today. url_query_date = QUrlQuery(url).queryItemValue("date") if url_query_date: - curr_date = datetime.datetime.strptime(url_query_date, "%Y-%m-%d") + curr_date = datetime.datetime.strptime(url_query_date, "%Y-%m-%d").date() else: curr_date = datetime.date.today() - ONE_DAY = datetime.timedelta(days=1) - next_date = curr_date + ONE_DAY - prev_date = curr_date - ONE_DAY + one_day = datetime.timedelta(days=1) + next_date = curr_date + one_day + prev_date = curr_date - one_day def history_iter(): for item in objreg.get('web-history').history_dict.values(): # Convert timestamp - item_date = None try: - item_date = datetime.datetime.fromtimestamp(item.atime) - except Exception: + item_atime = datetime.datetime.fromtimestamp(item.atime) + except (ValueError, OSError, OverflowError): log.misc.error("Invalid timestamp {}.".format(item.atime)) continue - display_url = item.url.toDisplayString() - # Skip items not on curr_date # Skip redirects and items without title # Skip qute:// links - has_no_title = len(item.title) <= 0 - is_internal = display_url.startswith("qute://") - is_redirect = item.redirect - is_not_today = ( - item_date.year != curr_date.year or - item_date.month != curr_date.month or - item_date.day != curr_date.day - ) - if (is_redirect or is_internal or has_no_title or is_not_today): + is_internal = item.url.scheme() == 'qute' + is_not_today = item_atime.date() != curr_date + if item.redirect or is_internal or not item.title or is_not_today: continue - display_atime = item_date.strftime("%X") - yield (display_url, item.title, display_atime) + display_atime = item_atime.strftime("%X") + yield (item.url.toDisplayString(), item.title, display_atime) - history = [item for item in history_iter()] try: - history = reversed(history) + history = reversed(history_iter()) except TypeError: # Python < 3.5 - history = reversed(list(history)) + history = reversed(list(history_iter())) html = jinja.render('history.html', title='History', From be12b4cccfa68b9d7e1d52f5fdebf2c38998ccd7 Mon Sep 17 00:00:00 2001 From: Imran Sobir Date: Tue, 7 Feb 2017 16:06:19 +0500 Subject: [PATCH 04/24] Use history item's url as title if no title. --- qutebrowser/browser/qutescheme.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/qutebrowser/browser/qutescheme.py b/qutebrowser/browser/qutescheme.py index 3c4874928..9ece0e1de 100644 --- a/qutebrowser/browser/qutescheme.py +++ b/qutebrowser/browser/qutescheme.py @@ -185,15 +185,19 @@ def qute_history(url): continue # Skip items not on curr_date - # Skip redirects and items without title + # Skip redirects # Skip qute:// links is_internal = item.url.scheme() == 'qute' is_not_today = item_atime.date() != curr_date - if item.redirect or is_internal or not item.title or is_not_today: + if item.redirect or is_internal or is_not_today: continue + # Use item's url as title if there's no title. + item_url = item.url.toDisplayString() + item_title = item.title if item.title else item_url display_atime = item_atime.strftime("%X") - yield (item.url.toDisplayString(), item.title, display_atime) + + yield (item_url, item_title, display_atime) try: history = reversed(history_iter()) From 2c40be31a2b30cb0939a6f71e9459c8bf40f572e Mon Sep 17 00:00:00 2001 From: Imran Sobir Date: Tue, 7 Feb 2017 16:15:10 +0500 Subject: [PATCH 05/24] Prevent crash if invalid date is passed to qute:history. --- qutebrowser/browser/qutescheme.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/qutebrowser/browser/qutescheme.py b/qutebrowser/browser/qutescheme.py index 9ece0e1de..1e996d1f2 100644 --- a/qutebrowser/browser/qutescheme.py +++ b/qutebrowser/browser/qutescheme.py @@ -165,11 +165,13 @@ def qute_bookmarks(_url): def qute_history(url): """Handler for qute:history. Display history.""" # Get current date from query parameter, if not given choose today. - url_query_date = QUrlQuery(url).queryItemValue("date") - if url_query_date: - curr_date = datetime.datetime.strptime(url_query_date, "%Y-%m-%d").date() - else: - curr_date = datetime.date.today() + curr_date = datetime.date.today() + try: + query_date = QUrlQuery(url).queryItemValue("date") + if query_date: + curr_date = datetime.datetime.strptime(query_date, "%Y-%m-%d").date() + except ValueError: + log.misc.error("Invalid date passed to qute:history: {}.".format(query_date)) one_day = datetime.timedelta(days=1) next_date = curr_date + one_day From 216cef8d9f69db7459c0da92a83d2e492573346e Mon Sep 17 00:00:00 2001 From: Imran Sobir Date: Tue, 7 Feb 2017 16:18:00 +0500 Subject: [PATCH 06/24] Add basic end-to-end test for qute:history. --- tests/end2end/features/history.feature | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/end2end/features/history.feature b/tests/end2end/features/history.feature index 7e9c55c99..b749171f6 100644 --- a/tests/end2end/features/history.feature +++ b/tests/end2end/features/history.feature @@ -67,6 +67,13 @@ Feature: Page history http://localhost:(port)/data/hints/html/simple.html Simple link http://localhost:(port)/data/hello.txt + Scenario: Listing history + When I open data/numbers/3.txt + And I open data/numbers/4.txt + And I open qute:history + Then the page should contain the plaintext "3.txt" + Then the page should contain the plaintext "4.txt" + ## Bugs @qtwebengine_skip From 9a218256b7d59ba8eddcb6b6f4f91385ce30c322 Mon Sep 17 00:00:00 2001 From: Imran Sobir Date: Tue, 7 Feb 2017 19:25:01 +0500 Subject: [PATCH 07/24] Fix pylint complaints. --- qutebrowser/browser/qutescheme.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/qutebrowser/browser/qutescheme.py b/qutebrowser/browser/qutescheme.py index 1e996d1f2..3960f24ed 100644 --- a/qutebrowser/browser/qutescheme.py +++ b/qutebrowser/browser/qutescheme.py @@ -169,9 +169,10 @@ def qute_history(url): try: query_date = QUrlQuery(url).queryItemValue("date") if query_date: - curr_date = datetime.datetime.strptime(query_date, "%Y-%m-%d").date() + curr_date = datetime.datetime.strptime(query_date, "%Y-%m-%d") + curr_date = curr_date.date() except ValueError: - log.misc.error("Invalid date passed to qute:history: {}.".format(query_date)) + log.misc.error("Invalid date passed to qute:history: " + query_date) one_day = datetime.timedelta(days=1) next_date = curr_date + one_day @@ -201,10 +202,7 @@ def qute_history(url): yield (item_url, item_title, display_atime) - try: - history = reversed(history_iter()) - except TypeError: # Python < 3.5 - history = reversed(list(history_iter())) + history = reversed(list(history_iter())) html = jinja.render('history.html', title='History', From ec0e95969ed7988eb5443156b9db8d4e9f7a4028 Mon Sep 17 00:00:00 2001 From: Imran Sobir Date: Wed, 8 Feb 2017 13:28:04 +0500 Subject: [PATCH 08/24] Add unit tests for qute://history. --- qutebrowser/browser/qutescheme.py | 4 +- tests/unit/browser/test_qutehistory.py | 95 ++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 tests/unit/browser/test_qutehistory.py diff --git a/qutebrowser/browser/qutescheme.py b/qutebrowser/browser/qutescheme.py index 3960f24ed..1b51f405b 100644 --- a/qutebrowser/browser/qutescheme.py +++ b/qutebrowser/browser/qutescheme.py @@ -172,7 +172,7 @@ def qute_history(url): curr_date = datetime.datetime.strptime(query_date, "%Y-%m-%d") curr_date = curr_date.date() except ValueError: - log.misc.error("Invalid date passed to qute:history: " + query_date) + log.misc.debug("Invalid date passed to qute:history: " + query_date) one_day = datetime.timedelta(days=1) next_date = curr_date + one_day @@ -184,7 +184,7 @@ def qute_history(url): try: item_atime = datetime.datetime.fromtimestamp(item.atime) except (ValueError, OSError, OverflowError): - log.misc.error("Invalid timestamp {}.".format(item.atime)) + log.misc.debug("Invalid timestamp {}.".format(item.atime)) continue # Skip items not on curr_date diff --git a/tests/unit/browser/test_qutehistory.py b/tests/unit/browser/test_qutehistory.py new file mode 100644 index 000000000..43df79d26 --- /dev/null +++ b/tests/unit/browser/test_qutehistory.py @@ -0,0 +1,95 @@ +# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et: + +# Copyright 2017 Imran Sobir +# +# 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 . + +from PyQt5.QtCore import QUrl +from qutebrowser.browser import history, qutescheme +from qutebrowser.utils import objreg +import datetime +import pytest +import tempfile + + +class TestHistoryHandler: + """Test the qute://history endpoint.""" + + @pytest.fixture(autouse=True) + def fake_objects(self, fake_save_manager): + """ Create fake web-history with history for three different days """ + temp_dir = tempfile.TemporaryDirectory() + fake_web_history = history.WebHistory(temp_dir.name, 'fake-history') + objreg.register('web-history', fake_web_history, update=True) + objreg.register('save-manager', fake_save_manager, update=True) + + # Add fake history items for different days + one_day = datetime.timedelta(days=1) + self.curr_date = datetime.datetime.today() + self.next_date = self.curr_date + one_day + self.prev_date = self.curr_date - one_day + + today = history.Entry(atime=str(self.curr_date.timestamp()), + url=QUrl('www.today.com'), title='today') + tomorrow = history.Entry(atime=str(self.next_date.timestamp()), + url=QUrl('www.tomorrow.com'), title='tomorrow') + yesterday = history.Entry(atime=str(self.prev_date.timestamp()), + url=QUrl('www.yesterday.com'), title='yesterday') + + web_history = objreg.get('web-history') + web_history._add_entry(today) + web_history._add_entry(tomorrow) + web_history._add_entry(yesterday) + web_history.save() + + def test_history_without_query(self): + """ Test qute://history shows today's history when it has no query """ + _mimetype, data = qutescheme.qute_history(QUrl("qute://history")) + key = "{}".format( + datetime.date.today().strftime("%a, %d %B %Y")) + assert key in data + + def test_history_with_bad_query(self): + """ Test qute://history shows today's history when given bad query """ + url = QUrl("qute://history?date=204-blaah") + _mimetype, data = qutescheme.qute_history(url) + key = "{}".format( + datetime.date.today().strftime("%a, %d %B %Y")) + assert key in data + + def test_history_today(self): + """ Test qute://history shows history for today """ + url = QUrl("qute://history") + _mimetype, data = qutescheme.qute_history(url) + assert "today" in data + assert "tomorrow" not in data + assert "yesterday" not in data + + def test_history_yesterday(self): + """ Test qute://history shows history for yesterday """ + url = QUrl("qute://history?date=" + self.prev_date.strftime("%Y-%m-%d")) + _mimetype, data = qutescheme.qute_history(url) + assert "today" not in data + assert "tomorrow" not in data + assert "yesterday" in data + + def test_history_tomorrow(self): + """ Test qute://history shows history for tomorrow """ + url = QUrl("qute://history?date=" + self.next_date.strftime("%Y-%m-%d")) + _mimetype, data = qutescheme.qute_history(url) + assert "today" not in data + assert "tomorrow" in data + assert "yesterday" not in data From 0ab7fd45816f76077c452aeb0bcf4d6e1439538b Mon Sep 17 00:00:00 2001 From: Imran Sobir Date: Wed, 8 Feb 2017 16:18:33 +0500 Subject: [PATCH 09/24] Restore original save-manager, web-history at end of test. --- tests/unit/browser/test_qutehistory.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/unit/browser/test_qutehistory.py b/tests/unit/browser/test_qutehistory.py index 43df79d26..67c9a05f8 100644 --- a/tests/unit/browser/test_qutehistory.py +++ b/tests/unit/browser/test_qutehistory.py @@ -31,6 +31,16 @@ class TestHistoryHandler: @pytest.fixture(autouse=True) def fake_objects(self, fake_save_manager): """ Create fake web-history with history for three different days """ + try: + original_save_manager = objreg.get('save-manager') + except KeyError: + original_save_manager = None + + try: + original_web_history = objreg.get('web-history') + except KeyError: + original_web_history = None + temp_dir = tempfile.TemporaryDirectory() fake_web_history = history.WebHistory(temp_dir.name, 'fake-history') objreg.register('web-history', fake_web_history, update=True) @@ -55,6 +65,18 @@ class TestHistoryHandler: web_history._add_entry(yesterday) web_history.save() + yield + + if original_save_manager: + objreg.register('save-manager', original_save_manager, update=True) + else: + objreg.delete('save-manager') + + if original_web_history: + objreg.register('web-history', original_web_history, update=True) + else: + objreg.delete('web-history') + def test_history_without_query(self): """ Test qute://history shows today's history when it has no query """ _mimetype, data = qutescheme.qute_history(QUrl("qute://history")) From 828b0c00b5d3e4cb2dd716f08f0038bdda3a3507 Mon Sep 17 00:00:00 2001 From: Imran Sobir Date: Thu, 9 Feb 2017 15:39:50 +0500 Subject: [PATCH 10/24] Rename test_qutehistory.py to test_qutescheme.py. --- tests/unit/browser/{test_qutehistory.py => test_qutescheme.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/unit/browser/{test_qutehistory.py => test_qutescheme.py} (100%) diff --git a/tests/unit/browser/test_qutehistory.py b/tests/unit/browser/test_qutescheme.py similarity index 100% rename from tests/unit/browser/test_qutehistory.py rename to tests/unit/browser/test_qutescheme.py From 4eccfd5396f7ceef14059a919b8f02521834f6a5 Mon Sep 17 00:00:00 2001 From: Imran Sobir Date: Thu, 9 Feb 2017 15:44:51 +0500 Subject: [PATCH 11/24] Style fixes. --- tests/unit/browser/test_qutescheme.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/tests/unit/browser/test_qutescheme.py b/tests/unit/browser/test_qutescheme.py index 67c9a05f8..f97194415 100644 --- a/tests/unit/browser/test_qutescheme.py +++ b/tests/unit/browser/test_qutescheme.py @@ -17,20 +17,23 @@ # You should have received a copy of the GNU General Public License # along with qutebrowser. If not, see . +import datetime +import tempfile + from PyQt5.QtCore import QUrl +import pytest + from qutebrowser.browser import history, qutescheme from qutebrowser.utils import objreg -import datetime -import pytest -import tempfile class TestHistoryHandler: + """Test the qute://history endpoint.""" @pytest.fixture(autouse=True) def fake_objects(self, fake_save_manager): - """ Create fake web-history with history for three different days """ + """Create fake web-history with history for three different days.""" try: original_save_manager = objreg.get('save-manager') except KeyError: @@ -78,14 +81,14 @@ class TestHistoryHandler: objreg.delete('web-history') def test_history_without_query(self): - """ Test qute://history shows today's history when it has no query """ + """Ensure qute://history shows today's history when it has no query.""" _mimetype, data = qutescheme.qute_history(QUrl("qute://history")) key = "{}".format( datetime.date.today().strftime("%a, %d %B %Y")) assert key in data def test_history_with_bad_query(self): - """ Test qute://history shows today's history when given bad query """ + """Ensure qute://history shows today's history when given bad query.""" url = QUrl("qute://history?date=204-blaah") _mimetype, data = qutescheme.qute_history(url) key = "{}".format( @@ -93,7 +96,7 @@ class TestHistoryHandler: assert key in data def test_history_today(self): - """ Test qute://history shows history for today """ + """Ensure qute://history shows history for today.""" url = QUrl("qute://history") _mimetype, data = qutescheme.qute_history(url) assert "today" in data @@ -101,7 +104,7 @@ class TestHistoryHandler: assert "yesterday" not in data def test_history_yesterday(self): - """ Test qute://history shows history for yesterday """ + """Ensure qute://history shows history for yesterday.""" url = QUrl("qute://history?date=" + self.prev_date.strftime("%Y-%m-%d")) _mimetype, data = qutescheme.qute_history(url) assert "today" not in data @@ -109,7 +112,7 @@ class TestHistoryHandler: assert "yesterday" in data def test_history_tomorrow(self): - """ Test qute://history shows history for tomorrow """ + """Ensure qute://history shows history for tomorrow.""" url = QUrl("qute://history?date=" + self.next_date.strftime("%Y-%m-%d")) _mimetype, data = qutescheme.qute_history(url) assert "today" not in data From 49271b7ce1328da15c1785f82ac46c2b27a71bc7 Mon Sep 17 00:00:00 2001 From: Imran Sobir Date: Thu, 9 Feb 2017 16:32:59 +0500 Subject: [PATCH 12/24] Generate and cleanup fake web-history in own fixture. --- tests/unit/browser/test_qutescheme.py | 49 +++++++++------------------ 1 file changed, 16 insertions(+), 33 deletions(-) diff --git a/tests/unit/browser/test_qutescheme.py b/tests/unit/browser/test_qutescheme.py index f97194415..c2b332a4a 100644 --- a/tests/unit/browser/test_qutescheme.py +++ b/tests/unit/browser/test_qutescheme.py @@ -31,25 +31,20 @@ class TestHistoryHandler: """Test the qute://history endpoint.""" - @pytest.fixture(autouse=True) - def fake_objects(self, fake_save_manager): - """Create fake web-history with history for three different days.""" - try: - original_save_manager = objreg.get('save-manager') - except KeyError: - original_save_manager = None - - try: - original_web_history = objreg.get('web-history') - except KeyError: - original_web_history = None - + @pytest.fixture + def fake_web_history(self, fake_save_manager): + """Create a fake web-history and register it into objreg.""" temp_dir = tempfile.TemporaryDirectory() fake_web_history = history.WebHistory(temp_dir.name, 'fake-history') - objreg.register('web-history', fake_web_history, update=True) - objreg.register('save-manager', fake_save_manager, update=True) + objreg.register('web-history', fake_web_history) - # Add fake history items for different days + yield fake_web_history + + objreg.delete('web-history') + + @pytest.fixture(autouse=True) + def generate_fake_history(self, fake_web_history): + """Create fake history for three different days.""" one_day = datetime.timedelta(days=1) self.curr_date = datetime.datetime.today() self.next_date = self.curr_date + one_day @@ -62,23 +57,11 @@ class TestHistoryHandler: yesterday = history.Entry(atime=str(self.prev_date.timestamp()), url=QUrl('www.yesterday.com'), title='yesterday') - web_history = objreg.get('web-history') - web_history._add_entry(today) - web_history._add_entry(tomorrow) - web_history._add_entry(yesterday) - web_history.save() - - yield - - if original_save_manager: - objreg.register('save-manager', original_save_manager, update=True) - else: - objreg.delete('save-manager') - - if original_web_history: - objreg.register('web-history', original_web_history, update=True) - else: - objreg.delete('web-history') + fake_web_history = objreg.get('web-history') + fake_web_history._add_entry(today) + fake_web_history._add_entry(tomorrow) + fake_web_history._add_entry(yesterday) + fake_web_history.save() def test_history_without_query(self): """Ensure qute://history shows today's history when it has no query.""" From 920fb8137716169070dcde7a80c51a1d17db954f Mon Sep 17 00:00:00 2001 From: Imran Sobir Date: Thu, 9 Feb 2017 16:39:21 +0500 Subject: [PATCH 13/24] Use pytest's tmpdir fixture. --- tests/unit/browser/test_qutescheme.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/unit/browser/test_qutescheme.py b/tests/unit/browser/test_qutescheme.py index c2b332a4a..08a3eaf1b 100644 --- a/tests/unit/browser/test_qutescheme.py +++ b/tests/unit/browser/test_qutescheme.py @@ -18,7 +18,6 @@ # along with qutebrowser. If not, see . import datetime -import tempfile from PyQt5.QtCore import QUrl import pytest @@ -32,10 +31,9 @@ class TestHistoryHandler: """Test the qute://history endpoint.""" @pytest.fixture - def fake_web_history(self, fake_save_manager): + def fake_web_history(self, fake_save_manager, tmpdir): """Create a fake web-history and register it into objreg.""" - temp_dir = tempfile.TemporaryDirectory() - fake_web_history = history.WebHistory(temp_dir.name, 'fake-history') + fake_web_history = history.WebHistory(tmpdir.dirname, 'fake-history') objreg.register('web-history', fake_web_history) yield fake_web_history From a15aa9eade99d74d4b47a8c473c331e13359322c Mon Sep 17 00:00:00 2001 From: Imran Sobir Date: Thu, 9 Feb 2017 17:18:57 +0500 Subject: [PATCH 14/24] Hide next links to future. --- qutebrowser/browser/qutescheme.py | 7 ++++--- qutebrowser/html/history.html | 8 +++++--- tests/unit/browser/test_qutescheme.py | 10 ++++++++++ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/qutebrowser/browser/qutescheme.py b/qutebrowser/browser/qutescheme.py index 1b51f405b..602dce336 100644 --- a/qutebrowser/browser/qutescheme.py +++ b/qutebrowser/browser/qutescheme.py @@ -207,9 +207,10 @@ def qute_history(url): html = jinja.render('history.html', title='History', history=history, - curr_date=curr_date.strftime("%a, %d %B %Y"), - next_date=next_date.strftime("%Y-%m-%d"), - prev_date=prev_date.strftime("%Y-%m-%d")) + curr_date=curr_date, + next_date=next_date, + prev_date=prev_date, + today=datetime.date.today()) return 'text/html', html diff --git a/qutebrowser/html/history.html b/qutebrowser/html/history.html index 35bb79b39..e117d7e80 100644 --- a/qutebrowser/html/history.html +++ b/qutebrowser/html/history.html @@ -70,7 +70,7 @@ tr:nth-child(odd) { {% block content %} -

Browsing history {{curr_date}}

+

Browsing history {{curr_date.strftime("%a, %d %B %Y")}}

@@ -83,7 +83,9 @@ tr:nth-child(odd) {
-Previous -Next +Previous +{% if today >= next_date %} +Next +{% endif %} {% endblock %} diff --git a/tests/unit/browser/test_qutescheme.py b/tests/unit/browser/test_qutescheme.py index 08a3eaf1b..5db896c83 100644 --- a/tests/unit/browser/test_qutescheme.py +++ b/tests/unit/browser/test_qutescheme.py @@ -99,3 +99,13 @@ class TestHistoryHandler: assert "today" not in data assert "tomorrow" in data assert "yesterday" not in data + + def test_no_next_link_to_future(self): + """Ensure there's no next link pointing to the future.""" + url = QUrl("qute://history") + _mimetype, data = qutescheme.qute_history(url) + assert "Next" not in data + + url = QUrl("qute://history?date=" + self.next_date.strftime("%Y-%m-%d")) + _mimetype, data = qutescheme.qute_history(url) + assert "Next" not in data From d21585f603a1728536fa2449b7d47270a2b86fb6 Mon Sep 17 00:00:00 2001 From: Imran Sobir Date: Thu, 9 Feb 2017 18:11:17 +0500 Subject: [PATCH 15/24] Add rel=prev, rel=next to pagination links. --- qutebrowser/html/history.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qutebrowser/html/history.html b/qutebrowser/html/history.html index e117d7e80..42c59efff 100644 --- a/qutebrowser/html/history.html +++ b/qutebrowser/html/history.html @@ -83,9 +83,9 @@ tr:nth-child(odd) { -Previous + {% if today >= next_date %} -Next + {% endif %} {% endblock %} From 100f90d9b3edd064ff4d14ee778b08e2971f2fe1 Mon Sep 17 00:00:00 2001 From: Imran Sobir Date: Thu, 9 Feb 2017 18:28:10 +0500 Subject: [PATCH 16/24] Fix pylint errors. --- tests/unit/browser/test_qutescheme.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/tests/unit/browser/test_qutescheme.py b/tests/unit/browser/test_qutescheme.py index 5db896c83..eb1ffb182 100644 --- a/tests/unit/browser/test_qutescheme.py +++ b/tests/unit/browser/test_qutescheme.py @@ -43,6 +43,7 @@ class TestHistoryHandler: @pytest.fixture(autouse=True) def generate_fake_history(self, fake_web_history): """Create fake history for three different days.""" + # pylint: disable=attribute-defined-outside-init one_day = datetime.timedelta(days=1) self.curr_date = datetime.datetime.today() self.next_date = self.curr_date + one_day @@ -62,14 +63,14 @@ class TestHistoryHandler: fake_web_history.save() def test_history_without_query(self): - """Ensure qute://history shows today's history when it has no query.""" + """Ensure qute://history shows today's history without any query.""" _mimetype, data = qutescheme.qute_history(QUrl("qute://history")) key = "{}".format( datetime.date.today().strftime("%a, %d %B %Y")) assert key in data def test_history_with_bad_query(self): - """Ensure qute://history shows today's history when given bad query.""" + """Ensure qute://history shows today's history with bad query.""" url = QUrl("qute://history?date=204-blaah") _mimetype, data = qutescheme.qute_history(url) key = "{}".format( @@ -86,7 +87,8 @@ class TestHistoryHandler: def test_history_yesterday(self): """Ensure qute://history shows history for yesterday.""" - url = QUrl("qute://history?date=" + self.prev_date.strftime("%Y-%m-%d")) + url = QUrl("qute://history?date=" + + self.prev_date.strftime("%Y-%m-%d")) _mimetype, data = qutescheme.qute_history(url) assert "today" not in data assert "tomorrow" not in data @@ -94,7 +96,8 @@ class TestHistoryHandler: def test_history_tomorrow(self): """Ensure qute://history shows history for tomorrow.""" - url = QUrl("qute://history?date=" + self.next_date.strftime("%Y-%m-%d")) + url = QUrl("qute://history?date=" + + self.next_date.strftime("%Y-%m-%d")) _mimetype, data = qutescheme.qute_history(url) assert "today" not in data assert "tomorrow" in data @@ -106,6 +109,7 @@ class TestHistoryHandler: _mimetype, data = qutescheme.qute_history(url) assert "Next" not in data - url = QUrl("qute://history?date=" + self.next_date.strftime("%Y-%m-%d")) + url = QUrl("qute://history?date=" + + self.next_date.strftime("%Y-%m-%d")) _mimetype, data = qutescheme.qute_history(url) assert "Next" not in data From 9001ec079c8f8923daea0122eb35bd719892bc10 Mon Sep 17 00:00:00 2001 From: Imran Sobir Date: Thu, 9 Feb 2017 18:37:33 +0500 Subject: [PATCH 17/24] Align history time to the right. --- qutebrowser/html/history.html | 1 + 1 file changed, 1 insertion(+) diff --git a/qutebrowser/html/history.html b/qutebrowser/html/history.html index 42c59efff..4135fc627 100644 --- a/qutebrowser/html/history.html +++ b/qutebrowser/html/history.html @@ -32,6 +32,7 @@ td.title { td.time { color: #555; + text-align: right; white-space: nowrap; } From 46c02bf5ae2330cb9717f86d062e689b5509e2d0 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 9 Feb 2017 18:27:32 +0100 Subject: [PATCH 18/24] Refactor qute:history unittests --- tests/unit/browser/test_qutescheme.py | 64 +++++++++++++++------------ 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/tests/unit/browser/test_qutescheme.py b/tests/unit/browser/test_qutescheme.py index eb1ffb182..f210c2e56 100644 --- a/tests/unit/browser/test_qutescheme.py +++ b/tests/unit/browser/test_qutescheme.py @@ -18,6 +18,7 @@ # along with qutebrowser. If not, see . import datetime +import collections from PyQt5.QtCore import QUrl import pytest @@ -26,40 +27,45 @@ from qutebrowser.browser import history, qutescheme from qutebrowser.utils import objreg +Dates = collections.namedtuple('Dates', ['yesterday', 'today', 'tomorrow']) + + class TestHistoryHandler: """Test the qute://history endpoint.""" + @pytest.fixture + def dates(self): + one_day = datetime.timedelta(days=1) + today = datetime.datetime.today() + tomorrow = today + one_day + yesterday = today - one_day + return Dates(yesterday, today, tomorrow) + + @pytest.fixture + def entries(self, dates): + today = history.Entry(atime=str(dates.today.timestamp()), + url=QUrl('www.today.com'), title='today') + tomorrow = history.Entry(atime=str(dates.tomorrow.timestamp()), + url=QUrl('www.tomorrow.com'), title='tomorrow') + yesterday = history.Entry(atime=str(dates.yesterday.timestamp()), + url=QUrl('www.yesterday.com'), title='yesterday') + return Dates(yesterday, today, tomorrow) + @pytest.fixture def fake_web_history(self, fake_save_manager, tmpdir): """Create a fake web-history and register it into objreg.""" - fake_web_history = history.WebHistory(tmpdir.dirname, 'fake-history') - objreg.register('web-history', fake_web_history) - - yield fake_web_history - + web_history = history.WebHistory(tmpdir.dirname, 'fake-history') + objreg.register('web-history', web_history) + yield web_history objreg.delete('web-history') @pytest.fixture(autouse=True) - def generate_fake_history(self, fake_web_history): + def fake_history(self, fake_web_history, entries): """Create fake history for three different days.""" - # pylint: disable=attribute-defined-outside-init - one_day = datetime.timedelta(days=1) - self.curr_date = datetime.datetime.today() - self.next_date = self.curr_date + one_day - self.prev_date = self.curr_date - one_day - - today = history.Entry(atime=str(self.curr_date.timestamp()), - url=QUrl('www.today.com'), title='today') - tomorrow = history.Entry(atime=str(self.next_date.timestamp()), - url=QUrl('www.tomorrow.com'), title='tomorrow') - yesterday = history.Entry(atime=str(self.prev_date.timestamp()), - url=QUrl('www.yesterday.com'), title='yesterday') - - fake_web_history = objreg.get('web-history') - fake_web_history._add_entry(today) - fake_web_history._add_entry(tomorrow) - fake_web_history._add_entry(yesterday) + fake_web_history._add_entry(entries.yesterday) + fake_web_history._add_entry(entries.today) + fake_web_history._add_entry(entries.tomorrow) fake_web_history.save() def test_history_without_query(self): @@ -85,31 +91,31 @@ class TestHistoryHandler: assert "tomorrow" not in data assert "yesterday" not in data - def test_history_yesterday(self): + def test_history_yesterday(self, dates): """Ensure qute://history shows history for yesterday.""" url = QUrl("qute://history?date=" + - self.prev_date.strftime("%Y-%m-%d")) + dates.yesterday.strftime("%Y-%m-%d")) _mimetype, data = qutescheme.qute_history(url) assert "today" not in data assert "tomorrow" not in data assert "yesterday" in data - def test_history_tomorrow(self): + def test_history_tomorrow(self, dates): """Ensure qute://history shows history for tomorrow.""" url = QUrl("qute://history?date=" + - self.next_date.strftime("%Y-%m-%d")) + dates.tomorrow.strftime("%Y-%m-%d")) _mimetype, data = qutescheme.qute_history(url) assert "today" not in data assert "tomorrow" in data assert "yesterday" not in data - def test_no_next_link_to_future(self): + def test_no_next_link_to_future(self, dates): """Ensure there's no next link pointing to the future.""" url = QUrl("qute://history") _mimetype, data = qutescheme.qute_history(url) assert "Next" not in data url = QUrl("qute://history?date=" + - self.next_date.strftime("%Y-%m-%d")) + dates.tomorrow.strftime("%Y-%m-%d")) _mimetype, data = qutescheme.qute_history(url) assert "Next" not in data From f063d4be6fcb0ac7cc9e5590321414efd063b43d Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 9 Feb 2017 21:56:06 +0100 Subject: [PATCH 19/24] Add a benchmark for qute:history --- misc/requirements/requirements-tests.txt | 1 + misc/requirements/requirements-tests.txt-raw | 1 + tests/unit/browser/test_qutescheme.py | 18 ++++++++++++++++++ 3 files changed, 20 insertions(+) diff --git a/misc/requirements/requirements-tests.txt b/misc/requirements/requirements-tests.txt index 1fb75ae0c..703faa2ec 100644 --- a/misc/requirements/requirements-tests.txt +++ b/misc/requirements/requirements-tests.txt @@ -19,6 +19,7 @@ parse-type==0.3.4 py==1.4.32 pytest==3.0.6 pytest-bdd==2.18.1 +pytest-benchmark==3.0.0 pytest-catchlog==1.2.2 pytest-cov==2.4.0 pytest-faulthandler==1.3.1 diff --git a/misc/requirements/requirements-tests.txt-raw b/misc/requirements/requirements-tests.txt-raw index 619095ad8..d0f3bec52 100644 --- a/misc/requirements/requirements-tests.txt-raw +++ b/misc/requirements/requirements-tests.txt-raw @@ -6,6 +6,7 @@ httpbin hypothesis pytest pytest-bdd +pytest-benchmark pytest-catchlog pytest-cov pytest-faulthandler diff --git a/tests/unit/browser/test_qutescheme.py b/tests/unit/browser/test_qutescheme.py index f210c2e56..5ceecb7f8 100644 --- a/tests/unit/browser/test_qutescheme.py +++ b/tests/unit/browser/test_qutescheme.py @@ -119,3 +119,21 @@ class TestHistoryHandler: dates.tomorrow.strftime("%Y-%m-%d")) _mimetype, data = qutescheme.qute_history(url) assert "Next" not in data + + def test_qute_history_benchmark(self, dates, entries, fake_web_history, + benchmark): + for i in range(100000): + entry = history.Entry( + atime=str(dates.yesterday.timestamp()), + url=QUrl('www.yesterday.com/{}'.format(i)), + title='yesterday') + fake_web_history._add_entry(entry) + fake_web_history._add_entry(entries.today) + fake_web_history._add_entry(entries.tomorrow) + + url = QUrl("qute://history") + _mimetype, data = benchmark(qutescheme.qute_history, url) + + assert "today" in data + assert "tomorrow" not in data + assert "yesterday" not in data From 46752a2c24d2a27ea0a9b627d18de6a4c1cd4c71 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 9 Feb 2017 21:56:25 +0100 Subject: [PATCH 20/24] Add some performance improvements for qute:history --- qutebrowser/browser/qutescheme.py | 35 ++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/qutebrowser/browser/qutescheme.py b/qutebrowser/browser/qutescheme.py index 602dce336..da4cbfff4 100644 --- a/qutebrowser/browser/qutescheme.py +++ b/qutebrowser/browser/qutescheme.py @@ -24,6 +24,8 @@ Module attributes: _HANDLERS: The handlers registered via decorators. """ +import sys +import time import datetime import urllib.parse @@ -178,8 +180,20 @@ def qute_history(url): next_date = curr_date + one_day prev_date = curr_date - one_day - def history_iter(): - for item in objreg.get('web-history').history_dict.values(): + def history_iter(reverse): + today_timestamp = time.mktime(datetime.date.today().timetuple()) + history = objreg.get('web-history').history_dict.values() + if reverse: + history = reversed(history) + + for item in history: + # If we can't apply the reverse performance trick below, + # at least continue as early as possible with old items. + # This gets us down from 550ms to 123ms with 500k old items on my + # machine. + if item.atime < today_timestamp and not reverse: + continue + # Convert timestamp try: item_atime = datetime.datetime.fromtimestamp(item.atime) @@ -187,6 +201,12 @@ def qute_history(url): log.misc.debug("Invalid timestamp {}.".format(item.atime)) continue + if reverse and item_atime.date() < curr_date: + # If we could reverse the history in-place, and this entry is + # older than today, only older entries will follow, so we can + # abort here. + return + # Skip items not on curr_date # Skip redirects # Skip qute:// links @@ -202,7 +222,16 @@ def qute_history(url): yield (item_url, item_title, display_atime) - history = reversed(list(history_iter())) + if sys.hexversion >= 0x03050000: + # On Python >= 3.5 we can reverse the ordereddict in-place and thus + # apply an additional performance improvement in history_iter. + # On my machine, this gets us down from 550ms to 72us with 500k old + # items. + history = list(history_iter(reverse=True)) + else: + # On Python 3.4, we can't do that, so we'd need to copy the entire + # history to a list. There, filter first and then reverse it here. + history = reversed(list(history_iter(reverse=False))) html = jinja.render('history.html', title='History', From 37c3b79b9b17e39c064c9fac18aa78411d37da23 Mon Sep 17 00:00:00 2001 From: Imran Sobir Date: Fri, 10 Feb 2017 17:47:20 +0500 Subject: [PATCH 21/24] Add :history command. --- qutebrowser/browser/commands.py | 13 +++++++++++++ tests/end2end/features/misc.feature | 18 ++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index 95dd0e4f2..342cc7a2c 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -1396,6 +1396,19 @@ class CommandDispatcher: tab.dump_async(callback, plain=plain) + @cmdutils.register(instance='command-dispatcher', name='history', + scope='window') + def show_history(self, tab=True, bg=False, window=False): + r"""Show browsing history + + Args: + tab: Open in a new tab. + bg: Open in a background tab. + window: Open in a new window. + """ + url = QUrl('qute://history/') + self._open(url, tab, bg, window) + @cmdutils.register(instance='command-dispatcher', name='help', scope='window') @cmdutils.argument('topic', completion=usertypes.Completion.helptopic) diff --git a/tests/end2end/features/misc.feature b/tests/end2end/features/misc.feature index 168ea98ca..ca45055b5 100644 --- a/tests/end2end/features/misc.feature +++ b/tests/end2end/features/misc.feature @@ -290,6 +290,24 @@ Feature: Various utility commands. - about:blank - qute://help/index.html (active) + # :history + + Scenario: :history without arguments + When I run :tab-only + And I run :history + And I wait until qute://history/ is loaded + Then the following tabs should be open: + - qute://history/ (active) + + Scenario: :history with -t + When I open about:blank + And I run :tab-only + And I run :history -t + And I wait until qute://history/ is loaded + Then the following tabs should be open: + - about:blank + - qute://history/ (active) + # :home Scenario: :home with single page From b15ae974447efc5f202911c0baa4ada2cd05b212 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sat, 11 Feb 2017 16:59:51 +0100 Subject: [PATCH 22/24] Get timestamp of curr_date instead of today --- qutebrowser/browser/qutescheme.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qutebrowser/browser/qutescheme.py b/qutebrowser/browser/qutescheme.py index da4cbfff4..d06f2ddf9 100644 --- a/qutebrowser/browser/qutescheme.py +++ b/qutebrowser/browser/qutescheme.py @@ -181,7 +181,7 @@ def qute_history(url): prev_date = curr_date - one_day def history_iter(reverse): - today_timestamp = time.mktime(datetime.date.today().timetuple()) + curr_timestamp = time.mktime(curr_date.timetuple()) history = objreg.get('web-history').history_dict.values() if reverse: history = reversed(history) @@ -191,7 +191,7 @@ def qute_history(url): # at least continue as early as possible with old items. # This gets us down from 550ms to 123ms with 500k old items on my # machine. - if item.atime < today_timestamp and not reverse: + if item.atime < curr_timestamp and not reverse: continue # Convert timestamp From 9c712929f508aca006aeae8a8b68910650506e89 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sat, 11 Feb 2017 17:08:09 +0100 Subject: [PATCH 23/24] Update docs --- CHANGELOG.asciidoc | 1 + README.asciidoc | 1 + doc/help/commands.asciidoc | 12 ++++++++++++ 3 files changed, 14 insertions(+) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index ff1a4aa52..df0b28ad9 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -31,6 +31,7 @@ Added - Support for the HTML5 fullscreen API (e.g. youtube videos) with QtWebEngine - Support for the `general -> print-element-backgrounds` option with QtWebEngine on Qt >= 5.8 - Support for `:download --mhtml` with QtWebEngine +- New `qute:history` URL and `:history` command to show the browsing history. Changed ~~~~~~~ diff --git a/README.asciidoc b/README.asciidoc index d25d02a61..dc3b427df 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -169,6 +169,7 @@ Contributors, sorted by the number of commits in descending order: * Artur Shaik * Nathan Isom * Thorsten Wißmann +* Imran Sobir * Austin Anderson * Fritz Reichwald * Jimmy diff --git a/doc/help/commands.asciidoc b/doc/help/commands.asciidoc index 03345ac64..0731ea381 100644 --- a/doc/help/commands.asciidoc +++ b/doc/help/commands.asciidoc @@ -44,6 +44,7 @@ It is possible to run or bind multiple commands by separating them with `;;`. |<>|Toggle fullscreen mode. |<>|Show help about a command or setting. |<>|Start hinting. +|<>|Show browsing history |<>|Clear all browsing history. |<>|Open main startpage in current tab. |<>|Insert text at cursor position. @@ -418,6 +419,17 @@ Start hinting. ==== note * This command does not split arguments after the last argument and handles quotes literally. +[[history]] +=== history +Syntax: +:history [*--tab*] [*--bg*] [*--window*]+ + +Show browsing history + +==== optional arguments +* +*-t*+, +*--tab*+: Open in a new tab. +* +*-b*+, +*--bg*+: Open in a background tab. +* +*-w*+, +*--window*+: Open in a new window. + [[history-clear]] === history-clear Syntax: +:history-clear [*--force*]+ From 66cbb8aa318bd7399cab6b0886887e454610b4f6 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sat, 11 Feb 2017 17:22:35 +0100 Subject: [PATCH 24/24] Fix lint --- qutebrowser/browser/commands.py | 7 +++---- qutebrowser/browser/qutescheme.py | 3 ++- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index 489627387..5013d6730 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -1408,10 +1408,9 @@ class CommandDispatcher: tab.dump_async(callback, plain=plain) - @cmdutils.register(instance='command-dispatcher', name='history', - scope='window') - def show_history(self, tab=True, bg=False, window=False): - r"""Show browsing history + @cmdutils.register(instance='command-dispatcher', scope='window') + def history(self, tab=True, bg=False, window=False): + """Show browsing history. Args: tab: Open in a new tab. diff --git a/qutebrowser/browser/qutescheme.py b/qutebrowser/browser/qutescheme.py index d06f2ddf9..ac2abb7e4 100644 --- a/qutebrowser/browser/qutescheme.py +++ b/qutebrowser/browser/qutescheme.py @@ -163,7 +163,7 @@ def qute_bookmarks(_url): return 'text/html', html -@add_handler('history') +@add_handler('history') # noqa def qute_history(url): """Handler for qute:history. Display history.""" # Get current date from query parameter, if not given choose today. @@ -181,6 +181,7 @@ def qute_history(url): prev_date = curr_date - one_day def history_iter(reverse): + """Iterate through the history and get the items we're interested in.""" curr_timestamp = time.mktime(curr_date.timetuple()) history = objreg.get('web-history').history_dict.values() if reverse: