| LEFT | RIGHT | 
|---|
| 1 # coding: utf-8 | 1 # coding: utf-8 | 
| 2 | 2 | 
| 3 # This file is part of the Adblock Plus web scripts, | 3 # This file is part of the Adblock Plus web scripts, | 
| 4 # Copyright (C) 2006-2015 Eyeo GmbH | 4 # Copyright (C) 2006-2015 Eyeo GmbH | 
| 5 # | 5 # | 
| 6 # Adblock Plus is free software: you can redistribute it and/or modify | 6 # Adblock Plus is free software: you can redistribute it and/or modify | 
| 7 # it under the terms of the GNU General Public License version 3 as | 7 # it under the terms of the GNU General Public License version 3 as | 
| 8 # published by the Free Software Foundation. | 8 # published by the Free Software Foundation. | 
| 9 # | 9 # | 
| 10 # Adblock Plus is distributed in the hope that it will be useful, | 10 # Adblock Plus is distributed in the hope that it will be useful, | 
| 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
| 13 # GNU General Public License for more details. | 13 # GNU General Public License for more details. | 
| 14 # | 14 # | 
| 15 # You should have received a copy of the GNU General Public License | 15 # You should have received a copy of the GNU General Public License | 
| 16 # along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. | 16 # along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. | 
| 17 | 17 | 
| 18 import sys, os, flask | 18 import mimetypes | 
|  | 19 import os | 
|  | 20 import sys | 
|  | 21 | 
|  | 22 import jinja2 | 
|  | 23 | 
| 19 from ..utils import process_page | 24 from ..utils import process_page | 
| 20 from ..sources import FileSource | 25 from ..sources import FileSource | 
| 21 from ..converters import converters | 26 from ..converters import converters | 
| 22 | 27 | 
| 23 source = None | 28 source = None | 
| 24 | 29 | 
| 25 mime_types = { | 30 UNICODE_ENCODING = "utf-8" | 
| 26   "": "text/html; charset=utf-8", | 31 | 
| 27   ".htm": "text/html; charset=utf-8", | 32 ERROR_TEMPLATE = """ | 
| 28   ".html": "text/html; charset=utf-8", | 33 <html> | 
| 29   ".js": "application/javascript; charset=utf-8", | 34   <head> | 
| 30   ".css": "text/css; charset=utf-8", | 35     <title>{{status}}</title> | 
| 31   ".xml": "text/xml; charset=utf-8", | 36   </head> | 
| 32   ".png": "image/png", | 37   <body> | 
| 33   ".jpg": "image/jpeg", | 38     <h1>{{status}}</h1> | 
| 34   ".jpeg": "image/jpeg", | 39     {% set code = status.split()|first|int %} | 
| 35 } | 40     {% if code == 404 %} | 
|  | 41       <p>No page found for the address {{uri}}.</p> | 
|  | 42     {% elif code == 500 %} | 
|  | 43       <p>An error occurred while processing the request for {{uri}}:</p> | 
|  | 44       <pre>{{error}}</pre> | 
|  | 45     {% endif %} | 
|  | 46   </body> | 
|  | 47 </html>""" | 
|  | 48 | 
|  | 49 # Create our own instance, the default one will introduce "random" host-specific | 
|  | 50 # behavior by parsing local config files. | 
|  | 51 mime_types = mimetypes.MimeTypes() | 
| 36 | 52 | 
| 37 def get_data(path): | 53 def get_data(path): | 
| 38   if source.has_static(path): | 54   if source.has_static(path): | 
| 39     return source.read_static(path) | 55     return source.read_static(path) | 
| 40 | 56 | 
| 41   path = path.strip("/") | 57   path = path.strip("/") | 
| 42   if path == "": | 58   if path == "": | 
| 43     path = source.read_config().get("general", "defaultlocale") | 59     path = source.read_config().get("general", "defaultlocale") | 
| 44   if "/" in path: | 60   if "/" in path: | 
| 45     locale, page = path.split("/", 1) | 61     locale, page = path.split("/", 1) | 
| 46   else: | 62   else: | 
| 47     locale, page = path, "" | 63     locale, page = path, "" | 
| 48 | 64 | 
| 49   default_page = source.read_config().get("general", "defaultpage") | 65   default_page = source.read_config().get("general", "defaultpage") | 
| 50   alternative_page = "/".join([page, default_page]).lstrip("/") | 66   alternative_page = "/".join([page, default_page]).lstrip("/") | 
| 51   for format in converters.iterkeys(): | 67   for format in converters.iterkeys(): | 
| 52     for p in (page, alternative_page): | 68     for p in (page, alternative_page): | 
| 53       if source.has_page(p, format): | 69       if source.has_page(p, format): | 
| 54         return process_page(source, locale, p, format, "http://127.0.0.1:5000").
     encode("utf-8") | 70         return process_page(source, locale, p, format, "http://127.0.0.1:5000") | 
| 55   if source.has_localizable_file(locale, page): | 71   if source.has_localizable_file(locale, page): | 
| 56     return source.read_localizable_file(locale, page) | 72     return source.read_localizable_file(locale, page) | 
| 57 | 73 | 
| 58   return None | 74   return None | 
| 59 | 75 | 
|  | 76 def show_error(start_response, status, **kwargs): | 
|  | 77   env = jinja2.Environment(autoescape=True) | 
|  | 78   template = env.from_string(ERROR_TEMPLATE) | 
|  | 79   mime = "text/html; encoding=%s" % UNICODE_ENCODING | 
|  | 80   start_response(status, [("Content-Type", mime)]) | 
|  | 81   for fragment in template.stream(status=status, **kwargs): | 
|  | 82     yield fragment.encode(UNICODE_ENCODING) | 
|  | 83 | 
| 60 def handler(environ, start_response): | 84 def handler(environ, start_response): | 
| 61   path = environ.get("REQUEST_URI") or environ.get("PATH_INFO") | 85   path = environ.get("PATH_INFO") | 
|  | 86 | 
| 62   data = get_data(path) | 87   data = get_data(path) | 
| 63   if data == None: | 88   if data == None: | 
| 64     flask.abort(404) | 89     return show_error(start_response, "404 Not Found", uri=path) | 
| 65 | 90 | 
| 66   root, ext = os.path.splitext(path) | 91   mime = mime_types.guess_type(path)[0] or "text/html" | 
| 67   mime = mime_types.get(ext.lower(), "application/octet-stream") |  | 
| 68 | 92 | 
| 69   if isinstance(data, unicode): | 93   if isinstance(data, unicode): | 
| 70     data = data.encode("utf-8") | 94     data = data.encode(UNICODE_ENCODING) | 
|  | 95     mime = "%s; charset=%s" % (mime, UNICODE_ENCODING) | 
| 71 | 96 | 
| 72   start_response("200 OK", [("Content-Type", mime)]) | 97   start_response("200 OK", [("Content-Type", mime)]) | 
| 73   return [data] | 98   return [data] | 
| 74 | 99 | 
| 75 if __name__ == "__main__": | 100 if __name__ == "__main__": | 
| 76   if len(sys.argv) < 2: | 101   if len(sys.argv) < 2: | 
| 77     print >>sys.stderr, "Usage: %s source_dir" % sys.argv[0] | 102     print >>sys.stderr, "Usage: %s source_dir" % sys.argv[0] | 
| 78     sys.exit(1) | 103     sys.exit(1) | 
| 79 | 104 | 
| 80   source = FileSource(sys.argv[1]) | 105   source = FileSource(sys.argv[1]) | 
| 81 | 106 | 
| 82   try: | 107   try: | 
| 83     from werkzeug.serving import run_simple | 108     from werkzeug.serving import run_simple | 
| 84   except ImportError: | 109   except ImportError: | 
| 85     from wsgiref.simple_server import make_server | 110     from wsgiref.simple_server import make_server | 
| 86     def run_simple(host, port, app, **kwargs): | 111     def run_simple(host, port, app, **kwargs): | 
| 87       server = make_server(host, port, app) | 112       def wrapper(environ, start_response): | 
|  | 113         try: | 
|  | 114           return app(environ, start_response) | 
|  | 115         except Exception, e: | 
|  | 116           return show_error(start_response, "500 Internal Server Error", | 
|  | 117               uri=environ.get("PATH_INFO"), error=e) | 
|  | 118 | 
|  | 119       server = make_server(host, port, wrapper) | 
| 88       print " * Running on http://%s:%i/" % server.server_address | 120       print " * Running on http://%s:%i/" % server.server_address | 
| 89       server.serve_forever() | 121       server.serve_forever() | 
| 90 | 122 | 
| 91   run_simple("localhost", 5000, handler, use_reloader=True, use_debugger=True) | 123   run_simple("localhost", 5000, handler, use_reloader=True, use_debugger=True) | 
| LEFT | RIGHT | 
|---|