Esempio n. 1
0
class App:
    def __init__(self):
        self._url_map = Map(strict_slashes=False)

    def route(self, rule, **kwargs):
        def decorator(func):
            kwargs['endpoint'] = func
            self._url_map.add(Rule(rule, **kwargs))
            return func
        return decorator

    def _dispatch(self, request):
        adapter = self._url_map.bind_to_environ(request.environ)
        try:
            endpoint, values = adapter.match()
            return endpoint(request, **values)
        except HTTPException as e:
            return e

    def __call__(self, env, sr):
        request = AppRequest(env)
        response = self._dispatch(request)
        after_handlers = getattr(request, '_after_request_handlers', None)
        if after_handlers:
            for h in after_handlers:
                response = h(response) or response
        return response(env, sr)
Esempio n. 2
0
class WebApp (object):
    """Subclass this to create a web app."""
    __url_map = None

    def __build_url_map(self):
        """Build the URL routing map.
        
        This is called the first time the app recieves a request.
        """
        l = []

        for name, view in getmembers(self):
            if getattr(view, "_is_web_view", False):
                args, kwargs = view._routing_args
                kwargs = copy(kwargs) # don't mess up other instances
                kwargs['endpoint'] = name
                l.append(Rule(*args, **kwargs))

        self.__url_map = Map(l)

    def __dispatch_request(self, request):
        """Dispatch a single request, and return a Werkzeug response."""
        if self.__url_map is None:
            self.__build_url_map()

        adapter = self.__url_map.bind_to_environ(request.environ)
        try:
            endpoint, values = adapter.match()
            return getattr(self, endpoint)(request, **values)
        except NotFound as e:
            return self.handle_not_found(request)
        except HTTPException, e:
            return e
Esempio n. 3
0
def handle_url(aConfig, environ, session):
    global gTileCache

    def handle_index(environ, session):
        statuscode, mimetype, body = 403, 'text/plain', 'Access deny'
        return statuscode, mimetype, body

    user_id = None
    if session and '_id' in session:
        user_id = session['_id']
    statuscode, mimetype, body = 200, 'text/json',  '{}'
    app = aConfig['gConfig']['wsgi']['application']
    urllist = []
    for key in aConfig['gConfig']['applications'][app]['url_mapping'].keys():
        urllist.append(Rule(key, endpoint=aConfig['gConfig']['applications'][app]['url_mapping'][key]))
    urlmap = Map(urllist, converters={'bool': BooleanConverter})
    urls = urlmap.bind_to_environ(environ)
    querydict, buf, stream = get_querydict_by_GET_POST(environ)
    try:
        endpoint, args = urls.match()
        if endpoint == 'handle_index':
            statuscode, mimetype, body = handle_index(environ, session)
        else:
            body = json.dumps({'result':u'access_deny'}, ensure_ascii=True, indent=4)

    # except HTTPException, e:
    except Exception as e:
        traceback.print_exc()
        body = json.dumps({'result':u'error:%s' % e.message}, ensure_ascii=True, indent=4)

    # if session:
    #     aConfig['gSessionStore'].save(session)
    # for k in hh.keys():
    #     headers[k] = hh[k]
    return statuscode, mimetype, body
Esempio n. 4
0
class InputReqApp(object):
    def __init__(self):
        self.url_map = Map()
        self.url_map.add(Rule('/test/<path:url>', endpoint=self.direct_input_request))
        self.url_map.add(Rule('/test-postreq', endpoint=self.post_fullrequest))

    def direct_input_request(self, environ, url=''):
        inputreq = DirectWSGIInputRequest(environ)
        return inputreq.reconstruct_request(url)

    def post_fullrequest(self, environ):
        params = dict(parse_qsl(environ.get('QUERY_STRING', '')))
        inputreq = POSTInputRequest(environ)
        return inputreq.reconstruct_request(params['url'])

    def __call__(self, environ, start_response):
        urls = self.url_map.bind_to_environ(environ)
        try:
            endpoint, args = urls.match()
        except HTTPException as e:
            return e(environ, start_response)

        result = endpoint(environ, **args)
        start_response('200 OK', [('Content-Type', 'text/plain; charset=utf-8')])
        return [result]
Esempio n. 5
0
class Forms(object):
    """
    This class listens for a form submission, checks that the data is valid, and
    sends the form data in a formatted message to the email specified in conf.py
    """
    def __init__(self, controller, logger):
        # Sets up the path to the template files
        template_path = os.path.join(os.path.dirname(__file__), 'templates')
        self.controller = controller
        self.error = None
        # Creates jinja template environment
        self.jinja_env = Environment(loader=FileSystemLoader(template_path),
                                     autoescape=True)
        # When the browser is pointed at the root of the website, call
        # on_form_page
        self.url_map = Map([Rule('/', endpoint='form_page')])
        self.logger = logger

    def dispatch_request(self, request):
        """Evaluates request to decide what happens"""
        adapter = self.url_map.bind_to_environ(request.environ)
        try:
            endpoint, values = adapter.match()
            return getattr(self, 'on_' + endpoint)(request, **values)
        except HTTPException, error:
            self.logger.error('formsender: %s', error)
            return error
Esempio n. 6
0
class holla_base_app(object):


    """
        This Class provide a Response Obj as an alias of HTTP_Resp.Response
        Usage: Let get_resp obj return a Response obj, and you don't need to do anything else 
    """
    
    def __init__(self):
        self.Response = Response  # Just an alias of Response Class
        self.url_map = Map([])
        pass
        
    def route(self, url, methods = None):
        def decorator(callback):
            add_Route(url, callback, self.url_map, methods)
            return callback
        return decorator

    def get_resp(self, env):
        self.env = env
        adapter = self.url_map.bind_to_environ(self.env)
        try:
            endpoint, values = adapter.match()
            return Response(endpoint(**values))
        except NotFound, e:
            return Response(status = 404)
        except HTTPException, e:
            return Response(status = 500)
Esempio n. 7
0
class RpcServer(object):

        def __init__(self, callbacks=None, host='', port=8000, ):
            self.host = host
            self.port = port

            self.views = {'get_rpc': self.get_rpc,
                          'images': self.get_file,
                          'save_file': self.save_file,
                          'get_log' : self.get_log}

            self.url_map = Map([Rule('/', endpoint='get_rpc'),
                                Rule('/jsonrpc', endpoint='get_rpc'),
                                Rule('/images', endpoint='images'),
                                Rule('/upload', endpoint='save_file'),
                                Rule('/log', endpoint='get_log')])


            # add the method names and the handlers to the dispatcher methods.
            if callbacks:
                for keys in callbacks.keys():
                    dispatcher[keys] = callbacks[keys]

        def get_rpc(self, environ, request):
             response = JSONRPCResponseManager.handle(request.data, dispatcher)
             return Response(response.json, mimetype="application/json")

        def get_file(self, environ, request):
            try:
                file = open('images/'+request.query_string.decode(), 'rb')
            except Exception as e:
                debug_logger.debug("could not read file" + str(e))
                raise NotFound()
            return Response(wrap_file(environ, file), direct_passthrough=True)

        def save_file(self, environ, request):
            try:
                file = request.files['image']
                filename = 'images/'+request.form["btn_name"].strip('"')+".jpg"
                id = request.form['btn_id']
                txt = request.form['btn_text'].strip('"')
                file.save(filename)
                dispatcher['update_image'](id, txt, filename)
            except Exception:
                return NotFound()
            return Response("Ok")

        def get_log(self, environ, request):
            response = dispatcher['get_log_data']()
            return Response(response, mimetype="application/json")

        @responder
        def application(self, environ, start_response):
            request = Request(environ)
            urls = self.url_map.bind_to_environ(environ)
            return urls.dispatch(lambda e, v: self.views[e](environ, request, **v),
                         catch_http_exceptions=True)

        def start(self):
            self.app = run_simple(self.host, self.port, self.application)
Esempio n. 8
0
class NovoMapia(object):
    
    def __init__(self, config):
        template_path = os.path.join(os.path.dirname(__file__), 'templates')
        self.jinja_env = Environment(loader=FileSystemLoader(template_path),autoescape=True)
        self.url_map = Map([
            Rule('/', endpoint='index'),
            Rule('/index.html', endpoint='index'),
            Rule('/<source>', endpoint='index'),
            Rule('/json/<source>', endpoint='json'),
            Rule('/json/<source>/', endpoint='json'),
        ])
    
    def render_template(self, template_name, **context):
        t = self.jinja_env.get_template(template_name)
        return Response(t.render(context), mimetype='text/html')

    def dispatch_request(self, request):
        return Response('Hello World!')
        
    def dispatch_request(self, request):
        adapter = self.url_map.bind_to_environ(request.environ)
        try:
            endpoint, values = adapter.match()
            return getattr(self, 'on_' + endpoint)(request, **values)
        except HTTPException, e:
            return e
Esempio n. 9
0
class Cup(object):
    def __init__(self, with_static=True):
        if with_static:
            self.wsgi_app = SharedDataMiddleware(self.wsgi_app, {
                '/static':  os.path.join(os.path.dirname(__file__), 'static')
            })
        self.url_map = Map()
        self.views = {}

    def add_url_rule(self, url, endpt, func):
        self.url_map.add(Rule(url, endpoint=endpt))
        self.views[endpt] = func

    def getView(self, endpoint):
        return self.views[endpoint]
    
    def route(self, url):
        def decorator(func):
            self.add_url_rule(url, func.__name__, func)
            def decorated(*args, **kwargs):
                func(*args, **kwargs)
            return decorated
        return decorator

    def dispatch_request(self, request):
        adapter = self.url_map.bind_to_environ(request.environ)
        try:
            endpoint, values = adapter.match()
            data = self.getView(endpoint)(request, **values)
            return Response(data, mimetype="text/html")
        except HTTPException, e:
            print "e"
            return e
Esempio n. 10
0
class Shortly(object):
    def __init__(self, config):
        self.redis = redis.Redis(config["redis_host"], config["redis_port"])
        # 模板路径
        template_path = os.path.join(os.path.dirname(__file__), "templates")
        # Jinja2 环境
        self.jinja_env = Environment(loader=FileSystemLoader(template_path), autoescape=True)
        # URL 映射
        self.url_map = Map(
            [
                Rule("/", endpoint="new_url"),
                Rule("/<short_id>", endpoint="follow_short_link"),
                Rule("/<short_id>+", endpoint="short_link_details"),
            ]
        )

    def render_template(self, template_name, **context):
        """使用 Jinja2 渲染模板"""
        t = self.jinja_env.get_template(template_name)
        return Response(t.render(context), mimetype="text/html")

    def dispatch_request(self, request):
        adapter = self.url_map.bind_to_environ(request.environ)
        try:
            endpoint, values = adapter.match()
            return getattr(self, "on_" + endpoint)(request, **values)
        except HTTPException, e:
            return e
Esempio n. 11
0
def application(environ, start_response):
    request = Request(environ)

    if os.path.exists(PATH):
        with open(PATH) as yaml:
            data = load(yaml)
    else:
        data = {}

    urls = {}

    for reference in data.get("references", []):
        urls[reference.get("alias")] = reference.get("url")

    url_map = Map([
        Rule('/<alias>', endpoint='shortener'),
    ])

    adapter = url_map.bind_to_environ(request.environ)

    endpoint, values = adapter.match()

    alias = values["alias"]

    if alias not in urls:
        raise NotFound()

    response = redirect(urls[alias])
    return response(environ, start_response)
Esempio n. 12
0
def handle_url(aConfig, environ, session):
    def handle_index(environ, session):
        statuscode, mimetype, body = handle_static(
            aConfig, environ, aConfig["gConfig"]["applications"][app]["static"]["page"]["indexpage"]
        )
        return statuscode, mimetype, body

    statuscode, mimetype, body = 200, "text/json", "{}"
    app = aConfig["gConfig"]["wsgi"]["application"]
    urllist = []
    for key in aConfig["gConfig"]["applications"][app]["url_mapping"].keys():
        urllist.append(Rule(key, endpoint=aConfig["gConfig"]["applications"][app]["url_mapping"][key]))
    urlmap = Map(urllist, converters={"bool": BooleanConverter})
    urls = urlmap.bind_to_environ(environ)
    try:
        endpoint, args = urls.match()
        if endpoint == "handle_index":
            statuscode, mimetype, body = handle_index(environ, session)
        else:
            body = json.dumps({"result": u"access_deny"}, ensure_ascii=True, indent=4)

    # except HTTPException, e:
    except Exception as e:
        traceback.print_exc()
        body = json.dumps({"result": u"error:%s" % e.message}, ensure_ascii=True, indent=4)

    return statuscode, mimetype, body
Esempio n. 13
0
class Shortly(object):

    def __init__(self, config):
        self.redis = redis.Redis(config['redis_host'], config['redis_port'])  
        template_path = os.path.join(os.path.dirname(__file__), 'templates')
        #autoescape=True的意思,就是xml/html不转义
        self.jinja_env = Environment(loader=FileSystemLoader(template_path),
                                     autoescape=True)
        #Map创建的这个实例,就像它名字一样,是一个url与函数端点一一对应的“地图”
        #参数是一个列表,起一个关系集中的作用
        self.url_map = Map([
            #Rule类,创建具体的函数端点的对应关系
            Rule('/', endpoint='new_url'),
            Rule('/<short_id>', endpoint='follow_short_link'),
            Rule('/<short_id>+', endpoint='short_link_details')
        ])

    def render_template(self, template_name, **context):
        t = self.jinja_env.get_template(template_name)
        return Response(t.render(context), mimetype='text/html')

    def dispatch_request(self, request):
        #创建一个适配器,在下面用来匹配请求
        adapter = self.url_map.bind_to_environ(request.environ)
        try:
            #返回函数的端点名,以及函数所需的参数字典
            endpoint, values = adapter.match()
            return getattr(self, 'on_'+endpoint)(request, **values)
        except HTTPException, e:
            return e
Esempio n. 14
0
class TaskTypeAPIMiddleware(object):
    """Describe TaskType parameters.

    The only duty (at the moment) for this class is to describe the
    format of parameters for TaskTypes. The only URL it handles (i.e.
    "/") returns a JSON-encoded dict whose keys are TaskType names and
    whose values are lists. Each of their item is a description of
    a ParameterType, as returned by its .describe() method (this means
    it could be a complex nested object).

    """
    def __init__(self):
        """Create an instance of this class.

        """
        self._url_map = Map([Rule("/", methods=["GET"], endpoint="get")],
                            encoding_errors="strict")

        self._task_types = plugin_list("cms.grading.tasktypes", "tasktypes")

    def __call__(self, environ, start_response):
        """Execute this instance as a WSGI application.

        See the PEP for the meaning of parameters. The separation of
        __call__ and wsgi_app eases the insertion of middlewares.

        """
        return self.wsgi_app(environ, start_response)

    @responder
    def wsgi_app(self, environ, start_response):
        """Execute this instance as a WSGI application.

        See the PEP for the meaning of parameters. The separation of
        __call__ and wsgi_app eases the insertion of middlewares.

        """
        urls = self._url_map.bind_to_environ(environ)
        try:
            endpoint, args = urls.match()
        except HTTPException as exc:
            return exc

        assert endpoint == "get"

        request = Request(environ)
        request.encoding_errors = "strict"

        response = Response()

        result = dict()
        for task_type in self._task_types:
            result[task_type.__name__] = \
                list(p.describe() for p in task_type.ACCEPTED_PARAMETERS)

        response.status_code = 200
        response.mimetype = "application/json"
        response.data = json.dumps(result)

        return response
Esempio n. 15
0
File: 1.py Progetto: bTanya/14.07
def app(req):

    url_map =Map([Rule('/',endpoint='index'),
                  Rule('/form',endpoint='form'),
                  Rule('/form/<id>', endpoint='form1')])
    urls = url_map.bind_to_environ(req.environ)
    return urls.dispatch(lambda e,v: route[e](req,**v))
Esempio n. 16
0
class Mongosm(object):

    def tileRequest(self, request, zoom, x, y):
        #(minlon, minlat, maxlon, maxlat) = request.args['bbox'].split(',')
        #bbox = [[float(minlat), float(minlon)],[float(maxlat), float(maxlon)]]

        api = OsmApi()
        data = api.getTile(int(zoom), int(x), int(y))

        outputter = OsmXmlOutput()

        return Response(outputter.iter(data), content_type='text/xml', direct_passthrough=True)

    def capabilitiesRequest(self, request):
        return Response("""
            <osm version="0.6" generator="mongosm 0.1">
                <api>
                    <version minimum="0.6" maximum="0.6"/>
                    <area maximum="0.5"/>
                </api>
            </osm>""")

    def __init__(self):
        self.url_map = Map([
            Rule('/tiles/0.6/<zoom>/<x>/<y>', endpoint='tileRequest'),
            Rule('/api/capabilities', endpoint='capabilitiesRequest'),
        ])

    def dispatch_request(self, request):
        adapter = self.url_map.bind_to_environ(request.environ)
        try:
            endpoint, values = adapter.match()
            return getattr(self, endpoint)(request, **values)
        except HTTPException, e:
            return e
Esempio n. 17
0
class App():
    def __init__(self, work_dir):
        self.work_dir = work_dir
        self.admin = adm_server.create_admin(self)
        self.task = None
        self.task_lock = Lock()
        self.users = {}
        self.roles = None
        self._busy = 0
        self.pid = os.getpid()
        self.task_server_modified = False
        self.task_client_modified = True
        self.under_maintenance = False
        self.work_dir = self.admin.work_dir
        self.jam_dir = os.path.dirname(jam.__file__)
        self.jam_version = jam.version()
        self.application_files = {
            '/': self.work_dir,
            '/jam/': self.jam_dir,
            '/static/': os.path.join(self.jam_dir, 'static'            )
        }
        self.fileserver = SharedDataMiddleware(None, self.application_files, cache_timeout=0.1)
        self.url_map = Map([
            Rule('/', endpoint='root_file'),
            Rule('/<file_name>', endpoint='root_file'),
            Rule('/js/<file_name>', endpoint='file'),
            Rule('/css/<file_name>', endpoint='file'),
            Rule('/jam/js/<file_name>', endpoint='file'),
            Rule('/jam/js/ace/<file_name>', endpoint='file'),
            Rule('/jam/css/<file_name>', endpoint='file'),
            Rule('/jam/img/<file_name>', endpoint='file'),
            Rule('/api', endpoint='api'),
            Rule('/upload', endpoint='upload')
        ])

    def get_task(self):
        if self.task is None:
            with self.task_lock:
                if self.task is None:
                    adm_server.create_task(self)
        return self.task

    def __call__(self, environ, start_response):
        return self.wsgi_app(environ, start_response)

    def wsgi_app(self, environ, start_response):
        request = Request(environ)
        adapter = self.url_map.bind_to_environ(request.environ)
        try:
            endpoint, values = adapter.match()
            if endpoint in ['file', 'root_file']:
                return self.serve_file(environ, start_response, endpoint, **values)
            elif endpoint in ['api', 'upload']:
                response = getattr(self, 'on_' + endpoint)(request, **values)
        except HTTPException, e:
            if peek_path_info(environ) == 'ext':
                response = self.on_ext(request)
            else:
                response = e
        return response(environ, start_response)
Esempio n. 18
0
def test_external_building_with_port_bind_to_environ_wrong_servername():
    """Test external URL building with port number (map.bind_to_environ) with wrong server name raises ValueError"""
    map = Map([
        Rule('/', endpoint='index'),
    ])
    environ = create_environ('/', 'http://example.org:5000/')
    assert_raises(ValueError, lambda: map.bind_to_environ(environ, server_name="example.org"))
Esempio n. 19
0
class GraphQLApp(object):

    def __init__(self):
        self.url_map = Map([
            Rule('/graphql', endpoint='graphql'),
            Rule('/graphiql', endpoint='graphiql')
        ])
        self.wsgi_app = SharedDataMiddleware(self.wsgi_app, {
            '/static':  os.path.join(os.path.dirname(__file__), 'static')
        })
        template_path = os.path.join(os.path.dirname(__file__), 'templates')
        self.jinja_env = Environment(loader=FileSystemLoader(template_path),
                                     autoescape=True)

    def wsgi_app(self, environ, start_response):
        request = Request(environ)
        response = self.dispatch_request(request)
        return response(environ, start_response)

    def __call__(self, environ, start_response):
        return self.wsgi_app(environ, start_response)

    def dispatch_request(self, request):
        adapter = self.url_map.bind_to_environ(request.environ)
        try:
            endpoint, values = adapter.match()
            return getattr(self, 'on_' + endpoint)(request, **values)
        except HTTPException, e:
            return e
Esempio n. 20
0
class Server(object):

	def __init__(self, config):
		self.url_map = Map([
			Rule('/', endpoint='generate_buy_list'),
		])
		self.magic_set_library = Magic_Set_Library()
	
	def generate_buy_list(self, request):
		params = self._parse_query_string(request.query_string)
		boosters = []
		for magic_set, booster_count in params.iteritems():
			for i in range(int(booster_count)):
				boosters.append(self.magic_set_library.make_booster(magic_set))
		card_map = {}
		for booster in boosters:
			for card in booster:
				card_map[card] = card_map.get(card, 0) + 1
		ret_str = ""
		for card, count in sorted(card_map.iteritems(), key=lambda x:x[0]):
			ret_str += "%s %s\n" %(count, card.name)
		return Response(ret_str)
	
	def _parse_query_string(self, query_string):
		if not query_string:
			return {}
		return dict(map(lambda x:(x.split('=')[0], x.split('=')[1]), query_string.strip().split('&')))

	def dispatch_request(self, request):
		adapter = self.url_map.bind_to_environ(request.environ)
		try:
			endpoint, values = adapter.match()
			return getattr(self, endpoint)(request, **values)
		except HTTPException, e:
			return e
Esempio n. 21
0
class TrabantMap(object):
    def __init__(self, config):
        self.url_map = Map([
            Rule('/', endpoint='root_map'),
            Rule('/cars', endpoint='car_map'),
            Rule('/shops', endpoint='shop_map'),
            Rule('/clubs', endpoint='club_map'),
            Rule('/parts', endpoint='part_map'),
            Rule('/new', endpoint='new_item'),
            Rule('/admin', endpoint='admin'),
            Rule('/admin/disable', endpoint='point_disable'),
            Rule('/admin/enable', endpoint='point_enable'),
            Rule('/static/<string:resource>', endpoint='static_get'),
        ])

        self.config = TrabantConfig(config)
        self.points = PointSqliteDatabase({'sqlfile': 'points.db'})
        self.jinjaenv = Environment(loader=FileSystemLoader('templates/'))
        logging.debug('TrabantMap instantiated')

    def dispatch_request(self, request):
        adapter = self.url_map.bind_to_environ(request.environ)
        try:
            endpoint, values = adapter.match()
            logging.debug('Request on_%s', endpoint)
            return getattr(self, 'on_' + endpoint)(request, **values)
        except HTTPException, e:
            return e
Esempio n. 22
0
class App(object):

    def __init__(self, name=__name__):
        modules = import_all_module(name)
        self.rules = []
        self.views = []
        for module in modules:
            for k, v in module.__dict__.items():
                if inspect.isclass(v) and issubclass(v, Resource)\
                        and v is not Resource:
                    self.rules.extend(v.rules)
                    if module not in self.views:
                        self.views.append(module)
        self.url_map = Map(self.rules)

    def dispatch_request(self, request):
        adapter = self.url_map.bind_to_environ(request.environ)
        endpoint, values = adapter.match()
        for view in self.views:
            if hasattr(view, endpoint):
                return getattr(view, endpoint)(request, endpoint, values)

    def __call__(self, environ, start_response):
        request = Request(environ)
        response = self.dispatch_request(request)
        return response(environ, start_response)
Esempio n. 23
0
class Isso(object):

    salt = b"Eech7co8Ohloopo9Ol6baimi"

    def __init__(self, conf):

        self.conf = conf
        self.db = db.SQLite3(conf.get('general', 'dbpath'), conf)
        self.signer = URLSafeTimedSerializer(conf.get('general', 'session-key'))

        super(Isso, self).__init__(conf)

        subscribers = []
        subscribers.append(Stdout(None))

        if conf.get("general", "notify") == "smtp":
            subscribers.append(SMTP(self))

        self.signal = ext.Signal(*subscribers)

        self.urls = Map()

        views.Info(self)
        comments.API(self)

    def sign(self, obj):
        return self.signer.dumps(obj)

    def unsign(self, obj, max_age=None):
        return self.signer.loads(obj, max_age=max_age or self.conf.getint('general', 'max-age'))

    def dispatch(self, request):
        local.request = request

        local.host = wsgi.host(request.environ)
        local.origin = origin(self.conf.getiter("general", "host"))(request.environ)

        adapter = self.urls.bind_to_environ(request.environ)

        try:
            handler, values = adapter.match()
        except HTTPException as e:
            return e
        else:
            try:
                response = handler(request.environ, request, **values)
            except HTTPException as e:
                return e
            except Exception:
                logger.exception("%s %s", request.method, request.environ["PATH_INFO"])
                return InternalServerError()
            else:
                return response

    def wsgi_app(self, environ, start_response):
        response = self.dispatch(JSONRequest(environ))
        return response(environ, start_response)

    def __call__(self, environ, start_response):
        return self.wsgi_app(environ, start_response)
Esempio n. 24
0
class TegolaRest(object):
    def __init__(self, db, mountpoint=""):
        self.db = db
        self.mountpoint = ""
        self.url_map = Map([
                Rule("%s/oauth/<site_name>" % mountpoint, endpoint="oauth"),
                Rule("%s/host/<macaddr>" % mountpoint, endpoint="host"),
                Rule("%s/host/<macaddr>/adj/link" % mountpoint, endpoint="link_adj"),
                Rule("%s/host/<macaddr>/adj/network" % mountpoint, endpoint="network_adj"),
                Rule("%s/host/<macaddr>/adj/ospf" % mountpoint, endpoint="ospf_adj"),
                Rule("%s/adj" % mountpoint, endpoint="adj"),
                Rule("%s/spectrum/" % mountpoint, endpoint="spectrum"),
                Rule("%s/spectrum/<freq>" % mountpoint, endpoint="spectrum")
                ])

    def __call__(self, environ, start_response):
        request = Request(environ)
        response = self.dispatch_request(request)
        return response(environ, start_response)

    def dispatch_request(self, request):
        adapter = self.url_map.bind_to_environ(request.environ)
        try:
            endpoint, values = adapter.match()
            return getattr(self, "on_" + endpoint)(request, **values)
        except HTTPException, e:
            return e
Esempio n. 25
0
class Shortly(object):

	def __init__(self, config):
		self.redis = redis.Redis(config['redis_host'], config['redis_port'])
		template_path = os.path.join(os.path.dirname(__file__), 'templates')
		self.jinja_env = Environment(loader=FileSystemLoader(template_path), 
										autoescape=True)
		self.url_map = Map([
			Rule('/', endpoint='new_url'),
			Rule('/<short_id>', endpoint='follow_short_link'),
			Rule('/<short_id>+', endpoint='short_link_details')
		])

	def __call__(self, environ, start_response):
		return self.wsgi_app(environ, start_response)

	def render_template(self, template_name, **context):
		t = self.jinja_env.get_template(template_name)
		return Response(t.render(context), mimetype='text/html')

	def dispatch_request(self, request):
		adapter = self.url_map.bind_to_environ(request.environ)
		try:
			endpoint, values = adapter.match()
			return getattr(self, 'on_' + endpoint)(request, **values)
		except HTTPException, e:
			return e
Esempio n. 26
0
class CrowdsourcingWeb(object):
    def __init__(self,configFile):
        self.url_map = Map([
                Rule("/get_fresh_rank",endpoint="get_fresh_rank"),
                ])
        self.logger1 = InitLog('./log/clc_info_%s.log'%server_no)
        self.CODE_CHN_TABLE={'01':'汽车服务','02':'汽车销售','03':'汽车维修','04':'摩托车服务','05':'餐饮服务','06':'购物服务','07':'生活服务','08':'体育休闲服务','09':'医疗保健服务','10':'住宿服务','11':'风景名胜','12':'商务住宅','13':'政府机构及社会团体','14':'科教文化服务','15':'交通设施服务','16':'金融保险服务','17':'公司企业','18':'道路附属设施','19':'地名地址信息','20':'公共设施','22':'事件活动','97':'室内设施','99':'通行设施'}
        self.date_map={}
        client_city,db_city,posts_city = Connect2Mongo("localhost", 27017,'roadgrid',"city")
        city_data=posts_city.find_one({'_id':'110000'})
        for i in range(1,13):
            self.date_map['m'+str(i)]=city_data['month_list'][i]
        for i in range(1,5):
            self.date_map['q'+str(i)]=city_data['qter_list'][i]
        for i in range(1,3):
            self.date_map['hy'+str(i)]=city_data['hy_list'][i]
    def __call__(self, environ, start_response):
        return self.wsgi_app(environ, start_response)

    def wsgi_app(self, environ, start_response):
        #self.m_sessionDict = environ['werkzeug.session']
        request =  Request(environ)
        response = self.dispatch_request(request)
        return response(environ, start_response)

    def dispatch_request(self, request):
        adapter=self.url_map.bind_to_environ(request.environ);
        try:
            endpoint,values= adapter.match();
            return getattr(self, "on_" + endpoint)(request,**values);
        except HTTPException, e:
            return e
Esempio n. 27
0
class NichtParasoup(object):

    # init webserver with routing
    def __init__(self):
        self.url_map = Map([
            Rule('/', endpoint='root'),
            Rule('/status', endpoint='cache_status'),
            Rule('/get', endpoint='cache_get'),
            Rule('/imagelist', endpoint='show_imagelist'),
            Rule('/blacklist', endpoint='show_blacklist'),
            Rule('/flush', endpoint='flush'),
            Rule('/reset', endpoint='reset'),
        ])

    # proxy call to the wsgi_app
    def __call__(self, environ, start_response):
        return self.wsgi_app(environ, start_response)

    # calculate the request and use the defined map to route
    def dispatch_request(self, request):
        adapter = self.url_map.bind_to_environ(request.environ)
        try:
            endpoint, values = adapter.match()
            return getattr(self, 'on_' + endpoint)(request, **values)
        except HTTPException as e:
            return e

    # the wsgi app itself
    def wsgi_app(self, environ, start_response):
        request = Request(environ)
        response = self.dispatch_request(request)
        return response(environ, start_response)

    # start page with js and scroll
    def on_root(self, request):
        return Response(tmpl.root, mimetype='text/html')

    # map function for print the status
    def on_cache_status(self, request):
        return Response(cache_status())

    # map function for getting an image url
    def on_cache_get(self, request):
        return Response(cache_get())

    # map function for showing blacklist
    def on_show_blacklist(self, request):
        return Response(show_blacklist())

    # map function for showing imagelist
    def on_show_imagelist(self, request):
        return Response(show_imagelist())

    # map function for flushing (deleting everything in cache)
    def on_flush(self, request):
        return Response(flush())

    # map function for resetting (deleting everythign in cache and blacklist)
    def on_reset(self, request):
        return Response(reset())
Esempio n. 28
0
class Shortly(object):
    def __init__(self, config):
        self.redis = redis.Redis(config['redis_host'], config['redis_port'])
        template_path = os.path.join(os.path.dirname(__file__), 'templates')
        self.jinja_env = Environment(loader=FileSystemLoader(template_path), autoescape=True)
        self.url_map = Map([
            Rule('/', endpoint='new_url'), 
            Rule('/<short_id>', endpoint='follow_short_link'), 
            Rule('/<short_id>+',endpoint='short_link_details')
        ])

    def insert_url(self, url):
        short_id = self.redis.get('reverse-url:' + url)
        if short_id is not None:
            return short_id
        url_num = self.redis.incr('last-url-id')
        short_id = base36_encode(url_num)
        self.redis.set('url-target:' + short_id, url)
        self.redis.set('reverse-url:' + url, short_id)
        return short_id

    def render_template(self, template_name, **context):
        t = self.jinja_env.get_template(template_name)
        return Response(t.render(context), mimetype='text/html')

    def dispatch_request(self, request):
        adapter = self.url_map.bind_to_environ(request.environ)
        try:
            endpoint, values = adapter.match()
            return getattr(self, 'on_' + endpoint)(request, **values)
        except HTTPException, e:
            return e 
Esempio n. 29
0
class Dispatcher(object):
    """Dispatch requests based on a WSGI environment.
        
    The routes are loaded from the <package>/config/routes file, and each line should be blank,
    a comment, or one of the following:
        <route> <page class>
        <route> redirect:<url>
        <route> template:<filename>
    """
    
    def __init__(self, app):
        """Load the URL routing map and instantiate the responders."""
 
        self.app = app
        
        # Set up URL routing
        self.map = Map()
        routes_file = file(os.path.join(app.directory, 'config', 'routes'), 'r')
        for line in routes_file:
            # Split the line from one of the documented formats
            parts = line.split()
            if len(parts) == 0 or parts[0][0] == '#':
                # Ignore comments and blank lines
                continue
            if len(parts) != 2:
                raise ConfigurationError("Error in routes file: %s" % line)
            path, destination = parts
            if ':' in destination:
                # Responder explicitly specified
                responder_name, extra = destination.split(':', 1)
                responder_type = responder_types.get(responder_name, None)
                if responder_type is None:
                    raise ConfigurationError("Invalid destination '%s' in routes file" % destination)
                responder = responder_type(extra)
            else:
                # Default to PageResponder if there's no ':' in the destination
                responder = PageResponder(destination)
            for p, r in responder.get_routes(path): # FIXME: Better names for p and r
                rule = Rule(p, endpoint=r, methods=r.methods)
                self.map.add(rule)
        self.map.update()

    def dispatch(self, environ):
        try:
            request = Request(environ)
            urls = self.map.bind_to_environ(environ)
            responder, args = urls.match()
            with Context(self.app, environ, request, args) as context:
                for hook in self.app.get_hook_functions('pre-request'):
                    hook(context)
                context.response = responder(context)
                for hook in self.app.get_hook_functions('post-request'):
                    context.response = hook(context) or context.response
            return context.response
        
        # HTTPExceptions are returned as the response, while any other 
        # exceptions are re-raised to be either caught by the in-browser debugger
        # or generate a 500 response.
        except HTTPException, e:
            return e
Esempio n. 30
0
File: wsgi.py Progetto: nott/avatr
class KeyProtectedApp(object):
    '''
    Base class for a WSGI-app with a GET paramter based auhtentication.
    '''
    @property
    def routing(self):
        '''
        Must return a dict like {'url':'endpoint'}
        '''
        raise NotImplementedError
    
    def __init__(self):
        self.url_map = Map(
            [Rule(k, endpoint=v) for k, v in self.routing.iteritems()])

    def dispatch_request(self, request):
        if not validate_key(request.args.get('key', '')):
            raise Forbidden
        endpoint, kw = self.url_map.bind_to_environ(request.environ).match()
        return getattr(self, endpoint)(request, **kw)

    def __call__(self, environ, start_response):
        request = Request(environ)
        try:
            response = self.dispatch_request(request)
        except HTTPException, e:
            response = e
        return response(environ, start_response)
Esempio n. 31
0
class FrontEndApp(object):
    REPLAY_API = 'http://localhost:%s/{coll}/resource/postreq'
    CDX_API = 'http://localhost:%s/{coll}/index'
    RECORD_SERVER = 'http://localhost:%s'
    RECORD_API = 'http://localhost:%s/%s/resource/postreq?param.recorder.coll={coll}'

    RECORD_ROUTE = '/record'

    PROXY_CA_NAME = 'pywb HTTPS Proxy CA'

    PROXY_CA_PATH = os.path.join('proxy-certs', 'pywb-ca.pem')

    def __init__(self, config_file='./config.yaml', custom_config=None):
        self.handler = self.handle_request
        self.warcserver = WarcServer(config_file=config_file,
                                     custom_config=custom_config)

        config = self.warcserver.config

        self.debug = config.get('debug', False)

        self.warcserver_server = GeventServer(self.warcserver, port=0)

        self.init_proxy(config)

        self.init_recorder(config.get('recorder'))

        self.init_autoindex(config.get('autoindex'))

        static_path = config.get('static_url_path',
                                 'pywb/static/').replace('/', os.path.sep)
        self.static_handler = StaticHandler(static_path)

        self.cdx_api_endpoint = config.get('cdx_api_endpoint', '/cdx')

        self._init_routes()

        upstream_paths = self.get_upstream_paths(self.warcserver_server.port)

        framed_replay = config.get('framed_replay', True)
        self.rewriterapp = RewriterApp(framed_replay,
                                       config=config,
                                       paths=upstream_paths)

        self.templates_dir = config.get('templates_dir', 'templates')
        self.static_dir = config.get('static_dir', 'static')

        metadata_templ = os.path.join(self.warcserver.root_dir, '{coll}',
                                      'metadata.yaml')
        self.metadata_cache = MetadataCache(metadata_templ)

    def _init_routes(self):
        self.url_map = Map()
        self.url_map.add(
            Rule('/static/_/<coll>/<path:filepath>',
                 endpoint=self.serve_static))
        self.url_map.add(
            Rule('/static/<path:filepath>', endpoint=self.serve_static))
        self.url_map.add(Rule('/collinfo.json', endpoint=self.serve_listing))

        if self.is_valid_coll('$root'):
            coll_prefix = ''
        else:
            coll_prefix = '/<coll>'
            self.url_map.add(Rule('/', endpoint=self.serve_home))

        self.url_map.add(
            Rule(coll_prefix + self.cdx_api_endpoint, endpoint=self.serve_cdx))
        self.url_map.add(Rule(coll_prefix + '/',
                              endpoint=self.serve_coll_page))
        self.url_map.add(
            Rule(coll_prefix + '/timemap/<timemap_output>/<path:url>',
                 endpoint=self.serve_content))

        if self.recorder_path:
            self.url_map.add(
                Rule(coll_prefix + self.RECORD_ROUTE + '/<path:url>',
                     endpoint=self.serve_record))

        self.url_map.add(
            Rule(coll_prefix + '/<path:url>', endpoint=self.serve_content))

    def get_upstream_paths(self, port):
        base_paths = {
            'replay': self.REPLAY_API % port,
            'cdx-server': self.CDX_API % port,
        }

        if self.recorder_path:
            base_paths['record'] = self.recorder_path

        return base_paths

    def init_recorder(self, recorder_config):
        if not recorder_config:
            self.recorder = None
            self.recorder_path = None
            return

        if isinstance(recorder_config, str):
            recorder_coll = recorder_config
            recorder_config = {}
        else:
            recorder_coll = recorder_config['source_coll']

        # TODO: support dedup
        dedup_index = None
        warc_writer = MultiFileWARCWriter(
            self.warcserver.archive_paths,
            max_size=int(recorder_config.get('rollover_size', 1000000000)),
            max_idle_secs=int(recorder_config.get('rollover_idle_secs', 600)),
            filename_template=recorder_config.get('filename_template'),
            dedup_index=dedup_index)

        self.recorder = RecorderApp(
            self.RECORD_SERVER % str(self.warcserver_server.port),
            warc_writer,
            accept_colls=recorder_config.get('source_filter'))

        recorder_server = GeventServer(self.recorder, port=0)

        self.recorder_path = self.RECORD_API % (recorder_server.port,
                                                recorder_coll)

    def init_autoindex(self, auto_interval):
        if not auto_interval:
            return

        from pywb.manager.autoindex import AutoIndexer

        colls_dir = self.warcserver.root_dir if self.warcserver.root_dir else None

        indexer = AutoIndexer(colls_dir=colls_dir, interval=int(auto_interval))

        if not os.path.isdir(indexer.root_path):
            msg = 'No managed directory "{0}" for auto-indexing'
            logging.error(msg.format(indexer.root_path))
            import sys
            sys.exit(2)

        msg = 'Auto-Indexing Enabled on "{0}", checking every {1} secs'
        logging.info(msg.format(indexer.root_path, auto_interval))
        indexer.start()

    def serve_home(self, environ):
        home_view = BaseInsertView(self.rewriterapp.jinja_env, 'index.html')
        fixed_routes = self.warcserver.list_fixed_routes()
        dynamic_routes = self.warcserver.list_dynamic_routes()

        routes = fixed_routes + dynamic_routes

        all_metadata = self.metadata_cache.get_all(dynamic_routes)

        content = home_view.render_to_string(environ,
                                             routes=routes,
                                             all_metadata=all_metadata)

        return WbResponse.text_response(
            content, content_type='text/html; charset="utf-8"')

    def serve_static(self, environ, coll='', filepath=''):
        if coll:
            path = os.path.join(self.warcserver.root_dir, coll,
                                self.static_dir)
        else:
            path = self.static_dir

        environ['pywb.static_dir'] = path

        try:
            return self.static_handler(environ, filepath)
        except:
            self.raise_not_found(environ,
                                 'Static File Not Found: {0}'.format(filepath))

    def get_metadata(self, coll):
        #if coll == self.all_coll:
        #    coll = '*'

        metadata = {'coll': coll, 'type': 'replay'}

        if coll in self.warcserver.list_fixed_routes():
            metadata.update(self.warcserver.get_coll_config(coll))
        else:
            metadata.update(self.metadata_cache.load(coll))

        return metadata

    def serve_coll_page(self, environ, coll='$root'):
        if not self.is_valid_coll(coll):
            self.raise_not_found(environ, 'No handler for "/{0}"'.format(coll))

        self.setup_paths(environ, coll)

        metadata = self.get_metadata(coll)

        view = BaseInsertView(self.rewriterapp.jinja_env, 'search.html')

        wb_prefix = environ.get('SCRIPT_NAME')
        if wb_prefix:
            wb_prefix += '/'

        content = view.render_to_string(environ,
                                        wb_prefix=wb_prefix,
                                        metadata=metadata,
                                        coll=coll)

        return WbResponse.text_response(
            content, content_type='text/html; charset="utf-8"')

    def serve_cdx(self, environ, coll='$root'):
        base_url = self.rewriterapp.paths['cdx-server']

        #if coll == self.all_coll:
        #    coll = '*'

        cdx_url = base_url.format(coll=coll)

        if environ.get('QUERY_STRING'):
            cdx_url += '&' if '?' in cdx_url else '?'
            cdx_url += environ.get('QUERY_STRING')

        try:
            res = requests.get(cdx_url, stream=True)

            content_type = res.headers.get('Content-Type')

            return WbResponse.bin_stream(StreamIter(res.raw),
                                         content_type=content_type)

        except Exception as e:
            return WbResponse.text_response('Error: ' + str(e),
                                            status='400 Bad Request')

    def serve_record(self, environ, coll='$root', url=''):
        if coll in self.warcserver.list_fixed_routes():
            return WbResponse.text_response(
                'Error: Can Not Record Into Custom Collection "{0}"'.format(
                    coll))

        return self.serve_content(environ, coll, url, record=True)

    def serve_content(self,
                      environ,
                      coll='$root',
                      url='',
                      timemap_output='',
                      record=False):
        if not self.is_valid_coll(coll):
            self.raise_not_found(environ, 'No handler for "/{0}"'.format(coll))

        self.setup_paths(environ, coll, record)

        request_uri = environ.get('REQUEST_URI')
        script_name = environ.get('SCRIPT_NAME', '') + '/'
        if request_uri and request_uri.startswith(script_name):
            wb_url_str = request_uri[len(script_name):]

        else:
            wb_url_str = to_native_str(url)

            if environ.get('QUERY_STRING'):
                wb_url_str += '?' + environ.get('QUERY_STRING')

        metadata = self.get_metadata(coll)
        if record:
            metadata['type'] = 'record'

        if timemap_output:
            metadata['output'] = timemap_output

        try:
            response = self.rewriterapp.render_content(wb_url_str, metadata,
                                                       environ)
        except UpstreamException as ue:
            response = self.rewriterapp.handle_error(environ, ue)
            raise HTTPException(response=response)

        return response

    def setup_paths(self, environ, coll, record=False):
        if not coll or not self.warcserver.root_dir:
            return

        if coll != '$root':
            pop_path_info(environ)
            if record:
                pop_path_info(environ)

        paths = [self.warcserver.root_dir]

        if coll != '$root':
            paths.append(coll)

        paths.append(self.templates_dir)

        # jinja2 template paths always use '/' as separator
        environ['pywb.templates_dir'] = '/'.join(paths)

    def serve_listing(self, environ):
        result = {
            'fixed': self.warcserver.list_fixed_routes(),
            'dynamic': self.warcserver.list_dynamic_routes()
        }

        return WbResponse.json_response(result)

    def is_valid_coll(self, coll):
        #if coll == self.all_coll:
        #    return True

        return (coll in self.warcserver.list_fixed_routes()
                or coll in self.warcserver.list_dynamic_routes())

    def raise_not_found(self, environ, msg):
        raise NotFound(response=self.rewriterapp._error_response(environ, msg))

    def _check_refer_redirect(self, environ):
        referer = environ.get('HTTP_REFERER')
        if not referer:
            return

        host = environ.get('HTTP_HOST')
        if host not in referer:
            return

        inx = referer[1:].find('http')
        if not inx:
            inx = referer[1:].find('///')
            if inx > 0:
                inx + 1

        if inx < 0:
            return

        url = referer[inx + 1:]
        host = referer[:inx + 1]

        orig_url = environ['PATH_INFO']
        if environ.get('QUERY_STRING'):
            orig_url += '?' + environ['QUERY_STRING']

        full_url = host + urljoin(url, orig_url)
        return WbResponse.redir_response(full_url, '307 Redirect')

    def __call__(self, environ, start_response):
        return self.handler(environ, start_response)

    def handle_request(self, environ, start_response):
        urls = self.url_map.bind_to_environ(environ)
        try:
            endpoint, args = urls.match()

            response = endpoint(environ, **args)
            return response(environ, start_response)

        except HTTPException as e:
            redir = self._check_refer_redirect(environ)
            if redir:
                return redir(environ, start_response)

            return e(environ, start_response)

        except Exception as e:
            if self.debug:
                traceback.print_exc()

            response = self.rewriterapp._error_response(
                environ, 'Internal Error: ' + str(e), '500 Server Error')
            return response(environ, start_response)

    @classmethod
    def create_app(cls, port):
        app = FrontEndApp()
        app_server = GeventServer(app, port=port, hostname='0.0.0.0')
        return app_server

    def init_proxy(self, config):
        proxy_config = config.get('proxy')
        self.proxy_prefix = None
        if not proxy_config:
            return

        if isinstance(proxy_config, str):
            proxy_coll = proxy_config
            proxy_config = {}
        else:
            proxy_coll = proxy_config['coll']

        if '/' in proxy_coll:
            raise Exception('Proxy collection can not contain "/"')

        proxy_config['ca_name'] = proxy_config.get('ca_name',
                                                   self.PROXY_CA_NAME)
        proxy_config['ca_file_cache'] = proxy_config.get(
            'ca_file_cache', self.PROXY_CA_PATH)

        if proxy_config.get('recording'):
            logging.info(
                'Proxy recording into collection "{0}"'.format(proxy_coll))
            if proxy_coll in self.warcserver.list_fixed_routes():
                raise Exception('Can not record into fixed collection')

            proxy_coll += self.RECORD_ROUTE
            if not config.get('recorder'):
                config['recorder'] = 'live'

        else:
            logging.info(
                'Proxy enabled for collection "{0}"'.format(proxy_coll))

        if proxy_config.get('use_head_insert', True):
            self.proxy_prefix = '/{0}/bn_/'.format(proxy_coll)
        else:
            self.proxy_prefix = '/{0}/id_/'.format(proxy_coll)

        self.handler = WSGIProxMiddleware(self.handle_request,
                                          self.proxy_route_request,
                                          proxy_host=proxy_config.get(
                                              'host', 'pywb.proxy'),
                                          proxy_options=proxy_config)

    def proxy_route_request(self, url, environ):
        """ Return the full url that this proxy request will be routed to
        The 'environ' PATH_INFO and REQUEST_URI will be modified based on the returned url

        Default is to use the 'proxy_prefix' to point to the proxy collection
        """
        return self.proxy_prefix + url
Esempio n. 32
0
class FreeswitchExporterApplication():
    """
    FreeSWITCH prometheus collector HTTP handler.
    """

    # pylint: disable=no-self-use

    def __init__(self, config, duration, errors):
        self._config = config
        self._duration = duration
        self._errors = errors

        self._url_map = Map([
            Rule('/', endpoint='index'),
            Rule('/metrics', endpoint='metrics'),
            Rule('/esl', endpoint='esl'),
        ])

        self._args = {'esl': ['module', 'target']}

        self._views = {
            'index': self.on_index,
            'metrics': self.on_metrics,
            'esl': self.on_esl,
        }

    def on_esl(self, module='default', target='localhost'):
        """
        Request handler for /esl route
        """

        if module in self._config:
            start = time.time()
            output = collect_esl(self._config[module], target)
            response = Response(output)
            response.headers['content-type'] = CONTENT_TYPE_LATEST
            self._duration.labels(module).observe(time.time() - start)
        else:
            response = Response(f"Module '{module}' not found in config")
            response.status_code = 400

        return response

    def on_metrics(self):
        """
        Request handler for /metrics route
        """

        response = Response(generate_latest())
        response.headers['content-type'] = CONTENT_TYPE_LATEST

        return response

    def on_index(self):
        """
        Request handler for index route (/).
        """

        response = Response("""<html>
            <head><title>FreeSWITCH Exporter</title></head>
            <body>
            <h1>FreeSWITCH Exporter</h1>
            <p>Visit <code>/esl?target=1.2.3.4</code> to use.</p>
            </body>
            </html>""")
        response.headers['content-type'] = 'text/html'

        return response

    def view(self, endpoint, values, args):
        """
        Werkzeug views mapping method.
        """

        params = dict(values)
        if endpoint in self._args:
            params.update({
                key: args[key]
                for key in self._args[endpoint] if key in args
            })

        try:
            return self._views[endpoint](**params)
        except Exception:  # pylint: disable=broad-except
            self._errors.labels(args.get('module', 'default')).inc()
            raise InternalServerError(traceback.format_exc())

    @Request.application
    def __call__(self, request):
        urls = self._url_map.bind_to_environ(request.environ)
        view_func = lambda endpoint, values: self.view(endpoint, values,
                                                       request.args)
        return urls.dispatch(view_func, catch_http_exceptions=True)
Esempio n. 33
0
class Isso(object):
    def __init__(self, conf):

        self.conf = conf
        self.db = db.SQLite3(conf.get('general', 'dbpath'), conf)
        self.signer = URLSafeTimedSerializer(
            self.db.preferences.get("session-key"))
        self.markup = html.Markup(conf.section('markup'))
        self.hasher = hash.new(conf.section("hash"))

        super(Isso, self).__init__(conf)

        subscribers = []
        smtp_backend = False
        for backend in conf.getlist("general", "notify"):
            if backend == "stdout":
                subscribers.append(Stdout(None))
            elif backend in ("smtp", "SMTP"):
                smtp_backend = True
            else:
                logger.warn("unknown notification backend '%s'", backend)
        if smtp_backend or conf.getboolean("general", "reply-notifications"):
            subscribers.append(SMTP(self))

        self.signal = ext.Signal(*subscribers)

        self.urls = Map()

        views.Info(self)
        comments.API(self, self.hasher)

    def render(self, text):
        return self.markup.render(text)

    def sign(self, obj):
        return self.signer.dumps(obj)

    def unsign(self, obj, max_age=None):
        return self.signer.loads(obj,
                                 max_age=max_age
                                 or self.conf.getint('general', 'max-age'))

    def dispatch(self, request):
        local.request = request

        local.host = wsgi.host(request.environ)
        local.origin = origin(self.conf.getiter("general",
                                                "host"))(request.environ)

        adapter = self.urls.bind_to_environ(request.environ)

        try:
            handler, values = adapter.match()
        except HTTPException as e:
            return e
        else:
            try:
                response = handler(request.environ, request, **values)
            except HTTPException as e:
                return e
            except Exception:
                logger.exception("%s %s", request.method,
                                 request.environ["PATH_INFO"])
                return InternalServerError()
            else:
                return response

    def wsgi_app(self, environ, start_response):
        response = self.dispatch(JSONRequest(environ))
        return response(environ, start_response)

    def __call__(self, environ, start_response):
        return self.wsgi_app(environ, start_response)
Esempio n. 34
0
class StoreHandler(object):
    def __init__(self, store, username, password, realm_name):
        self.store = store
        self.username = username
        self.password = password
        self.realm_name = realm_name

        self.router = Map([
            Rule("/<key>", methods=["GET"], endpoint="get"),
            Rule("/", methods=["GET"], endpoint="get_list"),
            Rule("/<key>", methods=["PUT"], endpoint="put"),
            Rule("/", methods=["PUT"], endpoint="put_list"),
            Rule("/<key>", methods=["DELETE"], endpoint="delete"),
            Rule("/", methods=["DELETE"], endpoint="delete_list"),
        ],
                          encoding_errors="strict")

    def __call__(self, environ, start_response):
        return self.wsgi_app(environ, start_response)

    @responder
    def wsgi_app(self, environ, start_response):
        route = self.router.bind_to_environ(environ)
        try:
            endpoint, args = route.match()
        except HTTPException as exc:
            return exc

        request = Request(environ)
        request.encoding_errors = "strict"

        response = Response()

        try:
            if endpoint == "get":
                self.get(request, response, args["key"])
            elif endpoint == "get_list":
                self.get_list(request, response)
            elif endpoint == "put":
                self.put(request, response, args["key"])
            elif endpoint == "put_list":
                self.put_list(request, response)
            elif endpoint == "delete":
                self.delete(request, response, args["key"])
            elif endpoint == "delete_list":
                self.delete_list(request, response)
            else:
                raise RuntimeError()
        except HTTPException as exc:
            return exc

        return response

    def authorized(self, request):
        return request.authorization is not None and \
            request.authorization.type == "basic" and \
            request.authorization.username == self.username and \
            request.authorization.password == self.password

    def get(self, request, response, key):
        # Limit charset of keys.
        if re.match("^[A-Za-z0-9_]+$", key) is None:
            return NotFound()
        if key not in self.store:
            raise NotFound()

        response.status_code = 200
        response.headers['Timestamp'] = "%0.6f" % time.time()
        response.mimetype = "application/json"
        response.data = json.dumps(self.store.retrieve(key))

    def get_list(self, request, response):
        response.status_code = 200
        response.headers['Timestamp'] = "%0.6f" % time.time()
        response.mimetype = "application/json"
        response.data = json.dumps(self.store.retrieve_list())

    def put(self, request, response, key):
        # Limit charset of keys.
        if re.match("^[A-Za-z0-9_]+$", key) is None:
            return Forbidden()
        if not self.authorized(request):
            logger.warning("Unauthorized request.",
                           extra={
                               'location': request.url,
                               'details': repr(request.authorization)
                           })
            raise CustomUnauthorized(self.realm_name)
        if request.mimetype != "application/json":
            logger.warning("Unsupported MIME type.",
                           extra={
                               'location': request.url,
                               'details': request.mimetype
                           })
            raise UnsupportedMediaType()

        try:
            data = json.load(request.stream)
        except (TypeError, ValueError):
            logger.warning("Wrong JSON.", extra={'location': request.url})
            raise BadRequest()

        try:
            if key not in self.store:
                self.store.create(key, data)
            else:
                self.store.update(key, data)
        except InvalidData:
            logger.warning("Invalid data.",
                           exc_info=True,
                           extra={
                               'location': request.url,
                               'details': pprint.pformat(data)
                           })
            raise BadRequest()

        response.status_code = 204

    def put_list(self, request, response):
        if not self.authorized(request):
            logger.info("Unauthorized request.",
                        extra={
                            'location': request.url,
                            'details': repr(request.authorization)
                        })
            raise CustomUnauthorized(self.realm_name)
        if request.mimetype != "application/json":
            logger.warning("Unsupported MIME type.",
                           extra={
                               'location': request.url,
                               'details': request.mimetype
                           })
            raise UnsupportedMediaType()

        try:
            data = json.load(request.stream)
        except (TypeError, ValueError):
            logger.warning("Wrong JSON.", extra={'location': request.url})
            raise BadRequest()

        try:
            self.store.merge_list(data)
        except InvalidData:
            logger.warning("Invalid data.",
                           exc_info=True,
                           extra={
                               'location': request.url,
                               'details': pprint.pformat(data)
                           })
            raise BadRequest()

        response.status_code = 204

    def delete(self, request, response, key):
        # Limit charset of keys.
        if re.match("^[A-Za-z0-9_]+$", key) is None:
            return NotFound()
        if key not in self.store:
            raise NotFound()
        if not self.authorized(request):
            logger.info("Unauthorized request.",
                        extra={
                            'location': request.url,
                            'details': repr(request.authorization)
                        })
            raise CustomUnauthorized(self.realm_name)

        self.store.delete(key)

        response.status_code = 204

    def delete_list(self, request, response):
        if not self.authorized(request):
            logger.info("Unauthorized request.",
                        extra={
                            'location': request.url,
                            'details': repr(request.authorization)
                        })
            raise CustomUnauthorized(self.realm_name)

        self.store.delete_list()

        response.status_code = 204
Esempio n. 35
0
class Word2VecGateway(object):

    ### @brief Constructor
    def __init__(self, config):
    
        self.url_map = Map([
                # Shows general info about this server
                Rule('/', endpoint='usage_info'),
                # Pings the server to check if everything is fine
                Rule('/ping', endpoint='ping'),
                # Call to get similarity value
                Rule('/word2vecdiff', endpoint='word2vec_diff')
            ])
        self.word2vec_model = models.Word2Vec.load_word2vec_format(config['word2vec_model'], binary=True )

    # Ensure clean up proceeds correctly
    def cleanup(self):
        self.send_to_log("Cleaning up gateway server...")
        ## Add any clean up here

    ### PROCESSORS ###
    
    ### @brief Displays general info
    ### Usage: http://<server>:<port>/
    ###  Parameters: None
    ###
    def on_usage_info(self,request):
       info = "This gateway helps services word similarity requests."
       return Response(info, mimetype='text/plain')

    ### @brief Pings the service to ensure that everything is fine
    ### Usage: http://<server>:<port>/ping
    ###  Parameters: None
    ###
    def on_ping(self, request):
        info = '{"status": 1}'
        return Response(info, mimetype='text/json')

    ### @brief Takes in two words and returns their similarity value
    ### Usage: http://<server>:<port>/word2vec_diff
    ###  Parameters: (POST) word1, word2
    ###  Multi-word expressions are accepted, delimited by spaces:
    ###    apple
    ###    burger king 
    ###    ...
    def on_word2vec_diff(self, request):
        self.send_to_log("\non_word2vec_diff() initiated...")
        if request.method == 'POST':
            
            proceed = True
            
            # Retrieve arguments from the POST request
            word1 = str(request.form['word1'])
            word1_tokens = word1.split( " " )
            word1_vectors = [ ]
            for token in word1_tokens:
                if not token in self.word2vec_model:
                    self.send_to_log("\nWARN: Ignoring word1 OOV token: " + token )
                    info = '{"status": 1, "word2vec_sim": 0}'
                    proceed = False
                    break
                word1_vectors.append( numpy.array( self.word2vec_model[token] ) )
            
            word2 = str(request.form['word2'])
            word2_tokens = word2.split( " " )
            word2_vectors = [ ]
            for token in word2_tokens:
                if not token in self.word2vec_model:
                    self.send_to_log("\nWARN: Ignoring word2 OOV token: " + token )
                    info = '{"status": 1, "word2vec_sim": 0}'
                    proceed = False
                    break
                word2_vectors.append( numpy.array( self.word2vec_model[token] ) )

            self.send_to_log("\n-> word1: " + word1 + " - word2: " + word2)

            if proceed:
                self.send_to_log("\nComputing...")
                word1_aggregate = word1_vectors[0]
                for i in range(1,len(word1_vectors)):
                    word1_aggregate *= word1_vectors[i]
                #print word1_aggregate
                #word1_aggregate /= len( word1_vectors )
                word2_aggregate = word2_vectors[0]
                for i in range(1, len(word2_vectors)):
                    word2_aggregate *= word2_vectors[i]
                #print word2_aggregate
                #word2_aggregate /= len( word2_vectors )
                mag_word1vec = math.sqrt( numpy.dot( word1_aggregate, word1_aggregate ) )
                mag_word2vec = math.sqrt( numpy.dot( word2_aggregate, word2_aggregate ) )
                cosim_value = numpy.dot( word1_aggregate, word2_aggregate ) / ( mag_word1vec * mag_word2vec )
                #cosim_value = numpy.dot( word1_aggregate, word2_aggregate )
                info = '{"status": 1, "word2vec_sim": ' + str(cosim_value) + '}'
                self.send_to_log("\n " + word1 + " <-> " + word2 + " :" + str(cosim_value) )

        else:
            info = '{"status": -1, "message": Only POST is supported"}'
       
        self.send_to_log("\n\n -> " + info + "\n\n" )
        return Response(info, mimetype='text/json')

    ### SCAFFOLDING ###

    ### @brief Decide on the type of request we get, and dispatch it to
    ###         a suitable handler
    def dispatch_request(self, request):
        adapter = self.url_map.bind_to_environ(request.environ)
        try:
            endpoint, values = adapter.match()
            return getattr(self, 'on_' + endpoint)(request, **values)
        except HTTPException, e:
            # Log error
            self.send_to_log("Error dispatching request.") 
            # + e)
            return e
Esempio n. 36
0
class Application(object):

    url_map = None
    view_map = {}
    mimetype_map = {}
    config = {}

    __method_map = {
        'get': 'load',
        'put': 'save',
        'post': 'save',
        'delete': 'delete'
    }

    def __init__(self):
        self.url_map = Map()
        self.mimetype_map['*/*'] = MimetypeHandlerBase

        config_path = os.path.join(
            os.getcwd(),
            os.environ.get('BLAMP_CONFIG', '/usr/local/etc/blamp.ini'))
        if not os.path.exists(config_path):
            raise Exception('Config file not found: ' + config_path)
        cp = SafeConfigParser()
        cp.read(config_path)
        self.config = dict(cp.items('default'))

        # Validate required config options
        if 'templates' not in self.config:
            raise Exception("'template' config option missing")
        self.config['templates'] = os.path.join(os.getcwd(),
                                                self.config['templates'])

    def add_mimetype(self, mimetype, handler):
        self.mimetype_map[mimetype] = handler

    def add_view(self,
                 url,
                 name,
                 methods=['GET'],
                 resource=None,
                 resource_get=None,
                 resource_put=None,
                 resource_post=None,
                 resource_delete=None,
                 template=None,
                 acl_get='load',
                 acl_put='update',
                 acl_post='create',
                 acl_delete='delete',
                 accept=None,
                 accept_get=None,
                 accept_put=None,
                 accept_post=None,
                 accept_delete=None):
        """ Add and configure a view. """

        self.url_map.add(Rule(url, endpoint=name))
        self.view_map[name] = {
            "methods": [m.lower() for m in methods],
            "resource": resource,
            "resource_get": resource_get,
            "resource_put": resource_put,
            "resource_post": resource_post,
            "resource_delete": resource_delete,
            "acl_get": acl_get,
            "acl_put": acl_put,
            "acl_post": acl_post,
            "acl_delete": acl_delete,
            "accept": accept,
            "accept_get": accept_get,
            "accept_put": accept_put,
            "accept_post": accept_post,
            "accept_delete": accept_delete,
            "template": template
        }

    def wsgi_app(self, environ, start_response):
        request = Request(environ)
        urls = self.url_map.bind_to_environ(environ)
        try:
            # Define view
            endpoint, args = urls.match()
            if endpoint not in self.view_map:
                raise NotFound("Endpoint not found in view_map.")
            view = self.view_map[endpoint]
            method = request.method.lower()
            if method not in view['methods']:
                raise MethodNotAllowed()

            resource = view['resource_' + method] or view['resource']
            accept = view['accept_' +
                          method] or view['accept'] or ['text/html']
            acl = view['acl_' + method]
            data = None
            query = None

            accepted = request.accept_mimetypes.best_match(accept)
            if not accepted:
                raise NotAcceptable()

            if resource:
                resource = resource(request)
                resource.load(args, query)

                if acl and not resource.check_acl(acl):
                    raise Forbidden()

                if not resource.check_exists():
                    raise NotFound()

                if method == 'put' or method == 'post':
                    resource.save(data)
                elif method == 'delete':
                    resource.delete()
                    resource = None

            accepted_handler = self.mimetype_map[accepted] \
                               if accepted in self.mimetype_map \
                               else self.mimetype_map['*/*']
            mimetype_handler = accepted_handler(self)
            response = Response(mimetype_handler(request, view, resource))
            response.headers['Content-Type'] = accepted

            if method == 'post' and resource:
                response.status_code = 201
                response.headers['Location'] = resource.resource_url()

            return response(environ, start_response)

        except HTTPException as e:
            return e(environ, start_response)

    def __call__(self, environ, start_response):
        return self.wsgi_app(environ, start_response)
Esempio n. 37
0
class App():
    def __init__(self, work_dir):
        self.work_dir = work_dir
        self._loading = False
        self._load_lock = Lock()
        self.admin = None
        self.task = None
        self.users = {}
        self.roles = None
        self._busy = 0
        self.pid = os.getpid()
        self.task_server_modified = False
        self.task_client_modified = True
        self.under_maintenance = False
        self.jam_dir = os.path.dirname(jam.__file__)
        self.jam_version = jam.version()
        self.application_files = {
            '/': self.work_dir,
            '/jam/': self.jam_dir
        }
        self.fileserver = SharedDataMiddleware(None, self.application_files, cache_timeout=0.1)
        self.url_map = Map([
            Rule('/', endpoint='root_file'),
            Rule('/<file_name>', endpoint='root_file'),
            Rule('/js/<file_name>', endpoint='file'),
            Rule('/css/<file_name>', endpoint='file'),
            Rule('/jam/js/<file_name>', endpoint='file'),
            Rule('/jam/js/ace/<file_name>', endpoint='file'),
            Rule('/jam/css/<file_name>', endpoint='file'),
            Rule('/jam/img/<file_name>', endpoint='file'),
            Rule('/api', endpoint='api'),
            Rule('/upload', endpoint='upload')
        ])

    def check_admin(self):
        if self.admin:
            return True
        else:
            result = False
            if not self._loading:
                self._loading = True;
                try:
                    with self._load_lock:
                        import adm_server
                        self.admin = adm_server.create_admin(self)
                finally:
                    self._loading = False;
                result = True
            return result

    def check_task(self):
        if self.task:
            return True
        else:
            result = False
            if not self._loading:
                self._loading = True
                try:
                    with self._load_lock:
                        if self.admin is None:
                            import adm_server
                            self.admin = adm_server.create_admin(self)
                        self.task = self.admin.create_task()
                finally:
                    self._loading = False
                result = True
            return result

    def get_task(self):
        self.check_task()
        return self.task

    def __call__(self, environ, start_response):
        return self.wsgi_app(environ, start_response)

    def wsgi_app(self, environ, start_response):
        if self.check_admin():
            request = Request(environ)
            adapter = self.url_map.bind_to_environ(request.environ)
            try:
                endpoint, values = adapter.match()
                if endpoint in ['file', 'root_file']:
                    return self.serve_file(environ, start_response, endpoint, **values)
                elif endpoint in ['api', 'upload']:
                    response = getattr(self, 'on_' + endpoint)(request, **values)
            except HTTPException, e:
                if peek_path_info(environ) == 'ext':
                    response = self.on_ext(request)
                else:
                    response = e
            return response(environ, start_response)
        else:
Esempio n. 38
0
class CheckmkRESTAPI:
    def __init__(self, debug: bool = False) -> None:
        self.debug = debug
        # This intermediate data structure is necessary because `Rule`s can't contain anything
        # other than str anymore. Technically they could, but the typing is now fixed to str.
        self.endpoints: Dict[str, WSGIApplication] = {
            "swagger-ui": ServeSwaggerUI(prefix="/[^/]+/check_mk/api/[^/]+/ui"),
            "swagger-ui-yaml": ServeSpec("swagger-ui", "yaml"),
            "swagger-ui-json": ServeSpec("swagger-ui", "json"),
            "doc-yaml": ServeSpec("doc", "yaml"),
            "doc-json": ServeSpec("doc", "json"),
        }
        rules: List[Rule] = []
        endpoint: Endpoint
        for endpoint in ENDPOINT_REGISTRY:
            if self.debug:
                # This helps us to make sure we can always generate a valid OpenAPI yaml file.
                _ = endpoint.to_operation_dict()

            rules.append(
                Rule(
                    endpoint.default_path,
                    methods=[endpoint.method],
                    endpoint=endpoint.ident,
                )
            )
            self.endpoints[endpoint.ident] = Authenticate(endpoint)

        self.url_map = Map(
            [
                Submount(
                    "/<path:_path>",
                    [
                        Rule("/ui/", endpoint="swagger-ui"),
                        Rule("/ui/<path:path>", endpoint="swagger-ui"),
                        Rule("/openapi-swagger-ui.yaml", endpoint="swagger-ui-yaml"),
                        Rule("/openapi-swagger-ui.json", endpoint="swagger-ui-json"),
                        Rule("/openapi-doc.yaml", endpoint="doc-yaml"),
                        Rule("/openapi-doc.json", endpoint="doc-json"),
                        *rules,
                    ],
                )
            ]
        )
        self.wsgi_app = OverrideRequestMethod(self._wsgi_app)

    def __call__(self, environ: WSGIEnvironment, start_response: StartResponse) -> WSGIResponse:
        return self.wsgi_app(environ, start_response)

    def _wsgi_app(self, environ: WSGIEnvironment, start_response: StartResponse) -> WSGIResponse:
        urls = self.url_map.bind_to_environ(environ)
        endpoint: Optional[Endpoint] = None
        try:
            result: Tuple[str, Mapping[str, Any]] = urls.match(return_rule=False)
            endpoint_ident, matched_path_args = result  # pylint: disable=unpacking-non-sequence
            wsgi_app = self.endpoints[endpoint_ident]
            if isinstance(wsgi_app, Authenticate):
                endpoint = wsgi_app.endpoint

            # Remove _path again (see Submount above), so the validators don't go crazy.
            path_args = {key: value for key, value in matched_path_args.items() if key != "_path"}

            # This is an implicit dependency, as we only know the args at runtime, but the
            # function at setup-time.
            environ[ARGS_KEY] = path_args

            req = Request(environ)
            resp = Response()
            with AppContext(self, stack=app_stack()), RequestContext(
                req=req,
                resp=resp,
                funnel=OutputFunnel(resp),
                config_obj=config.make_config_object(config.get_default_config()),
                endpoint=endpoint,
                user=LoggedInNobody(),
                display_options=DisplayOptions(),
                stack=request_stack(),
                url_filter=PrependURLFilter(),
            ), cmk.utils.store.cleanup_locks(), sites.cleanup_connections():
                config.initialize()
                load_dynamic_permissions()
                return wsgi_app(environ, start_response)
        except ProblemException as exc:
            return exc(environ, start_response)
        except HTTPException as exc:
            # We don't want to log explicit HTTPExceptions as these are intentional.
            assert isinstance(exc.code, int)
            return problem(
                status=exc.code,
                title=http.client.responses[exc.code],
                detail=str(exc),
            )(environ, start_response)
        except MKException as exc:
            if self.debug:
                raise

            return problem(
                status=EXCEPTION_STATUS.get(type(exc), 500),
                title="An exception occurred.",
                detail=str(exc),
            )(environ, start_response)
        except Exception as exc:
            crash = APICrashReport.from_exception()
            crash_reporting.CrashReportStore().save(crash)
            logger.exception("Unhandled exception (Crash-ID: %s)", crash.ident_to_text())
            if self.debug:
                raise

            request = Request(environ)
            site = config.omd_site()
            query_string = urllib.parse.urlencode(
                [
                    ("crash_id", (crash.ident_to_text())),
                    ("site", site),
                ]
            )
            crash_url = f"{request.host_url}{site}/check_mk/crash.py?{query_string}"
            crash_details = {
                "crash_id": (crash.ident_to_text()),
                "crash_report": {
                    "href": crash_url,
                    "method": "get",
                    "rel": "cmk/crash-report",
                    "type": "text/html",
                },
            }
            if user.may("general.see_crash_reports"):
                crash_details["stack_trace"] = traceback.format_exc().split("\n")

            return problem(
                status=500,
                title=http.client.responses[500],
                detail=str(exc),
                ext=crash_details,
            )(environ, start_response)
Esempio n. 39
0
class Application(object):
    endp_count = 0

    def __init__(self,
                 jinja_template_path=None,
                 jinja_dir="templates",
                 static_conf={
                     "enable": False,
                     "dir": "/static",
                     "path": ""
                 }):
        self.jinja_template_path = jinja_template_path
        self.jinja_dir = jinja_dir
        self.urls = Map([])
        self.endpoints = {}
        self.methods = {}
        self.calldata = {}
        self.cors_endpoints = []
        self.wrapper = HttpWrapper()
        self._setup_wsgi(enable_static=True,
                         static_dir=static_conf["dir"],
                         static_path=static_conf["path"])
        if not "banner" in static_conf:
            self.__banner = standard_banner
        else:
            self.__banner = static_conf["banner"]
        self._show_banner()

    def _show_banner(self):
        print(self.__banner)

    def run(self, host="127.0.0.1", port=8080, use_reloader=False):
        if os.environ["GOFRI_HAS_ROOT"] == "True":
            self.jinja_template_path = "{}/{}".format(
                os.environ["GOFRI_ROOT_PATH"], "templates")
            self.jinja_env = self._setup_jinja()

        run_simple(host, port, self, use_reloader=use_reloader)

    def _setup_jinja(self):
        env = Environment(loader=FileSystemLoader(self.jinja_template_path),
                          autoescape=True)
        env.trim_blocks = True
        return env

    def _setup_wsgi(self, enable_static, static_dir, static_path):
        if enable_static:
            self.wsgi_app = SharedDataMiddleware(self.wsgi_app,
                                                 {static_dir: static_path})

    def render_template(self, template_name, **kwargs):
        return self.jinja_env.get_template(template_name).render(**kwargs)

    def set_url_endpoint(self,
                         path,
                         func,
                         methods,
                         request_nm="",
                         params_nm="",
                         headers_nm="",
                         body_nm="",
                         json_nm="",
                         json="",
                         response_type="",
                         cors=False):

        endp_name = "endp{}".format(Application.endp_count)
        Application.endp_count += 1
        self.urls.add(Rule(path, endpoint=endp_name))

        param_names = [
            p.strip() for p in params_nm.split(";") if p.strip() != ""
        ]
        header_names = [
            h.strip() for h in headers_nm.split(";") if h.strip() != ""
        ]
        body_names = [b.strip() for b in body_nm.split(";") if b.strip() != ""]
        json_names = [j.strip() for j in json_nm.split(";") if j.strip() != ""]

        is_get = False

        func = self.wrapper.wrap_function(func, is_get, request_nm,
                                          param_names, header_names,
                                          body_names, json_names, json,
                                          response_type)

        self.endpoints[endp_name] = func
        self.methods[endp_name] = methods

        if cors:
            self.cors_endpoints.append(endp_name)

    def render(self, name, **context):
        template = self.jinja_env.get_template(name)
        return Response(template.render(context),
                        mimetype="text/html",
                        content_type="text/html")

    def dispatch_request(self, request):
        adapter = self.urls.bind_to_environ(request.environ)
        try:
            endpoint, values = adapter.match()
            cors_enabled = endpoint in self.cors_endpoints
            if not request.method in self.methods[endpoint]:

                if not cors_is_valid(request, self.methods):
                    raise E.MethodNotAllowed()

            resp = self.endpoints[endpoint](request, *(), **values)

            if cors_enabled:
                origin_present = "Access-Control-Allow-Origin" in resp.headers
                headers_present = "Access-Control-Allow-Headers" in resp.headers
                if not origin_present:
                    resp.headers["Access-Control-Allow-Origin"] = "*"
                if not headers_present:
                    resp.headers[
                        "Access-Control-Allow-Headers"] = "Content-Type, Accept"

            return resp
        except E.HTTPException as e:
            return Response(status=e.code,
                            response=e.get_body(),
                            mimetype="application/xml",
                            content_type="application/xml")

    def __call__(self, environ, start_response):
        return self.wsgi_app(environ, start_response)

    def wsgi_app(self, environ, start_response):
        request = Request(environ)
        response = self.dispatch_request(request)
        return response(environ, start_response)
Esempio n. 40
0
class Tumeme(object):
    def __init__(self):
        if not (os.path.isfile(config.DB_PATH) and os.path.isdir(
                config.IMG_DIR) and os.path.isdir(config.QUEUE_DIR)):
            print("the given img, db, or queue path points to nirvana")
            raise ValueError

        template_path = os.path.join(os.path.dirname(__file__), 'templates')
        self.jinja_env = Environment(loader=FileSystemLoader(template_path),
                                     autoescape=True)

        self.url_map = Map([
            Rule("/", endpoint="main_page"),
            Rule("/upload", endpoint="upload_page"),
            Rule("/vote", endpoint="vote")
        ])

    def dispatch_request(self, request):
        adapter = self.url_map.bind_to_environ(request.environ)

        try:
            endpoint, values = adapter.match()
            return getattr(self, endpoint)(request, **values)
        except NotFound as e:
            return self.error_404(request)
        # catch all other HTTPExceptions with generic error page
        except HTTPException as e:
            print("catched error, dude")
            return self.sum_ting_wong(request, str(e))

    def wsgi_app(self, environ, start_response):
        request = Request(environ)
        response = self.dispatch_request(request)
        return response(environ, start_response)

    def render_template(self, template_name, **context):
        #TODO: caching
        t = self.jinja_env.get_template(template_name)
        return Response(t.render(context), mimetype='text/html')

    """ the logic for the individual pages below  """

    def upload_page(self, request):
        """ upload page logic - does what you‘d expect """
        def allowed_file(filename):
            ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'gif'])
            """ see flask docs """
            return '.' in filename and \
            filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

        # detect "kackcha-spam"
        identity = str(request.remote_addr) + str(
            request.user_agent
        )  # not really secure, but might be good enough in many cases
        if len(
                Database.read(config.DB_PATH,
                              "SELECT * FROM kackchas WHERE identity=?",
                              payload=(identity, ),
                              fetch_number=10)) > 8:
            print("User spammy with the kackchas")
            kackcha.delete_by_id(identity)

        # first captcha stuff
        captcha_url = os.path.join("kackchas", kackcha.create_new(identity))
        if not captcha_url:
            return self.render_template(
                "upload.html",
                error=
                "Rolling out your own captcha: what could possibly go wrong? (sorry)"
            )

        # now the actual upload magic
        if request.method == "POST":
            # first: is the captcha solved at all, and if so, correctly?
            valid_captcha_names = [
                os.path.join("kackchas", kack[0]) for kack in Database.read(
                    config.DB_PATH,
                    "SELECT name FROM kackchas",
                    fetch_number=config.NUMBER_OF_KACKCHAS)
            ]
            print((request.form["kackcha-name"], ) in valid_captcha_names)

            # user tried to be smart, tell him/her/it to f**k off
            if "kackcha" not in request.form or "kackcha-name" not in request.form or request.form[
                    "kackcha-name"] not in valid_captcha_names:
                return self.render_template(
                    "upload.html",
                    error="You messed around with the captchas, didn‘t you?",
                    captcha_url=captcha_url)

            expected_result = Database.read(
                config.DB_PATH,
                "SELECT solution FROM kackchas WHERE name=?",
                payload=(request.form["kackcha-name"].replace(
                    "kackchas/", "", 1), ))  # TODO: less hacky

            if not expected_result:
                return self.render_template(
                    "upload.html",
                    error="I f****d something up with the captchas, sorry.",
                    captcha_url=captcha_url)

            # check if user entered the right solution for the captcha
            if str(expected_result[0][0]) != str(request.form["kackcha"]):
                kackcha._delete(request.form["kackcha-name"].replace(
                    "kackchas/", "", 1))  #TODO: less hacky
                return self.render_template(
                    "upload.html",
                    error=
                    "Captcha solution incorrect, so you‘re either brainlet or robot, can‘t tell.",
                    captcha_url=captcha_url)
            else:
                # user solved captcha, delet dis
                try:
                    kackcha._delete(request.form["kackcha-name"].replace(
                        "kackchas/", "", 1))  #TODO: less hacky
                except:
                    print("kakcha already ded")

            # now bunch of checks if form data seems valid
            if not "picture" in request.files or not allowed_file(
                    request.files["picture"].filename
            ):  # hey it‘s me ur de morgan
                return self.render_template(
                    "upload.html",
                    error="This does not look like a picture, m‘harald.",
                    captcha_url=captcha_url)
            elif not "title" in request.form or not "memetype" in request.form:
                print(request.form)
                return self.render_template(
                    "upload.html",
                    error=
                    "Your post needs a title and at least one keyword, m‘harald.",
                    captcha_url=captcha_url)
            elif len(request.form["title"]) == 0 or len(
                    request.form["title"]) > 42:  # check for too long words
                return self.render_template(
                    "upload.html",
                    error=
                    "Your title needs between one and 42 characters, m‘harald.",
                    captcha_url=captcha_url)
            elif len(request.form["memetype"]) > 16:
                return self.render_template(
                    "upload.html",
                    error=
                    "No more than 16 characters for the memetype, m‘harald.",
                    captcha_url=captcha_url)

            # okay, data seems kind of sane now, put the pic in our queue folder and save the metadata
            pic = request.files["picture"]
            filename = os.path.join(config.QUEUE_DIR,
                                    secure_filename(pic.filename))

            # make sure we don‘t overwrite existing files
            while os.path.isfile(os.path.abspath(filename)) or os.path.isfile(
                    os.path.abspath(
                        os.path.join(config.IMG_DIR,
                                     os.path.split(filename)[1]))):
                print(filename)
                filename = "".join(filename.split(".")[:-1]) + str(
                    random.randrange(0, 1000)) + "." + filename.split(".")[-1]

            pic.save(filename)

            # we insert the metadata of our image in the queue db, the MemeGatekeeper will keep track of which one‘s to actually deliver by putting them in /img and the corresponding img db
            metadata = (request.form["title"], request.form["memetype"],
                        os.path.split(filename)[1],
                        datetime.datetime.now().isoformat(), "0", "0", "0"
                        )  #    title, memetype, pic_url, date, upvotes
            Database.apply_query(
                config.DB_PATH,
                "INSERT INTO queue VALUES(?, ?, ?, ?, ?, ?, ?)",
                payload=metadata)

            # the user uploaded his image, back to the frontpage (we want the ones with the highest rank to be showed first)
            dankest_memes = Database.read(config.DB_PATH,
                                          "SELECT * FROM " +
                                          config.IMG_TABLE_NAME +
                                          " ORDER BY rank DESC",
                                          fetch_number=config.IMG_PER_PAGE)
            return redirect("/?success")

        return self.render_template("upload.html", captcha_url=captcha_url)

    def main_page(self, request):
        """ the front page """

        info, error, already_voted = None, None, None  # should use attributes instead, but f**k oop
        if "success" in request.args:
            info = "Thanks for uploading dank memes, m‘harald."

        current_page = 0
        if "page" in request.args:
            try:
                current_page = abs(int(request.args["page"]))
                if current_page > config.MAX_FRONTPAGE_LEN:
                    current_page = 0
                    info = "You outreached the last page. Congrats for not being normie."

            except:
                print("unable to parse given page")

        dankest_memes = Database.read(
            config.DB_PATH,
            "SELECT * FROM " + config.IMG_TABLE_NAME +
            " ORDER BY rank DESC LIMIT " + str(config.IMG_PER_PAGE) +
            " OFFSET " + str(current_page * config.IMG_PER_PAGE),
            fetch_number=config.IMG_PER_PAGE)

        max_page = math.ceil(
            len(
                Database.read(config.DB_PATH,
                              "SELECT * FROM " + config.IMG_TABLE_NAME,
                              fetch_number=config.MAX_FRONTPAGE_LEN)) /
            config.IMG_PER_PAGE) - 1

        # check if user already has user-id, if not. create a new one (this is just a temporary soulution)
        if not request.cookies.get("user-id"):
            identity = str(request.remote_addr) + str(
                request.user_agent
            )  # not really secure, but might be good enough in many cases
            evil_user = len(
                Database.read(
                    config.DB_PATH,
                    "SELECT identity FROM cookiejar WHERE identity=?",
                    payload=(identity, ))) != 0
            if evil_user:
                error = "Don‘t delete cookies if you want to vote. Try again later."
                response = self.render_template("content.html",
                                                error=error,
                                                content=dankest_memes,
                                                current_page=current_page,
                                                max_page=max_page)
                return response
            else:
                response = self.render_template("content.html",
                                                error=error,
                                                content=dankest_memes,
                                                current_page=current_page,
                                                max_page=max_page)
                response.set_cookie(
                    "user-id",
                    os.urandom(32) + "(nsa-random)".encode("utf-8"),
                    max_age=60 * 60 * 8)  #  8h  cookie TODO: use secure cookie
                return response
        else:
            # used to change the style of the buttons which the user already voted on
            already_voted = Database.read(
                config.DB_PATH,
                "SELECT pic_url, upvoted, downvoted FROM cookiejar WHERE uid=?",
                payload=(request.cookies.get("user-id"), ),
                fetch_number=config.MAX_FRONTPAGE_LEN)
            print(already_voted)
            # add vote_info of already_voted to the memes in dankest_memes TODO: make less ugly
            for i, meme in enumerate(dankest_memes):
                # select the matching vote info
                meme = list(meme)
                meme.append(None)
                dankest_memes[
                    i] = meme  # we want an additional element to store the vote-info
                for vote_info in already_voted:
                    if vote_info[0] == meme[
                            2]:  # pic_url == pic_url (TODO: result abstraction!)
                        print("vote-info", end="")
                        print(vote_info)
                        dankest_memes[i][-1] = vote_info[
                            1:]  #add the vote-info
                        break

        uid = request.cookies.get("user-id")
        identity = str(request.remote_addr) + str(
            request.user_agent
        )  # not really secure, but might be good enough in many cases
        # identify user with same identity but other user-id-cookie -> fishy, probably just deleted his cookie -> cant post till identities get deleted (every 25 mins, see MemeGatekeeper)
        evil_user = len(
            Database.read(
                config.DB_PATH,
                "SELECT identity FROM cookiejar WHERE identity=? AND uid != ?",
                payload=(identity, uid))) != 0
        if evil_user:
            error = "Don‘t delete cookies if you want to vote. Try again later."
        return self.render_template("content.html",
                                    content=dankest_memes,
                                    info=info,
                                    error=error,
                                    current_page=current_page,
                                    max_page=max_page)

    def vote(self, request):
        """ implementation of up/downvotes: the client sends an asynchronous POST-request """

        if request.method == "POST" and "vote" in request.form and "post" in request.form and request.cookies.get(
                "user-id"):
            #print("vote: " + request.form["vote"] + "\n post: " + request.form["post"])

            uid = request.cookies.get("user-id")
            pic_url = request.form["post"]
            vote = request.form["vote"]

            identity = str(request.remote_addr) + str(
                request.user_agent
            )  # not really secure, but might be good enough in many cases
            evil_user = len(
                Database.read(
                    config.DB_PATH,
                    "SELECT identity FROM cookiejar WHERE identity=? AND uid != ?",
                    payload=(identity, uid))) != 0
            if evil_user:
                print("evil user detected")
                return redirect("/")  # just do nothing

            # does the given meme even exist?
            if Database.read(config.DB_PATH,
                             "SELECT * FROM img WHERE pic_url=?",
                             payload=(pic_url, )):
                user_history = Database.read(
                    config.DB_PATH,
                    "SELECT * FROM cookiejar WHERE uid=? AND pic_url=?",
                    payload=(uid, pic_url),
                    result_abstraction=OrderedDict([("uid", ""), ("post", ""),
                                                    ("upvoted", ""),
                                                    ("downvoted", ""),
                                                    ("identity", "")]))

                # user has not voted on the meme given by pic_url
                if not user_history:
                    # check if still space
                    stored_cookies = Database.read(
                        config.DB_PATH,
                        "SELECT uid FROM cookiejar",
                        fetch_number=config.MAX_COOKIEJAR_ENTRIES)
                    # if not, delete the 40 first cookies
                    if len(stored_cookies) == config.MAX_COOKIEJAR_ENTRIES:
                        for i in range(40):
                            Database.apply_query(
                                config.DB_PATH,
                                "DELETE FROM cookiejar WHERE uid=?",
                                payload=(stored_cookies[i][0], ))

                    payload = (uid, pic_url, int(vote == "up"),
                               int(vote == "down"), identity)
                    Database.apply_query(
                        config.DB_PATH,
                        "INSERT INTO cookiejar VALUES(?, ?, ?, ?, ?)", payload)
                    if vote == "up":
                        Database.apply_query(
                            config.DB_PATH,
                            "UPDATE img SET upvotes=upvotes+1 WHERE pic_url=?",
                            payload=(pic_url, ))
                    elif vote == "down":
                        Database.apply_query(
                            config.DB_PATH,
                            "UPDATE img SET downvotes=downvotes+1 WHERE pic_url=?",
                            payload=(pic_url, ))

                # user wants to upvote, but has already downvoted the same meme
                elif request.form["vote"] == "up" and user_history[0][
                        "upvoted"] == 0:
                    Database.apply_query(
                        config.DB_PATH,
                        "UPDATE img SET downvotes=downvotes-1, upvotes=upvotes+1 WHERE pic_url=?",
                        payload=(pic_url, ))
                    Database.apply_query(
                        config.DB_PATH,
                        "UPDATE cookiejar SET upvoted=1, downvoted=0 WHERE pic_url=? AND uid=?",
                        payload=(pic_url, uid))

                # user wants to downvote, but has already upvoted the same meme
                elif request.form["vote"] == "down" and user_history[0][
                        "downvoted"] == 0:
                    Database.apply_query(
                        config.DB_PATH,
                        "UPDATE img SET upvotes=upvotes-1, downvotes=downvotes+1 WHERE pic_url=?",
                        payload=(pic_url, ))
                    Database.apply_query(
                        config.DB_PATH,
                        "UPDATE cookiejar SET upvoted=0, downvoted=1 WHERE pic_url=? AND uid=?",
                        payload=(pic_url, uid))

        votes = Database.read(
            config.DB_PATH,
            "SELECT upvotes, downvotes FROM img WHERE pic_url=?",
            payload=(request.form["post"], ))
        if not votes or len(votes[0]) != 2:
            votes = (0, 0)
        return Response(str(votes[0][0]) + " " + str(votes[0][1]),
                        mimetype="text/plain")

    def error_404(self, request):
        return self.render_template("404.html")

    def sum_ting_wong(self, request, e):
        return self.render_template("sumtingwong.html", error=e)

    def __call__(self, environ, start_response):
        return self.wsgi_app(environ, start_response)
Esempio n. 41
0
class CheckmkRESTAPI:
    def __init__(self, debug: bool = False):
        self.debug = debug
        rules = []
        for endpoint in ENDPOINT_REGISTRY:
            if self.debug:
                # This helps us to make sure we can always generate a valid OpenAPI yaml file.
                _ = endpoint.to_operation_dict()

            rules.append(
                Rule(endpoint.default_path,
                     methods=[endpoint.method],
                     endpoint=Authenticate(endpoint.wrapped)))

        swagger_ui = ServeSwaggerUI(prefix="/[^/]+/check_mk/api/[^/]+/ui")

        self.url_map = Map([
            Submount(
                "/<path:_path>",
                [
                    Rule("/ui/", endpoint=swagger_ui),
                    Rule("/ui/<path:path>", endpoint=swagger_ui),
                    Rule("/openapi-swagger-ui.yaml",
                         endpoint=swagger_ui.serve_spec('swagger-ui', 'yaml')),
                    Rule("/openapi-swagger-ui.json",
                         endpoint=swagger_ui.serve_spec('swagger-ui', 'json')),
                    Rule("/openapi-doc.yaml", endpoint=swagger_ui.serve_spec('doc', 'yaml')),
                    Rule("/openapi-doc.json", endpoint=swagger_ui.serve_spec('doc', 'json')),
                    *rules,
                ],
            ),
        ])
        self.wsgi_app = with_context_middleware(OverrideRequestMethod(self._wsgi_app))

    def __call__(self, environ: WSGIEnvironment, start_response):
        return self.wsgi_app(environ, start_response)

    def _wsgi_app(self, environ: WSGIEnvironment, start_response):
        urls = self.url_map.bind_to_environ(environ)
        try:
            wsgi_app, path_args = urls.match()

            # Remove this again (see Submount above), so the validators don't go crazy.
            del path_args['_path']

            # This is an implicit dependency, as we only know the args at runtime, but the
            # function at setup-time.
            environ[ARGS_KEY] = path_args
            return wsgi_app(environ, start_response)
        except HTTPException as exc:
            # We don't want to log explicit HTTPExceptions as these are intentional.
            assert isinstance(exc.code, int)
            return problem(
                status=exc.code,
                title=http.client.responses[exc.code],
                detail=str(exc),
            )(environ, start_response)
        except MKException as exc:
            if self.debug:
                raise

            return problem(
                status=EXCEPTION_STATUS.get(type(exc), 500),
                title="An exception occurred.",
                detail=str(exc),
            )(environ, start_response)
        except Exception as exc:
            crash = APICrashReport.from_exception()
            crash_reporting.CrashReportStore().save(crash)
            logger.exception("Unhandled exception (Crash-ID: %s)", crash.ident_to_text())
            if self.debug:
                raise

            crash_url = f"/{config.omd_site()}/check_mk/crash.py?" + urllib.parse.urlencode([
                ("crash_id", crash.ident_to_text()),
                ("site", config.omd_site()),
            ],)

            return problem(status=500,
                           title=str(exc),
                           detail="An internal error occured while processing your request.",
                           ext={
                               'crash_report': {
                                   'href': crash_url,
                                   'method': 'get',
                                   'rel': 'cmk/crash-report',
                                   'type': 'text/html',
                               },
                               'crash_id': crash.ident_to_text(),
                           })(environ, start_response)
Esempio n. 42
0
class Shortly(object):
    def __init__(self, config):
        self.redis = redis.Redis(config["redis_host"], config["redis_port"])
        template_path = os.path.join(os.path.dirname(__file__), "templates")
        self.jinja_env = Environment(
            loader=FileSystemLoader(template_path), autoescape=True
        )
        self.jinja_env.filters["hostname"] = get_hostname

        self.url_map = Map(
            [
                Rule("/", endpoint="home"),
                Rule("/<short_id>_details", endpoint="short_link_details"),
                Rule("/create", endpoint="new_url"),
                Rule("/<short_id>", endpoint="follow_short_link"),
                # TODO: Добавить ендпоинты на:
                # - создание шортката
                # - редирект по ссылке
                # - детальную информацию о ссылке
            ]
        )

    def render_template(self, template_name, **context):
        t = self.jinja_env.get_template(template_name)
        return Response(t.render(context), mimetype="text/html")

    def dispatch_request(self, request):
        adapter = self.url_map.bind_to_environ(request.environ)
        try:
            endpoint, values = adapter.match()
            return getattr(self, "on_" + endpoint)(request, **values)
        except NotFound:
            return self.error_404()
        except HTTPException as e:
            return e

    def wsgi_app(self, environ, start_response):
        request = Request(environ)
        response = self.dispatch_request(request)
        return response(environ, start_response)

    def on_home(self, request):
        return self.render_template("homepage.html")

    def on_new_url(self, request):
        error = None
        url = ""
        if request.method == 'POST':
            url = request.form['url']
            if not is_valid_url(url):
                error = 'invalid url'
            else:
                id = insert_url(self.redis, url)
                return redirect(b'/%s_details'% id)


        # TODO: Проверить что метод для создания новой ссылки "POST"
        # Проверить валидность ссылки используя is_valid_url
        # Если ссылка верна - создать запись в базе и
        # отправить пользователя на детальную информацию
        # Если неверна - написать ошибку

        return self.render_template("new_url.html", error=error, url=url)

    def on_follow_short_link(self, request, short_id):
        # TODO: Достать из базы запись о ссылке по ее ид (get_url)
        # если такого ид в базе нет то кинуть 404 (NotFount())
        # заинкрементить переход по ссылке (increment_url)
        link_target = get_url(self.redis, short_id)
        if not link_target:
            return NotFound()
        
        increment_url(self.redis, short_id)
        return redirect(link_target)

    def on_short_link_details(self, request, short_id):
        # TODO: Достать из базы запись о ссылке по ее ид (get_url)
        # если такого ид в базе нет то кинуть 404 (NotFount())
        url = get_url(self.redis, short_id)
        if not url:
            return NotFound()

        link_target = "/"

        click_count = get_count(self.redis, short_id)  # достать из базы кол-во кликов по ссылке (get_count)
        return self.render_template(
            "short_link_details.html",
            link_target=link_target,
            short_id=short_id,
            click_count=click_count,
        )

    def on_list_url(self, request):
        # TODO: ДЗ
        pass

    def error_404(self):
        response = self.render_template("404.html")
        response.status_code = 404
        return response

    def __call__(self, environ, start_response):
        return self.wsgi_app(environ, start_response)
Esempio n. 43
0
class App():
    def __init__(self, work_dir):
        mimetypes.add_type('text/cache-manifest', '.appcache')
        self.started = datetime.datetime.now()
        self.work_dir = work_dir
        self._loading = False
        self._load_lock = Lock()
        self._updating_task = False
        self.admin = None
        self.task = None
        self.privileges = None
        self._busy = 0
        self.pid = os.getpid()
        self.task_server_modified = False
        self.task_client_modified = True
        self.under_maintenance = False
        self.jam_dir = os.path.realpath(os.path.dirname(jam.__file__))
        self.jam_version = jam.version()
        self.__task_locked = False
        self.application_files = {
            '/': self.work_dir,
            '/jam/': self.jam_dir
        }
        self.fileserver = SharedDataMiddleware(None, self.application_files, cache_timeout=1)
        self.url_map = Map([
            Rule('/', endpoint='root_file'),
            Rule('/<file_name>', endpoint='root_file'),
            Rule('/js/<file_name>', endpoint='file'),
            Rule('/css/<file_name>', endpoint='file'),
            Rule('/jam/js/<file_name>', endpoint='file'),
            Rule('/jam/js/ace/<file_name>', endpoint='file'),
            Rule('/jam/css/<file_name>', endpoint='file'),
            Rule('/jam/css/themes/<file_name>', endpoint='file'),
            Rule('/jam/img/<file_name>', endpoint='file'),
            Rule('/api', endpoint='api'),
            Rule('/upload', endpoint='upload')
        ])
        self.admin = self.create_admin()
        self.max_content_length = self.admin.max_content_length

    def create_admin(self):
        return adm_server.create_admin(self)

    def get_task(self):
        if self.task:
            return self.task
        else:
            if not self._loading:
                self._loading = True
                try:
                    with self._load_lock:
                        self.task = self.admin.create_task()
                except:
                    traceback.print_exc()
                    raise
                finally:
                    self._loading = False
            if self.task:
                self.__task_locked = True
            return self.task

    def task_locked(self):
        return self.__task_locked

    def __call__(self, environ, start_response):
        jam.context.environ = environ
        request = JamRequest(environ)
        if self.max_content_length > 0:
            request.max_content_length = 1024 * 1024 * self.max_content_length
        adapter = self.url_map.bind_to_environ(request.environ)
        try:
            endpoint, values = adapter.match()
            if endpoint in ['file', 'root_file']:
                result = self.serve_file(environ, start_response, endpoint, **values)
                return result
            elif endpoint in ['api', 'upload']:
                response = getattr(self, 'on_' + endpoint)(request, **values)
        except HTTPException as e:
            if peek_path_info(environ) == 'ext':
                response = self.on_ext(request)
            else:
                response = e
        jam.context.session = None
        return response(environ, start_response)

    def check_modified(self, file_path, environ):
        if environ.get('HTTP_IF_MODIFIED_SINCE'):
            date1 = parse_date(environ['HTTP_IF_MODIFIED_SINCE'])
            date2 = datetime.datetime.utcfromtimestamp(os.path.getmtime(file_path)).replace(microsecond=0)
            if date1 != date2:
                try:
                    os.utime(file_path, None)
                except:
                    pass

    def serve_file(self, environ, start_response, endpoint, file_name=None):
        if endpoint == 'root_file':
            if not file_name:
                file_name = 'index.html'
                environ['PATH_INFO'] = environ['PATH_INFO'] + '/index.html'
            elif file_name == 'admin.html':
                file_name = 'builder.html'
            if file_name == 'index.html':
                self.check_modified(file_name, environ)
                if self.get_task():
                    self.check_project_modified()
                else:
                    return Response(self.admin.language('no_task'))(environ, start_response)
            elif file_name == 'builder.html':
                self.check_modified(os.path.join(to_unicode(self.jam_dir, 'utf-8'), file_name), environ)
                environ['PATH_INFO'] = os.path.join('jam', file_name)
        if file_name:
            base, ext = os.path.splitext(file_name)
        init_path_info = None
        if common.SETTINGS['COMPRESSED_JS'] and ext and ext in ['.js', '.css']:
            init_path_info = environ['PATH_INFO']
            min_file_name = base + '.min' + ext
            environ['PATH_INFO'] = environ['PATH_INFO'].replace(file_name, min_file_name)
        try:
            try:
                return self.fileserver(environ, start_response)
            except Exception as e:
                if init_path_info:
                    environ['PATH_INFO'] = init_path_info
                    return self.fileserver(environ, start_response)
                else:
                    raise
        except Exception as e:
            return Response('')(environ, start_response)

    def create_post_response(self, request, result):
        response = Response()
        accepts_gzip = 0
        try:
            if request.environ.get("HTTP_ACCEPT_ENCODING").find("gzip") != -1:
                accepts_gzip = 1
        except:
            pass
        try:
            buff = json.dumps(result, default=common.json_defaul_handler)
        except:
            print('wsgi.py create_post_response error:')
            print(result)
            raise
        response.headers['Content-Type'] = 'application/json'
        if accepts_gzip:
            buff = common.compressBuf(buff)
            response.headers['Content-encoding'] = 'gzip'
            response.headers['Content-Length'] = str(len(buff))
        response.set_data(buff)
        return response

    def get_client_address(self, request):
        try:
            return request.environ['HTTP_X_FORWARDED_FOR'].split(',')[-1].strip()
        except KeyError:
            return request.environ['REMOTE_ADDR']

    def create_session(self, request, task, user_info=None, session_uuid=None):
        if not user_info:
            user_info = {
                'user_id': None,
                'role_id': None,
                'role_name': '',
                'user_name': '',
                'admin': False
            }
        cookie = request.get_session(task)
        session = {}
        session['ip'] = self.get_client_address(request);
        session['uuid'] = session_uuid
        session['user_info'] = user_info
        cookie['info'] = session
        cookie.modified = True
        return cookie

    def connect(self, request, task):
        if self.check_session(request, task):
            return True

    def valid_session(self, task, session, request):
        if self.admin.safe_mode:
            user_info = session['user_info']
            if not (user_info and user_info.get('user_id')):
                return False
            if not self.admin.ignore_change_ip and task != self.admin:
                ip = self.get_client_address(request);
                if not adm_server.user_valid_ip(self.admin, user_info['user_id'], ip):
                    return False
            if not self.admin.ignore_change_uuid and task != self.admin:
                if not adm_server.user_valid_uuid(self.admin, user_info['user_id'], session['uuid']):
                    return False
        return True

    def check_session(self, request, task):
        c = request.get_session(task)
        if not c.get('info') and not self.admin.safe_mode:
            c = self.create_session(request, task)
        session = c.get('info')
        if session:
            if not self.valid_session(task, session, request):
                self.logout(request, task)
                return False
            jam.context.session = session
            return True

    def default_login(self, task, login, password, ip, session_uuid):
        return adm_server.login(self.admin, login, password, self.admin == task, ip, session_uuid)

    def login(self, request, task, login, password):
        ip = None
        session_uuid = None
        ip = self.get_client_address(request);
        session_uuid = str(uuid.uuid4())
        if self.admin == task or task.on_login is None:
            user_info = self.default_login(task, login, password, ip, session_uuid)
        elif task.on_login:
            try:
                try:
                    user_info = task.on_login(task, login, password, ip, session_uuid)
                except:
                    traceback.print_exc()
                    user_info = task.on_login(task, login, password)
                    print('The on_login event params have been changed (see the documentation). Please update the on_login event handler!!!')
            except:
                user_info = None
                traceback.print_exc()
        if user_info:
            self.create_session(request, task, user_info, session_uuid)
            return True

    def logout(self, request, task):
        cookie = cookie = request.get_session(task)
        cookie['info'] = None
        jam.context.session = None

    def check_project_modified(self):
        if self.task_server_modified or self.task_client_modified:
            if not self._updating_task:
                self._updating_task = True
                self.__task_locked = False
                try:
                    if self.task_server_modified:
                        self.admin.reload_task()
                        self.task_server_modified = False
                    if self.task_client_modified:
                        self.admin.update_events_code()
                        self.task_client_modified = False
                finally:
                    self._updating_task = False
                    self.__task_locked = True

    def import_metadata(self, task, task_id, file_name, from_client):
        if not from_client:
            return adm_server.import_metadata(task, task_id, file_name, from_client)
        elif self.get_task():
            self.__task_locked = False
            try:
                return adm_server.import_metadata(task, task_id, file_name, from_client)
            finally:
                self.__task_locked = True

    def get_privileges(self, role_id):
        if self.privileges is None:
            roles, privileges = adm_server.get_roles(self.admin)
            self.privileges = privileges
        try:
            result = self.privileges[role_id]
        except:
            result = {}
        return result

    def init_client(self, task):
        session = jam.context.session
        priv = None
        user_info = {}
        if session:
            user_info = session['user_info']
            role_id = user_info.get('role_id')
            if role_id:
                priv = self.get_privileges(role_id)
        result = {
            'task': task.get_info(),
            'settings': self.admin.get_settings(),
            'locale': self.admin.locale,
            'language': self.admin.lang,
            'user_info': user_info,
            'privileges': priv
        }
        return result, ''

    def on_api(self, request):
        error = ''
        if request.method == 'POST':
            r = {'result': None, 'error': None}
            try:
                data = request.get_data()
                if type(data) != str:
                    data = to_unicode(data, 'utf-8')
                method, task_id, item_id, params, date = json.loads(data)
                if task_id == 0:
                    task = self.admin
                else:
                    task = self.get_task()
                result = {'status': common.RESPONSE, 'data': None, 'version': task.version}
                if not task:
                    result['status'] = common.NO_PROJECT
                elif self.under_maintenance:
                    result['status'] = common.UNDER_MAINTAINANCE
                elif method == 'connect':
                    self.connect(request, task)
                    result['data'] = self.connect(request, task)
                elif method == 'login':
                    result['data'] = self.login(request, task, params[0], params[1])
                elif method == 'logout':
                    self.logout(request, task);
                    result['status'] = common.NOT_LOGGED
                    result['data'] = common.NOT_LOGGED
                else:
                    if not self.check_session(request, task):
                        result['status'] = common.NOT_LOGGED
                        result['data'] = common.NOT_LOGGED
                    else:
                        item = task
                        if task and item_id:
                            item = task.item_by_ID(item_id)
                        self._busy += 1
                        try:
                            data = None
                            started = datetime.datetime.now()
                            if task.on_before_request:
                                data = task.on_before_request(item, method, params)
                            if not data:
                                data = self.get_response(item, method, params)
                            if task.on_after_request:
                                task.on_after_request(item, method, params, datetime.datetime.now() - started)
                        finally:
                            self._busy -= 1
                        result['data'] = data
                r ['result'] = result
            except AbortException as e:
                traceback.print_exc()
                error = error_message(e)
                r['result'] = {'data': [None, error]}
                r['error'] = error
            except Exception as e:
                traceback.print_exc()
                error = error_message(e)
                if common.SETTINGS['DEBUGGING'] and task_id != 0:
                    raise
                r['result'] = {'data': [None, error]}
                r['error'] = error
            response = self.create_post_response(request, r)
            request.save_session(response, self, task)
            return response

    def get_response(self, item, method, params):
        if method == 'open':
            return item.select_records(params, safe=True)
        elif method == 'apply':
            return item.apply_changes(params, safe=True)
        elif method == 'server':
            return self.server_func(item, params[0], params[1])
        elif method == 'total_records':
            return item.get_record_count(params, safe=True)
        elif method == 'print':
            return item.print_report(*params, safe=True), ''
        elif method == 'load':
            return self.init_client(item)

    def server_func(self, obj, func_name, params):
        result = None
        error = ''
        func = getattr(obj, func_name)
        if func:
            result = func(obj, *params)
        else:
            raise Exception('item: %s no server function with name %s' % (obj.item_name, func_name))
        return result, error

    def on_ext(self, request):
        if request.method == 'POST':
            r = {'result': None, 'error': None}
            method = get_path_info(request.environ)
            data = request.get_data()
            if type(data) != str:
                data = to_unicode(data, 'utf-8')
            params = json.loads(data)
            task = self.get_task()
            try:
                data = None
                if self.under_maintenance:
                    status = common.UNDER_MAINTAINANCE
                elif task.on_ext_request:
                    status = common.RESPONSE
                    self._busy += 1
                    try:
                        data = task.on_ext_request(task, method, params)
                    finally:
                        self._busy -= 1
                else:
                    status = None
                r['result'] = {'status': status, 'data': data, 'version': task.version}
            except AbortException as e:
                traceback.print_exc()
                r['result'] = {'data': [None, error_message(e)]}
                r['error'] = error_message(e)
            except Exception as e:
                traceback.print_exc()
                #~ if common.SETTINGS['DEBUGGING']:
                    #~ raise
                r['result'] = {'data': [None, error_message(e)]}
                r['error'] = error_message(e)
            return self.create_post_response(request, r)

    def on_upload(self, request):
        if request.method == 'POST':
            task_id = int(request.form.get('task_id'))
            path = request.form.get('path')
            if task_id == 0:
                task = self.admin
            else:
                task = self.get_task()
            result = {'status': common.RESPONSE, 'data': None, 'version': task.version}
            r = {'result': result, 'error': None}
            if not self.check_session(request, task):
                r['result']['status'] = common.NOT_LOGGED
                r['result']['data'] = common.NOT_LOGGED
            else:
                f = request.files.get('file')
                file_name = request.form.get('file_name')
                if f and file_name:
                    base, ext = os.path.splitext(file_name)
                    if not path:
                        if task_id == 0:
                            path = os.path.join('static', 'builder')
                        else:
                            path = os.path.join('static', 'files')
                        file_name = ('%s%s%s') % (base, datetime.datetime.now().strftime('%Y-%m-%d_%H:%M:%S.%f'), ext)
                        file_name = secure_filename(file_name)
                        file_name = file_name.replace('?', '')
                    if not r['error']:
                        dir_path = os.path.join(to_unicode(self.work_dir, 'utf-8'), path)
                        if not os.path.exists(dir_path):
                            os.makedirs(dir_path)
                        f.save(os.path.join(dir_path, file_name))
                        task = self.get_task()
                        r['result'] = {'status': common.RESPONSE, 'data': {'file_name': file_name, 'path': path}, 'version': task.version}
                else:
                    r['error'] = 'File upload invalid parameters';
            return self.create_post_response(request, r)

    def stop(self, sigvalue):
        self.kill()

    def kill(self):
        import signal, subprocess
        if os.name == "nt":
            subprocess.Popen("taskkill /F /T /pid %i" % self.pid, shell=True)
        else :
            os.killpg(self.pid, signal.SIGKILL)
Esempio n. 44
0
class Application(object):

    def __init__(self, host, host_name, port, routing_rules = [], run = None):
        self._host = host
        self._host_name = host_name
        self._port = port
        self._run = run
        routing_rules.append(Rule('/<ruleset_name>', endpoint=self._ruleset_definition_request))
        routing_rules.append(Rule('/<ruleset_name>/<sid>', endpoint=self._state_request))
        self._url_map = Map(routing_rules)

    def _ruleset_definition_request(self, environ, start_response, ruleset_name):
        def encode_promise(obj):
            if isinstance(obj, engine.Promise) or hasattr(obj, '__call__'):
                return 'function'
            raise TypeError(repr(obj) + " is not JSON serializable")

        request = Request(environ)
        if request.method == 'GET':
            result = self._host.get_ruleset(ruleset_name)
            return Response(json.dumps(result.get_definition(), default=encode_promise))(environ, start_response)
        elif request.method == 'POST':
            ruleset_definition = json.loads(request.stream.read())
            self._host.set_ruleset(ruleset_name, ruleset_definition)

        return Response()(environ, start_response)

    def _state_request(self, environ, start_response, ruleset_name, sid):
        request = Request(environ)
        result = None
        if request.method == 'GET':
            result = self._host.get_state(ruleset_name, sid)
            return Response(json.dumps(result))(environ, start_response)
        elif request.method == 'POST':
            message = json.loads(request.stream.read())
            message['sid'] = sid
            result = self._host.post(ruleset_name, message)
            return Response(json.dumps({'outcome': result}))(environ, start_response)
        elif request.method == 'PATCH':
            document = json.loads(request.stream.read())
            document['id'] = sid
            result = self._host.patch_state(ruleset_name, document)
            return Response(json.dumps({'outcome': result}))(environ, start_response)
        
    def _not_found(self, environ, start_response):
        return Exception('File not found')

    def __call__(self, environ, start_response):
        request = Request(environ)
        adapter = self._url_map.bind_to_environ(environ)
        try:
            endpoint, values = adapter.match()
            return endpoint(environ, start_response, **values)
        except HTTPException as e:
            return e
    
    def run(self):
        if self._run:
            self._run(self._host, self)
        elif self._port != 443:
            run_simple(self._host_name, self._port, self, threaded=True)
        else:
            make_ssl_devcert('key', host=self._host_name)
            run_simple(self._host_name, self._port, self, threaded=True, ssl_context=('key.crt', 'key.key'))
Esempio n. 45
0
class LeanEngineApplication(object):
    def __init__(self):
        self.url_map = Map([
            Rule('/__engine/1/functions/<func_name>',
                 endpoint='cloud_function'),
            Rule('/__engine/1.1/functions/<func_name>',
                 endpoint='cloud_function'),
            Rule('/__engine/1/call/<func_name>', endpoint='rpc_function'),
            Rule('/__engine/1.1/call/<func_name>', endpoint='rpc_function'),
            Rule('/__engine/1/functions/BigQuery/<event>',
                 endpoint='on_bigquery'),
            Rule('/__engine/1.1/functions/BigQuery/<event>',
                 endpoint='on_bigquery'),
            Rule('/__engine/1.1/functions/_User/onLogin', endpoint='on_login'),
            Rule('/__engine/1/functions/_User/onLogin', endpoint='on_login'),
            Rule('/__engine/1/functions/<class_name>/<hook_name>',
                 endpoint='cloud_hook'),
            Rule('/__engine/1.1/functions/<class_name>/<hook_name>',
                 endpoint='cloud_hook'),
            Rule('/__engine/1/functions/onVerified/<verify_type>',
                 endpoint='on_verified'),
            Rule('/__engine/1.1/functions/onVerified/<verify_type>',
                 endpoint='on_verified'),
            Rule('/__engine/1/functions/_ops/metadatas',
                 endpoint='ops_meta_data'),
            Rule('/__engine/1.1/functions/_ops/metadatas',
                 endpoint='ops_meta_data'),
            Rule('/1/functions/<func_name>', endpoint='cloud_function'),
            Rule('/1.1/functions/<func_name>', endpoint='cloud_function'),
            Rule('/1/call/<func_name>', endpoint='rpc_function'),
            Rule('/1.1/call/<func_name>', endpoint='rpc_function'),
            Rule('/1/functions/BigQuery/<event>', endpoint='on_bigquery'),
            Rule('/1.1/functions/BigQuery/<event>', endpoint='on_bigquery'),
            Rule('/1.1/functions/_User/onLogin', endpoint='on_login'),
            Rule('/1/functions/_User/onLogin', endpoint='on_login'),
            Rule('/1/functions/<class_name>/<hook_name>',
                 endpoint='cloud_hook'),
            Rule('/1.1/functions/<class_name>/<hook_name>',
                 endpoint='cloud_hook'),
            Rule('/1/functions/onVerified/<verify_type>',
                 endpoint='on_verified'),
            Rule('/1.1/functions/onVerified/<verify_type>',
                 endpoint='on_verified'),
            Rule('/1/functions/_ops/metadatas', endpoint='ops_meta_data'),
            Rule('/1.1/functions/_ops/metadatas', endpoint='ops_meta_data'),
        ])

    def __call__(self, environ, start_response):
        self.process_session(environ)
        request = environ['leanengine.request']

        response = self.dispatch_request(request)

        return response(environ, start_response)

    @classmethod
    def process_session(cls, environ):
        if environ['_app_params']['session_token'] not in (None, ''):
            session_token = environ['_app_params']['session_token']
            user = leancloud.User.become(session_token)
            context.local.user = user
            return

        request = environ['leanengine.request']
        try:
            # the JSON object must be str, not 'bytes' for 3.x.
            data = json.loads(to_native(request.get_data()))
        except ValueError:
            context.local.user = None
            return

        if 'user' in data and data['user']:
            user = leancloud.User()
            user._finish_fetch(data['user'], True)
            context.local.user = user
            return

        context.local.user = None

    def dispatch_request(self, request):
        adapter = self.url_map.bind_to_environ(request.environ)
        try:
            endpoint, values = adapter.match()
        except HTTPException as e:
            return e

        # the JSON object must be str, not 'bytes' for 3.x.
        params = to_native(request.get_data())
        values['params'] = json.loads(params) if params != '' else {}

        try:
            if endpoint == 'cloud_function':
                result = {
                    'result': dispatch_cloud_func(decode_object=False,
                                                  **values)
                }
            elif endpoint == 'rpc_function':
                result = {
                    'result': dispatch_cloud_func(decode_object=True, **values)
                }
            elif endpoint == 'cloud_hook':
                result = dispatch_cloud_hook(**values)
            elif endpoint == 'on_verified':
                result = {'result': dispatch_on_verified(**values)}
            elif endpoint == 'on_login':
                result = {'result': dispatch_on_login(**values)}
            elif endpoint == 'ops_meta_data':
                result = {'result': dispatch_ops_meta_data()}
            elif endpoint == 'on_bigquery':
                result = {'result': dispatch_on_bigquery(**values)}
            else:
                raise ValueError  # impossible
            return Response(json.dumps(result), mimetype='application/json')
        except LeanEngineError as e:
            return Response(json.dumps({
                'code': e.code,
                'error': e.message
            }),
                            status=400,
                            mimetype='application/json')
        except Exception:
            print(traceback.format_exc())
            return Response(json.dumps({
                'code':
                141,
                'error':
                'Cloud Code script had an error.'
            }),
                            status=500,
                            mimetype='application/json')
Esempio n. 46
0
class SimpleWeb(BaseApp):

    request_class = Request

    def __init__(self, request_class=Request):
        if request_class:
            self.request_class = request_class
        self.url_map = Map()
        self.handler_map = {}

        self._before_request_hooks = []
        self._before_response_hooks = []
        self._login_hooks = []

    def add_route(
            self, uri, handler,
            endpoint=None, methods=('GET',),
            login_required=False):
        if not endpoint:
            endpoint = uri + '-' + handler.__name__
        self.url_map.add(Rule(uri, endpoint=endpoint, methods=methods))
        _validate = getattr(handler, constants.VALIDATOR, False)
        if _validate:
            handler = self._validate_resource(handler)
        _protect = getattr(handler, constants.LOGIN_REQUIRED, login_required)
        if _protect:
            handler = self._protect_resource(handler)
        self.handler_map[endpoint] = handler

    def add_routes(
            self, uri, handlers={}, endpoint=None, login_required=False):
        keys = handlers.keys()
        if not len(keys):
            return
        for key in keys:
            handler = handlers[key]
            self.add_route(
                uri, handler, endpoint=endpoint,
                methods=(key.upper(),),
                login_required=login_required
            )

    def before_request(self, handler):
        self._before_request_hooks.append(handler)
        return handler

    def after_request(self, handler):
        self._before_response_hooks.append(handler)
        return handler

    def login_handler(self, handler):
        self._login_hooks.append(handler)
        return handler

    def wsgi_app(self, environ, start_response):
        request = self.request_class(environ)
        response = self._dispatch_request(request)
        return response(environ, start_response)

    def run(self, host='0.0.0.0', port=5000, **kwargs):
        logger.info('Running development server on port {}'.format(port))
        run_simple(host, port, self, **kwargs)

    def _protect_resource(self, func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            for hook in self._login_hooks:
                hook()
            return func(*args, **kwargs)
        return wrapper

    def _validate_resource(self, func):
        @wraps(func)
        def wrapper(**kwargs):
            validator = getattr(func, constants.VALIDATOR)
            parser = WerkzeugParser(kwargs, error_handler=validation_handler)
            try:
                data = parser.parse(validator, context.request)
            except ValidationError as e:
                raise InvalidData(error)
            else:
                return func(**data)
        return wrapper

    def _dispatch_before_req_hooks(self):
        for hook in self._before_request_hooks:
            hook()

    def _dispatch_before_resp_hooks(self, response):
        for hook in self._before_response_hooks:
            resp = hook(response)
            if resp:
                response = resp
        return response

    def _dispatch(self, adapter):
        status_code = 200
        mimetype = 'text/plain'
        try:
            endpoint, values = adapter.match()
        except HTTPException as e:
            status_code = e.code
            result = SWException(
                code=status_code,
                description=e.description
            ).to_dict()
        else:
            try:
                handler = self.handler_map[endpoint]
                result = handler(**values)
                if isinstance(result, Response):
                    return result
            except SWException as e:
                result = e.to_dict()
                status_code = e.code
            except Exception as e:
                logger.exception('Error while handling {}'.format(endpoint), e)
                result = 'Server error'
                status_code = 500
        if isinstance(result, (dict,)):
            result = json.dumps(result)
            mimetype = MIMETYPE_JSON
        return Response(result, status=status_code, mimetype=mimetype)

    def _dispatch_request(self, request):
        adapter = self.url_map.bind_to_environ(request)
        if request.method == 'OPTIONS':
            response = dispatch_options_handler(adapter)
        else:
            context.request = request
            self._dispatch_before_req_hooks()
            response = self._dispatch(adapter)
        return self._dispatch_before_resp_hooks(response)
Esempio n. 47
0
class Shortly(object):
    def __init__(self, config):
        self.redis = redis.Redis(config['redis_host'], config['redis_port'])
        template_path = os.path.join(os.path.dirname(__file__), 'templates')
        self.jinja_env = Environment(loader=FileSystemLoader(template_path),
                                     autoescape=True)
        self.url_map = Map([
            Rule('/', endpoint='new_url'),
            Rule('/<short_id>', endpoint='follow_short_link'),
            Rule('/<short_id>+', endpoint='short_link_details')
        ])

    def render_template(self, template_name, **context):
        t = self.jinja_env.get_template(template_name)
        return Response(t.render(context), mimetype='text/html')

    def dispatch_request(self, request):
        adapter = self.url_map.bind_to_environ(request.environ)
        try:
            endpoint, values = adapter.match()
            return getattr(self, 'on_' + endpoint)(request, **values)
        except HTTPException as e:
            return e

    def on_new_url(self, request):
        error = None
        url = ''
        if request.method == 'POST':
            url = request.form['url']
            if not is_valid_url(url):
                error = 'Please enter a valid URL'
            else:
                short_id = self.insert_url(url)
                return redirect('/%s+' % short_id)
        return self.render_template('new_url.html', error=error, url=url)

    def on_follow_short_link(self, request, short_id):
        link_target = self.redis.get('url-target:' + short_id)
        if link_target is None:
            raise NotFound()
        self.redis.incr('click-count:' + short_id)
        return redirect(link_target)

    def on_short_link_details(self, request, short_id):
        link_target = self.redis.get('url-target:' + short_id)
        if link_target is None:
            raise NotFound()
        click_count = int(self.redis.get('click-count:' + short_id) or 0)
        return self.render_template('short_link_details.html',
                                    link_target=link_target,
                                    short_id=short_id,
                                    click_count=click_count)

    def insert_url(self, url):
        short_id = self.redis.get('reverse-url:' + url)
        if short_id is not None:
            return short_id
        url_num = self.redis.incr('last-url-id')
        short_id = base36_encode(url_num)
        self.redis.set('url-target:' + short_id, url)
        self.redis.set('reverse-url:' + url, short_id)
        return short_id

    def wsgi_app(self, environ, start_response):
        request = Request(environ)
        response = self.dispatch_request(request)
        return response(environ, start_response)

    def __call__(self, environ, start_response):
        return self.wsgi_app(environ, start_response)
Esempio n. 48
0
class WSGIApplication(object):
    def __init__(self, proxy):
        self.proxy = proxy
        self.proxy_http = ProxyHTTP(proxy)
        self.xmlrpc_dispatcher = XMLRPCDispatcher()
        self.xmlrpc_dispatcher.register_instance(proxy)
        self.url_map = RoutingMap([
            # pseudo-XML-RPC calls used in kickstarts:
            # (these permit GET to make it more convenient to trigger them using curl)
            Rule('/nopxe/<fqdn>', endpoint=(self.proxy, 'clear_netboot')),
            Rule('/install_start/<recipe_id>',
                 endpoint=(self.proxy, 'install_start')),
            Rule('/install_done/<recipe_id>/',
                 endpoint=(self.proxy, 'install_done')),
            Rule('/install_done/<recipe_id>/<fqdn>',
                 endpoint=(self.proxy, 'install_done')),
            Rule('/postinstall_done/<recipe_id>',
                 endpoint=(self.proxy, 'postinstall_done')),
            Rule('/postreboot/<recipe_id>',
                 endpoint=(self.proxy, 'postreboot')),
            Rule('/install_fail/<recipe_id>/',
                 endpoint=(self.proxy, 'install_fail')),

            # Harness API:
            Rule('/recipes/<recipe_id>/',
                 methods=['GET'],
                 endpoint=(self.proxy_http, 'get_recipe')),
            Rule('/recipes/<recipe_id>/watchdog',
                 methods=['GET'],
                 endpoint=(self.proxy_http, 'get_watchdog')),
            Rule('/recipes/<recipe_id>/watchdog',
                 methods=['POST'],
                 endpoint=(self.proxy_http, 'post_watchdog')),
            Rule('/recipes/<recipe_id>/status',
                 methods=['POST'],
                 endpoint=(self.proxy_http, 'post_recipe_status')),
            Rule('/recipes/<recipe_id>/tasks/<task_id>/',
                 methods=['PATCH'],
                 endpoint=(self.proxy_http, 'patch_task')),
            Rule('/recipes/<recipe_id>/tasks/<task_id>/status',
                 methods=['POST'],
                 endpoint=(self.proxy_http, 'post_task_status')),
            Rule('/recipes/<recipe_id>/tasks/<task_id>/results/',
                 methods=['POST'],
                 endpoint=(self.proxy_http, 'post_result')),
            Rule('/recipes/<recipe_id>/logs/',
                 methods=['GET'],
                 endpoint=(self.proxy_http, 'list_recipe_logs')),
            Rule('/recipes/<recipe_id>/logs/<path:path>',
                 methods=['GET', 'PUT'],
                 endpoint=(self.proxy_http, 'do_recipe_log')),
            Rule('/recipes/<recipe_id>/tasks/<task_id>/logs/',
                 methods=['GET'],
                 endpoint=(self.proxy_http, 'list_task_logs')),
            Rule('/recipes/<recipe_id>/tasks/<task_id>/logs/<path:path>',
                 methods=['GET', 'PUT'],
                 endpoint=(self.proxy_http, 'do_task_log')),
            Rule(
                '/recipes/<recipe_id>/tasks/<task_id>/results/<result_id>/logs/',
                methods=['GET'],
                endpoint=(self.proxy_http, 'list_result_logs')),
            Rule(
                '/recipes/<recipe_id>/tasks/<task_id>/results/<result_id>/logs/<path:path>',
                methods=['GET', 'PUT'],
                endpoint=(self.proxy_http, 'do_result_log')),
            Rule('/power/<fqdn>/',
                 methods=['PUT'],
                 endpoint=(self.proxy_http, 'put_power')),
            Rule('/healthz/',
                 methods=['HEAD', 'GET'],
                 endpoint=(self.proxy_http, 'healthz'))
        ])

    @LimitedRequest.application
    def __call__(self, req):
        try:
            # Limit request data in all cases.
            if req.max_content_length is not None and \
                req.content_length > req.max_content_length:
                raise RequestEntityTooLarge()
            if req.path in ('/', '/RPC2', '/server'):
                if req.method == 'POST':
                    # XML-RPC
                    if req.mimetype != 'text/xml':
                        return BadRequest('XML-RPC requests must be text/xml')
                    result = self.xmlrpc_dispatcher._marshaled_dispatch(
                        req.data)
                    return Response(response=result, content_type='text/xml')
                elif req.method in ('GET', 'HEAD'):
                    # XML-RPC docs
                    return Response(response=self.xmlrpc_dispatcher.
                                    generate_html_documentation(),
                                    content_type='text/html')
                else:
                    return MethodNotAllowed()
            else:
                (obj, attr), args = self.url_map.bind_to_environ(
                    req.environ).match()
                if obj is self.proxy:
                    # pseudo-XML-RPC
                    result = getattr(obj, attr)(**args)
                    return Response(response=repr(result),
                                    content_type='text/plain')
                else:
                    return getattr(obj, attr)(req, **args)
        except HTTPException, e:
            return e
Esempio n. 49
0
class Rdir(object):
    def __init__(self, conf, backend, logger=None):
        self.conf = conf
        self.logger = logger or get_logger(conf)
        self.backend = backend
        self.ns = conf['namespace']
        self.url_map = Map([
            Rule('/status', endpoint='status'),
            Rule('/v1/rdir/admin/show', endpoint='rdir_admin_show'),
            Rule('/v1/rdir/admin/unlock', endpoint='rdir_admin_unlock'),
            Rule('/v1/rdir/admin/lock', endpoint='rdir_admin_lock'),
            Rule('/v1/rdir/create', endpoint='rdir_create'),
            Rule('/v1/rdir/push', endpoint='rdir_push'),
            Rule('/v1/rdir/delete', endpoint='rdir_delete'),
            Rule('/v1/rdir/fetch', endpoint='rdir_fetch'),
            Rule('/v1/rdir/status', endpoint='rdir_status'),
            Rule('/v1/rdir/admin/clear', endpoint='rdir_admin_clear'),
            Rule('/v1/rdir/admin/incident', endpoint='rdir_admin_incident'),
        ])

    def _get_volume(self, req):
        volume = req.args.get('vol')
        if not volume:
            raise BadRequest('Missing volume id')
        return volume

    def on_status(self, req):
        status = self.backend.status()
        return Response(json.dumps(status), mimetype='application/json')

    def on_rdir_admin_show(self, req):
        volume = self._get_volume(req)
        data = self.backend.admin_show(volume)
        return Response(json.dumps(data), mimetype='application/json')

    def on_rdir_admin_unlock(self, req):
        volume = self._get_volume(req)
        self.backend.admin_unlock(volume)
        return Response(status=204)

    def on_rdir_admin_lock(self, req):
        volume = self._get_volume(req)
        decoded = json.loads(req.get_data())
        who = decoded.get('who')
        if who is None:
            return BadRequest('Missing token who')

        desc = self.backend.admin_lock(volume, who)

        if desc is not None:
            message = "Already locked by %s" % desc
            return Response(message, 403)

        return Response(status=204)

    def on_rdir_create(self, req):
        volume = self._get_volume(req)
        self.backend.create(volume)
        return Response(status=201)

    def _check_push(self, meta):
        data = {}
        missing_keys = []

        def add_keys(keys, transform_func=None, required=True):
            for k in keys:
                if k in meta:
                    if transform_func:
                        data[k] = transform_func(meta[k])
                    else:
                        data[k] = meta[k]
                else:
                    if required:
                        missing_keys.append(k)

        add_keys(['container_id', 'content_id', 'chunk_id'])
        add_keys(['mtime', 'rtime'], lambda k: int(k), False)
        if missing_keys:
            raise BadRequest('Missing %s' % missing_keys)
        return data

    def on_rdir_push(self, req):
        volume = self._get_volume(req)
        decoded = json.loads(req.get_data())
        data = self._check_push(decoded)

        try:
            self.backend.chunk_push(volume, **data)
        except NoSuchDB:
            if req.args.get('create'):
                self.backend.create(volume)
                self.backend.chunk_push(volume, **data)
            else:
                return NotFound('No such volume')
        return Response(status=204)

    def on_rdir_delete(self, req):
        volume = self._get_volume(req)
        decoded = json.loads(req.get_data())
        chunk_id = decoded.get('chunk_id')
        if chunk_id is None:
            return BadRequest('Missing token chunk_id')
        container_id = decoded.get('container_id')
        if container_id is None:
            return BadRequest('Missing token container_id')
        content_id = decoded.get('content_id')
        if content_id is None:
            return BadRequest('Missing token content_id')
        self.backend.chunk_delete(volume, container_id, content_id, chunk_id)
        return Response(status=204)

    def on_rdir_fetch(self, req):
        volume = self._get_volume(req)
        pretty = req.args.get('pretty')

        decoded = json.loads(req.get_data())
        start_after = decoded.get('start_after')
        limit = decoded.get('limit')
        if limit is not None and limit <= 0:
            return BadRequest('limit must be greater than 0')
        rebuild = decoded.get('rebuild', False)
        if not isinstance(rebuild, bool):
            return BadRequest('rebuild must be true or false')

        data = self.backend.chunk_fetch(volume,
                                        start_after=start_after,
                                        limit=limit,
                                        rebuild=rebuild)

        if pretty:
            body = json.dumps(data, indent=4)
        else:
            body = json.dumps(data)
        return Response(body, mimetype='application/json')

    def on_rdir_status(self, req):
        volume = self._get_volume(req)
        pretty = req.args.get('pretty')

        data = self.backend.chunk_status(volume)

        if pretty:
            body = json.dumps(data, indent=4)
        else:
            body = json.dumps(data)

        return Response(body, mimetype='application/json')

    def on_rdir_admin_incident(self, req):
        volume = self._get_volume(req)

        if req.method == 'POST':
            decoded = json.loads(req.get_data())
            date = decoded.get('date')
            if date is None or not isinstance(date, int):
                return BadRequest('Missing date or bad format')

            self.backend.admin_set_incident_date(volume, date)

            return Response(status=204)
        else:
            date = self.backend.admin_get_incident_date(volume)
            resp = {}
            if date:
                resp = {'date': date}
            return Response(json.dumps(resp), mimetype='application/json')

    def on_rdir_admin_clear(self, req):
        volume = self._get_volume(req)

        decoded = json.loads(req.get_data())
        clear_all = decoded.get('all', False)
        if not isinstance(clear_all, bool):
            return BadRequest('"all" must be true or false')

        lock = self.backend.admin_lock(volume, 'admin_clear')
        if lock is not None:
            return Response("Already locked by %s" % lock, 403)

        nb = self.backend.admin_clear(volume, clear_all)

        self.backend.admin_unlock(volume)

        resp = {'removed': nb}
        return Response(json.dumps(resp), mimetype='application/json')

    def dispatch_request(self, req):
        adapter = self.url_map.bind_to_environ(req.environ)
        try:
            endpoint, values = adapter.match()
            return getattr(self, 'on_' + endpoint)(req)
        except NotFound:
            return BadRequest()
        except HTTPException as e:
            return e
        except Exception:
            self.logger.exception('ERROR Unhandled exception in request')
            return InternalServerError()

    def wsgi_app(self, environ, start_response):
        req = Request(environ)
        resp = self.dispatch_request(req)
        return resp(environ, start_response)

    def __call__(self, environ, start_response):
        return self.wsgi_app(environ, start_response)
Esempio n. 50
0
class Application(object):
    """ Plain WSGI application for Resource API service

    service (:class:`Service's <resource_api.service.Service>` subclass instance)
        Service to generate HTTP interface for
    debug (bool)
        If True 500 responses will include detailed traceback describing the error
    """

    def __init__(self, service, debug=False):
        service.setup()
        url_map = []

        def rule(url, endpoint, method="GET", **kwargs):
            url_map.append(Rule(url, methods=[method], endpoint=partial(endpoint, **kwargs)))

        rule("/", get_schema, service=service, method="OPTIONS")

        schema = service.get_schema()

        for resource_name, resource_meta in schema.iteritems():
            kwargs = dict(resource_name=resource_name, service=service)

            rule("/%s" % resource_name, get_resource_collection, **kwargs)
            rule("/%s:count" % resource_name, get_resource_collection_count, **kwargs)
            rule("/%s" % resource_name, create_resource_item, "POST", **kwargs)
            rule("/%s/<resource_pk>" % resource_name, get_resource_item, "GET", **kwargs)
            rule("/%s/<resource_pk>" % resource_name, delete_resource_item, "DELETE", **kwargs)
            rule("/%s/<resource_pk>" % resource_name, update_resource_item, "PATCH", **kwargs)

            for link_name, link_meta in resource_meta.get("links", {}).iteritems():
                kwargs = dict(kwargs)
                kwargs["link_name"] = link_name
                base_url = "/%s/<resource_pk>/%s" % (resource_name, link_name)

                def link_rule(endpoint, suffix="", method="GET"):
                    rule(base_url + suffix, endpoint, method, **kwargs)

                if link_meta.get("cardinality", "MANY") == "ONE":
                    link_rule(get_link_to_one_target, suffix="/item")
                    link_rule(set_link_to_one, method="PUT")
                    link_rule(get_link_to_one_data, suffix="/item:data")
                    link_rule(update_link_to_one, method="PATCH", suffix="/item")
                    link_rule(delete_link_to_one, method="DELETE", suffix="/item")
                else:
                    link_rule(get_link_to_many_collection)
                    link_rule(get_link_to_many_collection_count, suffix=":count")
                    link_rule(create_link_to_many_item, method="POST")
                    link_rule(update_link_to_many_item, method="PATCH", suffix="/<target_pk>")
                    link_rule(delete_link_to_many_item, method="DELETE", suffix="/<target_pk>")
                    link_rule(get_link_to_many_item_data, suffix="/<target_pk>:data")

        self._url_map = Map(url_map)
        self._debug = debug

    def __call__(self, environ, start_response):

        def _resp(data, status):
            resp = Response(json.dumps(data, indent=2 if self._debug else None), mimetype="application/json")
            if data is None:
                status = 204
            resp.status_code = status
            return resp(environ, start_response)

        try:
            urls = self._url_map.bind_to_environ(environ)
            endpoint, params = urls.match()
            rval = endpoint(Request(environ), **params)
            if isinstance(rval, Response):
                return rval(environ, start_response)
            else:
                rval, status = rval
                return _resp(rval, status)
        except errors.MultipleFound, e:
            return _resp(e.message, 500)  # this is actually a server problem
        except errors.ValidationError, e:
            return _resp(e.message, 400)
Esempio n. 51
0
class App(object):
    def __init__(self, work_dir, load_task):
        mimetypes.add_type('text/cache-manifest', '.appcache')
        self.started = datetime.datetime.now()
        self.work_dir = work_dir
        self.state = consts.PROJECT_NONE
        self.__task = None
        self.privileges = None
        self._busy = 0
        self.pid = os.getpid()
        self.jam_dir = os.path.realpath(os.path.dirname(jam.__file__))
        self.jam_version = jam.version()
        self.__is_locked = 0
        self.application_files = {'/': self.work_dir, '/jam/': self.jam_dir}
        self.fileserver = SharedDataMiddleware(None,
                                               self.application_files,
                                               cache_timeout=1)
        self.url_map = Map([
            Rule('/', endpoint='root_file'),
            Rule('/<file_name>.html', endpoint='root_file'),
            Rule('/js/<file_name>', endpoint='file'),
            Rule('/css/<file_name>', endpoint='file'),
            Rule('/jam/js/<file_name>', endpoint='file'),
            Rule('/jam/js/ace/<file_name>', endpoint='file'),
            Rule('/jam/css/<file_name>', endpoint='file'),
            Rule('/jam/css/themes/<file_name>', endpoint='file'),
            Rule('/jam/img/<file_name>', endpoint='file'),
            Rule('/api', endpoint='api'),
            Rule('/upload', endpoint='upload')
        ])
        consts.app = self
        self.log = JamLogger(self)
        create_admin(self)
        self.build_id_prefix = '$buildID'
        self.save_build_id()
        if load_task:
            with self.admin.lock('$creating_task'):
                self.__task = create_task(self)
        self.check_migration()

    def create_task(self):
        result = None
        if self.state != consts.PROJECT_LOADING:
            self.state = consts.PROJECT_LOADING
            try:
                result = create_task(self)
                update_events_code(self.admin)
                consts.CLIENT_MODIFIED = False
                consts.SERVER_MODIFIED = False
                consts.write_settings()
                self.state = consts.RESPONSE
                result.__task_locked = True
            except ProjectNotCompleted:
                self.state = consts.PROJECT_NO_PROJECT
            except:
                self.state = consts.PROJECT_ERROR
                traceback.print_exc()
        return result

    @property
    def task(self):
        if not self.__task:
            self.__task = self.create_task()
        return self.__task

    def task_locked(self):
        return self.__is_locked > 0

    @property
    def __task_locked(self):
        pass

    @__task_locked.setter
    def __task_locked(self, value):
        if value:
            self.__is_locked += 1
        else:
            self.__is_locked -= 1

    def __call__(self, environ, start_response):
        jam.context.environ = environ
        jam.context.session = None
        request = JamRequest(environ)
        if consts.MAX_CONTENT_LENGTH > 0:
            request.max_content_length = 1024 * 1024 * consts.MAX_CONTENT_LENGTH
        adapter = self.url_map.bind_to_environ(request.environ)
        try:
            endpoint, values = adapter.match()
            if endpoint in ['file', 'root_file']:
                result = self.serve_file(environ, start_response, endpoint,
                                         **values)
                return result
            elif endpoint in ['api', 'upload']:
                response = getattr(self, 'on_' + endpoint)(request, **values)
        except HTTPException as e:
            if peek_path_info(environ) == 'ext':
                response = self.on_ext(request)
            else:
                response = e
        return response(environ, start_response)

    def check_modified(self, file_path, environ):
        if environ.get('HTTP_IF_MODIFIED_SINCE'):
            date1 = parse_date(environ['HTTP_IF_MODIFIED_SINCE'])
            date2 = datetime.datetime.utcfromtimestamp(
                os.path.getmtime(file_path)).replace(microsecond=0)
            if date1 != date2:
                try:
                    os.utime(file_path, None)
                except:
                    pass

    def serve_file(self, environ, start_response, endpoint, file_name=None):
        if endpoint == 'root_file':
            if file_name:
                file_name += '.html'
            if not file_name:
                file_name = 'index.html'
                environ['PATH_INFO'] = '/index.html'
            elif file_name == 'admin.html':
                file_name = 'builder.html'
            if file_name == 'index.html':
                self.check_modified(file_name, environ)
                self.check_project_modified()
            elif file_name == 'builder.html':
                if os.path.exists(file_name):
                    self.check_modified(file_name, environ)
                else:
                    self.check_modified(
                        os.path.join(to_unicode(self.jam_dir, 'utf-8'),
                                     file_name), environ)
                    environ['PATH_INFO'] = '/jam/builder.html'
        if file_name:
            base, ext = os.path.splitext(file_name)
        init_path_info = None
        if consts.COMPRESSED_JS and ext and ext in ['.js', '.css']:
            init_path_info = environ['PATH_INFO']
            min_file_name = base + '.min' + ext
            environ['PATH_INFO'] = environ['PATH_INFO'].replace(
                file_name, min_file_name)
        try:
            try:
                return self.fileserver(environ, start_response)
            except Exception as e:
                if init_path_info:
                    environ['PATH_INFO'] = init_path_info
                    return self.fileserver(environ, start_response)
                else:
                    raise
        except Exception as e:
            return Response('')(environ, start_response)

    def create_post_response(self, request, result):
        response = Response()
        accepts_gzip = 0
        try:
            if request.environ.get("HTTP_ACCEPT_ENCODING").find("gzip") != -1:
                accepts_gzip = 1
        except:
            pass
        try:
            buff = json.dumps(result, default=json_defaul_handler)
        except:
            self.log.exception('wsgi.py create_post_response error')
            self.log.debug(result)
            raise
        response.headers['Content-Type'] = 'application/json'
        if accepts_gzip:
            buff = compressBuf(buff)
            response.headers['Content-encoding'] = 'gzip'
            response.headers['Content-Length'] = str(len(buff))
        response.set_data(buff)
        return response

    def get_client_address(self, request):
        try:
            return request.environ['HTTP_X_FORWARDED_FOR'].split(
                ',')[-1].strip()
        except KeyError:
            return request.environ['REMOTE_ADDR']

    def create_session(self, request, task, user_info=None, session_uuid=None):
        if not user_info:
            user_info = {
                'user_id': None,
                'role_id': None,
                'role_name': '',
                'user_name': '',
                'admin': False
            }
        cookie = request.client_cookie
        session = {}
        session['ip'] = self.get_client_address(request)
        session['uuid'] = session_uuid
        session['user_info'] = user_info
        cookie['info'] = session
        cookie.modified = True
        return cookie

    def connect(self, request, task):
        if self.check_session(request, task):
            return consts.PROJECT_LOGGED

    def valid_session(self, task, session, request):
        if consts.SAFE_MODE:
            user_info = session['user_info']
            if not (user_info and user_info.get('user_id')):
                return False
            if not self.admin.ignore_change_ip and task != self.admin:
                ip = self.get_client_address(request)
                if not user_valid_ip(self.admin, user_info['user_id'], ip):
                    return False
            if not self.admin.ignore_change_uuid and task != self.admin:
                if not user_valid_uuid(self.admin, user_info['user_id'],
                                       session['uuid']):
                    return False
        return True

    def check_session(self, request, task):
        c = request.client_cookie
        if not c.get('info') and not consts.SAFE_MODE:
            c = self.create_session(request, task)
        session = c.get('info')
        if session:
            if not self.valid_session(task, session, request):
                self.logout(request, task)
                return False
            jam.context.session = session
            return True

    def default_login(self, task, login, password, ip, session_uuid):
        return login_user(self.admin, login, password, self.admin == task, ip,
                          session_uuid)

    def login(self, request, task, form_data):
        time.sleep(0.3)
        ip = None
        session_uuid = None
        ip = self.get_client_address(request)
        session_uuid = str(uuid.uuid4())
        if self.admin == task or task.on_login is None:
            user_info = self.default_login(task, form_data['login'],
                                           form_data['password'], ip,
                                           session_uuid)
        elif task.on_login:
            try:
                try:
                    user_info = task.on_login(task, form_data, {
                        'ip': ip,
                        'session_uuid': session_uuid
                    })
                except:
                    # for compatibility with previous versions
                    if get_function_code(task.on_login).co_argcount == 5:
                        user_info = task.on_login(task, form_data['login'],
                                                  form_data['password'], ip,
                                                  session_uuid)
                    else:
                        raise

            except:
                user_info = None
                traceback.print_exc()
        if user_info:
            self.create_session(request, task, user_info, session_uuid)
            return True

    def logout(self, request, task):
        del request.client_cookie['info']
        jam.context.session = None

    def create_connection_pool(self):
        if self.task:
            self.__task_locked = False
            try:
                self.task.create_pool()
            finally:
                self.__task_locked = True

    def get_privileges(self, role_id):
        if self.privileges is None:
            roles, privileges = get_roles(self.admin)
            self.privileges = privileges
        try:
            result = self.privileges[role_id]
        except:
            result = {}
        return result

    def init_client(self, task):
        session = jam.context.session
        priv = None
        user_info = {}
        if session:
            user_info = session['user_info']
            role_id = user_info.get('role_id')
            if role_id:
                priv = self.get_privileges(role_id)
        result = {
            'task': task.get_info(),
            'settings': consts.settings,
            'locale': consts.locale,
            'language': consts.lang,
            'user_info': user_info,
            'privileges': priv
        }
        return result, ''

    def check_migration(self):
        path = os.path.join(self.work_dir, 'migration')
        files = []
        if os.path.exists(path):
            for file_name in os.listdir(path):
                files.append(
                    os.path.join(self.work_dir, 'migration', file_name))
        files_len = len(files)
        if files_len:
            if files_len == 1:
                self.import_md(files[0], False)
            else:
                self.log.error('More than one file in migration folder')

    def import_metadata(
            self, task, task_id, file_name,
            from_client):  #for compatibility with previous versions
        self.import_md(file_name, from_client)

    def import_md(self, file_name, from_client):
        if not self.under_maintenance:
            with self.admin.lock('$metadata_import'):
                consts.MAINTENANCE = True
                consts.PARAMS_VERSION += 1
                consts.write_settings()
                self.save_build_id()
                self.__task_locked = False
                try:
                    result = import_metadata(self.admin, file_name,
                                             from_client)
                    success, error, message = result
                    if success and self.task:
                        reload_task(self)
                        update_events_code(self.admin)
                        self.privileges = None
                finally:
                    self.__task_locked = True
                    consts.MAINTENANCE = False
                    consts.PARAMS_VERSION += 1
                    if success:
                        consts.BUILD_VERSION += 1
                        consts.MODIFICATION += 1
                    consts.write_settings()
                    self.save_build_id()
                return result

    def get_under_maintenance(self):
        return consts.MAINTENANCE

    under_maintenance = property(get_under_maintenance)

    def __get_client_modified(self):
        return consts.CLIENT_MODIFIED

    def __set_client_modified(self, value):
        consts.CLIENT_MODIFIED = value
        consts.MODIFICATION += 1
        consts.PARAMS_VERSION += 1
        consts.write_settings()
        self.save_build_id()

    client_modified = property(__get_client_modified, __set_client_modified)

    def __get_server_modified(self):
        return consts.SERVER_MODIFIED

    def __set_server_modified(self, value):
        consts.SERVER_MODIFIED = value
        consts.MODIFICATION += 1
        consts.PARAMS_VERSION += 1
        consts.write_settings()
        self.save_build_id()

    server_modified = property(__get_server_modified, __set_server_modified)

    def check_project_modified(self):
        if self.task:
            with self.admin.lock('$code_updating'):
                params = consts.read_params(
                    ['CLIENT_MODIFIED', 'SERVER_MODIFIED', 'MAINTENANCE'])
                if not params['MAINTENANCE'] and (params['CLIENT_MODIFIED'] or
                                                  params['SERVER_MODIFIED']):
                    self.__task_locked = False
                    try:
                        if params['SERVER_MODIFIED']:
                            reload_task(self)
                            consts.BUILD_VERSION += 1
                        if params['CLIENT_MODIFIED']:
                            update_events_code(self.admin)
                        consts.CLIENT_MODIFIED = False
                        consts.SERVER_MODIFIED = False
                        consts.MODIFICATION += 1
                        consts.PARAMS_VERSION += 1
                        consts.write_settings()
                        self.save_build_id()
                    finally:
                        self.__task_locked = True

    @property
    def build_id(self):
        return '%s_%s_%s' % (self.build_id_prefix, consts.BUILD_VERSION,
                             consts.PARAMS_VERSION)

    def save_build_id(self):
        with self.admin.lock('$save_build_id'):
            path = os.path.join(self.work_dir, 'locks')
            for file_name in os.listdir(path):
                if file_name.startswith(self.build_id_prefix):
                    os.remove(os.path.join(path, file_name))
            file_write(os.path.join(path, self.build_id), '')

    def check_build(self):
        path = os.path.join(self.work_dir, 'locks')
        if not os.path.exists(os.path.join(path, self.build_id)):
            with self.admin.lock('$build_checking'):
                cur_build_version = consts.BUILD_VERSION
                cur_params_version = consts.PARAMS_VERSION
                build_version = None
                params_version = None
                for file_name in os.listdir(path):
                    if file_name.startswith(self.build_id_prefix):
                        cur_build_id = file_name
                        arr = cur_build_id.split('_')
                        build_version = int(arr[1])
                        params_version = int(arr[2])
                        break
                if params_version != cur_params_version:
                    consts.read_settings()
                if build_version != cur_build_version:
                    self.__task_locked = False
                    try:
                        reload_task(self)
                    finally:
                        self.__task_locked = True
                    consts.read_settings()

    def on_api(self, request):
        error = ''
        if request.method == 'POST':
            r = {'result': None, 'error': None}
            try:
                data = request.get_data()
                if type(data) != str:
                    data = to_unicode(data, 'utf-8')
                method, task_id, item_id, params, modification = json.loads(
                    data)
                if task_id == 0:
                    task = self.admin
                else:
                    task = self.task
                    if not task:
                        task = self.task
                        if not task:
                            lang = consts.lang
                            result = {'status': None, 'data': {'error': lang['error'], \
                                'info': lang['info']}, 'modification': None}
                            result['status'] = self.state
                            if self.state == consts.PROJECT_LOADING:
                                result['data']['project_loading'] = lang[
                                    'project_loading']
                            elif self.state == consts.PROJECT_NO_PROJECT:
                                result['data']['no_project'] = lang[
                                    'no_project']
                            elif self.state == consts.PROJECT_ERROR:
                                result['data']['project_error'] = lang[
                                    'project_error']
                            r['result'] = result
                            return self.create_post_response(request, r)
                if not task:
                    result = {
                        'status': consts.PROJECT_NO_PROJECT,
                        'data': None,
                        'modification': None
                    }
                else:
                    request.task = task
                    self.check_build()
                    result = {
                        'status': consts.RESPONSE,
                        'data': None,
                        'modification': consts.MODIFICATION
                    }
                    if task_id and modification and modification != consts.MODIFICATION:
                        result['status'] = consts.PROJECT_MODIFIED
                    elif self.under_maintenance:
                        result['status'] = consts.PROJECT_MAINTAINANCE
                    elif method == 'connect':
                        self.connect(request, task)
                        result['data'] = self.connect(request, task)
                    elif method == 'login':
                        result['data'] = self.login(request, task, params[0])
                    elif method == 'logout':
                        self.logout(request, task)
                        result['status'] = consts.PROJECT_NOT_LOGGED
                        result['data'] = consts.PROJECT_NOT_LOGGED
                    else:
                        if not self.check_session(request, task):
                            result['status'] = consts.PROJECT_NOT_LOGGED
                            result['data'] = consts.PROJECT_NOT_LOGGED
                        else:
                            item = task
                            if task and item_id:
                                item = task.item_by_ID(item_id)
                            self._busy += 1
                            try:
                                data = self.get_response(item, method, params)
                            finally:
                                self._busy -= 1
                            result['data'] = data
                r['result'] = result
            except AbortException as e:
                traceback.print_exc()
                error = error_message(e)
                r['result'] = {'data': [None, error]}
                r['error'] = error
            except Exception as e:
                traceback.print_exc()
                error = error_message(e)
                if consts.DEBUGGING and task_id != 0:
                    raise
                r['result'] = {'data': [None, error]}
                r['error'] = error
            response = self.create_post_response(request, r)
            request.save_client_cookie(response, self, task)
            return response

    def get_response(self, item, method, params):
        if method == 'open':
            return item.select_records(params, safe=True)
        elif method == 'apply':
            return item.apply_changes(params, safe=True)
        elif method == 'server':
            return self.server_func(item, params[0], params[1])
        elif method == 'print':
            return item.print_report(*params, safe=True), ''
        elif method == 'load':
            return self.init_client(item)

    def server_func(self, obj, func_name, params):
        result = None
        error = ''
        func = getattr(obj, func_name)
        if func:
            result = func(obj, *params)
        else:
            raise Exception('item: %s no server function with name %s' %
                            (obj.item_name, func_name))
        return result, error

    def on_ext(self, request):
        if request.method == 'POST':
            r = {'result': None, 'error': None}
            method = get_path_info(request.environ)
            data = request.get_data()
            if type(data) != str:
                data = to_unicode(data, 'utf-8')
            try:
                params = json.loads(data)
            except:
                params = None
            if self.task:
                try:
                    data = None
                    if self.under_maintenance:
                        status = consts.UNDER_MAINTAINANCE
                    elif self.task.on_ext_request:
                        status = consts.RESPONSE
                        self._busy += 1
                        try:
                            data = self.task.on_ext_request(
                                self.task, method, params)
                        finally:
                            self._busy -= 1
                    else:
                        status = None
                    r['result'] = {
                        'status': status,
                        'data': data,
                        'modification': consts.MODIFICATION
                    }
                except AbortException as e:
                    traceback.print_exc()
                    r['result'] = {'data': [None, error_message(e)]}
                    r['error'] = error_message(e)
                except Exception as e:
                    traceback.print_exc()
                    r['result'] = {'data': [None, error_message(e)]}
                    r['error'] = error_message(e)
            else:
                r['result'] = {
                    'status': self.state,
                    'data': None,
                    'modification': None
                }
            return self.create_post_response(request, r)

    def on_upload(self, request):
        if request.method == 'POST':
            r = {'result': None, 'error': None}
            task_id = int(request.form.get('task_id'))
            item_id = int(request.form.get('item_id'))
            field_id = int(request.form.get('field_id'))
            path = request.form.get('path')
            if task_id == 0:
                task = self.admin
            else:
                task = self.task
            if task:
                request.task = task
                result = {
                    'status': consts.RESPONSE,
                    'data': None,
                    'modification': consts.MODIFICATION
                }
                r['result'] = result
                if not self.check_session(request, task):
                    r['result']['status'] = consts.NOT_LOGGED
                    r['result']['data'] = consts.NOT_LOGGED
                else:
                    f = request.files.get('file')
                    file_name = request.form.get('file_name')
                    if f and file_name:
                        base, ext = os.path.splitext(file_name)
                        upload_result = None
                        if task.on_upload:
                            upload_result = task.on_upload(
                                task, path, file_name, f)
                        if upload_result:
                            path, file_name = upload_result
                            r['result']['data'] = {
                                'file_name': file_name,
                                'path': path
                            }
                        else:
                            if item_id != -1 and field_id != -1:
                                item = task.item_by_ID(item_id)
                                field = item.field_by_ID(field_id)
                                if field.data_type == consts.IMAGE:
                                    if ext != validate_image(f):
                                        r['error'] = 'Invalid image file'
                            else:
                                if not ext in consts.upload_file_ext:
                                    r['error'] = 'Invalid file extension'
                            file_name = ('%s%s%s') % (
                                base, datetime.datetime.now().strftime(
                                    '%Y-%m-%d_%H:%M:%S.%f'), ext)
                            file_name = secure_filename(file_name)
                            file_name = file_name.replace('?', '')
                            if task_id == 0:
                                path = os.path.join('static', 'builder')
                            else:
                                path = os.path.join('static', 'files')
                            if not r['error']:
                                dir_path = os.path.join(
                                    to_unicode(self.work_dir, 'utf-8'), path)
                                if not os.path.exists(dir_path):
                                    os.makedirs(dir_path)
                                f.save(os.path.join(dir_path, file_name))
                                r['result']['data'] = {
                                    'file_name': file_name,
                                    'path': path
                                }
                    else:
                        r['error'] = 'File upload invalid parameters'
            else:
                r['result'] = {
                    'status': self.state,
                    'data': None,
                    'modification': None
                }
            return self.create_post_response(request, r)

    def stop(self, sigvalue):
        self.kill()

    def kill(self):
        import signal, subprocess
        if os.name == "nt":
            subprocess.Popen("taskkill /F /T /pid %i" % self.pid, shell=True)
        else:
            os.killpg(self.pid, signal.SIGKILL)
Esempio n. 52
0
class TrytondWSGI(object):
    def __init__(self):
        self.url_map = Map([], converters={
            'base64': Base64Converter,
        })
        self.protocols = [JSONProtocol, XMLProtocol]
        self.error_handlers = []

    def route(self, string, methods=None):
        def decorator(func):
            self.url_map.add(Rule(string, endpoint=func, methods=methods))
            return func

        return decorator

    @wrapt.decorator
    def auth_required(self, wrapped, instance, args, kwargs):
        request = args[0]
        if request.user_id:
            return wrapped(*args, **kwargs)
        else:
            response = Response(None, http.client.UNAUTHORIZED,
                                {'WWW-Authenticate': 'Basic realm="Tryton"'})
            abort(http.client.UNAUTHORIZED, response=response)

    def check_request_size(self, request, size=None):
        if request.method not in {'POST', 'PUT', 'PATCH'}:
            return
        if size is None:
            if request.user_id:
                max_size = config.getint('request', 'max_size_authenticated')
            else:
                max_size = config.getint('request', 'max_size')
        else:
            max_size = size
        if max_size:
            content_length = request.content_length
            if content_length is None:
                abort(http.client.LENGTH_REQUIRED)
            elif content_length > max_size:
                abort(http.client.REQUEST_ENTITY_TOO_LARGE)

    def dispatch_request(self, request):
        adapter = self.url_map.bind_to_environ(request.environ)
        try:
            endpoint, request.view_args = adapter.match()
            max_request_size = getattr(endpoint, 'max_request_size', None)
            self.check_request_size(request, max_request_size)
            return endpoint(request, **request.view_args)
        except HTTPException as e:
            return e
        except Exception as e:
            tb_s = ''.join(traceback.format_exception(*sys.exc_info()))
            for path in sys.path:
                tb_s = tb_s.replace(path, '')
            e.__format_traceback__ = tb_s
            response = e
            for error_handler in self.error_handlers:
                rv = error_handler(e)
                if isinstance(rv, Response):
                    response = rv
            return response

    def make_response(self, request, data):
        for cls in self.protocols:
            for mimetype, _ in request.accept_mimetypes:
                if cls.content_type in mimetype:
                    response = cls.response(data, request)
                    break
            else:
                continue
            break
        else:
            for cls in self.protocols:
                if cls.content_type in request.environ.get('CONTENT_TYPE', ''):
                    response = cls.response(data, request)
                    break
            else:
                if isinstance(data, Exception):
                    response = InternalServerError(data)
                else:
                    response = Response(data)
        return response

    def wsgi_app(self, environ, start_response):
        for cls in self.protocols:
            if cls.content_type in environ.get('CONTENT_TYPE', ''):
                request = cls.request(environ)
                break
        else:
            request = Request(environ)

        origin = request.headers.get('Origin')
        origin_host = urllib.parse.urlparse(origin).netloc if origin else ''
        host = request.headers.get('Host')
        if origin and origin_host != host:
            cors = filter(None,
                          config.get('web', 'cors', default='').splitlines())
            if origin not in cors:
                abort(HTTPStatus.FORBIDDEN)

        data = self.dispatch_request(request)
        if not isinstance(data, (Response, HTTPException)):
            response = self.make_response(request, data)
        else:
            response = data

        if origin and isinstance(response, Response):
            response.headers['Access-Control-Allow-Origin'] = origin
            response.headers['Vary'] = 'Origin'
            method = request.headers.get('Access-Control-Request-Method')
            if method:
                response.headers['Access-Control-Allow-Methods'] = method
            headers = request.headers.get('Access-Control-Request-Headers')
            if headers:
                response.headers['Access-Control-Allow-Headers'] = headers
            response.headers['Access-Control-Max-Age'] = config.getint(
                'web', 'cache_timeout')
        return response(environ, start_response)

    def __call__(self, environ, start_response):
        return self.wsgi_app(environ, start_response)
Esempio n. 53
0
class Shortly():

    def __init__(self, config):
        self.redis = redis.Redis(config['redis_host'], config['redis_port'])
        template_path = os.path.join(os.path.dirname(__file__), 'templates')
        self.jinja_env = Environment(loader=FileSystemLoader(template_path),
                                    autoescape=True)
        self.url_map = Map([
            Rule('/', endpoint='new_url'),
            Rule('/<short_id>', endpoint='follow_short_link'),
            Rule('/<short_id>+', endpoint='short_link_details')
        ])

    def render_template(self, template_name, **context):
        t = self.jinja_env.get_template(template_name)
        return Response(t.render(context), mimetype='text/html')

    def dispatch_request(self, request):
        # return Response('Hello World!')
        # 将 RUL 绑定到目前的环境返回一个 URLAdapter 。适配器 可以用于匹配请求也可以翻转 URLS。
        adapter = self.url_map.bind_to_environ(request.environ)
        try:
            endpoint, values = adapter.match()  # 匹配方法将会返回 endpoint 和一个 URL 值字典。
            # 所有的 URL 参数做作为关键字参数调用 on_ + endpoint 函数可以返回响应对象
            return getattr(self, 'on_' + endpoint)(request, **values)   
        except HTTPException(e):
            return e

    def on_new_url(self, request):
        error = None
        url = ''
        if request.method == 'POST':
            # 从 request 中获取 url
            url = request.form['url']
            if not is_valid_url(url):
                error = 'Please enter a valid URL'
            else:
                short_id = self.insert_url(url)
                return redirect('/%s+' % short_id)
        return self.render_template('new_url.html', error=error, url=url)

    def on_follow_short_link(self, request, short_id):
        link_target = self.redis.get('url-target:' + short_id)
        if link_target is None:
            raise NotFound()
        self.redis.incr('click-count:' + short_id)
        return redirect(link_target)

    def on_short_link_details(self, request, short_id):
        link_target = self.redis.get('url-target:' + short_id)
        if link_target is None:
            raise NotFound()
        click_count = int(self.redis.get('click-count:' + short_id) or 0)
        return self.render_template('short_link_details.html',
            link_target=link_target,
            short_id=short_id,
            click_count=click_count
        )


    def insert_url(self, url):
        short_id = self.redis.get('reverse-url:' + url)
        if short_id is not None:
            return short_id
        url_num = self.redis.incr('last-url-id')
        short_id = base36_encode(url_num)
        self.redis.set('url-target:' + short_id, url)
        self.redis.set('reverse-url' + url, short_id)
        return short_id


    def wsgi_app(self, environ, start_response):
        '''
         wsgi_app 实际上创建了一个 Request 对象, 之后通过 
         dispatch_request 调用 Request 对象然后给 WSGI 应
         用返回一个 Response 对象。
         '''
        request = Request(environ)
        response = self.dispatch_request(request)
        return response(environ, start_response)

    def __call__(self, environ, start_response):
        # __call__ 方法直接调 用 wsgi_app
        return self.wsgi_app(environ, start_response)
Esempio n. 54
0
class IconikApp(object):

    credential_keys = ['app-id', 'auth-token', 'storage-id']

    def __init__(self):
        template_path = os.path.join(os.path.dirname(__file__), 'templates')
        self.jinja_env = Environment(loader=FileSystemLoader(template_path),
                                     autoescape=True)
        self.jinja_env.filters['hostname'] = get_hostname

        self.url_map = Map([
            Rule('/', endpoint='index'),
            Rule('/update_credentials', endpoint='update_credentials'),
            Rule('/credential_success', endpoint='credential_success'),
        ])

    def on_index(self, request):
        config = self.get_config_contents()
        keys_present = len(
            list(
                filter(
                    lambda v: v and v[0],
                    map(lambda key: re.findall(fr'{key}.*=[\t ]*(.*)', config),
                        self.credential_keys)))) == 3
        return self.render_template('index.html',
                                    credentials_exist=keys_present)

    def get_config_contents(self):
        with open(CONFIG_FILE_PATH, 'r') as f:
            return f.read()

    def update_config_contents(self, data):
        with open(CONFIG_FILE_PATH, 'w') as f:
            f.write(data)

    def on_credential_success(self, request):
        return self.render_template('credential_success.html')

    def on_update_credentials(self, request):
        if request.method == 'POST':
            config = self.get_config_contents()
            for key, value in {
                    k: request.form[k.replace('-', '_')]
                    for k in self.credential_keys
            }.items():
                config = re.sub(fr'({key}.*)=[\t ]*(.*)', fr'\1= {value}',
                                config)

            self.update_config_contents(config)
            return redirect('credential_success')

        else:
            return self.error_404()

    def error_404(self):
        response = self.render_template('404.html')
        response.status_code = 404
        return response

    def render_template(self, template_name, **context):
        template = self.jinja_env.get_template(template_name)
        return Response(template.render(context), mimetype='text/html')

    def dispatch_request(self, request):
        adapter = self.url_map.bind_to_environ(request.environ)
        try:
            endpoint, values = adapter.match()
            return getattr(self, 'on_' + endpoint)(request, **values)
        except NotFound:
            return self.error_404()
        except HTTPException as e:
            return e

    def wsgi_app(self, environ, start_response):
        request = Request(environ)
        response = self.dispatch_request(request)
        return response(environ, start_response)

    def __call__(self, environ, start_response):
        return self.wsgi_app(environ, start_response)
Esempio n. 55
0
class LeanEngineApplication(object):
    def __init__(self, fetch_user):
        self.fetch_user = fetch_user
        self.url_map = Map([
            Rule('/__engine/1/functions/<func_name>', endpoint='cloud_function'),
            Rule('/__engine/1.1/functions/<func_name>', endpoint='cloud_function'),
            Rule('/__engine/1/call/<func_name>', endpoint='rpc_function'),
            Rule('/__engine/1.1/call/<func_name>', endpoint='rpc_function'),
            Rule('/__engine/1/functions/BigQuery/<event>', endpoint='on_bigquery'),
            Rule('/__engine/1.1/functions/BigQuery/<event>', endpoint='on_bigquery'),
            Rule('/__engine/1.1/functions/_User/onLogin', endpoint='on_login'),
            Rule('/__engine/1/functions/_User/onLogin', endpoint='on_login'),
            Rule('/__engine/1/functions/<class_name>/<hook_name>', endpoint='cloud_hook'),
            Rule('/__engine/1.1/functions/<class_name>/<hook_name>', endpoint='cloud_hook'),
            Rule('/__engine/1/functions/onVerified/<verify_type>', endpoint='on_verified'),
            Rule('/__engine/1.1/functions/onVerified/<verify_type>', endpoint='on_verified'),
            Rule('/__engine/1/functions/_ops/metadatas', endpoint='ops_meta_data'),
            Rule('/__engine/1.1/functions/_ops/metadatas', endpoint='ops_meta_data'),

            Rule('/1/functions/<func_name>', endpoint='cloud_function'),
            Rule('/1.1/functions/<func_name>', endpoint='cloud_function'),
            Rule('/1/call/<func_name>', endpoint='rpc_function'),
            Rule('/1.1/call/<func_name>', endpoint='rpc_function'),
            Rule('/1/functions/BigQuery/<event>', endpoint='on_bigquery'),
            Rule('/1.1/functions/BigQuery/<event>', endpoint='on_bigquery'),
            Rule('/1.1/functions/_User/onLogin', endpoint='on_login'),
            Rule('/1/functions/_User/onLogin', endpoint='on_login'),
            Rule('/1/functions/<class_name>/<hook_name>', endpoint='cloud_hook'),
            Rule('/1.1/functions/<class_name>/<hook_name>', endpoint='cloud_hook'),
            Rule('/1/functions/onVerified/<verify_type>', endpoint='on_verified'),
            Rule('/1.1/functions/onVerified/<verify_type>', endpoint='on_verified'),
            Rule('/1/functions/_ops/metadatas', endpoint='ops_meta_data'),
            Rule('/1.1/functions/_ops/metadatas', endpoint='ops_meta_data'),
        ])
        self.cloud_codes = {}

    def __call__(self, environ, start_response):
        self.process_session(environ)
        response = self.dispatch_request(environ)
        return response(environ, start_response)

    def process_session(self, environ):
        request = environ['leanengine.request']
        context.local.current = context.Current()
        context.local.current.meta = {
            'remote_address': get_remote_address(request),
        }

        if environ['_app_params']['session_token'] not in (None, ''):
            session_token = environ['_app_params']['session_token']
            if self.fetch_user:
                user = leancloud.User.become(session_token)
                context.local.current.user = user
                context.local.user = user
            context.local.current.session_token = session_token
            return

        try:
            data = json.loads(request.get_data(as_text=True))
        except ValueError:
            context.local.user = None
            return

        if 'user' in data and data['user']:
            user = leancloud.User()
            user._update_data(data['user'])
            context.local.current.user = user
            context.local.current.session_token = user.get_session_token()
            context.local.user = user
            return

        context.local.user = None

    def dispatch_request(self, environ):
        request = environ['leanengine.request']
        app_params = environ['_app_params']
        adapter = self.url_map.bind_to_environ(request.environ)
        try:
            endpoint, values = adapter.match()
        except HTTPException as e:
            return e

        params = request.get_data(as_text=True)
        values['params'] = json.loads(params) if params != '' else {}

        try:
            if endpoint == 'cloud_function':
                result = {'result': dispatch_cloud_func(self.cloud_codes, app_params, decode_object=False, **values)}
            elif endpoint == 'rpc_function':
                result = {'result': dispatch_cloud_func(self.cloud_codes, app_params, decode_object=True, **values)}
            elif endpoint == 'cloud_hook':
                result = dispatch_cloud_hook(self.cloud_codes, app_params, **values)
            elif endpoint == 'on_verified':
                result = {'result': dispatch_on_verified(self.cloud_codes, app_params, **values)}
            elif endpoint == 'on_login':
                result = {'result': dispatch_on_login(self.cloud_codes, app_params, **values)}
            elif endpoint == 'ops_meta_data':
                from .authorization import MASTER_KEY
                if request.environ.get('_app_params', {}).get('master_key') != MASTER_KEY:
                    raise LeanEngineError(code=401, message='Unauthorized.')
                result = {'result': dispatch_ops_meta_data(self.cloud_codes)}
            elif endpoint == 'on_bigquery':
                result = {'result': dispatch_on_bigquery(self.cloud_codes, app_params, **values)}
            else:
                raise ValueError    # impossible
            return Response(json.dumps(result), mimetype='application/json')
        except LeanEngineError as e:
            return Response(
                json.dumps({'code': e.code, 'error': e.message}),
                status=e.code if e.code else 400,
                mimetype='application/json'
            )
        except Exception:
            print(traceback.format_exc(), file=sys.stderr)
            return Response(
                json.dumps({'code': 141, 'error': 'Cloud Code script had an error.'}),
                status=500,
                mimetype='application/json'
            )

    def update_cloud_codes(self, engine_cloud_codes):
        already_register_func_name = set(self.cloud_codes.keys()).intersection(set(engine_cloud_codes.keys()))
        if already_register_func_name:
            is_are = "is" if len(already_register_func_name) == 1 else "are"
            raise RuntimeError("cloud function: {0} {1} already registerd.".format(",".join(already_register_func_name), is_are))
        self.cloud_codes.update(engine_cloud_codes)
Esempio n. 56
0
class App():
    def __init__(self, work_dir):
        mimetypes.add_type('text/cache-manifest', '.appcache')
        self.started = datetime.datetime.now()
        self.work_dir = work_dir
        self._loading = False
        self._load_lock = Lock()
        self.admin = None
        self.task = None
        self.privileges = None
        self._busy = 0
        self.pid = os.getpid()
        self.task_server_modified = False
        self.task_client_modified = True
        self.under_maintenance = False
        self.jam_dir = os.path.dirname(jam.__file__)
        self.jam_version = jam.version()
        self.application_files = {
            '/': self.work_dir,
            '/jam/': self.jam_dir
        }
        self.fileserver = SharedDataMiddleware(None, self.application_files, cache_timeout=1)
        self.url_map = Map([
            Rule('/', endpoint='root_file'),
            Rule('/<file_name>', endpoint='root_file'),
            Rule('/js/<file_name>', endpoint='file'),
            Rule('/css/<file_name>', endpoint='file'),
            Rule('/jam/js/<file_name>', endpoint='file'),
            Rule('/jam/js/ace/<file_name>', endpoint='file'),
            Rule('/jam/css/<file_name>', endpoint='file'),
            Rule('/jam/css/themes/<file_name>', endpoint='file'),
            Rule('/jam/img/<file_name>', endpoint='file'),
            Rule('/api', endpoint='api'),
            Rule('/upload', endpoint='upload')
        ])
        self.admin = self.create_admin()

    def create_admin(self):
        return adm_server.create_admin(self)

    def get_task(self):
        if self.task:
            return self.task
        else:
            if not self._loading:
                self._loading = True
                try:
                    with self._load_lock:
                        self.task = self.admin.create_task()
                except:
                    traceback.print_exc()
                    raise
                finally:
                    self._loading = False
            return self.task

    def __call__(self, environ, start_response):
        return self.wsgi_app(environ, start_response)

    def wsgi_app(self, environ, start_response):
        jam.context.environ = environ
        request = JamRequest(environ)
        adapter = self.url_map.bind_to_environ(request.environ)
        try:
            endpoint, values = adapter.match()
            if endpoint in ['file', 'root_file']:
                return self.serve_file(environ, start_response, endpoint, **values)
            elif endpoint in ['api', 'upload']:
                response = getattr(self, 'on_' + endpoint)(request, **values)
        except HTTPException as e:
            if peek_path_info(environ) == 'ext':
                response = self.on_ext(request)
            else:
                response = e
        return response(environ, start_response)

    def check_modified(self, file_path, environ):
        if environ.get('HTTP_IF_MODIFIED_SINCE'):
            date1 = parse_date(environ['HTTP_IF_MODIFIED_SINCE'])
            date2 = datetime.datetime.utcfromtimestamp(os.path.getmtime(file_path)).replace(microsecond=0)
            if date1 != date2:
                try:
                    os.utime(file_path, None)
                except:
                    pass

    def serve_file(self, environ, start_response, endpoint, file_name=None):
        if endpoint == 'root_file':
            if not file_name:
                file_name = 'index.html'
                environ['PATH_INFO'] = environ['PATH_INFO'] + '/index.html'
            elif file_name == 'admin.html':
                file_name = 'builder.html'
            if file_name == 'index.html':
                self.check_modified(file_name, environ)
                if self.get_task():
                    self.check_task_client_modified()
                    self.check_task_server_modified()
                else:
                    return Response(self.admin.lang['no_task'])(environ, start_response)
            elif file_name == 'builder.html':
                self.check_modified(os.path.join(self.jam_dir, file_name), environ)
                environ['PATH_INFO'] = os.path.join('jam', file_name)
        if file_name:
            base, ext = os.path.splitext(file_name)
        init_path_info = None
        if common.SETTINGS['COMPRESSED_JS'] and ext and ext in ['.js', '.css']:
            init_path_info = environ['PATH_INFO']
            min_file_name = base + '.min' + ext
            environ['PATH_INFO'] = environ['PATH_INFO'].replace(file_name, min_file_name)
        try:
            try:
                return self.fileserver(environ, start_response)
            except Exception as e:
                if init_path_info:
                    environ['PATH_INFO'] = init_path_info
                    return self.fileserver(environ, start_response)
                else:
                    raise
        except Exception as e:
            return Response('')(environ, start_response)

    def create_post_response(self, request, result):
        response = Response()
        accepts_gzip = 0
        try:
            if request.environ.get("HTTP_ACCEPT_ENCODING").find("gzip") != -1:
                accepts_gzip = 1
        except:
            pass
        buff = json.dumps(result, default=common.json_defaul_handler)
        response.headers['Content-Type'] = 'application/json'
        if accepts_gzip:
            buff = common.compressBuf(buff)
            response.headers['Content-encoding'] = 'gzip'
            response.headers['Content-Length'] = str(len(buff))
        response.set_data(buff)
        return response

    def get_client_address(self, request):
        try:
            return request.environ['HTTP_X_FORWARDED_FOR'].split(',')[-1].strip()
        except KeyError:
            return request.environ['REMOTE_ADDR']

    def create_session(self, request, task, user_info=None):
        if not user_info:
            user_info = {
                'user_id': None,
                'role_id': None,
                'role_name': '',
                'user_name': '',
                'admin': False
            }
        cookie = request.get_session(task)
        session = {}
        session['ip'] = self.get_client_address(request);
        session['uuid'] = str(uuid.uuid4())
        session['user_info'] = user_info
        cookie['info'] = session
        cookie.modified = True
        return cookie

    def connect(self, request, task):
        if self.check_session(request, task):
            return True

    def valid_session(self, task, session, request):
        if self.admin.safe_mode:
            user_info = session['user_info']
            if not (user_info and user_info.get('user_id')):
                return False
            if not self.admin.ignore_change_ip and task != self.admin:
                ip = self.get_client_address(request);
                if not adm_server.user_valid_ip(self.admin, user_info['user_id'], ip):
                    return False
        return True

    def check_session(self, request, task):
        c = request.get_session(task)
        if not c.get('info') and not self.admin.safe_mode:
            c = self.create_session(request, task)
        session = c.get('info')
        if session:
            if not self.valid_session(task, session, request):
                self.logout(request, task)
                return False
            jam.context.session = session
            return True

    def login(self, request, task, login, psw_hash):
        ip = None
        if not self.admin.ignore_change_ip:
            ip = self.get_client_address(request);
        user_info = adm_server.login(self.admin, login, psw_hash, self.admin == task, ip)
        if user_info:
            self.create_session(request, task, user_info)
            return True

    def logout(self, request, task):
        cookie = cookie = request.get_session(task)
        cookie['info'] = None
        jam.context.session = None

    def check_task_server_modified(self):
        if self.task_server_modified:
            self.admin.reload_task()
            self.task_server_modified = False

    def check_task_client_modified(self):
        if self.task_client_modified:
            self.admin.update_events_code()
            self.task_client_modified = False

    def get_privileges(self, role_id):
        if self.privileges is None:
            roles, privileges = adm_server.get_roles(self.admin)
            self.privileges = privileges
        return self.privileges[role_id]

    def init_client(self, task):
        session = jam.context.session
        priv = None
        user_info = {}
        if session:
            user_info = session['user_info']
            role_id = user_info.get('role_id')
            if role_id:
                priv = self.get_privileges(role_id)
        result = {
            'task': task.get_info(),
            'settings': self.admin.get_settings(),
            'language': self.admin.lang,
            'user_info': user_info,
            'privileges': priv
        }
        return result, ''

    def on_api(self, request):
        error = ''
        if request.method == 'POST':
            r = {'result': None, 'error': None}
            try:
                data = request.get_data()
                if type(data) != str:
                    data = to_unicode(data, 'utf-8')
                method, task_id, item_id, params, date = json.loads(data)
                if task_id == 0:
                    task = self.admin
                else:
                    task = self.get_task()
                result = {'status': common.RESPONSE, 'data': None, 'version': task.version}
                if not task:
                    result['status'] = common.NO_PROJECT
                elif self.under_maintenance:
                    result['status'] = common.UNDER_MAINTAINANCE
                elif method == 'connect':
                    self.connect(request, task)
                    result['data'] = self.connect(request, task)
                elif method == 'login':
                    result['data'] = self.login(request, task, params[0], params[1])
                elif method == 'logout':
                    self.logout(request, task);
                    result['status'] = common.NOT_LOGGED
                    result['data'] = common.NOT_LOGGED
                else:
                    if not self.check_session(request, task):
                        result['status'] = common.NOT_LOGGED
                        result['data'] = common.NOT_LOGGED
                    else:
                        item = task
                        if task and item_id:
                            item = task.item_by_ID(item_id)
                        self._busy += 1
                        try:
                            data = None
                            started = datetime.datetime.now()
                            if task.on_before_request:
                                data = task.on_before_request(item, method, params)
                            if not data:
                                data = self.get_response(item, method, params)
                            if task.on_after_request:
                                task.on_after_request(item, method, params, datetime.datetime.now() - started)
                        finally:
                            self._busy -= 1
                        result['data'] = data
                r ['result'] = result
            except AbortException as e:
                traceback.print_exc()
                error = error_message(e)
                r['result'] = {'data': [None, error]}
                r['error'] = error
            except Exception as e:
                traceback.print_exc()
                error = error_message(e)
                if common.SETTINGS['DEBUGGING'] and task_id != 0:
                    raise
                r['result'] = {'data': [None, error]}
                r['error'] = error
            response = self.create_post_response(request, r)
            request.save_session(response, self, task)
            return response

    def get_response(self, item, method, params):
        if method == 'open':
            return item.select_records(params, safe=True)
        elif method == 'apply':
            return item.apply_changes(params, safe=True)
        elif method == 'server':
            return self.server_func(item, params[0], params[1])
        elif method == 'total_records':
            return item.get_record_count(params, safe=True)
        elif method == 'print':
            return item.print_report(*params, safe=True), ''
        elif method == 'load':
            return self.init_client(item)

    def server_func(self, obj, func_name, params):
        result = None
        error = ''
        func = getattr(obj, func_name)
        if func:
            result = func(obj, *params)
        else:
            raise Exception('item: %s no server function with name %s' % (obj.item_name, func_name))
        return result, error

    def on_ext(self, request):
        if request.method == 'POST':
            r = {'result': None, 'error': None}
            method = get_path_info(request.environ)
            data = request.get_data()
            if type(data) != str:
                data = to_unicode(data, 'utf-8')
            params = json.loads(data)
            task = self.get_task()
            try:
                data = None
                if self.under_maintenance:
                    status = common.UNDER_MAINTAINANCE
                elif task.on_ext_request:
                    status = common.RESPONSE
                    self._busy += 1
                    try:
                        data = task.on_ext_request(task, method, params)
                    finally:
                        self._busy -= 1
                else:
                    status = None
                r['result'] = {'status': status, 'data': data, 'version': task.version}
            except AbortException as e:
                traceback.print_exc()
                r['result'] = {'data': [None, error_message(e)]}
                r['error'] = error_message(e)
            except Exception as e:
                traceback.print_exc()
                #~ if common.SETTINGS['DEBUGGING']:
                    #~ raise
                r['result'] = {'data': [None, error_message(e)]}
                r['error'] = error_message(e)
            return self.create_post_response(request, r)

    def on_upload(self, request):

        def find_param(data):
            pos = data.find(to_bytes(';', 'utf-8'))
            return data[:pos], pos + 1

        def read_user_info(data):
            info_len, pos = find_param(data)
            info_len = int(info_len)
            user_info = data[pos:pos+info_len]
            task_ID, p = find_param(user_info)
            task_name = user_info[p:]
            pos = pos + info_len + 1
            return task_name, int(task_ID), pos

        if request.method == 'POST':
            try:
                data = request.get_data()
                header = []
                header_str = to_bytes('', 'utf-8')
                length = 0
                string = to_bytes('', 'utf-8')
                task_name, task_id, pos = read_user_info(data)
                if task_id == 0:
                    task = self.admin
                else:
                    task = self.get_task()
                if self.admin.safe_mode:
                    if not request.get_session(task).get('info'):
                        return Response()
                for i in range(len(data)):
                    s = data[pos + i:pos+i+1]
                    header_str += s
                    if s == to_bytes(';', 'utf-8'):
                        if len(header) == 0:
                            length = int(string)
                        header.append(int(string))
                        if len(header) == 2 * (length + 1):
                            break;
                        string = to_bytes('', 'utf-8')
                    else:
                        string += s
                start = len(header_str) + pos
                path = os.path.join(os.getcwd(), os.path.normpath(to_unicode(data[start: start + header[1]], 'utf-8')))
                if not os.path.exists(path):
                    os.makedirs(path)
                start = start + header[1]
                for i in range(length):
                    index = 2 * i + 2
                    file_name = to_unicode(data[start: start + header[index]], 'utf-8')
                    start = start + header[index]
                    index += 1
                    content = data[start: start + header[index]]
                    file_name = os.path.join(path, file_name)
                    with open(file_name, 'wb') as f:
                        f.write(content)
                    os.chmod(file_name, 0o666)
                    start = start + header[index]
            except:
                traceback.print_exc()
            return Response()

    def get_client_ip(self, environ):
        x_forwarded_for = environ.get('HTTP_X_FORWARDED_FOR')
        if x_forwarded_for:
            ip = x_forwarded_for.split(',')[-1].strip()
        else:
            ip = environ.get('REMOTE_ADDR')
        return ip

    def stop(self, sigvalue):
        self.kill()

    def kill(self):
        import signal, subprocess
        if os.name == "nt":
            subprocess.Popen("taskkill /F /T /pid %i" % self.pid, shell=True)
        else :
            os.killpg(self.pid, signal.SIGKILL)
Esempio n. 57
0
class WebServer:
    def __init__(self,
                 data,
                 jcontrol,
                 uri,
                 warn_data=False,
                 warn_secure=False):
        self.__data = data
        self.__warn_data = warn_data
        self.__warn_secure = warn_secure

        analysis = Analysis()
        configure = Configure(data, uri)
        diary = Diary()
        jupyter = Jupyter(jcontrol)
        kit = Kit()
        static = Static('.static')
        upload = Upload(data)
        thumbnail = Thumbnail(data.base)
        search = Search()

        self.url_map = Map([
            Rule('/api/analysis/parameters',
                 endpoint=self.check(analysis.read_parameters),
                 methods=(GET, )),
            Rule('/api/configure/profiles',
                 endpoint=self.check(configure.read_profiles, config=False),
                 methods=(GET, )),
            Rule('/api/configure/initial',
                 endpoint=self.check(configure.write_profile, config=False),
                 methods=(POST, )),
            Rule('/api/configure/delete',
                 endpoint=self.check(configure.delete, config=False),
                 methods=(POST, )),
            Rule('/api/configure/import',
                 endpoint=self.check(configure.read_import, empty=False),
                 methods=(GET, )),
            Rule('/api/configure/import',
                 endpoint=self.check(configure.write_import, empty=False),
                 methods=(POST, )),
            Rule('/api/configure/constants',
                 endpoint=self.check(configure.read_constants, empty=False),
                 methods=(GET, )),
            Rule('/api/configure/constant',
                 endpoint=self.check(configure.write_constant, empty=False),
                 methods=(PUT, )),
            Rule('/api/configure/delete-constant',
                 endpoint=self.check(configure.delete_constant, empty=False),
                 methods=(PUT, )),
            Rule('/api/diary/neighbour-activities/<date>',
                 endpoint=diary.read_neighbour_activities,
                 methods=(GET, )),
            Rule('/api/diary/active-days/<month>',
                 endpoint=diary.read_active_days,
                 methods=(GET, )),
            Rule('/api/diary/active-months/<year>',
                 endpoint=diary.read_active_months,
                 methods=(GET, )),
            Rule('/api/diary/statistics',
                 endpoint=self.check(diary.write_statistics),
                 methods=(PUT, )),
            Rule('/api/diary/latest',
                 endpoint=diary.read_latest,
                 methods=(GET, )),
            Rule('/api/diary/<date>',
                 endpoint=self.check(diary.read_diary),
                 methods=(GET, )),
            Rule('/api/search/activity/<query>',
                 endpoint=search.query_activity,
                 methods=(GET, )),
            Rule('/api/search/activity-terms',
                 endpoint=search.read_activity_terms,
                 methods=(GET, )),
            Rule('/api/jupyter/<template>', endpoint=jupyter, methods=(GET, )),
            Rule('/api/kit/edit',
                 endpoint=self.check(kit.read_edit, empty=False),
                 methods=(GET, )),
            Rule('/api/kit/retire-item',
                 endpoint=self.check(kit.write_retire_item, empty=False),
                 methods=(PUT, )),
            Rule('/api/kit/replace-model',
                 endpoint=self.check(kit.write_replace_model, empty=False),
                 methods=(PUT, )),
            Rule('/api/kit/add-component',
                 endpoint=self.check(kit.write_add_component, empty=False),
                 methods=(PUT, )),
            Rule('/api/kit/add-group',
                 endpoint=self.check(kit.write_add_group, empty=False),
                 methods=(PUT, )),
            Rule('/api/kit/items',
                 endpoint=self.check(kit.read_items, empty=False),
                 methods=(GET, )),
            Rule('/api/kit/statistics',
                 endpoint=self.check(kit.read_statistics, empty=False),
                 methods=(GET, )),
            Rule('/api/kit/<date>',
                 endpoint=self.check(kit.read_snapshot, empty=False),
                 methods=(GET, )),
            Rule('/api/thumbnail/<activity>',
                 endpoint=thumbnail,
                 methods=(GET, )),
            Rule('/api/static/<path:path>', endpoint=static, methods=(GET, )),
            Rule('/api/upload',
                 endpoint=self.check(upload, empty=False),
                 methods=(PUT, )),
            Rule('/api/busy', endpoint=self.read_busy, methods=(GET, )),
            Rule('/api/warnings', endpoint=self.read_warnings,
                 methods=(GET, )),
            Rule('/api/<path:_>', endpoint=error(BadRequest)),

            # ignore path and serve index.html
            Rule('/<path:_>',
                 defaults={'path': 'index.html'},
                 endpoint=static,
                 methods=(GET, )),
            Rule('/',
                 defaults={'path': 'index.html'},
                 endpoint=static,
                 methods=(GET, ))
        ])

        self.__configure = configure

    def dispatch_request(self, request):
        adapter = self.url_map.bind_to_environ(request.environ)
        try:
            endpoint, values = adapter.match()
            values.pop('_', None)
            if self.__data.db:
                with self.__data.db.session_context() as s:
                    return endpoint(request, s, **values)
            else:
                return endpoint(request, None, **values)
        except HTTPException as e:
            return e

    def wsgi_app(self, environ, start_response):
        request = JSONRequest(environ)
        response = self.dispatch_request(request)
        return response(environ, start_response)

    def __call__(self, environ, start_response):
        return self.wsgi_app(environ, start_response)

    def get_busy(self):
        percent = self.__data.sys.get_percent(READ)
        if percent is None: percent = 100
        # the client uses the complete message when the problem has passed
        return {
            MESSAGE: 'Loading data and recalculating statistics.',
            COMPLETE: 'Data loaded and statistics updated.',
            PERCENT: percent
        }

    def read_busy(self, request, s):
        return JsonResponse({BUSY: self.get_busy()})

    def read_warnings(self, request, s):
        warnings = []
        if self.__warn_data:
            warnings.append({
                'title':
                'Your Data Are Not Stored Permanently',
                'text':
                'The default Docker configuration stores your data within the same '
                'container that runs the code.  If you update / delete / prune the '
                'container you will lose your data.'
            })
        if self.__warn_secure:
            warnings.append({
                'title':
                'This System Is Not Secured For External Use',
                'text':
                'Choochoo should not be deployed on a public server.  '
                'It is intended only for local, personal use.'
            })
        return JsonResponse({DATA: warnings})

    def check(self, handler, config=True, empty=True):
        def wrapper(request, s, *args, **kargs):
            if config:
                if not self.__configure.is_configured():
                    log.debug(f'Redirect (not configured)')
                    return JsonResponse({REDIRECT: '/configure/initial'})
                # if we don't care about config we certainly don't care about data
                if s and empty:
                    if self.__configure.is_empty(s):
                        log.debug(f'Redirect (no data)')
                        return JsonResponse({REDIRECT: '/upload'})
            busy = self.get_busy()
            if busy[PERCENT] is None or busy[PERCENT] == 100:
                try:
                    data = handler(request, s, *args, **kargs)
                    msg = f'Returning data: {data}'
                    if len(msg) > MAX_MSG:
                        msg = msg[:MAX_MSG - 20] + ' ... ' + msg[-10:]
                    log.debug(msg)
                    return JsonResponse({DATA: data})
                except Exception as e:
                    log_current_exception()
                    # maybe some errors are redirects?
                    error = str(e).strip()
                    if not error.endswith('.'): error += '.'
                    log.debug(f'Returning error: {error}')
                    return JsonResponse({ERROR: error})
            else:
                log.debug(f'Returning busy: {busy}')
                return JsonResponse({BUSY: busy})

        return wrapper
Esempio n. 58
0
class WebServer:
    def __init__(self, config, warn_data=False, warn_secure=False):
        self.__config = config
        self.__warn_data = warn_data
        self.__warn_secure = warn_secure

        analysis = Analysis()
        configure = Configure(config)
        diary = Diary()
        jupyter = Jupyter(config)
        kit = Kit()
        route = Route()
        sector = Sector(config)
        static = Static('.static')
        upload = Upload(config)
        thumbnail = Thumbnail(config)
        sparkline = Sparkline(config)
        search = Search()

        self.url_map = Map([
            Rule('/api/analysis/parameters',
                 endpoint=self.check(analysis.read_parameters),
                 methods=(GET, )),
            Rule('/api/configure/profiles',
                 endpoint=self.check(configure.read_profiles, config=False),
                 methods=(GET, )),
            Rule('/api/configure/initial',
                 endpoint=self.check(configure.write_profile, config=False),
                 methods=(POST, )),
            Rule('/api/configure/delete',
                 endpoint=self.check(configure.delete, config=False,
                                     busy=True),
                 methods=(POST, )),
            Rule('/api/configure/import',
                 endpoint=self.check(configure.read_import, empty=False),
                 methods=(GET, )),
            Rule('/api/configure/import',
                 endpoint=self.check(configure.write_import,
                                     empty=False,
                                     busy=True),
                 methods=(POST, )),
            Rule('/api/configure/constants',
                 endpoint=self.check(configure.read_constants, empty=False),
                 methods=(GET, )),
            Rule('/api/configure/constant',
                 endpoint=self.check(configure.write_constant, empty=False),
                 methods=(PUT, )),
            Rule('/api/configure/delete-constant',
                 endpoint=self.check(configure.delete_constant, empty=False),
                 methods=(PUT, )),
            Rule('/api/diary/neighbour-activities/<date>',
                 endpoint=diary.read_neighbour_activities,
                 methods=(GET, )),
            Rule('/api/diary/active-days/<month>',
                 endpoint=diary.read_active_days,
                 methods=(GET, )),
            Rule('/api/diary/active-months/<year>',
                 endpoint=diary.read_active_months,
                 methods=(GET, )),
            Rule('/api/diary/statistics',
                 endpoint=self.check(diary.write_statistics),
                 methods=(PUT, )),
            Rule('/api/diary/latest',
                 endpoint=diary.read_latest,
                 methods=(GET, )),
            Rule('/api/diary/<date>',
                 endpoint=self.check(diary.read_diary),
                 methods=(GET, )),
            Rule('/api/search/activity/<query>',
                 endpoint=search.query_activity,
                 methods=(GET, )),
            Rule('/api/search/activity-terms',
                 endpoint=search.read_activity_terms,
                 methods=(GET, )),
            Rule('/api/jupyter/<template>', endpoint=jupyter, methods=(GET, )),
            Rule('/api/kit/edit',
                 endpoint=self.check(kit.read_edit, empty=False),
                 methods=(GET, )),
            Rule('/api/kit/retire-item',
                 endpoint=self.check(kit.write_retire_item, empty=False),
                 methods=(PUT, )),
            Rule('/api/kit/replace-model',
                 endpoint=self.check(kit.write_replace_model, empty=False),
                 methods=(PUT, )),
            Rule('/api/kit/add-component',
                 endpoint=self.check(kit.write_add_component, empty=False),
                 methods=(PUT, )),
            Rule('/api/kit/add-group',
                 endpoint=self.check(kit.write_add_group, empty=False),
                 methods=(PUT, )),
            Rule('/api/kit/items',
                 endpoint=self.check(kit.read_items, empty=False),
                 methods=(GET, )),
            Rule('/api/kit/statistics',
                 endpoint=self.check(kit.read_statistics, empty=False),
                 methods=(GET, )),
            Rule('/api/kit/<date>',
                 endpoint=self.check(kit.read_snapshot, empty=False),
                 methods=(GET, )),
            Rule('/api/thumbnail/<int:activity>',
                 endpoint=thumbnail,
                 methods=(GET, )),
            Rule('/api/thumbnail/<int:activity>/<int:sector>',
                 endpoint=thumbnail,
                 methods=(GET, )),
            Rule('/api/route/latlon/activity/<int:activity>',
                 endpoint=self.check(route.read_activity_latlon, empty=False),
                 methods=(GET, )),
            Rule('/api/route/latlon/sector/<int:sector>',
                 endpoint=self.check(route.read_sector_latlon, empty=False),
                 methods=(GET, )),
            Rule('/api/sector',
                 endpoint=self.check(sector.create_sector, empty=False),
                 methods=(POST, )),
            Rule('/api/sector/<int:sector>',
                 endpoint=self.check(sector.read_sector_journals, empty=False),
                 methods=(GET, )),
            Rule('/api/sparkline/<int:statistic>',
                 endpoint=sparkline,
                 methods=(GET, )),
            Rule('/api/sparkline/<int:statistic>/<int:sector>',
                 endpoint=sparkline,
                 methods=(GET, )),
            Rule('/api/sparkline/<int:statistic>/<int:sector>/<int:activity>',
                 endpoint=sparkline,
                 methods=(GET, )),
            Rule('/api/isparkline/<int:statistic>',
                 endpoint=sparkline,
                 methods=(GET, ),
                 defaults={'invert': True}),
            Rule('/api/isparkline/<int:statistic>/<int:sector>',
                 endpoint=sparkline,
                 methods=(GET, ),
                 defaults={'invert': True}),
            Rule('/api/isparkline/<int:statistic>/<int:sector>/<int:activity>',
                 endpoint=sparkline,
                 methods=(GET, ),
                 defaults={'invert': True}),
            Rule('/api/static/<path:path>', endpoint=static, methods=(GET, )),
            Rule('/api/upload',
                 endpoint=self.check(upload, empty=False),
                 methods=(PUT, )),
            Rule('/api/warnings', endpoint=self.read_warnings,
                 methods=(GET, )),
            Rule('/api/busy', endpoint=self.read_busy, methods=(GET, )),
            Rule('/api/<path:_>', endpoint=error(BadRequest)),

            # ignore path and serve index.html
            Rule('/<path:_>',
                 defaults={'path': 'index.html'},
                 endpoint=static,
                 methods=(GET, )),
            Rule('/',
                 defaults={'path': 'index.html'},
                 endpoint=static,
                 methods=(GET, ))
        ])

        self.__configure = configure

    def dispatch_request(self, request):
        adapter = self.url_map.bind_to_environ(request.environ)
        try:
            endpoint, values = adapter.match()
            values.pop('_', None)
            if self.__config.db:
                with self.__config.db.session_context() as s:
                    return endpoint(request, s, **values)
            else:
                return endpoint(request, None, **values)
        except HTTPException as e:
            return e

    def wsgi_app(self, environ, start_response):
        request = JSONRequest(environ)
        response = self.dispatch_request(request)
        return response(environ, start_response)

    def __call__(self, environ, start_response):
        return self.wsgi_app(environ, start_response)

    def read_warnings(self, request, s):
        warnings = []
        if self.__warn_data:
            warnings.append({
                'title':
                'Your Data Are Not Stored Permanently',
                'text':
                'The default Docker configuration stores your data within the same '
                'container that runs the code.  If you update / delete / prune the '
                'container you will lose your data.'
            })
        if self.__warn_secure:
            warnings.append({
                'title':
                'This System Is Not Secured For External Use',
                'text':
                'Choochoo should not be deployed on a public server.  '
                'It is intended only for local, personal use.'
            })
        return JsonResponse({DATA: warnings})

    def read_busy(self, request, s):
        return JsonResponse({DATA: self.__configure.is_busy()})

    def check(self, handler, config=True, empty=True, busy=False):
        def wrapper(request, s, *args, **kargs):
            if config:
                if not self.__configure.is_configured():
                    log.debug(f'Redirect (not configured)')
                    return JsonResponse({REDIRECT: '/configure/initial'})
                # if we don't care about config we certainly don't care about data
                if s and empty:
                    if self.__configure.is_empty(s):
                        log.debug(f'Redirect (no data)')
                        return JsonResponse({REDIRECT: '/upload'})
                # todo - should we test for if s here?
                if s and busy and self.__config.exists_any_process():
                    return JsonResponse({REDIRECT:
                                         '.'})  # todo - does this work?
            data = handler(request, s, *args, **kargs)
            msg = f'Returning data: {data}'
            if len(msg) > MAX_MSG:
                msg = msg[:MAX_MSG - 20] + ' ... ' + msg[-10:]
            log.debug(msg)
            return JsonResponse({DATA: data})

        return wrapper
Esempio n. 59
0
class Shortly(object):
    def __init__(self):
        #self.sessions = ["sid":"1"]
        #response.set_cookie('cookie_name', request.sessions.sid)
        self.session = {}

        template_path = os.path.join(os.path.dirname(__file__), 'templates')
        self.jinja_env = Environment(loader=FileSystemLoader(template_path),
                                     autoescape=True)
        self.url_map = Map([
            Rule('/', endpoint='index_url'),
            Rule('/search_controller', endpoint='search_controller'),
            Rule('/like_update', endpoint='like_update')
        ])

    def index_url(self, request):
        session_id = request.cookies.get('session_id')
        print('==========>session', session_id)

        if not session_id:
            session_id = self.make_token()
            self.session = self.create_session(session_id)
        else:
            self.session = self.read_session(session_id)

        with open('static/dataUrl.json') as response:
            source = response.read()

        data = json.loads(source)
        response = self.render_template("app.html",
                                        data=data,
                                        session_data=self.session)
        response.set_cookie('session_id', self.session['session_id'])

        return response

    def like_update(self, request):
        # global session
        Mylikes = request.args.get('likes')
        Myid = request.args.get('id')
        # import pdb ; pdb.set_trace()

        with open('static/dataUrl.json') as response:
            source = response.read()
        data = json.loads(source)
        updated_row = []
        for i in data["results"]:
            if Myid in i['id']:
                if int(Mylikes) < 0:
                    i["dislike"] = Mylikes
                    self.session['totalDisLikes'] += 1

                else:
                    i["like"] = Mylikes
                    self.session['totalLikes'] += 1
                updated_row.append(i)

        result = {"row": updated_row}
        print(self.session)

        jsonFile = open("static/dataUrl.json", "w+")
        jsonFile.write(json.dumps(data))

        jsonFile.close()
        with open('static/session.json') as response:
            session_source = response.read()
        session_data = json.loads(session_source)
        newData = []
        for session in session_data["session_data"]:
            if self.session['session_id'] in session['session_id']:
                session = self.session
            newData.append(session)

        sessionFile = open("static/session.json", "w+")
        sessionData = {'session_data': newData}
        sessionFile.write(json.dumps(sessionData))

        sessionFile.close()

        response = {"updated_row": updated_row, "session": self.session}
        return Response(json.dumps(response), mimetype='application/json')

    def search_controller(self, request):
        filterdata = request.args.get('filter')
        with open('static/dataUrl.json') as response:
            source = response.read()
        data = json.loads(source)

        myFilterData = []

        for i in data["results"]:
            if filterdata in i['Question']:
                myFilterData.append(i)

        return Response(json.dumps(myFilterData), mimetype='application/json')

    def make_token(self):
        return secrets.token_urlsafe(16)

    def read_session(self, session_id):
        with open('static/session.json') as response:
            source = response.read()
        data = json.loads(source)

        for session in data["session_data"]:
            if session_id in session['session_id']:
                return session

    def create_session(self, session_id):
        with open('static/session.json') as response:
            data = response.read()
        session_data = json.loads(data)
        data = {"session_id": session_id, "totalLikes": 0, "totalDisLikes": 0}
        session_data['session_data'].append(data)
        jsonFile = open("static/session.json", "w")
        jsonFile.write(json.dumps(session_data))
        jsonFile.write("\n")
        jsonFile.close()
        return data

    def dispatch_request(self, request):
        adapter = self.url_map.bind_to_environ(request.environ)
        try:
            endpoint, values = adapter.match()
            return getattr(self, endpoint)(request, **values)
        except HTTPException as e:
            return e

    def wsgi_app(self, environ, start_response):
        request = Request(environ)
        response = self.dispatch_request(request)
        return response(environ, start_response)

    def render_template(self, templatename, **context):
        t = self.jinja_env.get_template(templatename)
        return Response(t.render(context), mimetype='text/html')

    def __call__(self, environ, start_response):
        return self.wsgi_app(environ, start_response)
Esempio n. 60
0
class TrytondWSGI(object):
    def __init__(self):
        self.url_map = Map([])
        self.protocols = [JSONProtocol, XMLProtocol]
        self.error_handlers = []

    def route(self, string, methods=None):
        def decorator(func):
            self.url_map.add(Rule(string, endpoint=func, methods=methods))
            return func

        return decorator

    @wrapt.decorator
    def auth_required(self, wrapped, instance, args, kwargs):
        request = args[0]
        if request.user_id:
            return wrapped(*args, **kwargs)
        else:
            # ABDC: Here we change the code from UNAUTHORIZED because it
            # is not properly handled by the client and causes a crash.
            abort(http.client.FORBIDDEN)

    def check_request_size(self, request, size=None):
        if request.method not in {'POST', 'PUT', 'PATCH'}:
            return
        if size is None:
            if request.user_id:
                max_size = config.getint('request', 'max_size_authenticated')
            else:
                max_size = config.getint('request', 'max_size')
        else:
            max_size = size
        if max_size:
            content_length = request.content_length
            if content_length is None:
                abort(http.client.LENGTH_REQUIRED)
            elif content_length > max_size:
                abort(http.client.REQUEST_ENTITY_TOO_LARGE)

    def dispatch_request(self, request):
        adapter = self.url_map.bind_to_environ(request.environ)
        try:
            endpoint, request.view_args = adapter.match()
            max_request_size = getattr(endpoint, 'max_request_size', None)
            self.check_request_size(request, max_request_size)
            return endpoint(request, **request.view_args)
        except HTTPException as e:
            return e
        except Exception as e:
            tb_s = ''.join(traceback.format_exception(*sys.exc_info()))
            for path in sys.path:
                tb_s = tb_s.replace(path, '')
            e.__format_traceback__ = tb_s
            response = e
            for error_handler in self.error_handlers:
                rv = error_handler(e)
                if isinstance(rv, Response):
                    response = rv
            return response

    def wsgi_app(self, environ, start_response):
        for cls in self.protocols:
            if cls.content_type in environ.get('CONTENT_TYPE', ''):
                request = cls.request(environ)
                break
        else:
            request = Request(environ)
        data = self.dispatch_request(request)
        if not isinstance(data, (Response, HTTPException)):
            for cls in self.protocols:
                for mimetype, _ in request.accept_mimetypes:
                    if cls.content_type in mimetype:
                        response = cls.response(data, request)
                        break
                else:
                    continue
                break
            else:
                for cls in self.protocols:
                    if cls.content_type in environ.get('CONTENT_TYPE', ''):
                        response = cls.response(data, request)
                        break
                else:
                    if isinstance(data, Exception):
                        response = InternalServerError(data)
                    else:
                        response = Response(data)
        else:
            response = data
        # TODO custom process response
        return response(environ, start_response)

    def __call__(self, environ, start_response):
        return self.wsgi_app(environ, start_response)