def add_event(self, title, day, timeFromTo, freq): logger.info('cmd: event') args = Dataparser.parse('e', title, day, timeFromTo, freq) self.db.new_event(*args) # tupel to parameters (*) Out.info("event added")
def _parse(self): line_number = 0 # store header self._header = [] while not re.match('^F 0 "', self._original_content[line_number]): self._header.append(self._original_content[line_number]) line_number += 1 # create fields while re.match('^F [0-9]', self._original_content[line_number]): line = self._original_content[line_number] # obtain position of the value if re.match('^F 1 "', line): tokens = line.split('"') tokens2 = tokens[2].split(' ') self._x_pos = int(tokens2[2]) self._y_pos = int(tokens2[3]) Out.fine('Detected component position [' + str(self._x_pos) + '|' + str(self._y_pos) + ']') # parse fields new_field = FieldParser.parse(line) self._fields.append(new_field) line_number += 1 # store trailer last_line = '$EndComp' line = '' while line != last_line: line = self._original_content[line_number] self._trailer.append(line) line_number += 1
def remove_by_id(self, id, typ): logger.info(f'cmd: remove_by_id -{typ} {id}') self.db.delete_data(id, typ) if typ == 't': Out.info(f"task {id} deleted") elif typ == 'e': Out.info(f"event {id} deleted")
def main(): c = Controller() if len(sys.argv) != 2: Output.error("usage: dlimport [filename]") c.exit() return 0 try: csvfile = open(sys.argv[1], newline='', encoding='utf-8-sig') reader = csv.reader(csvfile, delimiter=';') category = '' for row in reader: if row[0] == 'events': category = 'e' continue elif row[0] == 'tasks': category = 't' continue elif row[0] == '': continue if category == 'e': pass print(row[0], row[2], f'{row[3]}-{row[4]}', row[1]) c.add_event(row[0], row[2], f'{row[3]}-{row[4]}', row[1]) elif category == 't': print(row[0], row[2], row[3], row[1]) c.add_task(row[0], row[2], row[3], row[1]) csvfile.close() except FileNotFoundError: Output.error("file not found") finally: c.exit()
def parse(line): assert(type(line) is str) if re.match('^F [0-3] "', line): # native field Out.fine('Parsing native field: ' + line) return NativeField.parse(line) else: # custom field Out.fine('Parsing custom field: ' + line) return CustomField.parse(line)
def test_filter_value(self): for i in range(0, len(self.test_files)): # filter all 100n capacitors Out.test('Counting matches of value=100n') self.test_filter.add_constraint('Value', '100n') matching = self.test_schematics[i].filter_components(self.test_filter) assert(len(matching) == self.matching_100n[i])
def show_overview(self): logger.info('cmd: show overview') data = self.db.get_overview_data() e = Dataparser.prepare_out_events(data[0]) t = Dataparser.prepare_out_tasks(data[1]) td = Dataparser.prepare_out_tasks(data[2]) Out.overview(e, t, td)
def test_merge(self): target_component = Component(self.input_data[2]) source_component = Component(self.input_data[1]) target_component.merge(source_component) assert(target_component.get_field('Value').value == '100M') assert(target_component.get_field('Value')._x_pos == 3750) assert(target_component.get_field('Supplier').value == 'Mouser') assert(target_component.get_field('Supplier')._x_pos == 3750) Out.test(target_component.serialize())
def done(self, id): t = self.db.get_task_by(id) if not t: Out.error(f'no task with id {id} found') return 0 done_time = Dataparser.nearest_deadline(t).strftime('%Y-%m-%d %H:%M') Out.info(f'task {id} done until {done_time}') self.db.set_done(id, done_time)
def test_filter_value_and_footprint(self): for i in range(0, len(self.test_files)): # filter all 100n capacitors with a certain footprint Out.test('Counting matches of value=100n and footprint=Capacitors_SMD:C_0603') self.test_filter.add_constraint('Value', '100n') self.test_filter.add_constraint('Footprint', 'Capacitors_SMD:C_0603') matching = self.test_schematics[i].filter_components(self.test_filter) assert(len(matching) == self.matching_100n_0603[i])
def _load(self): """ Load the file to original content member """ if os.path.isfile(self.filename): with open(self.filename, 'r') as input_file: self._original_content = input_file.read().splitlines() else: Out.fail('File ' + self.filename + ' not found.') sys.exit()
def get_field(self, name): """ Return field instance with a given name """ matching_fields = list(filter(lambda field: field.name == name, self._fields)) if len(matching_fields) == 1: return matching_fields[0] elif len(matching_fields) > 1: Out.warn('More than one field with name ' + name + ' defined!') return None else: Out.fine('No field with name ' + name) return None
def write(self, inplace=False): """ Writes the current state to the (eventually given) filename """ # determine filename if not inplace: filename = self.filename + '.edit' else: filename = self.filename # write Out.ok('Writing schematic to ' + filename) with open(filename,'w') as out_file: out_file.write(self.serialize())
def test_3(self): """ Add a second field to the filter """ Out.log('Adding a second field (value) to the filter') self.test_filter.add_constraint('Value','180') self.test_filter.add_constraint('Manufacturer','Vishay/Dale') matching_components = [] for comp in self.test_components: if self.test_filter.matches(comp): matching_components.append(comp) Out.log('Matching components: %s' % matching_components) assert(len(matching_components) == 1)
def test_2(self): """ Filter custom field manufacturer """ Out.log('Generating filter for a given manufacturer') self.test_filter = Filter() self.test_filter.add_constraint('Manufacturer','Vishay/Dale') matching_components = [] for comp in self.test_components: if self.test_filter.matches(comp): matching_components.append(comp) Out.log('Matching components: %s' % matching_components) assert(len(matching_components) == 5)
def setUp(self): self.test_schematics = [] self.serialized_schematics = [] self.test_files = ['test1.sch', 'test2.sch', 'test3.sch', 'test4.sch'] self.matching_100n = [2,9,1,0] self.matching_100n_0603 = [2,0,0,0] # init and serialize all schematics for i in range(0, len(self.test_files)): test_file = self.test_files[i] Out.test('Initialize and serialize schematic file ' + test_file + ' ...') self.test_schematics.append(Schematic(test_file)) self.serialized_schematics.append(self.test_schematics[i].serialize()) # init filter self.test_filter = Filter()
def matches(self, name, value): """ Return true if both name and value are equal """ if self.name == name: if self.value == value: return True else: if self.value == value: # exact match return True else: # check regex match # value may contain a regex, i.e. R[1-3] for matching R1, R2 and R3 pattern = re.compile(value) if pattern.match(self.value) != None: Out.fine('Detected field match using regular expression: ' + value) return True else: return False
def edit(self): """ Open an editor to edit the filter """ if len(self._constraints) != 0: Out.warn('Editing filters that already have constraints is not yet supported') # create initial content initial_content = '# FILTER EDITOR\n' initial_content += '# - an asterisk (*) indicates "dont-care" fields\n' initial_content += '# - you may either\n' initial_content += '# - simply specify a field such as value = 100n, or\n' initial_content += '# - you can use regular expressiong i.e. ^R for getting all resistors\n\n' for field_name in Field.known_names: initial_content += '\'' + field_name + '\' = *\n' # run editor editor = Editor(initial_content) filter_file_content = editor.run() # parse content and add fields fields_dict = editor.parse(filter_file_content) for name, value in fields_dict.items(): self.add_constraint(name, value)
def add_or_update_field(self, name, value): """ Add a new (custom) field or replace an existing field """ # warn and return if name is empty if name == '': Out.warn('Will not add or update field in ' + self.get_field('Designator').value + ' due to empty name') return # log when clearing a value elif value == '': Out.log('Clearing value of field "' + name + '" in ' + self.get_field('Designator').value + '.') # change value of name-matching fields Out.fine('Changing value of fields matching the name "' + name + '"') for index, field in enumerate(self._fields): if field.name == name: Out.fine('Overwriting value of field #' + str(index) + ' with ' + name + ':' + value) self._fields[index].value = value # only designator and value should be visible if name == 'Designator' or name == 'Value': self._fields[index].set_visible(True) else: self._fields[index].set_visible(False) return # Construct and add new custom field new_field = CustomField.copy(self.get_field('Designator')) new_field.name = name new_field.value = value new_field.number = len(self._fields) new_field.set_visible(False) Out.fine('Adding new custom field:' + new_field.serialize()) self._fields.append(new_field)
def edit_component_template(self): """ Edit first matching component """ self.component_template = self.matching_components[0] self.component_template.edit() Out.fine('Component template:\n' + self.component_template.serialize())
def print_matches(self): """ Print all matching components """ Out.ok('Matching components:') for component in self.matching_components: Out.log(component)
def exit(self): self.db.close() Out.close()
def verify_matches(self): """ Show matches and ask to continue """ self.print_matches() if not self.confirm('Proceed?'): Out.ok('Bye!') sys.exit()
def validate(args): ''' validates input values of the user ''' # only need to validate if cmd is event or task if args.cmd == 'event' or args.cmd == 'task': # -t -d -f are available but -d is optional # try to match -f w/o/d if not re.match('^(w|weekly|d|daily|o|once)$', args.f): O.error(f'wrong frequency format: {args.f}') return False # if daily: no date/day set if args.f[0] == 'd': if args.d != None: O.error( f'you cannot use -d here because the {args.cmd} is daily.' ) return False # if once: date YYYY-MM-DD needs to be set elif args.f[0] == 'o': if not args.d or not re.match( '^((\d\d\d\d)-(0[1-9]|1[0-2])-(0[1-9]|(1|2)[0-9]|3[0-1]))$', args.d): O.error(f'wrong date format: {args.d}') return False # if weekly: day needs to be set else: if not args.d or not re.match( '^(mon|tue|wed|thu|fri|sat|sun)$', args.d): O.error(f'wrong day format: {args.d}') return False # if event try to match HH:MM-HH:MM if args.cmd == 'event': if not re.match( '^([0-1][0-9]|2[0-3]):[0-5][0-9]-([0-1][0-9]|2[0-3]):[0-5][0-9]$', args.t): O.error(f'wrong time format: {args.t}') return False # if event try to match HH:MM else: if not re.match('^([0-1][0-9]|2[0-3]):[0-5][0-9]$', args.t): O.error(f'wrong time format: {args.t}') return False return True
def setUp(self): Out.log('Preparing components using schematic class') self.test_schematic = Schematic('test1.sch') self.test_components = self.test_schematic._components self.test_filter = Filter()
def list_ids(self): logger.info(f'cmd: list_ids') data = self.db.get_id_list() Out.list_all(data[0], data[1])
def add_task(self, title, day, time, freq): logger.info('cmd: task') args = Dataparser.parse('t', title, day, time, freq) self.db.new_task(*args) # tupel to parameters (*) Out.info("task added")
def __init__(self): Out.open() self.db = Database()