def remove_name(self, pattern): invalid_modifications = [] # Ensure name manipulation does not create an invalid rule name for entry_id, entry_name in self.values_list('id', 'name'): new_name = entry_name.replace(pattern, '') if not check_lexical_convention(new_name): invalid_modifications.append(entry_id) self.exclude(id__in=invalid_modifications).update(name=REPLACE('name', Value(pattern), Value('')))
def prepend_name(self, modifier): invalid_modifications = [] # Ensure name manipulation does not create an invalid rule name for entry_id, entry_name in self.values_list('id', 'name'): new_name = modifier + entry_name if not check_lexical_convention(new_name): invalid_modifications.append(entry_id) self.exclude(id__in=invalid_modifications).update(name=Concat(Value(modifier), 'name'))
def rename_metakey(self, old_metakey, new_metakey): if check_lexical_convention(new_metakey): # Copy old metadata into an hstore container with new key value TEMP_HSTORE = Func(Value(new_metakey), GET_VALUE('metadata') + Value(old_metakey), function='hstore') # Delete old key entry from original hstore META_HSTORE = Func(F('metadata'), Value(old_metakey), function='delete') # Combine the two hstores using internal 'hs_concat' function CONCAT_HSTORE = Func(TEMP_HSTORE, META_HSTORE, function='hs_concat') self.filter(metadata__has_key=old_metakey).update(metadata=CONCAT_HSTORE)
def set_metadata(self, metakey, metavalue): if check_lexical_convention(metakey) and \ (metavalue.isdigit() or metavalue in ('true', 'false') or \ (metavalue.startswith('\"') and metavalue.endswith('\"'))): # Copy old metadata into an hstore container with new key value TEMP_HSTORE = Func(Value(metakey), Value(metavalue), function='hstore') # Delete old key entry from original hstore META_HSTORE = Func(F('metadata'), Value(metakey), function='delete') # Combine the two hstores using internal 'hs_concat' function CONCAT_HSTORE = Func(TEMP_HSTORE, META_HSTORE, function='hs_concat') self.update(metadata=CONCAT_HSTORE)
def add_tags(self, tag_elements, update_feedback=None): if isinstance(tag_elements, str): tag_elements = delimit_filtervalue(tag_elements) if not update_feedback: update_feedback = { 'warnings': [], 'changes': [] } for tag_value in tag_elements: if check_lexical_convention(tag_value): self.exclude(tags__overlap=[tag_value]).update(tags=ARRAY_APPEND('tags', Value(tag_value))) msg = 'Added Tag: {}'.format(tag_value) update_feedback['changes'].append(msg) else: msg = 'Skipped Invalid Tag: {}'.format(tag_value) update_feedback['warnings'].append(msg) return update_feedback
def process_parsed_rules(self, rules, source, category, submitter, owner, status='active', add_tags=None, add_metadata=None, prepend_name=None, append_name=None): # Ensure specified source is valid if not owner.groupmeta.source_required and not source: pass elif owner.groupmeta.source_required and not source: raise IntegrityError('No Source Specified') elif source not in owner.groupmeta.source_options: raise IntegrityError('Invalid Source Specified: {}'.format(source)) # Ensure specified category is valid if not owner.groupmeta.category_required and not category: pass elif owner.groupmeta.category_required and not category: raise IntegrityError('No Category Specified') elif category not in owner.groupmeta.category_options: raise IntegrityError('Invalid Category Specified: {}'.format(category)) # Container for results feedback = {'errors': [], 'warnings': [], 'rule_upload_count': 0, 'rule_collision_count': 0} # Rules must have a non-anonymous submitter if not submitter.is_anonymous(): prepend_conflicts = 0 append_conflicts = 0 for rule in rules: try: rule_kwargs = generate_kwargs_from_parsed_rule(rule) rule_kwargs['owner'] = owner rule_kwargs['submitter'] = submitter rule_kwargs['source'] = source rule_kwargs['category'] = category rule_kwargs['status'] = status # Pop comments from kwargs so they don't get processed prematurely comments = rule_kwargs.pop('comments') # Process Modifications if add_tags: if isinstance(add_tags, str): add_tags = delimit_filtervalue(add_tags) for tag_value in add_tags: if check_lexical_convention(tag_value): if tag_value not in rule_kwargs['tags']: rule_kwargs['tags'].append(tag_value) else: msg = 'Skipped Invalid Tag: {}'.format(tag_value) if msg not in feedback['warnings']: feedback['warnings'].append(msg) if add_metadata: for metakey, metavalue in add_metadata.items(): if check_lexical_convention(metakey) and \ (metavalue.isdigit() or metavalue in ('true', 'false') or \ (metavalue.startswith('\"') and metavalue.endswith('\"'))): rule_kwargs['metadata'][metakey] = metavalue else: msg = 'Skipped Invalid Metadata: {}'.format(metakey) if msg not in feedback['warnings']: feedback['warnings'].append(msg) if prepend_name: new_name = prepend_name + rule_kwargs['name'] if check_lexical_convention(new_name): rule_kwargs['name'] = new_name else: prepend_conflicts += 1 if append_name: new_name = rule_kwargs['name'] + append_name if check_lexical_convention(new_name): rule_kwargs['name'] = new_name else: append_conflicts += 1 # Check for rules with exact same detection logic if self.filter(owner=owner, logic_hash=rule_kwargs['logic_hash']).exists(): raise IntegrityError('A rule with the same logic already exists') new_rule = self.create(**rule_kwargs) new_rule.save() # Process extracted comments process_extracted_comments(new_rule, comments) feedback['rule_upload_count'] += 1 except IntegrityError: feedback['rule_collision_count'] += 1 # Check to see if any name manipulation conflicts occurred for feedback if prepend_conflicts: msg = 'Unable To Prepend {} Rule Names'.format(prepend_conflicts) feedback['warnings'].append(msg) if append_conflicts: msg = 'Unable To Append {} Rule Names'.format(append_conflicts) feedback['warnings'].append(msg) return feedback