def doc(self, db=None, with_attachments=True, force=False): """ Function to reetrieve document object from document directory. If `with_attachments` is True attachments will be included and encoded""" manifest = [] objects = {} signatures = {} attachments = {} self._doc = {"_id": self.docid} # get designdoc self._doc.update(self.dir_to_fields(self.docdir, manifest=manifest)) if not "couchapp" in self._doc: self._doc["couchapp"] = {} self.olddoc = {} if db is not None: try: self.olddoc = db.open_doc(self._doc["_id"]) attachments = self.olddoc.get("_attachments") or {} self._doc.update({"_rev": self.olddoc["_rev"]}) except ResourceNotFound: self.olddoc = {} if "couchapp" in self.olddoc: old_signatures = self.olddoc["couchapp"].get("signatures", {}) else: old_signatures = {} for name, filepath in self.attachments(): signatures[name] = util.sign(filepath) if with_attachments and not old_signatures: logger.debug("attach %s ", name) attachments[name] = self.attachment_stub(name, filepath) if old_signatures: for name, signature in old_signatures.items(): cursign = signatures.get(name) if not cursign: logger.debug("detach %s ", name) del attachments[name] elif cursign != signature: logger.debug("detach %s ", name) del attachments[name] else: continue if with_attachments: for name, filepath in self.attachments(): if old_signatures.get(name) != signatures.get(name) or force: logger.debug("attach %s ", name) attachments[name] = self.attachment_stub(name, filepath) self._doc["_attachments"] = attachments self._doc["couchapp"].update({"manifest": manifest, "objects": objects, "signatures": signatures}) if self.docid.startswith("_design/"): # process macros for funs in ["shows", "lists", "updates", "filters", "spatial"]: if funs in self._doc: package_shows(self._doc, self._doc[funs], self.docdir, objects) if "validate_doc_update" in self._doc: tmp_dict = {"validate_doc_update": self._doc["validate_doc_update"]} package_shows(self._doc, tmp_dict, self.docdir, objects) self._doc.update(tmp_dict) if "views" in self._doc: # clean views # we remove empty views and malformed from the list # of pushed views. We also clean manifest views = {} dmanifest = {} for i, fname in enumerate(manifest): if fname.startswith("views/") and fname != "views/": name, ext = os.path.splitext(fname) if name.endswith("/"): name = name[:-1] dmanifest[name] = i for vname, value in self._doc["views"].iteritems(): if value and isinstance(value, dict): views[vname] = value else: del manifest[dmanifest["views/%s" % vname]] self._doc["views"] = views package_views(self._doc, self._doc["views"], self.docdir, objects) if "fulltext" in self._doc: package_views(self._doc, self._doc["fulltext"], self.docdir, objects) return self._doc
def doc(self, db=None, with_attachments=True): """ Function to reetrieve document object from document directory. If `with_attachments` is True attachments will be included and encoded""" manifest = [] objects = {} self._doc = {'_id': self.docid} # get designdoc self._doc.update(self.dir_to_fields(self.docdir, manifest=manifest)) if not 'couchapp' in self._doc: self._doc['couchapp'] = {} signatures = {} attachments = {} for name, filepath in self.attachments(): signatures[name] = util.sign(filepath) if with_attachments: logger.debug("attach %s " % name) attachments[name] = {} with open(filepath, "rb") as f: re_sp = re.compile('\s') attachments[name]['data'] = re_sp.sub('', base64.b64encode(f.read())) attachments[name]['content_type'] = ';'.join(filter(None, mimetypes.guess_type(name))) if with_attachments: self._doc['_attachments'] = attachments self._doc['couchapp'].update({ 'manifest': manifest, 'objects': objects, 'signatures': signatures }) if self.docid.startswith('_design/'): # process macros for funs in ['shows', 'lists', 'updates', 'filters', 'fulltext']: if funs in self._doc: package_shows(self._doc, self._doc[funs], self.docdir, objects) if 'validate_doc_update' in self._doc: tmp_dict = dict(validate_doc_update=self._doc[ "validate_doc_update"]) package_shows( self._doc, tmp_dict, self.docdir, objects) self._doc.update(tmp_dict) if 'views' in self._doc: # clean views # we remove empty views and malformed from the list # of pushed views. We also clean manifest views = {} dmanifest = {} for i, fname in enumerate(manifest): if fname.startswith("views/") and fname != "views/": name, ext = os.path.splitext(fname) if name.endswith('/'): name = name[:-1] dmanifest[name] = i for vname, value in self._doc['views'].iteritems(): if value and isinstance(value, dict): views[vname] = value else: del manifest[dmanifest["views/%s" % vname]] self._doc['views'] = views package_views(self._doc,self._doc["views"], self.docdir, objects) self.olddoc = {} if db is not None: try: self.olddoc = db.open_doc(self._doc['_id']) self._doc.update({'_rev': self.olddoc['_rev']}) except ResourceNotFound: pass return self._doc
def fs_to_designdoc(self, app_name, pre_callback=None, post_callback=None): """ function used to get design_doc from app_dir. It return a dict with all properties. attachements are file handles and shoul be processed before saving design_doc to couchdb. :attr app_name: string, name of applicaton. used to create design doc id. :attr pre_callback: callable. Used to proccess aapp_dir and add default value to design_doc before retrieving properties from app_dir. ex. .. code-block:: python def mycallbacl(app_dir, app_name, design_doc, verbose=verbose): pass :attr post_callback: callable, like pre_callback but called after the app_dir was processed. :attr verbose: boolean, default False :return: dict, design_doc or error. """ # init variables manifest = [] design_doc = {} objects = {} docid = design_doc["_id"] = "_design/%s" % app_name attach_dir = self.ui.rjoin(self.app_dir, "_attachments") # what we do before retrieving design_doc from app_dir if pre_callback and callable(pre_callback): pre_callback(self.app_dir, app_name, design_doc, verbose=verbose) # get fields design_doc.update(self.dir_to_fields(self.app_dir, manifest=manifest)) if not "couchapp" in design_doc: design_doc["couchapp"] = {} if "shows" in design_doc: package_shows(design_doc, design_doc["shows"], self.app_dir, objects, self.ui) if "lists" in design_doc: package_shows(design_doc, design_doc["lists"], self.app_dir, objects, self.ui) if "validate_doc_update" in design_doc: tmp_dict = dict(validate_doc_update=design_doc["validate_doc_update"]) package_shows(design_doc, tmp_dict, self.app_dir, objects, self.ui) design_doc.update(tmp_dict) if "views" in design_doc: package_views(design_doc, design_doc["views"], self.app_dir, objects, self.ui) couchapp = design_doc.get("couchapp", {}) couchapp.update({"manifest": manifest, "objects": objects}) design_doc["couchapp"] = couchapp self.attachments(design_doc, attach_dir, docid) self.vendor_attachments(design_doc, docid) # what we do after retrieving design_doc from app_dir if pre_callback and callable(pre_callback): pre_callback(self.app_dir, app_name, design_doc, verbose=self.ui.verbose) return design_doc
def doc(self, db=None, with_attachments=True, force=False): """ Function to retrieve document object from document directory. :param with_attachments: If ``True``, attachments will be included and encoded """ manifest = [] objects = {} signatures = {} attachments = {} self._doc = {'_id': self.docid} # get designdoc self._doc.update(self.dir_to_fields(self.docdir, manifest=manifest)) if not 'couchapp' in self._doc: self._doc['couchapp'] = {} self.olddoc = {} if db is not None: try: self.olddoc = db.open_doc(self._doc['_id']) attachments = self.olddoc.get('_attachments') or {} self._doc.update({'_rev': self.olddoc['_rev']}) except ResourceNotFound: self.olddoc = {} if 'couchapp' in self.olddoc: old_signatures = self.olddoc['couchapp'].get('signatures', {}) else: old_signatures = {} for name, filepath in self.attachments(): signatures[name] = util.sign(filepath) if with_attachments and not old_signatures: logger.debug("attach %s ", name) attachments[name] = self.attachment_stub(name, filepath) if old_signatures: for name, signature in old_signatures.items(): cursign = signatures.get(name) if not cursign: logger.debug("detach %s ", name) del attachments[name] elif cursign != signature: logger.debug("detach %s ", name) del attachments[name] else: continue if with_attachments: for name, filepath in self.attachments(): if old_signatures.get(name) != \ signatures.get(name) or force: logger.debug("attach %s ", name) attachments[name] = self.attachment_stub( name, filepath) self._doc['_attachments'] = attachments self._doc['couchapp'].update({ 'manifest': manifest, 'objects': objects, 'signatures': signatures }) if self.docid.startswith('_design/'): # process macros for funs in ['shows', 'lists', 'updates', 'filters', 'spatial']: if funs in self._doc: package_shows(self._doc, self._doc[funs], self.docdir, objects) if 'validate_doc_update' in self._doc: tmp_dict = { 'validate_doc_update': self._doc["validate_doc_update"] } package_shows(self._doc, tmp_dict, self.docdir, objects) self._doc.update(tmp_dict) if 'views' in self._doc: # clean views # we remove empty views and malformed from the list # of pushed views. We also clean manifest views = {} dmanifest = {} for i, fname in enumerate(manifest): if fname.startswith("views/") and fname != "views/": name, ext = os.path.splitext(fname) if name.endswith('/'): name = name[:-1] dmanifest[name] = i for vname, value in self._doc['views'].iteritems(): if value and isinstance(value, dict): views[vname] = value else: del manifest[dmanifest["views/%s" % vname]] self._doc['views'] = views package_views(self._doc, self._doc["views"], self.docdir, objects) if "fulltext" in self._doc: package_views(self._doc, self._doc["fulltext"], self.docdir, objects) return self._doc
def fs_to_designdoc(self, app_name, pre_callback=None, post_callback=None): """ function used to get design_doc from app_dir. It return a dict with all properties. attachements are file handles and shoul be processed before saving design_doc to couchdb. :attr app_name: string, name of applicaton. used to create design doc id. :attr pre_callback: callable. Used to proccess aapp_dir and add default value to design_doc before retrieving properties from app_dir. ex. .. code-block:: python def mycallbacl(app_dir, app_name, design_doc, verbose=verbose): pass :attr post_callback: callable, like pre_callback but called after the app_dir was processed. :attr verbose: boolean, default False :return: dict, design_doc or error. """ # init variables manifest = [] design_doc = {} objects = {} docid = design_doc['_id'] = '_design/%s' % app_name attach_dir = self.ui.rjoin(self.app_dir, '_attachments') # what we do before retrieving design_doc from app_dir if pre_callback and callable(pre_callback): pre_callback(self.app_dir, app_name, design_doc, verbose=verbose) # get fields design_doc.update(self.dir_to_fields(self.app_dir, manifest=manifest)) if not 'couchapp' in design_doc: design_doc['couchapp'] = {} for funs in ['shows', 'lists', 'updates', 'filters']: if funs in design_doc: package_shows(design_doc, design_doc[funs], self.app_dir, objects, self.ui) if 'validate_doc_update' in design_doc: tmp_dict = dict(validate_doc_update=design_doc["validate_doc_update"]) package_shows(design_doc, tmp_dict, self.app_dir, objects, self.ui) design_doc.update(tmp_dict) if 'views' in design_doc: # clean views # we remove empty views and malformed from the list # of pushed views. We also clean manifest views = {} dmanifest = {} for i, fname in enumerate(manifest): if fname.startswith("views/") and fname != "views/": name, ext = os.path.splitext(fname) if name.endswith('/'): name = name[:-1] dmanifest[name] = i for vname, value in design_doc['views'].iteritems(): if value and isinstance(value, dict): views[vname] = value else: del manifest[dmanifest["views/%s" % vname]] design_doc['views'] = views package_views(design_doc, design_doc["views"], self.app_dir, objects, self.ui) couchapp = design_doc.get('couchapp', {}) couchapp.update({ 'manifest': manifest, 'objects': objects }) design_doc['couchapp'] = couchapp self.attachments(design_doc, attach_dir, docid) self.vendor_attachments(design_doc, docid) # what we do after retrieving design_doc from app_dir if pre_callback and callable(pre_callback): pre_callback(self.app_dir, app_name, design_doc, verbose=self.ui.verbose) return design_doc