class InterfaceBaseHandler(RequestHandler, TraceAbleObject): TemplatePath = None def __init__(self, *args, **kwargs): super(InterfaceBaseHandler, self).__init__(*args, **kwargs) self.make_trace() def genReturn(self, response={}): raise Return(response) def is_active_page(self, reverse_name, second_name=None): return 'active' if reverse_name == self.ReverseName else '' def is_active_showcase(self, second_name, showcase): return 'active' if second_name == showcase else '' def initialize(self, *args, **kwargs): self.cookies_name = self.config.interface['cookie']['name'] cookie = self.get_secure_cookie(self.cookies_name) self.cookie_data = ObjectDict( json.loads(cookie)) if cookie else ObjectDict() def check_browser(self): useragent = user_agents.parse(self.request.header.user_agent) if useragent.browser.family == 'Microsoft IE' and int( useragent.browser.version) < 9: message = self.translate('Microsoft IE is not supported') raise error.CheckBrowerError(message) def update_cookies(self, **kwargs): self.cookie_data.update(**kwargs) self.set_secure_cookie(self.cookies_name, json.dumps(self.cookie_data)) @property def config(self): return self.application.settings['config'] @property def env(self): return self.application._jinja_env @property def session_factory(self): return self.application.session_factory @property def mailgun(self): return self.application.settings['mailgun'] def _render(self, template, **kwargs): self.env.globals.update(translate=self.translate, reverse_url=self.reverse_url, current_user=self.current_user, is_active_page=self.is_active_page, is_active_showcase=self.is_active_showcase, config=self.config) template = self.env.get_template(template) self.env.globals['static_url'] = self.static_url self.write(template.render(kwargs)) def render(self, **kwargs): self._render(self.TemplatePath, **kwargs) def get_current_user(self): sessionid = self.cookie_data.get('sessionid') if not sessionid: session = self.create_session() else: session = self.session_factory.get_session(sessionid, expire_sec=3600) if not session: self.clear_cookie(self.cookies_name) session = self.create_session() self.session = session return session def create_session(self): sessionid = uuid4().get_hex() session = self.session_factory.generate(sessionid) self.set_secure_cookie(self.cookies_name, json.dumps({'sessionid': sessionid})) return session def get_login_url(self): return self.reverse_url('account.signin') def get_user_locale(self): return locale.get(self.cookie_data.get('locale', 'zh_CN')) def translate(self, text): return self.get_user_locale().translate(text) def _get_argument(self, name, default, source, strip=True): args = self._get_arguments(name, source, strip=strip) if not args: print 'default is self._ARG_DEFAULT:', (default is self._ARG_DEFAULT) if default is self._ARG_DEFAULT: raise error.ArgumentError(name=name) return default return args[-1] def redirect_to(self, reverse_name, **kwargs): self.redirect(self.reverse_url(reverse_name, **kwargs)) def output(self, response): response['data']['trace'] = self.trace self._chunk = json.dumps(response) self.set_header('Content-Type', 'application/json; charset=UTF-8') self.write(self._chunk) self.finish() def make_response(self, data, **kwargs): return { 'success': True, 'message': data.get('message') or 'ok', 'data': data } def make_error(self, error, **kwargs): return {'success': False, 'message': error.msg, 'data': {}} def make_exception(self, **kwargs): return {'success': False, 'message': 'system_error', 'data': {}} @coroutine def handle(self, *args, **kwargs): try: data = yield self.post_operate(*args, **kwargs) response = self.make_response(data) except error.LogicError, e: logger.error(e, extra={'trace': self.trace}) response = self.make_error(e) except error.SysError, e: logger.error(e, exc_info=True, extra={'trace': self.trace}) response = self.make_error(e)
class TrackRequest(RequestHandler): """Subclass this class to track requests. A track member is available to store additional state to the mongo tracker collection if required. This class can be initialized with a different Stats interface to send metrics somewhere else. The default StatsdStats sends to statsd/graphite. """ max_response_size = 120 def skip_dotted_names(self, d): # and multiple values return dict( (key, value[0] if len(value) == 1 else value) for key, value in \ d.iteritems() if '.' not in key) def prepare(self): function = self.request.path if function.startswith('/stubo/api/'): function = function.partition('/stubo/api/')[-1] elif function == '/stubo/default/execCmds': # LEGACY function = 'exec/cmds' args = self.skip_dotted_names(self.request.arguments) headers = self.skip_dotted_names(self.request.headers) self.track = ObjectDict(request_params=args, request_headers=headers, request_method=self.request.method) host_parts = self.request.host.partition(':') host = host_parts[0].lower() port = host_parts[-1] cache = Cache(host) track_setting = cache.get_stubo_setting('tracking_level') if not track_setting: track_setting = cache.get_stubo_setting('tracking_level', all_hosts=True) if not track_setting: track_setting = 'normal' self.track.tracking_level = args.get('tracking_level', track_setting) request_size = len(self.request.body) # always track put/stub recordings if self.track.tracking_level == 'full' or function == 'put/stub': self.track.request_text = self.request.body if function == 'get/response' and request_size <= 0: self.track.error = 'NoTextInBody' self.track.update(dict(function=function, start_time=tsecs_to_date(self.request._start_time), host=host, port=port, remote_ip=self.request.remote_ip, server=socket.getfqdn(), request_size=request_size)) log.debug('tracking: {0}:{1}'.format(self.request.host, function)) def send_stats(self): stats = self.settings.get('stats') if stats: stats.send(self.settings, self.track) def on_finish(self): elapsed_ms = int(1000.0 * self.request.request_time()) tracker = Tracker() # handle fail early cases that don't have a response if not hasattr(self.track, 'stubo_response'): self.track.stubo_response = '' return_code = self.get_status() record = dict(duration_ms=elapsed_ms, return_code=return_code) if self._headers_written: record['response_headers'] = self._headers record['response_size'] = int(self._headers.get('Content-Length', len(self.track.stubo_response))) self.track.update(record) if self.track.function == 'get/response' \ and return_code > 399: self.track.request_text = self.request.body if self.track.tracking_level != 'full' and \ self.track.response_size > self.max_response_size: try: # response will typically be json dict so convert to str to chop self.track.stubo_response = str(self.track.stubo_response )[:self.max_response_size] except Exception, e: log.error("unable to trim tracked stubo response: {0}".format(e)) if self.track.function == 'get/stublist': # don't want to store stub listing in the track self.track.stubo_response = 'stubs listed ...' elif self.track.function == 'exec/cmds': self.track.stubo_response = 'commands executed ...' try: write_concern = 1 if self.track.function == 'put/stub' else 0 tracker.insert(self.track, write_concern) except Exception, e: log.warn(u"error inserting track: {0}".format(e))
class TrackRequest(RequestHandler): """Subclass this class to track requests. A track member is available to store additional state to the mongo tracker collection if required. This class can be initialized with a different Stats interface to send metrics somewhere else. The default StatsdStats sends to statsd/graphite. """ max_response_size = 120 def skip_dotted_names(self, d): # and multiple values return dict( (key, value[0] if len(value) == 1 else value) for key, value in \ d.iteritems() if '.' not in key) def prepare(self): function = self.request.path if function.startswith('/stubo/api/'): function = function.partition('/stubo/api/')[-1] elif function == '/stubo/default/execCmds': # LEGACY function = 'exec/cmds' args = self.skip_dotted_names(self.request.arguments) headers = self.skip_dotted_names(self.request.headers) self.track = ObjectDict(request_params=args, request_headers=headers, request_method=self.request.method) host_parts = self.request.host.partition(':') host = host_parts[0].lower() port = host_parts[-1] cache = Cache(host) track_setting = cache.get_stubo_setting('tracking_level') if not track_setting: track_setting = cache.get_stubo_setting('tracking_level', all_hosts=True) if not track_setting: track_setting = 'normal' self.track.tracking_level = args.get('tracking_level', track_setting) request_size = len(self.request.body) # always track put/stub recordings if self.track.tracking_level == 'full' or function == 'put/stub': self.track.request_text = self.request.body if function == 'get/response' and request_size <= 0: self.track.error = 'NoTextInBody' self.track.update( dict(function=function, start_time=tsecs_to_date(self.request._start_time), host=host, port=port, remote_ip=self.request.remote_ip, server=socket.getfqdn(), request_size=request_size)) log.debug('tracking: {0}:{1}'.format(self.request.host, function)) def send_stats(self): stats = self.settings.get('stats') if stats: stats.send(self.settings, self.track) def on_finish(self): elapsed_ms = int(1000.0 * self.request.request_time()) tracker = Tracker() # handle fail early cases that don't have a response if not hasattr(self.track, 'stubo_response'): self.track.stubo_response = '' return_code = self.get_status() record = dict(duration_ms=elapsed_ms, return_code=return_code) if self._headers_written: record['response_headers'] = self._headers record['response_size'] = int( self._headers.get('Content-Length', len(self.track.stubo_response))) self.track.update(record) if self.track.function == 'get/response' \ and return_code > 399: self.track.request_text = self.request.body if self.track.tracking_level != 'full' and \ self.track.response_size > self.max_response_size: try: # response will typically be json dict so convert to str to chop self.track.stubo_response = str( self.track.stubo_response)[:self.max_response_size] except Exception, e: log.error( "unable to trim tracked stubo response: {0}".format(e)) if self.track.function == 'get/stublist': # don't want to store stub listing in the track self.track.stubo_response = 'stubs listed ...' elif self.track.function == 'exec/cmds': self.track.stubo_response = 'commands executed ...' try: write_concern = 1 if self.track.function == 'put/stub' else 0 tracker.insert(self.track, write_concern) except Exception, e: log.warn(u"error inserting track: {0}".format(e))
# mongodb settings dbname = 'mapthisnow', dbhost = None, dbport = None, # httpd server settings httpd_address = '127.0.0.1', httpd_port = 9988, cookie_secret = None, # ya you're gonna have to set this locally # file paths static_path = path.join(path.dirname(__file__), "static"), template_path = path.join(path.dirname(__file__), "app/templates"), login_url = '/auth/netflix/connect', # debuggery debug = False, debug_pdb = False, netflix_client_secret = None, netflix_client_id = None, netflix_callback_uri = 'http://127.0.0.1:9988/auth/netflix/connect', ) # pull in our local overrides, if any try: from settings_local import settings as settings_local settings.update(settings_local) except ImportError: pass
# mongodb settings dbname='mapthisnow', dbhost=None, dbport=None, # httpd server settings httpd_address='127.0.0.1', httpd_port=9988, cookie_secret=None, # ya you're gonna have to set this locally # file paths static_path=path.join(path.dirname(__file__), "static"), template_path=path.join(path.dirname(__file__), "app/templates"), login_url='/auth/netflix/connect', # debuggery debug=False, debug_pdb=False, netflix_client_secret=None, netflix_client_id=None, netflix_callback_uri='http://127.0.0.1:9988/auth/netflix/connect', ) # pull in our local overrides, if any try: from settings_local import settings as settings_local settings.update(settings_local) except ImportError: pass