def _get_metadata(self, key, default=[]): """ Get an item from the database. Default is an empty list, which is a mutable and thus a bad default (pylint will complain). However, it is just used as a value, and not altered, so its use here is ok. """ doc = self.db.metadata.find_one({"setting": key}) if doc: type_name = doc["type"] if type_name in ('int', 'str', 'list'): return doc["value"] elif type_name == 'set': return set(doc["value"]) elif type_name == 'tuple': return tuple(doc["value"]) else: return from_json(json.dumps(doc["value"])) elif default == []: return [] else: return default
def doc_to_obj(doc): """ Convert a MongoDB document into a Gramps object. """ doc['handle'] = doc['_id'] del doc['_id'] obj = from_json(json.dumps(doc)) return obj
def post(self) -> Response: """Post the transaction.""" require_permissions([PERM_ADD_OBJ, PERM_EDIT_OBJ, PERM_DEL_OBJ]) payload = request.json if not payload: abort(400) # disallow empty payload db_handle = get_db_handle(readonly=False) with DbTxn("Raw transaction", db_handle) as trans: for item in payload: try: class_name = item["_class"] trans_type = item["type"] handle = item["handle"] old_data = item["old"] if not self.old_unchanged(db_handle, class_name, handle, old_data): abort(409) # object has changed! new_data = item["new"] if new_data: new_obj = from_json(json.dumps(new_data)) if trans_type == "delete": self.handle_delete(trans, class_name, handle) elif trans_type == "add": self.handle_add(trans, class_name, new_obj) elif trans_type == "update": self.handle_commit(trans, class_name, new_obj) else: abort(400) # unexpected type except (KeyError, UnicodeDecodeError, json.JSONDecodeError, TypeError): abort(400) trans_dict = transaction_to_json(trans) # update search index indexer: SearchIndexer = current_app.config["SEARCH_INDEXER"] with indexer.get_writer(overwrite=False, use_async=True) as writer: for _trans_dict in trans_dict: handle = _trans_dict["handle"] class_name = _trans_dict["_class"] if _trans_dict["type"] == "delete": indexer.delete_object(writer, handle) else: indexer.add_or_update_object(writer, handle, db_handle, class_name) res = Response( response=json.dumps(trans_dict), status=200, mimetype="application/json", ) res.headers.add("X-Total-Count", len(trans_dict)) return res
def _parse_objects(self) -> Sequence[GrampsObject]: """Parse the objects.""" payload = request.json objects = [] for obj_dict in payload: try: obj_dict = fix_object_dict(obj_dict) except ValueError: abort(400) if not validate_object_dict(obj_dict): abort(400) obj = from_json(json.dumps(obj_dict)) objects.append(obj) return objects
def _parse_object(self) -> GrampsObject: """Parse the object.""" obj_dict = request.json if obj_dict is None: abort(400) if "_class" not in obj_dict: obj_dict["_class"] = self.gramps_class_name elif obj_dict["_class"] != self.gramps_class_name: abort(400) try: obj_dict = fix_object_dict(obj_dict) except ValueError: abort(400) if not validate_object_dict(obj_dict): abort(400) return from_json(json.dumps(obj_dict))
def importData(db, filename, user): """Function called by Gramps to import data on persons in CSV format.""" db.disable_signals() try: with DbTxn(_("JSON import"), db, batch=True) as trans: with OpenFileOrStdin(filename, encoding="utf-8") as fp: line = fp.readline() while line: obj = from_json(line) if isinstance(obj, Person): db.add_person(obj, trans) elif isinstance(obj, Family): db.add_family(obj, trans) elif isinstance(obj, Event): db.add_event(obj, trans) elif isinstance(obj, Media): db.add_media(obj, trans) elif isinstance(obj, Repository): db.add_repository(obj, trans) elif isinstance(obj, Tag): db.add_tag(obj, trans) elif isinstance(obj, Source): db.add_source(obj, trans) elif isinstance(obj, Citation): db.add_citation(obj, trans) elif isinstance(obj, Note): db.add_note(obj, trans) elif isinstance(obj, Place): db.add_place(obj, trans) else: LOG.warn("ignored: " + data) line = fp.readline() except EnvironmentError as err: user.notify_error(_("%s could not be opened\n") % filename, str(err)) db.enable_signals() db.request_rebuild()