diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-09-13 12:05:33 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-09-13 12:05:33 +0700 |
| commit | 8f3d096dbae18bacd95796d03b17d4d94a806c85 (patch) | |
| tree | ae90032724dabe417b907db43145639e6df9565f /jasper_reports/JasperReports/websrv_lib.py | |
| parent | 0d87fec0c4c6fb573b1a09076f6d50844d8d0a80 (diff) | |
jasper report integration
Diffstat (limited to 'jasper_reports/JasperReports/websrv_lib.py')
| -rwxr-xr-x | jasper_reports/JasperReports/websrv_lib.py | 245 |
1 files changed, 245 insertions, 0 deletions
diff --git a/jasper_reports/JasperReports/websrv_lib.py b/jasper_reports/JasperReports/websrv_lib.py new file mode 100755 index 0000000..1c0d3c4 --- /dev/null +++ b/jasper_reports/JasperReports/websrv_lib.py @@ -0,0 +1,245 @@ +# -*- coding: utf-8 -*- +# +# Copyright P. Christeas <p_christ@hol.gr> 2008-2010 +# +# WARNING: This program as such is intended to be used by professional +# programmers who take the whole responsibility of assessing all potential +# consequences resulting from its eventual inadequacies and bugs +# End users who are looking for a ready-to-use solution with commercial +# guarantees and support are strongly advised to contract a Free Software +# Service Company +# +# This program 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 2 +# of the License, or (at your option) any later version. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +############################################################################### + + +""" Framework for generic http servers + + This library contains *no* Odoo-specific functionality. It should be + usable in other projects, too. +""" + +import logging +from http.server import SimpleHTTPRequestHandler + +_logger = logging.getLogger(__name__) + +# A list of HTTPDir. +handlers = [] + + +class AuthRequiredExc(Exception): + def __init__(self, atype, realm): + Exception.__init__(self) + self.atype = atype + self.realm = realm + + +class AuthRejectedExc(Exception): + pass + + +class AuthProvider: + def __init__(self, realm): + self.realm = realm + + def authenticate(self, user, passwd, client_address): + return False + + def log(self, msg): + _logger.info(msg) + + def check_request(self, handler, path='/'): + """ Check if we are allowed to process that request + """ + pass + + +class HTTPHandler(SimpleHTTPRequestHandler): + def __init__(self, request, client_address, server): + SimpleHTTPRequestHandler.__init__( + self, request, client_address, server) + self.protocol_version = 'HTTP/1.1' + self.connection = DummyConn() + + def handle(self): + """ Classes here should NOT handle inside their constructor + """ + pass + + def finish(self): + pass + + def setup(self): + pass + + +class HTTPDir: + """ A dispatcher class, like a virtual folder in httpd + """ + + def __init__(self, path, handler, auth_provider=None, secure_only=False): + self.path = path + self.handler = handler + self.auth_provider = auth_provider + self.secure_only = secure_only + + def matches(self, request): + """ Test if some request matches us. If so, return + the matched path. """ + if request.startswith(self.path): + return self.path + return False + + def instanciate_handler(self, request, client_address, server): + handler = self.handler(NoConnection(request), client_address, server) + if self.auth_provider: + handler.auth_provider = self.auth_provider() + return handler + + +def reg_http_service(path, handler, auth_provider=None, secure_only=False): + """ Register a HTTP handler at a given path. + + The auth_provider will be instanciated and set on the handler instances. + """ + global handlers + service = HTTPDir(path, handler, auth_provider, secure_only) + pos = len(handlers) + lastpos = pos + while pos > 0: + pos -= 1 + if handlers[pos].matches(service.path): + lastpos = pos + # we won't break here, but search all way to the top, to + # ensure there is no lesser entry that will shadow the one + # we are inserting. + handlers.insert(lastpos, service) + + +def list_http_services(protocol=None): + global handlers + ret = [] + for svc in handlers: + if protocol is None or protocol == 'http' or svc.secure_only: + ret.append((svc.path, str(svc.handler))) + + return ret + + +def find_http_service(path, secure=False): + global handlers + for vdir in handlers: + p = vdir.matches(path) + if p is False or (vdir.secure_only and not secure): + continue + return vdir + return None + + +class NoConnection(object): + """ a class to use instead of the real connection + """ + + def __init__(self, realsocket=None): + self.__hidden_socket = realsocket + + def makefile(self, mode, bufsize): + return None + + def close(self): + pass + + def getsockname(self): + """ We need to return info about the real socket that is used for the request + """ + if not self.__hidden_socket: + raise AttributeError("No-connection class cannot tell real socket") + return self.__hidden_socket.getsockname() + + +class DummyConn: + def shutdown(self, tru): + pass + + +def _quote_html(html): + return html.replace("&", "&").replace("<", "<").replace(">", ">") + + +class FixSendError: + def send_error(self, code, message=None): + + try: + short, long = self.responses[code] + except KeyError: + short, long = '???', '???' + if message is None: + message = short + explain = long + _logger.error("code %d, message %s", code, message) + content = (self.error_message_format % { + 'code': code, + 'message': _quote_html(message), + 'explain': explain + }) + self.send_response(code, message) + self.send_header("Content-Type", self.error_content_type) + self.send_header('Connection', 'close') + self.send_header('Content-Length', len(content) or 0) + self.end_headers() + if hasattr(self, '_flush'): + self._flush() + if self.command != 'HEAD' and code >= 200 and code not in (204, 304): + self.wfile.write(content) + + +class HttpOptions: + + _HTTP_OPTIONS = {'Allow': ['OPTIONS']} + + def do_OPTIONS(self): + """return the list of capabilities """ + + opts = self._HTTP_OPTIONS + nopts = self._prep_OPTIONS(opts) + if nopts: + opts = nopts + + self.send_response(200) + self.send_header("Content-Length", 0) + if 'Microsoft' in self.headers.get('User-Agent', ''): + self.send_header('MS-Author-Via', 'DAV') + # Microsoft's webdav lib ass-umes that the server would + # be a FrontPage(tm) one, unless we send a non-standard + # header that we are not an elephant. + # http://www.ibm.com/developerworks/rational/library/2089.html + + for key, value in opts.items(): + if isinstance(value, str): + self.send_header(key, value) + elif isinstance(value, (tuple, list)): + self.send_header(key, ', '.join(value)) + self.end_headers() + + def _prep_OPTIONS(self, opts): + """ Prepare the OPTIONS response, if needed. + Sometimes, like in special DAV folders, the OPTIONS may + contain extra keywords, perhaps also dependant on the + request url. + :param opts: MUST be copied before being altered + :returns: the updated options. + """ + return opts |
