|
| 1 | +import datetime |
| 2 | +import os |
| 3 | +import sys |
| 4 | +import traceback |
| 5 | + |
| 6 | +if sys.version_info[0] == 3: |
| 7 | + def to_str(value): |
| 8 | + return value.decode(sys.getfilesystemencoding()) |
| 9 | + |
| 10 | + def execfile(path, global_dict): |
| 11 | + """Execute a file""" |
| 12 | + with open(path, 'r') as f: |
| 13 | + code = f.read() |
| 14 | + code = code.replace('\r\n', '\n') + '\n' |
| 15 | + exec(code, global_dict) |
| 16 | +else: |
| 17 | + def to_str(value): |
| 18 | + return value.encode(sys.getfilesystemencoding()) |
| 19 | + |
| 20 | +def log(txt): |
| 21 | + """Logs fatal errors to a log file if WSGI_LOG env var is defined""" |
| 22 | + log_file = os.environ.get('WSGI_LOG') |
| 23 | + if log_file: |
| 24 | + f = open(log_file, 'a+') |
| 25 | + try: |
| 26 | + f.write('%s: %s' % (datetime.datetime.now(), txt)) |
| 27 | + finally: |
| 28 | + f.close() |
| 29 | + |
| 30 | +def get_wsgi_handler(handler_name): |
| 31 | + if not handler_name: |
| 32 | + raise Exception('WSGI_ALT_VIRTUALENV_HANDLER env var must be set') |
| 33 | + |
| 34 | + if not isinstance(handler_name, str): |
| 35 | + handler_name = to_str(handler_name) |
| 36 | + |
| 37 | + module_name, _, callable_name = handler_name.rpartition('.') |
| 38 | + should_call = callable_name.endswith('()') |
| 39 | + callable_name = callable_name[:-2] if should_call else callable_name |
| 40 | + name_list = [(callable_name, should_call)] |
| 41 | + handler = None |
| 42 | + last_tb = '' |
| 43 | + |
| 44 | + while module_name: |
| 45 | + try: |
| 46 | + handler = __import__(module_name, fromlist=[name_list[0][0]]) |
| 47 | + last_tb = '' |
| 48 | + for name, should_call in name_list: |
| 49 | + handler = getattr(handler, name) |
| 50 | + if should_call: |
| 51 | + handler = handler() |
| 52 | + break |
| 53 | + except ImportError: |
| 54 | + module_name, _, callable_name = module_name.rpartition('.') |
| 55 | + should_call = callable_name.endswith('()') |
| 56 | + callable_name = callable_name[:-2] if should_call else callable_name |
| 57 | + name_list.insert(0, (callable_name, should_call)) |
| 58 | + handler = None |
| 59 | + last_tb = ': ' + traceback.format_exc() |
| 60 | + |
| 61 | + if handler is None: |
| 62 | + raise ValueError('"%s" could not be imported%s' % (handler_name, last_tb)) |
| 63 | + |
| 64 | + return handler |
| 65 | + |
| 66 | +activate_this = os.getenv('WSGI_ALT_VIRTUALENV_ACTIVATE_THIS') |
| 67 | +if not activate_this: |
| 68 | + raise Exception('WSGI_ALT_VIRTUALENV_ACTIVATE_THIS is not set') |
| 69 | + |
| 70 | +def get_virtualenv_handler(): |
| 71 | + log('Activating virtualenv with %s\n' % activate_this) |
| 72 | + execfile(activate_this, dict(__file__=activate_this)) |
| 73 | + |
| 74 | + log('Getting handler %s\n' % os.getenv('WSGI_ALT_VIRTUALENV_HANDLER')) |
| 75 | + handler = get_wsgi_handler(os.getenv('WSGI_ALT_VIRTUALENV_HANDLER')) |
| 76 | + log('Got handler: %r\n' % handler) |
| 77 | + return handler |
| 78 | + |
| 79 | +def get_venv_handler(): |
| 80 | + log('Activating venv with executable at %s\n' % activate_this) |
| 81 | + import site |
| 82 | + sys.executable = activate_this |
| 83 | + old_sys_path, sys.path = sys.path, [] |
| 84 | + |
| 85 | + site.main() |
| 86 | + |
| 87 | + sys.path.insert(0, '') |
| 88 | + for item in old_sys_path: |
| 89 | + if item not in sys.path: |
| 90 | + sys.path.append(item) |
| 91 | + |
| 92 | + log('Getting handler %s\n' % os.getenv('WSGI_ALT_VIRTUALENV_HANDLER')) |
| 93 | + handler = get_wsgi_handler(os.getenv('WSGI_ALT_VIRTUALENV_HANDLER')) |
| 94 | + log('Got handler: %r\n' % handler) |
| 95 | + return handler |
0 commit comments