#!/usr/bin/env python3 # -*- coding: utf-8 -*- import configparser import csv import os.path import re import unicodedata def slugify(value): ''' wandelt einen String in einen ASCII Bezeichner um (wie Djangos slugify) ''' value = unicodedata.normalize('NFKD', str(value)) value = value.encode('ascii', 'ignore').decode('ascii') value = re.sub(r'[^\w\s-]', '', value).strip().lower() return re.sub(r'[-\s]+', '-', value) def csv_open(csvfile, dialect=None): fh = open(csvfile, 'r', encoding='utf-8', newline='') if dialect is None: sniffer = csv.Sniffer() dialect = sniffer.sniff(fh.read(1024), delimiters=';,\t') fh.seek(0) reader = csv.reader(fh, dialect=dialect) return reader class CSVRow(object): def __init__(self, field_refinition, row): self.row = row self.firstrow = field_refinition for i, field in enumerate(field_refinition): try: setattr(self, field, row[i]) except IndexError: setattr(self, field, None) def __getattr__(self, name): # 'None'-fallback to make life easy return None def __repr__(self): ret = repr(self.__dict__) return ret def row(self): return self.row class CSVImport(object): def __init__(self, csvfile, dialect=None, translate=None): self.reader = csv_open(csvfile, dialect) self.rows = [] for row in self.reader: self.rows.append(row) self.firstrow = self.rows[0] self.field_definition = [] for i, field in enumerate(self.rows[0]): if not field: field = 'column_%d' % i if translate: if field in translate: print(field + ' -> ' + translate[field]) field = translate[field] field = slugify(field.strip()).replace('-', '_') self.field_definition.append(field) def __getitem__(self, key): try: return CSVRow(self.field_definition, self.rows[int(key) + 1]) except (ValueError, TypeError): raise IndexError() def __iter__(self): for row in self.rows[1:]: yield CSVRow(self.field_definition, row) def firstrow(self): return self.firstrow def get_translation(cfg_path, sec_name): """ lädt die Zuordnung zwischen einem .csv Eingabefile und den Attributen """ config = configparser.RawConfigParser(strict=False) config.read(cfg_path, encoding='utf-8') trans = dict(config.items(sec_name)) return dict([[v,k] for k,v in trans.items()]) def CompleteEnding(path, newext): ''' Fügt die gegebene File Extension an den Filename/Pfad ''' if not path: raise Csv2CouchError('no path given') path, ext = os.path.splitext(path) if not re.match(newext, ext): path = path +'.'+newext return path def RemoveEnding(path, oldext): ''' entfernt die File Extension vom Filename/Pfad ''' newpath, ext = os.path.splitext(path) if not re.match(oldext, ext): path = newpath return path # vim: set tw=75 ft=python ts=4 sw=4: