- piccreate.py, utils.py: print, configparser, has_key -> in, UTF-8 I/O - smart_str/smart_unicode entfernt, eigenes slugify() in utils.py - configparser mit strict=False (doppelte [+] Sektion in den Font-cfgs) - Shebangs und bin/piccreate auf python3 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
106 lines
3.1 KiB
Python
106 lines
3.1 KiB
Python
#!/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:
|