def compress_css(self, css): re_url = re.compile('url\s*\(([^\s"].*)\)') src_fpath = '' fname_dir = '' def replace_url(mo): """ make sure urls are relative to css path """ css_url = mo.group(0)[4:].strip(")").replace("'", "").replace('"', '') css_path = os.path.join(os.path.dirname(src_fpath), css_url) rel_path = util.relpath(css_path, fname_dir) return "url(%s)" % rel_path for fname, src_files in css.iteritems(): output_css = '' dest_path = os.path.join(self.attach_dir, fname) fname_dir = os.path.dirname(dest_path) for src_fname in src_files: src_fpath = os.path.join(self.appdir, src_fname) if os.path.exists(src_fpath): content_css = \ str(compress_css.CSSParser(util.read(src_fpath))) content_css = re_url.sub(replace_url, content_css) output_css += content_css logger.debug("Merging %s in %s" % (src_fname, fname)) if not os.path.isdir(fname_dir): os.makedirs(fname_dir) util.write(dest_path, output_css)
def compress_css(self, css): re_url = re.compile('url\s*\(([^\s"].*)\)') src_fpath = '' fname_dir = '' def replace_url(mo): """ make sure urls are relative to css path """ css_url = mo.group(0)[4:].strip(")").replace("'", "").replace('"', '') css_path = os.path.join(os.path.dirname(src_fpath), css_url) rel_path = util.relpath(css_path, fname_dir) return "url(%s)" % rel_path for fname, src_files in css.iteritems(): output_css = '' dest_path = os.path.join(self.attach_dir, fname) fname_dir = os.path.dirname(dest_path) for src_fname in src_files: src_fpath = os.path.join(self.appdir, src_fname) if os.path.exists(src_fpath): content_css = str( compress_css.CSSParser(util.read(src_fpath))) content_css = re_url.sub(replace_url, content_css) output_css += content_css logger.debug("Merging %s in %s" % (src_fname, fname)) if not os.path.isdir(fname_dir): os.makedirs(fname_dir) util.write(dest_path, output_css)
def setup_views(self): ''' Create ``views/`` ``views`` dir will have following structure:: views/ view_name/ map.js reduce.js (optional) view_name2/ ... ''' vs_dir = os.path.join(self.path, 'views') if not os.path.isdir(vs_dir): self.setup_dir(vs_dir) for vsname, vs_item in self.doc['views'].iteritems(): vs_item_dir = os.path.join(vs_dir, vsname) if not os.path.isdir(vs_item_dir): self.setup_dir(vs_item_dir) for func_name, func in vs_item.iteritems(): filename = os.path.join(vs_item_dir, '{0}.js'.format(func_name)) util.write(filename, func) logger.warning( 'clone view not in manifest: "{0}"'.format(filename))
def create(self): util.setup_dir(self.docdir, require_empty=False) rcfile = os.path.join(self.docdir, ".couchapprc") ignfile = os.path.join(self.docdir, ".couchappignore") if not os.path.isfile(rcfile): util.write_json(rcfile, {}) util.write(ignfile, DEFAULT_IGNORE) else: logger.info("CouchApp already initialized in %s.", self.docdir)
def create(self): util.setup_dir(self.docdir, require_empty=False) rcfile = os.path.join(self.docdir, '.couchapprc') ignfile = os.path.join(self.docdir, '.couchappignore') if not os.path.isfile(rcfile): util.write_json(rcfile, {}) util.write(ignfile, DEFAULT_IGNORE) else: logger.info("CouchApp already initialized in %s." % self.docdir)
def create(self): if not os.path.isdir(self.docdir): logger.error("%s directory doesn't exist." % self.docdir) rcfile = os.path.join(self.docdir, '.couchapprc') ignfile = os.path.join(self.docdir, '.couchappignore') if not os.path.isfile(rcfile): util.write_json(rcfile, {}) util.write(ignfile, DEFAULT_IGNORE) else: logger.info("CouchApp already initialized in %s." % self.docdir)
def dump_file(self, path, content): ''' Dump the content of doc to file ''' if not path: return if path.endswith('.json'): content = util.json.dumps(content).encode('utf-8') # make sure file dir have been created filedir = os.path.dirname(path) if not os.path.isdir(filedir): self.setup_dir(filedir) util.write(path, content)
def create(self): ''' Init a dir as a couchapp. Only create ``.couchapprc`` and ``.couchappignore``. Do nothing if ``.couchapprc`` exists. ''' util.setup_dir(self.docdir, require_empty=False) rcfile = os.path.join(self.docdir, '.couchapprc') ignfile = os.path.join(self.docdir, '.couchappignore') if not os.path.isfile(rcfile): util.write_json(rcfile, {}) util.write(ignfile, DEFAULT_IGNORE) else: logger.info("CouchApp already initialized in %s.", self.docdir)
def setup_func(self, func): ''' Create dir for function: - ``shows`` - ``lists - ``filters`` - ``updates`` ''' func_dir = os.path.join(self.path, func) if not os.path.isdir(func_dir): self.setup_dir(func_dir) for func_name, func in self.doc[func].iteritems(): filename = os.path.join(func_dir, '{0}.js'.format(func_name)) util.write(filename, func) logger.warning( 'clone function "{0}" not in manifest: {1}'.format(func_name, filename))
def compress_js(self, backend, js): logger.info("compress js with %s " % backend.__about__) for fname, src_files in js.iteritems(): output_js = '' dest_path = os.path.join(self.attach_dir, fname) fname_dir = os.path.dirname(dest_path) for src_fname in src_files: src_fpath = os.path.join(self.appdir, src_fname) if os.path.isfile(src_fpath): output_js += "/* %s */\n" % src_fpath output_js += util.read(src_fpath) logger.debug("merging %s in %s" % (src_fname, fname)) if not os.path.isdir(fname_dir): os.makedirs(fname_dir) output_js = backend.compress(output_js) util.write(dest_path, output_js)
def clone(source, dest=None, rev=None): """ Clone an application from a design_doc given. :attr design_doc: dict, the design doc retrieved from couchdb if something was wrong. """ try: dburl, docid = source.split('_design/') except ValueError: raise AppError("%s isn't a valid source" % source) if not dest: dest = docid path = os.path.normpath(os.path.join(os.getcwd(), dest)) if not os.path.exists(path): os.makedirs(path) db = client.Database(dburl[:-1], create=False) if not rev: doc = db.open_doc("_design/%s" % docid) else: doc = db.open_doc("_design/%s" % docid, rev=rev) docid = doc['_id'] metadata = doc.get('couchapp', {}) # get manifest manifest = metadata.get('manifest', {}) # get signatures signatures = metadata.get('signatures', {}) # get objects refs objects = metadata.get('objects', {}) # create files from manifest if manifest: for filename in manifest: logger.debug("clone property: %s" % filename) filepath = os.path.join(path, filename) if filename.endswith('/'): if not os.path.isdir(filepath): os.makedirs(filepath) elif filename == "couchapp.json": continue else: parts = util.split_path(filename) fname = parts.pop() v = doc while 1: try: for key in parts: v = v[key] except KeyError: break # remove extension last_key, ext = os.path.splitext(fname) # make sure key exist try: content = v[last_key] except KeyError: break if isinstance(content, basestring): _ref = md5(util.to_bytestring(content)).hexdigest() if objects and _ref in objects: content = objects[_ref] if content.startswith('base64-encoded;'): content = base64.b64decode(content[15:]) if fname.endswith('.json'): content = util.json.dumps(content).encode('utf-8') del v[last_key] # make sure file dir have been created filedir = os.path.dirname(filepath) if not os.path.isdir(filedir): os.makedirs(filedir) util.write(filepath, content) # remove the key from design doc temp = doc for key2 in parts: if key2 == key: if not temp[key2]: del temp[key2] break temp = temp[key2] # second pass for missing key or in case # manifest isn't in app for key in doc.iterkeys(): if key.startswith('_'): continue elif key in ('couchapp'): app_meta = copy.deepcopy(doc['couchapp']) if 'signatures' in app_meta: del app_meta['signatures'] if 'manifest' in app_meta: del app_meta['manifest'] if 'objects' in app_meta: del app_meta['objects'] if 'length' in app_meta: del app_meta['length'] if app_meta: couchapp_file = os.path.join(path, 'couchapp.json') util.write_json(couchapp_file, app_meta) elif key in ('views'): vs_dir = os.path.join(path, key) if not os.path.isdir(vs_dir): os.makedirs(vs_dir) for vsname, vs_item in doc[key].iteritems(): vs_item_dir = os.path.join(vs_dir, vsname) if not os.path.isdir(vs_item_dir): os.makedirs(vs_item_dir) for func_name, func in vs_item.iteritems(): filename = os.path.join(vs_item_dir, '%s.js' % func_name) util.write(filename, func) logger.warning("clone view not in manifest: %s" % filename) elif key in ('shows', 'lists', 'filter', 'updates'): showpath = os.path.join(path, key) if not os.path.isdir(showpath): os.makedirs(showpath) for func_name, func in doc[key].iteritems(): filename = os.path.join(showpath, '%s.js' % func_name) util.write(filename, func) logger.warning("clone show or list not in manifest: %s" % filename) else: filedir = os.path.join(path, key) if os.path.exists(filedir): continue else: logger.warning("clone property not in manifest: %s" % key) if isinstance(doc[key], ( list, tuple, )): util.write_json(filedir + ".json", doc[key]) elif isinstance(doc[key], dict): if not os.path.isdir(filedir): os.makedirs(filedir) for field, value in doc[key].iteritems(): fieldpath = os.path.join(filedir, field) if isinstance(value, basestring): if value.startswith('base64-encoded;'): value = base64.b64decode(content[15:]) util.write(fieldpath, value) else: util.write_json(fieldpath + '.json', value) else: value = doc[key] if not isinstance(value, basestring): value = str(value) util.write(filedir, value) # save id idfile = os.path.join(path, '_id') util.write(idfile, doc['_id']) util.write_json(os.path.join(path, '.couchapprc'), {}) if '_attachments' in doc: # process attachments attachdir = os.path.join(path, '_attachments') if not os.path.isdir(attachdir): os.makedirs(attachdir) for filename in doc['_attachments'].iterkeys(): if filename.startswith('vendor'): attach_parts = util.split_path(filename) vendor_attachdir = os.path.join(path, attach_parts.pop(0), attach_parts.pop(0), '_attachments') filepath = os.path.join(vendor_attachdir, *attach_parts) else: filepath = os.path.join(attachdir, filename) filepath = _replace_slash(filepath) currentdir = os.path.dirname(filepath) if not os.path.isdir(currentdir): os.makedirs(currentdir) if signatures.get(filename) != util.sign(filepath): resp = db.fetch_attachment(docid, filename) with open(filepath, 'wb') as f: for chunk in resp.body_stream(): f.write(chunk) logger.debug("clone attachment: %s" % filename) logger.info("%s cloned in %s" % (source, dest))
def clone(source, dest=None, rev=None): """ Clone an application from a design_doc given. :attr design_doc: dict, the design doc retrieved from couchdb if something was wrong. """ try: dburl, docid = source.split('_design/') except ValueError: raise AppError("%s isn't a valid source" % source) if not dest: dest = docid path = os.path.normpath(os.path.join(os.getcwd(), dest)) if not os.path.exists(path): os.makedirs(path) db = client.Database(dburl[:-1], create=False) if not rev: doc = db.open_doc("_design/%s" % docid) else: doc = db.open_doc("_design/%s" % docid, rev=rev) docid = doc['_id'] metadata = doc.get('couchapp', {}) # get manifest manifest = metadata.get('manifest', {}) # get signatures signatures = metadata.get('signatures', {}) # get objects refs objects = metadata.get('objects', {}) # create files from manifest if manifest: for filename in manifest: logger.debug("clone property: %s" % filename) filepath = os.path.join(path, filename) if filename.endswith('/'): if not os.path.isdir(filepath): os.makedirs(filepath) elif filename == "couchapp.json": continue else: parts = util.split_path(filename) fname = parts.pop() v = doc while 1: try: for key in parts: v = v[key] except KeyError: break # remove extension last_key, ext = os.path.splitext(fname) # make sure key exist try: content = v[last_key] except KeyError: break if isinstance(content, basestring): _ref = md5(util.to_bytestring(content)).hexdigest() if objects and _ref in objects: content = objects[_ref] if content.startswith('base64-encoded;'): content = base64.b64decode(content[15:]) if fname.endswith('.json'): content = util.json.dumps(content).encode('utf-8') del v[last_key] # make sure file dir have been created filedir = os.path.dirname(filepath) if not os.path.isdir(filedir): os.makedirs(filedir) util.write(filepath, content) # remove the key from design doc temp = doc for key2 in parts: if key2 == key: if not temp[key2]: del temp[key2] break temp = temp[key2] # second pass for missing key or in case # manifest isn't in app for key in doc.iterkeys(): if key.startswith('_'): continue elif key in ('couchapp'): app_meta = copy.deepcopy(doc['couchapp']) if 'signatures' in app_meta: del app_meta['signatures'] if 'manifest' in app_meta: del app_meta['manifest'] if 'objects' in app_meta: del app_meta['objects'] if 'length' in app_meta: del app_meta['length'] if app_meta: couchapp_file = os.path.join(path, 'couchapp.json') util.write_json(couchapp_file, app_meta) elif key in ('views'): vs_dir = os.path.join(path, key) if not os.path.isdir(vs_dir): os.makedirs(vs_dir) for vsname, vs_item in doc[key].iteritems(): vs_item_dir = os.path.join(vs_dir, vsname) if not os.path.isdir(vs_item_dir): os.makedirs(vs_item_dir) for func_name, func in vs_item.iteritems(): filename = os.path.join(vs_item_dir, '%s.js' % func_name) util.write(filename, func) logger.warning("clone view not in manifest: %s" % filename) elif key in ('shows', 'lists', 'filter', 'update'): showpath = os.path.join(path, key) if not os.path.isdir(showpath): os.makedirs(showpath) for func_name, func in doc[key].iteritems(): filename = os.path.join(showpath, '%s.js' % func_name) util.write(filename, func) logger.warning( "clone show or list not in manifest: %s" % filename) else: filedir = os.path.join(path, key) if os.path.exists(filedir): continue else: logger.warning("clone property not in manifest: %s" % key) if isinstance(doc[key], (list, tuple,)): util.write_json(filedir + ".json", doc[key]) elif isinstance(doc[key], dict): if not os.path.isdir(filedir): os.makedirs(filedir) for field, value in doc[key].iteritems(): fieldpath = os.path.join(filedir, field) if isinstance(value, basestring): if value.startswith('base64-encoded;'): value = base64.b64decode(content[15:]) util.write(fieldpath, value) else: util.write_json(fieldpath + '.json', value) else: value = doc[key] if not isinstance(value, basestring): value = str(value) util.write(filedir, value) # save id idfile = os.path.join(path, '_id') util.write(idfile, doc['_id']) util.write_json(os.path.join(path, '.couchapprc'), {}) if '_attachments' in doc: # process attachments attachdir = os.path.join(path, '_attachments') if not os.path.isdir(attachdir): os.makedirs(attachdir) for filename in doc['_attachments'].iterkeys(): if filename.startswith('vendor'): attach_parts = util.split_path(filename) vendor_attachdir = os.path.join(path, attach_parts.pop(0), attach_parts.pop(0), '_attachments') filepath = os.path.join(vendor_attachdir, *attach_parts) else: filepath = os.path.join(attachdir, filename) filepath = _replace_slash(filepath) currentdir = os.path.dirname(filepath) if not os.path.isdir(currentdir): os.makedirs(currentdir) if signatures.get(filename) != util.sign(filepath): resp = db.fetch_attachment(docid, filename) with open(filepath, 'wb') as f: for chunk in resp.body_stream(): f.write(chunk) logger.debug("clone attachment: %s" % filename) logger.info("%s cloned in %s" % (source, dest))
def setup_id(self): ''' Create ``_id`` file ''' idfile = os.path.join(self.path, '_id') util.write(idfile, self.doc['_id'])