Merge commit 'be254be13a61171d4109224450db9e67d1076080' into imransobir/fix-webkit-history

This commit is contained in:
Florian Bruhin 2017-04-06 20:34:49 +02:00
commit 760dca475e
4 changed files with 135 additions and 35 deletions

View File

@ -24,6 +24,7 @@ Module attributes:
_HANDLERS: The handlers registered via decorators. _HANDLERS: The handlers registered via decorators.
""" """
from datetime import date, datetime, timedelta
import json import json
import os import os
import sys import sys
@ -35,7 +36,7 @@ from PyQt5.QtCore import QUrlQuery
import qutebrowser import qutebrowser
from qutebrowser.config import config from qutebrowser.config import config
from qutebrowser.utils import (version, utils, jinja, log, message, docutils, from qutebrowser.utils import (version, utils, jinja, log, message, docutils,
objreg) objreg, usertypes, qtutils)
from qutebrowser.misc import objects from qutebrowser.misc import objects
@ -165,26 +166,29 @@ def qute_bookmarks(_url):
return 'text/html', html return 'text/html', html
@add_handler('history') # noqa def history_data(start_time): # noqa
def qute_history(url): """Return history data
"""Handler for qute:history. Display and serve history."""
Arguments:
start_time -- select history starting from this timestamp.
"""
def history_iter(start_time, reverse=False): def history_iter(start_time, reverse=False):
"""Iterate through the history and get items we're interested. """Iterate through the history and get items we're interested.
Arguments: Arguments:
reverse -- whether to reverse the history_dict before iterating. reverse -- whether to reverse the history_dict before iterating.
start_time -- select history starting from this timestamp.
""" """
history = objreg.get('web-history').history_dict.values() history = objreg.get('web-history').history_dict.values()
if reverse: if reverse:
history = reversed(history) history = reversed(history)
end_time = start_time - 24*60*60 # end is 24hrs earlier than start
# when history_dict is not reversed, we need to keep track of last item # when history_dict is not reversed, we need to keep track of last item
# so that we can yield its atime # so that we can yield its atime
last_item = None last_item = None
# end is 24hrs earlier than start
end_time = start_time - 24*60*60
for item in history: for item in history:
# Skip redirects # Skip redirects
# Skip qute:// links # Skip qute:// links
@ -226,6 +230,23 @@ def qute_history(url):
# if we reached here, we had reached the end of history # if we reached here, we had reached the end of history
yield {"next": int(last_item.atime if last_item else -1)} yield {"next": int(last_item.atime if last_item else -1)}
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 = history_iter(start_time, 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(start_time, reverse=False)))
return list(history)
@add_handler('history')
def qute_history(url):
"""Handler for qute:history. Display and serve history."""
if url.path() == '/data': if url.path() == '/data':
# Use start_time in query or current time. # Use start_time in query or current time.
try: try:
@ -234,21 +255,55 @@ def qute_history(url):
except ValueError as e: except ValueError as e:
raise QuteSchemeError("Query parameter start_time is invalid", e) raise QuteSchemeError("Query parameter start_time is invalid", e)
if sys.hexversion >= 0x03050000: return 'text/html', json.dumps(history_data(start_time))
# 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 = history_iter(start_time, 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(start_time, reverse=False)))
return 'text/html', json.dumps(list(history))
else: else:
return 'text/html', jinja.render('history.html', title='History', try:
session_interval=config.get('ui', 'history-session-interval')) from PyQt5.QtWebKit import qWebKitVersion
is_webkit_ng = qtutils.is_qtwebkit_ng(qWebKitVersion())
except ImportError: # pragma: no cover
is_webkit_ng = False
if (
config.get('content', 'allow-javascript') and
(objects.backend == usertypes.Backend.QtWebEngine or is_webkit_ng)
):
return 'text/html', jinja.render(
'history.html',
title='History',
session_interval=config.get('ui', 'history-session-interval')
)
else:
# Get current date from query parameter, if not given choose today.
curr_date = date.today()
try:
query_date = QUrlQuery(url).queryItemValue("date")
if query_date:
curr_date = datetime.strptime(query_date,
"%Y-%m-%d").date()
except ValueError:
log.misc.debug("Invalid date passed to qute:history: " +
query_date)
one_day = timedelta(days=1)
next_date = curr_date + one_day
prev_date = curr_date - one_day
# start_time is the last second of curr_date
start_time = time.mktime(next_date.timetuple()) - 1
history = [
(i["url"], i["title"], datetime.fromtimestamp(i["time"]/1000))
for i in history_data(start_time) if "next" not in i
]
return 'text/html', jinja.render(
'history_nojs.html',
title='History',
history=history,
curr_date=curr_date,
next_date=next_date,
prev_date=prev_date,
today=date.today(),
)
@add_handler('javascript') @add_handler('javascript')

View File

@ -47,22 +47,9 @@ table {
text-align: center; text-align: center;
} }
.error {
background-color: #ffbbbb;
border-radius: 5px;
font-weight: bold;
padding: 10px;
text-align: center;
width: 100%;
border: 1px solid #ff7777;
}
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<h1>Browsing history</h1> <h1>Browsing history</h1>
<noscript>
<div class="error">Javascript is required to view this page.</div>
</noscript>
<div id="hist-container"></div> <div id="hist-container"></div>
<span id="eof" style="display: none">end</span> <span id="eof" style="display: none">end</span>
<a href="#" id="load" style="display: none">Show more</a> <a href="#" id="load" style="display: none">Show more</a>

View File

@ -0,0 +1,58 @@
{% extends "styled.html" %}
{% block style %}
{{super()}}
body {
max-width: 1440px;
}
td.title {
word-break: break-all;
}
td.time {
color: #555;
text-align: right;
white-space: nowrap;
}
table {
margin-bottom: 30px;
}
.date {
color: #555;
font-size: 12pt;
padding-bottom: 15px;
font-weight: bold;
text-align: left;
}
.pagination-link {
color: #555;
font-weight: bold;
margn-bottom: 15px;
text-decoration: none;
}
{% endblock %}
{% block content %}
<h1>Browsing history</h1>
<table>
<caption class="date">{{curr_date.strftime("%a, %d %B %Y")}}</caption>
<tbody>
{% for url, title, time in history %}
<tr>
<td class="title"><a href="{{url}}">{{title}}</a></td>
<td class="time">{{time.strftime("%X")}}</td>
</tr>
{% endfor %}
</tbody>
</table>
<span class="pagination-link"><a href="qute://history/?date={{prev_date.strftime("%Y-%m-%d")}}" rel="prev">Previous</a></span>
{% if today >= next_date %}
<span class="pagination-link"><a href="qute://history/?date={{next_date.strftime("%Y-%m-%d")}}" rel="next">Next</a></span>
{% endif %}
{% endblock %}

View File

@ -79,7 +79,7 @@ Feature: Page history
Scenario: Listing history Scenario: Listing history
When I open data/numbers/3.txt When I open data/numbers/3.txt
And I open data/numbers/4.txt And I open data/numbers/4.txt
And I open qute://history/data And I open qute://history
Then the page should contain the plaintext "3.txt" Then the page should contain the plaintext "3.txt"
Then the page should contain the plaintext "4.txt" Then the page should contain the plaintext "4.txt"