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)
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
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
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]
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
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)
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)
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
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
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
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)
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
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
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
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))
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
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)
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"))
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
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
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
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)
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)
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
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
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
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())
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
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
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)
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
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)
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)
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
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
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)
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:
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)
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)
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)
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)
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)
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)
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'))
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')
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)
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)
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
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)
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)
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)
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)
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)
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)
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)
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)
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
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
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)
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)