diff --git a/CHANGES.rst b/CHANGES.rst index 8dbb4ba3..f245db9b 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,12 @@ pywb 0.6.1 changelist ~~~~~~~~~~~~~~~~~~~~~ +* Easier to customize just the banner html, via `banner_html` setting in the config. Default banner uses ui/banner.html and inserts the script default_banner.js, which creates the banner. + + Other implementations may create banner via custom JS or directly insert HTML, as needed. Setting `banner_html: False` will disable the banner. + +* Small improvements to streaming response, read in fixed chunks to allow better streaming from live. + * New, implified notation for fuzzy match rules on query params (See: `Fuzzy Match Rules `_) diff --git a/config.yaml b/config.yaml index 2d8aee7f..de1610bd 100644 --- a/config.yaml +++ b/config.yaml @@ -73,6 +73,11 @@ enable_http_proxy: true # template for insert into replayed html content #head_insert_html: ui/head_insert.html +# +# +# template for just the banner modifications +# set to False to disable completely +#banner_html: banner.html # template to for 'calendar' query, # eg, a listing of captures in response to a ../*/ diff --git a/pywb/static/default_banner.js b/pywb/static/default_banner.js new file mode 100644 index 00000000..476c5a10 --- /dev/null +++ b/pywb/static/default_banner.js @@ -0,0 +1,65 @@ +/* +Copyright(c) 2013-2014 Ilya Kreymer. Released under the GNU General Public License. + +This file is part of pywb. + + pywb 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. + + pywb 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 pywb. If not, see . + +*/ + +// Creates the default pywb banner. +// Override this function/script to create a different type of banner + + +_wb_js.create_banner_element = function(banner_id) +{ + + var banner_labels = {LOADING_MSG: "Loading...", + REPLAY_MSG: "This is an archived page from ", + LIVE_MSG: "This is a live page loaded on "}; + + var banner = document.createElement("wb_div"); + banner.setAttribute("id", banner_id); + banner.setAttribute("lang", "en"); + + var text; + + if (wbinfo.is_frame) { + text = banner_labels.LOADING_MSG; + } else if (wbinfo.is_live) { + text = banner_labels.LIVE_MSG; + } else { + text = banner_labels.REPLAY_MSG; + } + + text = "" + text + ""; + + var capture_str = ""; + if (wbinfo && wbinfo.timestamp) { + capture_str = _wb_js.ts_to_date(wbinfo.timestamp, true); + } + + text += "" + capture_str + ""; + + if (wbinfo.proxy_magic && wbinfo.url) { + var select_url = wbinfo.proxy_magic + "/" + wbinfo.url; + var query_url = wbinfo.proxy_magic + "/*/" + wbinfo.url; + text += ' All Capture Times'; + text += '
' + text += 'From collection "' + wbinfo.coll + '" All Collections'; + } + + banner.innerHTML = text; + document.body.insertBefore(banner, document.body.firstChild); +} diff --git a/pywb/static/wb.js b/pywb/static/wb.js index 203f0b6c..22b3c746 100644 --- a/pywb/static/wb.js +++ b/pywb/static/wb.js @@ -17,12 +17,7 @@ This file is part of pywb. along with pywb. If not, see . */ -_wb_js = (function() { - - -var labels = {LOADING_MSG: "Loading...", - REPLAY_MSG: "This is an archived page from ", - LIVE_MSG: "This is a live page loaded on "}; +function __WbJsInit() { function init_banner() { @@ -40,49 +35,19 @@ function init_banner() { bid = PLAIN_BANNER_ID; } - var banner = document.getElementById(bid); - - if (banner) { + if (document.getElementById(bid) != null) { return; } - - banner = document.createElement("wb_div"); - banner.setAttribute("id", bid); - banner.setAttribute("lang", "en"); - - var text; - - if (wbinfo.is_frame) { - text = labels.LOADING_MSG; - } else if (wbinfo.is_live) { - text = labels.LIVE_MSG; - } else { - text = labels.REPLAY_MSG; - } - text = "" + text + ""; - - var capture_str = ""; - if (wbinfo && wbinfo.timestamp) { - capture_str = ts_to_date(wbinfo.timestamp, true); - } - - text += "" + capture_str + ""; - - if (wbinfo.proxy_magic && wbinfo.url) { - var select_url = wbinfo.proxy_magic + "/" + wbinfo.url; - var query_url = wbinfo.proxy_magic + "/*/" + wbinfo.url; - text += ' All Capture Times'; - text += '
' - text += 'From collection "' + wbinfo.coll + '" All Collections'; - } - - banner.innerHTML = text; - - document.body.insertBefore(banner, document.body.firstChild); + _wb_js.create_banner_element(bid); } -function ts_to_date(ts, is_gmt) +this.create_banner_element = function() { + // No banner by default + return null; +} + +this.ts_to_date = function(ts, is_gmt) { if (ts.length < 14) { return ts; @@ -147,22 +112,21 @@ function notify_top() { remove_event("readystatechange", notify_top, document); } -if ((window.self == window.top) && wbinfo) { - if (wbinfo.canon_url && (window.location.href != wbinfo.canon_url) && wbinfo.mod != "bn_") { - // Auto-redirect to top frame - window.location.replace(wbinfo.canon_url); - } else { - // Init Banner (no frame or top frame) - add_event("readystatechange", init_banner, document); +this.load = function() { + if ((window.self == window.top) && wbinfo) { + if (wbinfo.canon_url && (window.location.href != wbinfo.canon_url) && wbinfo.mod != "bn_") { + // Auto-redirect to top frame + window.location.replace(wbinfo.canon_url); + } else { + // Init Banner (no frame or top frame) + add_event("readystatechange", init_banner, document); + } + } else if (window.self != window.parent && window.parent.update_wb_url) { + add_event("readystatechange", notify_top, document); } -} else if (window.self != window.parent && window.parent.update_wb_url) { - add_event("readystatechange", notify_top, document); } +}; -return { - 'labels': labels, - 'ts_to_date': ts_to_date - }; -})(); +_wb_js = new __WbJsInit(); diff --git a/pywb/ui/banner.html b/pywb/ui/banner.html new file mode 100644 index 00000000..a63ee89f --- /dev/null +++ b/pywb/ui/banner.html @@ -0,0 +1,2 @@ + + diff --git a/pywb/ui/head_insert.html b/pywb/ui/head_insert.html index bb86c3d7..9bc84dc7 100644 --- a/pywb/ui/head_insert.html +++ b/pywb/ui/head_insert.html @@ -21,8 +21,15 @@ wbinfo.coll = "{{ wbrequest.coll }}"; wbinfo.proxy_magic = "{{ wbrequest.env.pywb_proxy_magic }}"; + + +{% include banner_html ignore missing %} + + + + diff --git a/pywb/webapp/pywb_init.py b/pywb/webapp/pywb_init.py index 7b225a48..7ecac1f9 100644 --- a/pywb/webapp/pywb_init.py +++ b/pywb/webapp/pywb_init.py @@ -29,6 +29,8 @@ DEFAULTS = { 'archive_paths': './sample_archive/warcs/', 'head_insert_html': 'ui/head_insert.html', + 'banner_html': 'banner.html', + 'query_html': 'ui/query.html', 'search_html': 'ui/search.html', 'home_html': 'ui/index.html', diff --git a/pywb/webapp/views.py b/pywb/webapp/views.py index a6250234..6560b8d0 100644 --- a/pywb/webapp/views.py +++ b/pywb/webapp/views.py @@ -72,15 +72,17 @@ class J2TemplateView(object): def __init__(self, filename): template_dir, template_file = path.split(filename) - self.template_file = template_file self.jinja_env = self.make_jinja_env(template_dir) def make_jinja_env(self, template_dir): - filesys_loader = FileSystemLoader(template_dir) - pkg_loader = PackageLoader(self.env_globals['package'], template_dir) - loader = ChoiceLoader([filesys_loader, pkg_loader]) + loaders = [] + loaders.append(FileSystemLoader(template_dir)) + loaders.append(FileSystemLoader('.')) + loaders.append(PackageLoader(self.env_globals['package'], template_dir)) + + loader = ChoiceLoader(loaders) jinja_env = Environment(loader=loader, trim_blocks=True) jinja_env.filters.update(FILTERS) @@ -133,20 +135,24 @@ class HeadInsertView(J2TemplateView): canon_url=canon_url, include_ts=include_ts, include_wombat=include_wombat, + banner_html=self.banner_html, rule=rule)) return make_head_insert - @staticmethod - def create_template(filename, desc=''): - return J2TemplateView.create_template(filename, desc, - HeadInsertView) - @staticmethod def init_from_config(config): view = config.get('head_insert_view') if not view: html = config.get('head_insert_html', 'ui/head_insert.html') - view = HeadInsertView.create_template(html, 'Head Insert') + + if html: + banner_html = config.get('banner_html', 'banner.html') + view = HeadInsertView(html) + logging.debug('Adding HeadInsert: {0}, Banner {1}'. + format(html, banner_html)) + + view.banner_html = banner_html + return view