# coding: utf-8 """ weasyprint.navigator -------------------- A WeasyPrint-based web browser. In your web browser. :copyright: Copyright 2011-2014 Simon Sapin and contributors, see AUTHORS. :license: BSD, see LICENSE for details. """ # Do NOT import unicode_literals here. Raw WSGI requires native strings. from __future__ import division import os.path from wsgiref.simple_server import make_server from weasyprint import CSS, HTML from weasyprint.compat import base64_encode, iteritems, parse_qs from weasyprint.urls import url_is_absolute FAVICON = os.path.join(os.path.dirname(__file__), 'tests', 'resources', 'icon.png') STYLESHEET = CSS(string=''' :root { font-size: 10pt } ''') def get_pages(html): document = html.render(enable_hinting=True, stylesheets=[STYLESHEET]) for page in document.pages: png_bytes, width, height = document.copy([page]).write_png() data_url = 'data:image/png;base64,' + ( base64_encode(png_bytes).decode('ascii').replace('\n', '')) yield width, height, data_url, page.links, page.anchors def render_template(url): parts = ['''\ WeasyPrint Navigator
\n\n') if url: write('PDF\n') write('
\n') if url: for width, height, data_url, links, anchors in get_pages(html): write('
\n' ' \n'.format(width, height, data_url)) for link_type, target, (pos_x, pos_y, width, height) in links: href = ('#' + target if link_type == 'internal' else '/view/' + target) write(' \n' .format(pos_x, pos_y, width, height, href)) for anchor_name, (pos_x, pos_y) in iteritems(anchors): # Remove 60px to pos_y so that the real pos is below # the address bar. write(' \n' .format(pos_x, pos_y - 60, anchor_name)) write('
\n') else: write(''' ''') return ''.join(parts).encode('utf8') def normalize_url(url, query_string=None): if url: if query_string: url += '?' + query_string if not url_is_absolute(url): # Default to HTTP rather than relative filenames url = 'http://' + url return url def app(environ, start_response): def make_response(body, status='200 OK', headers=(), content_type='text/html; charset=UTF-8'): start_response(status, [ ('Content-Type', content_type), ('Content-Length', str(len(body))), ] + list(headers)) return [body] path = environ['PATH_INFO'] if path == '/favicon.ico': with open(FAVICON, 'rb') as fd: return make_response(fd.read(), content_type='image/x-icon') elif path.startswith('/pdf/') and len(path) > 5: # len('/pdf/') == 5 url = normalize_url(path[5:], environ.get('QUERY_STRING')) body = HTML(url=url).write_pdf(stylesheets=[STYLESHEET]) filename = url.rstrip('/').rsplit('/', 1)[-1] or 'out' return make_response( body, content_type='application/pdf', headers=[('Content-Disposition', 'attachment; filename=%s.pdf' % filename)]) elif path.startswith('/view/'): url = normalize_url(path[6:], environ.get('QUERY_STRING')) return make_response(render_template(url)) elif path == '/': args = parse_qs(environ.get('QUERY_STRING') or '') url = normalize_url(args.get('url', [''])[0]) return make_response(render_template(url)) return make_response(b'

Not Found

', status='404 Not Found') def run(port=5000): host = '127.0.0.1' server = make_server(host, port, app) print('Listening on http://%s:%s/ ...' % (host, port)) server.serve_forever() if __name__ == '__main__': run()