Bubble 2016.08.16

bubble.rules

Contents

Source code for bubble.rules

# -*- coding: utf-8 -*-
# Part of bubble. See LICENSE file for full copyright and licensing details.

''' bubble rules have a simple notation,
with a line based rule format and a single rule definitions seperator ">>>"
every line starting and ending with the rule separator,
becomes a rule for the bubble transformer.
anything else is treated as comment.
'''
from . import Bubble
from .functions import get_registered_rule_functions
from .util.cli_misc import load_rule_functions

rule_functions = get_registered_rule_functions()


##########################################################################


[docs]class Rule(Bubble): input = None fun = None output = None depend = [] src_nr = 0 def __init__(self, input=None, output=None, fun=None, depend=None, name=None, src_nr=0): self.say('Rule init :' + str(id(self)) + '>i>' + str(input) + '>f>' + str(fun) + '>o>' + str(output) + '>d>' + str(depend) + '>n>' + str(name) + '>>>', verbosity=100) super(Bubble, self).__init__() self.input = input # function without input?? # for example:date / time self.fun = rule_functions.get_function(fun) self.fun.set_parent(self) if output: self.output = output else: self.output = input # just copy single ok, (structure?) #todo self.depend = depend self.name = name self.src_nr = src_nr def __repr__(self): srep = '<Rule ' srep += str(self.src_nr) srep += ' >>> ' + str(self.input) srep += ' >>> ' + str(self.fun) srep += ' >>> ' + str(self.output) srep += ' >>> ' + str(self.depend) srep += ' >>> ' + str(self.name) + ' >>>' return srep
[docs] def run(self, *a): self.say('running my function, with:', stuff=a, verbosity=100) return self.fun.run(*a)
[docs]class Rules(Bubble): _rules = [] def __init__(self, rules=None, rule_type='bubble', home='', verbose=0): Bubble.__init__(self, name='Rules', verbose=verbose) self.home = home self.say('home:' + home, verbosity=10) self.say('init, no functions yet', verbosity=100) load_rule_functions(self) self.say('after loading functions:' + str(len(get_registered_rule_functions())), verbosity=100) self._rule_type = rule_type if rule_type == 'bubble': self._rules = self._convert_rules_bubble(rules) def _convert_rules_bubble(self, srules=''): """srules, a string containing the rules in bubble format will be converted to the internal list of dictonary based rules. '>>>': seperator : a rule has only certain amount of seperators a rule is built like: >>>input>>>function>>>output>>> for example: >>>i>>>adder>>>o>>>> >>>42>>>is_it_the_answer>>>the_answer>>> is converted to: [{'in':'i','fun':'adder','out':'o'}, {'in':'42','fun':'is_it_the_answer','out':'the_answer'}] a rule withhout a name, but with a depency on rule_one >>>panic>>>is_there_an_answer>>>dont_panic>>>rule_one>>> a rule without depencies and a name >>>42>>>is_it_the_answer>>>the_answer>>>nodeps>>rule_one>>> """ if not isinstance(srules, str): self.cry('convert_rules_bubble: cannot convert srules of type,' + 'list of rules ==> [] :' + str(type(srules)), stuff=srules, verbosity=10) return [] if not srules: self.say('convert_rules_bubble: cannot convert empty srules', verbosity=10) return [] # no rules lines = srules.splitlines() self.say('convert_rules_bubble:lines', stuff=lines, verbosity=10) line_number = 0 rules = [] for r in lines: line_number += 1 # todo: do we wan't this in a configuration, yes! add magic! # in util.escaped it's defined as an escape # but for rules it is best to define a magic value something like # BMGC.TRANSFORMER.RULES_SEPERATOR #seems better option for # or # BMGC.TRANSFORMER_RULES_SEPERATOR #seems simpler # BMGC should implement a sane default magic for undefined values. r = r.strip() if not r.endswith('>>>'): continue if not r.startswith('>>>'): continue parts = [p.strip() for p in r.split('>>>')] rule = None lp = len(parts) if lp == 3: rule = Rule(input=parts[1], src_nr=line_number) if lp == 4: rule = Rule(input=parts[1], fun=parts[2], src_nr=line_number) if lp == 5: rule = Rule(input=parts[1], fun=parts[2], output=parts[3], src_nr=line_number) if lp == 6: rule = Rule(input=parts[1], fun=parts[2], output=parts[3], depend=parts[4], src_nr=line_number) if lp == 7: rule = Rule(input=parts[1], fun=parts[2], output=parts[3], depend=parts[4], name=parts[5], src_nr=line_number) if rule: rules.append(rule) else: self.cry( 'parts not 3..7 rule with parts[' + str(lp) + '] from line:[' + str(line_number) + ']\n\'' + r + '\'', verbosity=10) for r in rules: r.set_parent(self) self._rules = rules self.say('convert_rules_bubble:res:rules', stuff=rules, verbosity=10) return rules
[docs] def has_rules(self): return len(self._rules) > 0
[docs] def get_rules(self): return self._rules

Contents