def edit_filter_save(uistate, filterdb, objclass): """ If a filter changed, save them all. Reloads, and also calls callback. """ filterdb.save() reload_custom_filters() uistate.emit('filters-changed', (objclass,))
def makefilter( self, category, filtername, filtertext, initial_statements, statements ): the_filter = GenericFilterFactory(category.objclass)() rule = category.filterrule([filtertext, initial_statements, statements]) if not filtername: OkDialog( _("Error"), "Please supply a title/name", parent=self.uistate.window ) return if not filtertext: OkDialog( _("Error"), "Please supply a filtering condition", parent=self.uistate.window, ) return the_filter.add_rule(rule) the_filter.set_name(filtername) filterdb = FilterList(CUSTOM_FILTERS) filterdb.load() filters = filterdb.get_filters_dict(category.objclass) if filtername in filters: msg = "Filter '{}' already exists; choose another name".format(filtername) OkDialog(_("Error"), msg, parent=self.uistate.window) return filterdb.add(category.objclass, the_filter) print("added filter", the_filter) filterdb.save() reload_custom_filters() self.uistate.emit("filters-changed", (category.objclass,)) msg = "Created filter {0}".format(filtername) OkDialog(_("Done"), msg, parent=self.uistate.window)
def get_custom_filters(args: Dict[str, Any], namespace: str) -> List[Dict]: """Return a list of custom filters for a namespace.""" filter_list = [] filters.reload_custom_filters() for filter_class in filters.CustomFilters.get_filters(namespace): add_filter = True if "filters" in args and args["filters"]: if filter_class.get_name() not in args["filters"]: add_filter = False if add_filter: filter_list.append({ "comment": filter_class.get_comment(), "function": filter_class.get_logical_op(), "invert": filter_class.invert, "name": filter_class.get_name(), "rules": [{ "name": filter_rule.__class__.__name__, "regex": filter_rule.use_regex, "values": filter_rule.values(), } for filter_rule in filter_class.get_rules()], }) if "filters" in args and len(args["filters"]) != len(filter_list): abort(404) return filter_list
def get_custom_filter(self, name: str, namespace: str): """Get the named custom filter from a namespace.""" filters.reload_custom_filters() for filter_class in filters.CustomFilters.get_filters(namespace): if name == filter_class.get_name(): return filter_class raise ValueError("can not find filter '%s' in namespace '%s'" % (name, namespace))
def edit_filter_save(self, filterdb, filter_name): """ If a filter changed, save them all. Reloads, and sets name. Takes the filter database, and the filter name edited. """ from gramps.gen.filters import reload_custom_filters filterdb.save() reload_custom_filters() self.on_filters_changed(self.namespace) self.set_filters_to_name(filter_name)
def get_reports(db_handle: DbReadBase, report_id: str = None): """Extract and return report attributes and options.""" reload_custom_filters() plugin_manager = BasePluginManager.get_instance() reports = [] for report_data in plugin_manager.get_reg_reports(gui=False): if report_id is not None and report_data.id != report_id: continue if report_data.category not in REPORT_DEFAULTS: continue report = get_report_profile(db_handle, plugin_manager, report_data) reports.append(report) return reports
def run_report( db_handle: DbReadBase, report_id: str, report_options: Dict, allow_file: bool = False, ): """Generate the report.""" if "off" in report_options and report_options["off"] in REPORT_FILTERS: abort(422) _resources = ResourcePath() os.environ["GRAMPS_RESOURCES"] = str(Path(_resources.data_dir).parent) reload_custom_filters() plugin_manager = BasePluginManager.get_instance() for report_data in plugin_manager.get_reg_reports(gui=False): if report_data.id == report_id: if report_data.category not in REPORT_DEFAULTS: abort(404) if "off" not in report_options: report_options["off"] = REPORT_DEFAULTS[report_data.category] file_type = "." + report_options["off"] file_type = _EXTENSION_MAP.get(file_type) or file_type if file_type not in MIME_TYPES: current_app.logger.error( "Can not find {} in MIME_TYPES".format(file_type) ) abort(500) if current_app.config.get("REPORT_DIR"): report_path = current_app.config.get("REPORT_DIR") else: report_path = tempfile.gettempdir() file_name = os.path.join( report_path, "{}{}".format(uuid.uuid4(), file_type) ) report_options["of"] = file_name report_profile = get_report_profile(db_handle, plugin_manager, report_data) validate_options(report_profile, report_options, allow_file=allow_file) module = plugin_manager.load_plugin(report_data) option_class = getattr(module, report_data.optionclass) report_class = getattr(module, report_data.reportclass) cl_report( db_handle, report_data.name, report_data.category, report_class, option_class, report_options, ) return file_name, file_type abort(404)
def edit_filter_save(self, filterdb, namespace): """ If a filter changed, save them all. Reloads, and also calls callback. """ from gramps.gen.filters import CustomFilters from gramps.gen.filters import reload_custom_filters filterdb.save() reload_custom_filters() if namespace == "Person": model = self.build_model("person") widget = self.filter_obj elif namespace == "Note": model = self.build_model("note") widget = self.filter_note widget.set_model(model) widget.set_active(0)
def post(self, args: Dict, namespace: str) -> Response: """Create a custom filter.""" try: namespace = GRAMPS_NAMESPACES[namespace] except KeyError: abort(404) new_filter = build_filter(args, namespace) filters.reload_custom_filters() for filter_rule in filters.CustomFilters.get_filters(namespace): if new_filter.get_name() == filter_rule.get_name(): abort(422) filters.CustomFilters.add(namespace, new_filter) filters.CustomFilters.save() return self.response( 201, {"message": "Added filter: " + new_filter.get_name()})
def get_person_filter(db_handle: DbReadBase, args: Dict) -> Union[GenericFilter, None]: """Return the specified person filter.""" if args["person"] is None: if args["gramps_id"] is not None or args["handle"] is not None: abort(422) return None if args["gramps_id"]: gramps_id = args["gramps_id"] if db_handle.get_person_from_gramps_id(gramps_id) is None: abort(422) else: try: person = db_handle.get_person_from_handle(args["handle"]) except HandleError: abort(422) gramps_id = person.gramps_id person_filter = filters.GenericFilter() if args["person"] == "Descendants": person_filter.set_name(_("Descendants of %s") % gramps_id) person_filter.add_rule( filters.rules.person.IsDescendantOf([gramps_id, 1])) elif args["person"] == "DescendantFamilies": person_filter.set_name(_("Descendant Families of %s") % gramps_id) person_filter.add_rule( filters.rules.person.IsDescendantFamilyOf([gramps_id, 1])) elif args["person"] == "Ancestors": person_filter.set_name(_("Ancestors of %s") % gramps_id) person_filter.add_rule( filters.rules.person.IsAncestorOf([gramps_id, 1])) elif args["person"] == "CommonAncestor": person_filter.set_name( _("People with common ancestor with %s") % gramps_id) person_filter.add_rule( filters.rules.person.HasCommonAncestorWith([gramps_id])) else: person_filter = None filters.reload_custom_filters() for filter_class in filters.CustomFilters.get_filters("Person"): if args["person"] == filter_class.get_name(): person_filter = filter_class break if person_filter is None: abort(422) return person_filter
def run_export(db_handle: DbReadBase, extension: str, options): """Generate the export.""" export_path = TEMP_DIR if current_app.config.get("EXPORT_PATH"): export_path = current_app.config.get("EXPORT_PATH") file_name = os.path.join(export_path, "{}.{}".format(uuid.uuid4(), extension)) _resources = ResourcePath() os.environ["GRAMPS_RESOURCES"] = str(Path(_resources.data_dir).parent) filters.reload_custom_filters() plugin_manager = BasePluginManager.get_instance() for plugin in plugin_manager.get_export_plugins(): if extension == plugin.get_extension(): export_function = plugin.get_export_function() result = export_function(db_handle, file_name, User(), options) if not result: abort(500) return file_name, "." + extension
def on_filter_changed(self, combo): # import random # random.shuffle(self.colors) tree_iter = combo.get_active_iter() if tree_iter is None: return model = combo.get_model() try: filtername = model[tree_iter][0] except: traceback.print_exc() return # load from xml file, any temporary changes are lost reload_custom_filters() self.filterdb = gramps.gen.filters.CustomFilters self.current_filtername = filtername if self.frame: self.frame.destroy() self.grid = self.MyGrid() self.entries = [] self.filterparams = [] self.regexes = [] self.values = defaultdict(list) lbl = Gtk.Label(filtername) lbl.set_halign(Gtk.Align.START) lbl.set_markup("<b>"+filtername+"</b>") frame2 = Gtk.Frame() frame2.set_label_widget(lbl) if self.use_colors: frame2.override_background_color(Gtk.StateFlags.NORMAL, self.get_color(0)) frame2.add(self.grid) self.addfilter(self.grid, self.current_category, filtername, 1) self.box.add(frame2) self.frame = frame2 self.dialog.resize(1, 1) # shrink to minimum size needed self.dialog.show_all() self.edit_button.set_sensitive(True) self.delete_button.set_sensitive(True) self.execute_button.set_sensitive(True) self.update_button.set_sensitive(True)
def startcli(errors, argparser): """ Starts a cli session of Gramps. :param errors: errors already encountered :param argparser: :class:`.ArgParser` instance """ if errors: #already errors encountered. Show first one on terminal and exit errmsg = _('Error encountered: %s') % errors[0][0] print(errmsg, file=sys.stderr) errmsg = _(' Details: %s') % errors[0][1] print(errmsg, file=sys.stderr) sys.exit(1) if argparser.errors: errmsg = _('Error encountered in argument parsing: %s' ) % argparser.errors[0][0] print(errmsg, file=sys.stderr) errmsg = _(' Details: %s') % argparser.errors[0][1] print(errmsg, file=sys.stderr) sys.exit(1) #we need to keep track of the db state dbstate = DbState() #we need a manager for the CLI session from .user import User user = User(auto_accept=argparser.auto_accept, quiet=argparser.quiet) climanager = CLIManager(dbstate, True, user) #load the plugins climanager.do_reg_plugins(dbstate, uistate=None) reload_custom_filters() # handle the arguments from .arghandler import ArgHandler handler = ArgHandler(dbstate, argparser, climanager) # create a manager to manage the database handler.handle_args_cli() if handler.dbstate.is_open(): handler.dbstate.db.close() sys.exit(0)
def delete(self, args: Dict, namespace: str, name: str) -> Response: """Delete a custom filter.""" try: namespace = GRAMPS_NAMESPACES[namespace] except KeyError: abort(404) filters.reload_custom_filters() custom_filters = filters.CustomFilters.get_filters(namespace) for custom_filter in custom_filters: if name == custom_filter.get_name(): filter_set = set() self._find_dependent_filters(namespace, custom_filter, filter_set) if len(filter_set) > 1: if "force" not in args or not args["force"]: abort(405) list(map(custom_filters.remove, filter_set)) filters.CustomFilters.save() return self.response(200, {"message": "Deleted filter: " + name}) return abort(404)
def apply_filter( db_handle: DbReadBase, args: Dict, namespace: str, handles: Optional[List[Handle]] = None, ) -> List[Handle]: """Apply an existing or dynamically defined filter.""" filters.reload_custom_filters() if args.get("filter"): for filter_class in filters.CustomFilters.get_filters(namespace): if args["filter"] == filter_class.get_name(): return filter_class.apply(db_handle, id_list=handles) abort(404) try: filter_parms = FilterSchema().load(json.loads(args["rules"])) except json.JSONDecodeError: abort(400) except ValidationError: abort(422) filter_object = build_filter(filter_parms, namespace) return filter_object.apply(db_handle, id_list=handles)
def update(self): self.filterdb.save() reload_custom_filters() self.populate_filters(self.current_category) self.uistate.emit('filters-changed', (self.current_category,))
def close(self, *obj): self.filterdb.save() reload_custom_filters() #reload_system_filters() self.uistate.emit('filters-changed', (self.namespace, )) ManagedWindow.close(self, *obj)
import sys import traceback import tempfile import shutil import logging import contextlib from io import TextIOWrapper, BytesIO, StringIO from gramps.gen.dbstate import DbState from gramps.gen.user import User from gramps.cli.grampscli import CLIManager from gramps.cli.argparser import ArgParser from gramps.cli.arghandler import ArgHandler from gramps.gen.const import USER_DIRLIST from gramps.gen.filters import reload_custom_filters reload_custom_filters() # so reports with filter options don't fail # _caller_context is primarily here to support and document the process # of determining the test-module's directory. # # NB: the traceback 0-element is 'limit'-levels back, or earliest calling # context if that is less than limit. # The -1 element is this very function; -2 is its caller, etc. # A traceback context tuple is: # (file, line, active function, text of the call-line) def _caller_context(): """Return context of first caller outside this module""" lim = 5 # 1 for this function, plus futrher chain within this module st = traceback.extract_stack(limit=lim) thisfile = __file__.rstrip("co") # eg, in ".py[co] while st and st[-1][0] == thisfile:
def close_clicked(self, _widget): #print("FilterParams closing") reload_custom_filters() # so that our (non-saved) changes will be discarded self.dialog.destroy() self.dialog = None self.close()
def close(self, *obj): self.filterdb.save() reload_custom_filters() #reload_system_filters() self.uistate.emit('filters-changed', (self.namespace,)) ManagedWindow.close(self, *obj)