def wrapped_func(self, *args, **kwargs): self.api_uri = api_uri try: return fn(self, *args, **kwargs) except Exception as e: logger.error('API call error: {e}'.format(e=e)) raise
def create(args): location = path.abspath(args.path) if path.exists(location): logger.error('Directory %s already exists' % location) sys.exit(1) logger.info('Creating project') if args.bootstrap: paths = (('', ), ('content', )) else: paths = (('', ), ('static', ), ('static', 'img'), ('static', 'css'), ('static', 'js'), ('templates', ), ('content', )) for p in paths: new_path = path.join(location, *p) logger.info('Creating directory %s' % new_path) os.mkdir(new_path) if args.bootstrap: logger.info('Copying Twitter Bootstrap framework files') paths_copy = ('static', 'templates') for p in paths_copy: new_path = path.join(location, p) bootstrap_path = path.join(skeleton_path, 'bootstrap', p) shutil.copytree(bootstrap_path, new_path) yaml_src = path.join(skeleton_path, 'app.yaml') yaml_dest = path.join(location, 'app.yaml') logger.info('Creating blank project file %s' % yaml_dest) shutil.copy(yaml_src, yaml_dest) os.chmod(yaml_dest, stat.S_IWUSR | stat.S_IRUSR)
def upload(args): app_path = path.abspath(args.path) yaml_path = path.join(app_path, 'app.yaml') templates_path = path.join(app_path, 'templates') content_path = path.join(app_path, 'content') static_path = path.join(app_path, 'static') yaml_data = yaml.load(open(yaml_path, 'r').read()) if 'api_access_key' not in yaml_data or \ 'api_secret_key' not in yaml_data: logger.error( 'app.yaml does not have data for keys "api_access_key" and "api_secret_key"' ) sys.exit(3) payload = {} cut_start = len(app_path) + 1 for dirname, subdirs, files in os.walk(app_path): dn = dirname[cut_start:] if dn.startswith('templates') or \ dn.startswith('content') or \ dn.startswith('static'): if dn.startswith('templates'): key = 'templates' if dn.startswith('content'): key = 'content' if dn.startswith('static'): key = 'static' payload.setdefault(key, {}) for filename in files: # skip all files starting with ".", "#", or "_" if filename[0] not in '.#_': filepath = path.join(dn, filename)[len(key) + 1:] fullfilepath = path.join(dirname, filename) payload[key][filepath] = file_data(fullfilepath) payload['application_config'] = base64.b64encode(json.dumps(yaml_data)) payload_json = json.dumps(payload) api = MarkupHive(yaml_data) try: logger.info('Uploading') response_data = api.put_application(payload_json) logger.debug( 'API response data: {response}'.format(response=response_data)) if response_data['success']: logger.info('Upload complete. Your site is available at ' 'http://%s.app.markuphive.com/' % yaml_data['application_name']) else: logger.info('Upload failed.') if 'error' in response_data: for error in response_data['error']: logger.info('Error message: {error}'.format(error=error)) except urllib2.HTTPError, e: logger.error('API call returned a 404. Please check api ' 'credentials in the app.yaml file.')
def upload(args): app_path = path.abspath(args.path) yaml_path = path.join(app_path, 'app.yaml') templates_path = path.join(app_path, 'templates') content_path = path.join(app_path, 'content') static_path = path.join(app_path, 'static') yaml_data = yaml.load(open(yaml_path, 'r').read()) if 'api_access_key' not in yaml_data or \ 'api_secret_key' not in yaml_data: logger.error('app.yaml does not have data for keys "api_access_key" and "api_secret_key"') sys.exit(3) payload = {} cut_start = len(app_path) + 1 for dirname, subdirs, files in os.walk(app_path): dn = dirname[cut_start:] if dn.startswith('templates') or \ dn.startswith('content') or \ dn.startswith('static'): if dn.startswith('templates'): key = 'templates' if dn.startswith('content'): key = 'content' if dn.startswith('static'): key = 'static' payload.setdefault(key, {}) for filename in files: # skip all files starting with ".", "#", or "_" if filename[0] not in '.#_': filepath = path.join(dn, filename)[len(key)+1:] fullfilepath = path.join(dirname, filename) payload[key][filepath] = file_data(fullfilepath) payload['application_config'] = base64.b64encode(json.dumps(yaml_data)) payload_json = json.dumps(payload) api = MarkupHive(yaml_data) try: logger.info('Uploading') response_data = api.put_application(payload_json) logger.debug('API response data: {response}'.format(response=response_data)) if response_data['success']: logger.info( 'Upload complete. Your site is available at ' 'http://%s.app.markuphive.com/' % yaml_data['application_name'] ) else: logger.info('Upload failed.') if 'error' in response_data: for error in response_data['error']: logger.info('Error message: {error}'.format(error=error)) except urllib2.HTTPError, e: logger.error('API call returned a 404. Please check api ' 'credentials in the app.yaml file.')
def load_app_yaml(self, path=None): # default to the initialized path set with command args if path is None: self.set_app_path(self.app_path) else: self.set_app_path(path) try: with open(self.app_yaml_path, 'r') as yaml_file: self.app_yaml = yaml.safe_load(yaml_file.read()) except IOError: logger.error('Cannot load %s' % self.app_yaml_path) sys.exit(2) except yaml.YAMLError as e: logger.error('Cannot parse yaml file %s' % self.app_yaml_path) sys.exit(2)
def _compile_defaults(files, app_path): if not isinstance(files, list): files = [files] data = {} for f in files: try: file_path = path.join(app_path, 'data', f) file_type = file_path.split('.')[-1] file_data = {} with open(file_path, 'r') as fh: if file_type == 'json': file_data = json.load(fh) elif file_type == 'yaml': file_data = yaml.load(fh.read()) except: logger.error('Error reading data file %s' % file_path) data.update(file_data) return data
def _compile_defaults(self, files): '''creates the default content dict to send to the jade template''' if not isinstance(files, list): files = [files] content = {} for f in files: try: file_path = os.path.join(self.content_path, f) with open(file_path, 'r') as fh: if file_path.endswith('.json'): file_content = json.load(fh) elif file_path.endswith('.yaml'): file_content = yaml.safe_load(fh.read()) else: logger.info('Skipping content file due to unrecognized file format %s' % file_path) file_content = {} except: logger.error('Error reading content file %s' % file_path) content.update(file_content) return content
def create(args): location = path.abspath(args.path) if path.exists(location): logger.error('Directory %s already exists' % location) sys.exit(1) logger.info('Creating project') if args.bootstrap: paths = ( ('',), ('data',) ) else: paths = ( ('',), ('static',), ('static', 'img'), ('static', 'css'), ('static', 'js'), ('templates',), ('data',) ) for p in paths: new_path = path.join(location, *p) logger.info('Creating directory %s' % new_path) os.mkdir(new_path) if args.bootstrap: logger.info('Copying Twitter Bootstrap framework files') paths_copy = ('static', 'templates') for p in paths_copy: new_path = path.join(location, p) bootstrap_path = path.join(skeleton_path, 'bootstrap', p) shutil.copytree(bootstrap_path, new_path) yaml_src = path.join(skeleton_path, 'app.yaml') yaml_dest = path.join(location, 'app.yaml') logger.info('Creating blank project file %s' % yaml_dest) shutil.copy(yaml_src, yaml_dest) os.chmod(yaml_dest, stat.S_IWUSR | stat.S_IRUSR)
def call(self, verb, payload, uri_vars={}, get_vars={}): ''' callable for all api calls this handles all signature creation and date header preparation ''' try: uri = self.api_uri.format(**uri_vars) endpoint = '{domain}{endpoint}'.format(domain=self.domain, endpoint=uri) # have to prepare just to get URI for signature creation req = requests.Request(method=verb, url=endpoint, params=get_vars) request = req.prepare() uri = request.url[len(self.domain):] date = date_header() sign = self.signature(verb, payload, date, uri) auth_header = '{key}:{sign}'.format(key=self.access_key, sign=sign) headers = {'Date': date, 'X-Authentication': auth_header} logger.debug('Sending API call to {uri} with GET variables {params}'.format(uri=endpoint, params=get_vars)) logger.debug('API call HTTP headers {headers}'.format(headers=headers)) request_args = {'params': get_vars, 'headers': headers} if verb in ('POST', 'PUT'): request_args['data'] = payload requester = getattr(requests, verb.lower()) res = requester(endpoint, **request_args) logger.debug( 'Response code: %s\n' 'Response headers: %s\n' 'Response body: %s' % (res.status_code, res.headers, res.content) ) data = json.loads(res.content) return data except Exception as e: logger.error('API call error: {e}'.format(e=e)) raise
def _compile_defaults(self, files): '''creates the default content dict to send to the jade template''' if not isinstance(files, list): files = [files] content = {} for f in files: try: file_path = os.path.join(self.content_path, f) with open(file_path, 'r') as fh: if file_path.endswith('.json'): file_content = json.load(fh) elif file_path.endswith('.yaml'): file_content = yaml.safe_load(fh.read()) else: logger.info( 'Skipping content file due to unrecognized file format %s' % file_path) file_content = {} except: logger.error('Error reading content file %s' % file_path) content.update(file_content) return content
def run_server(args): app_path = path.abspath(args.path) yaml_path = path.join(app_path, 'app.yaml') templates_path = path.join(app_path, 'templates') static_path = path.join(app_path, 'static') try: logger.info('Loading %s' % yaml_path) config = yaml.load(open(yaml_path, 'r').read()) except IOError: logger.error('Error reading %s' % yaml_path) sys.exit(2) if 'routes' not in config: logger.error('Routes not specified in app.yaml') sys.exit(3) jinja_env = Environment( loader=FileSystemLoader(templates_path), extensions=['pyjade.ext.jinja.PyJadeExtension'] ) def _dispatch_rule(**kwargs): for k, v in kwargs.iteritems(): if isinstance(v, unicode): kwargs[k] = str(v) template = jinja_env.get_template(kwargs['__sdk_template__']) data = _compile_defaults(kwargs['__sdk_data__'], app_path) for k in data: kwargs.setdefault(k, data[k]) kwargs['REQ'] = request kwargs['GET'] = request.args kwargs['POST'] = request.form kwargs['COOKIES'] = request.cookies return template.render(**kwargs) def _dispatch_static(filename): return send_from_directory(static_path, filename) def _compile_defaults(files, app_path): if not isinstance(files, list): files = [files] data = {} for f in files: try: file_path = path.join(app_path, 'data', f) file_type = file_path.split('.')[-1] file_data = {} with open(file_path, 'r') as fh: if file_type == 'json': file_data = json.load(fh) elif file_type == 'yaml': file_data = yaml.load(fh.read()) except: logger.error('Error reading data file %s' % file_path) data.update(file_data) return data app = Flask(__name__) i = 0 for route in config['routes']: rule = route['rule'] endpoint = 'dispatch_%s' % str(i) defaults = {} defaults['__sdk_template__'] = route['template'] defaults['__sdk_data__'] = route.get('data', []) app.add_url_rule( rule, endpoint, _dispatch_rule, defaults=defaults ) i += 1 app.add_url_rule('/static/<path:filename>', 'static', _dispatch_static) host = ''.join(args.address.split(':')[:-1]) port = int(args.address.split(':')[-1]) app.run(host=host, port=port, debug=True)
def __call__(self, environ, start_response): try: self.load_app_yaml() # if app.yaml has no routes use default welcome site if self.app_yaml is None or 'routes' not in self.app_yaml: self.load_app_yaml(routeless_path) if self.app_yaml is None or \ 'application_name' not in self.app_yaml or \ 'api_access_key' not in self.app_yaml or \ 'api_secret_key' not in self.app_yaml: api = None else: api = MarkupHive(self.app_yaml) cms = CMSUtil(api) self.setup_jinja() get = GetUtil(environ) path = PathUtil(environ) static = StaticUtil() app = Flask(__name__) i = 0 for route in self.app_yaml['routes']: rule = route['rule'] # hidden data we tack on to use when serving defaults = { '__sdk_template__': route['template'], '__sdk_content__': route.get('content', []), '__utils__': { 'deployment': 'sdk', 'cms': cms, 'get': get, 'path': path, 'static': static, 'markdown': markdown, } } # register special 404 rule if rule == 404: app.register_error_handler(404, self._dispatch_not_found(defaults)) # register regular rules with actual URI patterns else: endpoint = 'dispatch_{index}'.format(index=i) app.add_url_rule(rule, endpoint, self._dispatch_rule, defaults=defaults) i += 1 app.add_url_rule('/static/<path:filename>', 'static', self._dispatch_static) app.add_url_rule('/favicon.ico', 'favicon', self._dispatch_favicon) app.add_url_rule('/robots.txt', 'robotstxt', self._dispatch_robots) return app.wsgi_app(environ, start_response) except Exception as e: logger.error('WSGI request dispatch exception: {e}'.format(e=e))
def __call__(self, environ, start_response): try: self.load_app_yaml() # if app.yaml has no routes use default welcome site if self.app_yaml is None or 'routes' not in self.app_yaml: self.load_app_yaml(routeless_path) if self.app_yaml is None or \ 'application_name' not in self.app_yaml or \ 'api_access_key' not in self.app_yaml or \ 'api_secret_key' not in self.app_yaml: api = None else: api = MarkupHive(self.app_yaml) cms = CMSUtil(api) self.setup_jinja() get = GetUtil(environ) path = PathUtil(environ) static = StaticUtil() app = Flask(__name__) i = 0 for route in self.app_yaml['routes']: rule = route['rule'] # hidden data we tack on to use when serving defaults = { '__sdk_template__': route['template'], '__sdk_content__': route.get('content', []), '__utils__': { 'deployment': 'sdk', 'cms': cms, 'get': get, 'path': path, 'static': static, 'markdown': markdown, } } # register special 404 rule if rule == 404: app.register_error_handler( 404, self._dispatch_not_found(defaults)) # register regular rules with actual URI patterns else: endpoint = 'dispatch_{index}'.format(index=i) app.add_url_rule(rule, endpoint, self._dispatch_rule, defaults=defaults) i += 1 app.add_url_rule('/static/<path:filename>', 'static', self._dispatch_static) app.add_url_rule('/favicon.ico', 'favicon', self._dispatch_favicon) app.add_url_rule('/robots.txt', 'robotstxt', self._dispatch_robots) return app.wsgi_app(environ, start_response) except Exception as e: logger.error('WSGI request dispatch exception: {e}'.format(e=e))