2015-01-12 00:28:06 -08:00
|
|
|
from pywb.utils.timeutils import timestamp_to_datetime, timestamp_to_sec
|
2014-03-02 21:42:05 -08:00
|
|
|
from pywb.framework.wbrequestresponse import WbResponse
|
2014-03-24 14:00:06 -07:00
|
|
|
from pywb.framework.memento import make_timemap, LINK_FORMAT
|
2014-02-12 13:16:07 -08:00
|
|
|
|
2014-02-09 01:42:42 -08:00
|
|
|
import urlparse
|
2015-01-26 09:52:04 -08:00
|
|
|
import urllib
|
2014-03-23 12:44:28 -07:00
|
|
|
import logging
|
2014-01-28 16:41:19 -08:00
|
|
|
|
2014-01-28 22:03:01 -08:00
|
|
|
from os import path
|
2014-01-28 16:41:19 -08:00
|
|
|
from itertools import imap
|
2014-10-16 20:33:17 -07:00
|
|
|
from jinja2 import Environment
|
|
|
|
from jinja2 import FileSystemLoader, PackageLoader, ChoiceLoader
|
2014-01-28 16:41:19 -08:00
|
|
|
|
|
|
|
|
2014-03-28 10:57:55 -07:00
|
|
|
FILTERS = {}
|
|
|
|
|
|
|
|
|
|
|
|
#=================================================================
|
|
|
|
class template_filter(object):
|
|
|
|
"""
|
|
|
|
Decorator for registering a function as a jinja2 filter
|
|
|
|
If optional argument is supplied, it is used as the filter name
|
|
|
|
Otherwise, the func name is the filter name
|
|
|
|
"""
|
|
|
|
def __init__(self, param=None):
|
2015-01-11 23:02:48 -08:00
|
|
|
self.name = param
|
2014-03-28 10:57:55 -07:00
|
|
|
|
|
|
|
def __call__(self, func):
|
|
|
|
name = self.name
|
|
|
|
if not name:
|
|
|
|
name = func.__name__
|
|
|
|
|
|
|
|
FILTERS[name] = func
|
|
|
|
return func
|
|
|
|
|
|
|
|
|
|
|
|
#=================================================================
|
|
|
|
# Filters
|
2015-01-11 23:02:48 -08:00
|
|
|
@template_filter()
|
2014-03-28 10:57:55 -07:00
|
|
|
def format_ts(value, format_='%a, %b %d %Y %H:%M:%S'):
|
2015-01-10 20:59:23 -08:00
|
|
|
if format_ == '%s':
|
2015-01-12 00:28:06 -08:00
|
|
|
return timestamp_to_sec(value)
|
2015-01-10 20:59:23 -08:00
|
|
|
else:
|
2015-01-12 00:28:06 -08:00
|
|
|
value = timestamp_to_datetime(value)
|
2015-01-10 20:59:23 -08:00
|
|
|
return value.strftime(format_)
|
2014-03-28 10:57:55 -07:00
|
|
|
|
|
|
|
|
2014-04-27 01:04:20 -07:00
|
|
|
@template_filter('urlsplit')
|
|
|
|
def get_urlsplit(url):
|
|
|
|
split = urlparse.urlsplit(url)
|
|
|
|
return split
|
2014-03-28 10:57:55 -07:00
|
|
|
|
|
|
|
|
2014-04-03 08:56:18 -07:00
|
|
|
@template_filter()
|
|
|
|
def is_wb_handler(obj):
|
|
|
|
if not hasattr(obj, 'handler'):
|
|
|
|
return False
|
|
|
|
|
2014-07-21 21:25:10 -07:00
|
|
|
return obj.handler.__class__.__name__ == "WBHandler"
|
2014-04-03 08:56:18 -07:00
|
|
|
|
|
|
|
|
2014-01-28 16:41:19 -08:00
|
|
|
#=================================================================
|
2014-05-01 11:58:34 -07:00
|
|
|
class J2TemplateView(object):
|
2014-04-13 18:17:31 -07:00
|
|
|
env_globals = {'static_path': 'static/default',
|
2015-01-19 21:54:11 -05:00
|
|
|
'packages': ['pywb']}
|
2014-04-04 12:20:54 -07:00
|
|
|
|
2014-01-31 10:04:21 -08:00
|
|
|
def __init__(self, filename):
|
2014-01-28 22:03:01 -08:00
|
|
|
template_dir, template_file = path.split(filename)
|
2014-01-28 16:41:19 -08:00
|
|
|
self.template_file = template_file
|
|
|
|
|
2014-01-31 10:04:21 -08:00
|
|
|
self.jinja_env = self.make_jinja_env(template_dir)
|
|
|
|
|
|
|
|
def make_jinja_env(self, template_dir):
|
2014-10-17 09:24:16 -07:00
|
|
|
loaders = self._make_loaders(template_dir)
|
2014-10-17 08:28:06 -07:00
|
|
|
loader = ChoiceLoader(loaders)
|
2014-10-21 19:06:16 -07:00
|
|
|
|
2014-03-23 12:44:28 -07:00
|
|
|
jinja_env = Environment(loader=loader, trim_blocks=True)
|
2014-03-28 10:57:55 -07:00
|
|
|
jinja_env.filters.update(FILTERS)
|
2014-04-04 12:20:54 -07:00
|
|
|
jinja_env.globals.update(self.env_globals)
|
2014-01-31 10:04:21 -08:00
|
|
|
return jinja_env
|
2014-01-28 16:41:19 -08:00
|
|
|
|
2014-10-17 09:24:16 -07:00
|
|
|
def _make_loaders(self, template_dir):
|
|
|
|
loaders = []
|
|
|
|
loaders.append(FileSystemLoader(template_dir))
|
2014-10-18 11:21:07 -07:00
|
|
|
# add relative and absolute path loaders for banner support
|
|
|
|
loaders.append(FileSystemLoader('.'))
|
|
|
|
loaders.append(FileSystemLoader('/'))
|
2015-01-19 21:54:11 -05:00
|
|
|
|
|
|
|
# add loaders for all specified packages
|
|
|
|
for package in self.env_globals['packages']:
|
|
|
|
loaders.append(PackageLoader(package,
|
|
|
|
template_dir))
|
2014-10-17 09:24:16 -07:00
|
|
|
return loaders
|
|
|
|
|
2014-01-31 10:04:21 -08:00
|
|
|
def render_to_string(self, **kwargs):
|
2014-01-28 16:41:19 -08:00
|
|
|
template = self.jinja_env.get_template(self.template_file)
|
|
|
|
|
2014-01-31 10:04:21 -08:00
|
|
|
template_result = template.render(**kwargs)
|
2014-01-28 16:41:19 -08:00
|
|
|
|
2014-01-31 10:04:21 -08:00
|
|
|
return template_result
|
2014-01-28 16:41:19 -08:00
|
|
|
|
2014-01-31 10:04:21 -08:00
|
|
|
def render_response(self, **kwargs):
|
|
|
|
template_result = self.render_to_string(**kwargs)
|
2014-01-31 19:45:01 -08:00
|
|
|
status = kwargs.get('status', '200 OK')
|
2014-06-27 19:03:06 -07:00
|
|
|
content_type = kwargs.get('content_type', 'text/html; charset=utf-8')
|
2014-04-30 21:16:05 -07:00
|
|
|
return WbResponse.text_response(template_result.encode('utf-8'),
|
2014-03-23 12:44:28 -07:00
|
|
|
status=status,
|
|
|
|
content_type=content_type)
|
2014-01-28 16:41:19 -08:00
|
|
|
|
2014-04-09 10:01:44 -07:00
|
|
|
@staticmethod
|
|
|
|
def create_template(filename, desc='', view_class=None):
|
2014-04-19 12:04:43 -07:00
|
|
|
if not filename:
|
|
|
|
return None
|
|
|
|
|
2014-04-09 10:01:44 -07:00
|
|
|
if not view_class:
|
|
|
|
view_class = J2TemplateView
|
|
|
|
|
|
|
|
logging.debug('Adding {0}: {1}'.format(desc, filename))
|
|
|
|
return view_class(filename)
|
|
|
|
|
2014-01-28 20:18:47 -08:00
|
|
|
|
2014-04-04 12:20:54 -07:00
|
|
|
#=================================================================
|
|
|
|
def add_env_globals(glb):
|
|
|
|
J2TemplateView.env_globals.update(glb)
|
|
|
|
|
|
|
|
|
2014-01-31 10:04:21 -08:00
|
|
|
#=================================================================
|
2014-04-09 10:01:44 -07:00
|
|
|
class HeadInsertView(J2TemplateView):
|
2014-07-29 12:20:22 -07:00
|
|
|
def create_insert_func(self, wbrequest,
|
|
|
|
include_ts=True):
|
2014-04-09 10:57:43 -07:00
|
|
|
|
2015-02-14 20:55:36 -08:00
|
|
|
url = wbrequest.wb_url.get_url()
|
2015-01-26 09:52:04 -08:00
|
|
|
|
2014-10-18 11:21:07 -07:00
|
|
|
top_url = wbrequest.wb_prefix
|
2015-02-14 20:55:36 -08:00
|
|
|
top_url += wbrequest.wb_url.to_str(mod=wbrequest.final_mod)
|
2014-10-18 11:21:07 -07:00
|
|
|
|
2014-07-29 12:20:22 -07:00
|
|
|
include_wombat = not wbrequest.wb_url.is_banner_only
|
2014-04-09 10:57:43 -07:00
|
|
|
|
2014-04-09 15:46:03 -07:00
|
|
|
def make_head_insert(rule, cdx):
|
2015-01-26 09:52:04 -08:00
|
|
|
cdx['url'] = url
|
2014-04-09 10:01:44 -07:00
|
|
|
return (self.render_to_string(wbrequest=wbrequest,
|
|
|
|
cdx=cdx,
|
2014-10-18 11:21:07 -07:00
|
|
|
top_url=top_url,
|
2014-04-13 18:17:31 -07:00
|
|
|
include_ts=include_ts,
|
2014-07-29 12:20:22 -07:00
|
|
|
include_wombat=include_wombat,
|
2014-10-17 08:28:06 -07:00
|
|
|
banner_html=self.banner_html,
|
2014-04-09 10:01:44 -07:00
|
|
|
rule=rule))
|
|
|
|
return make_head_insert
|
2014-03-23 12:44:28 -07:00
|
|
|
|
2014-08-04 01:18:46 -07:00
|
|
|
@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')
|
2014-10-17 08:28:06 -07:00
|
|
|
|
|
|
|
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
|
|
|
|
|
2014-08-04 01:18:46 -07:00
|
|
|
return view
|
|
|
|
|
2014-01-28 20:18:47 -08:00
|
|
|
|
|
|
|
#=================================================================
|
2014-03-24 14:00:06 -07:00
|
|
|
# query views
|
2014-01-31 10:04:21 -08:00
|
|
|
#=================================================================
|
2014-03-23 12:44:28 -07:00
|
|
|
class J2HtmlCapturesView(J2TemplateView):
|
2014-05-01 11:58:34 -07:00
|
|
|
def render_response(self, wbrequest, cdx_lines, **kwargs):
|
2015-01-26 09:52:04 -08:00
|
|
|
def format_cdx_lines():
|
|
|
|
for cdx in cdx_lines:
|
2015-02-14 20:55:36 -08:00
|
|
|
cdx['url'] = wbrequest.wb_url.get_url(url=cdx['original'])
|
2015-01-26 09:52:04 -08:00
|
|
|
yield cdx
|
|
|
|
|
2014-03-23 12:44:28 -07:00
|
|
|
return J2TemplateView.render_response(self,
|
2015-01-26 09:52:04 -08:00
|
|
|
cdx_lines=list(format_cdx_lines()),
|
2015-02-14 20:55:36 -08:00
|
|
|
url=wbrequest.wb_url.get_url(),
|
2014-03-28 10:57:55 -07:00
|
|
|
type=wbrequest.wb_url.type,
|
2014-05-01 11:58:34 -07:00
|
|
|
prefix=wbrequest.wb_prefix,
|
|
|
|
**kwargs)
|
2014-03-24 14:00:06 -07:00
|
|
|
|
2014-04-09 10:01:44 -07:00
|
|
|
@staticmethod
|
|
|
|
def create_template(filename, desc=''):
|
|
|
|
return J2TemplateView.create_template(filename, desc,
|
|
|
|
J2HtmlCapturesView)
|
|
|
|
|
2014-03-24 14:00:06 -07:00
|
|
|
|
|
|
|
#=================================================================
|
|
|
|
class MementoTimemapView(object):
|
2015-02-24 10:35:49 -08:00
|
|
|
def render_response(self, wbrequest, cdx_lines, **kwargs):
|
2014-03-24 14:00:06 -07:00
|
|
|
memento_lines = make_timemap(wbrequest, cdx_lines)
|
|
|
|
return WbResponse.text_stream(memento_lines,
|
|
|
|
content_type=LINK_FORMAT)
|