confini

Parse and merge multiple ini files in python3
git clone git://git.defalsify.org/python-confini.git
Log | Files | Refs | README | LICENSE

export.py (3628B)


      1 # standard imports
      2 import sys
      3 import configparser
      4 import os
      5 import stat
      6 import enum
      7 import io
      8 import logging
      9 
     10 logg = logging.getLogger(__name__)
     11 
     12 
     13 class ConfigExporterTarget(enum.Enum):
     14     HANDLE = 1
     15     FILE = 2
     16     DIR = 3
     17 
     18 
     19 class ConfigExporter:
     20 
     21     def __init__(self, config, target=None, split=False, doc=False):
     22         self.config = config
     23         self.sections = {}
     24         self.target_split = split
     25         self.target_typ = ConfigExporterTarget.HANDLE
     26         self.target = None
     27         self.make_doc = doc
     28         self.doc = None
     29         if target == None:
     30             self.target = sys.stdout
     31         elif isinstance(target, io.IOBase):
     32             self.target = target
     33         else:
     34             st = os.stat(target)
     35             if stat.S_ISDIR(st.st_mode):
     36                 self.target_typ = ConfigExporterTarget.DIR
     37                 self.target = os.path.realpath(target)
     38             else:
     39                 self.target_typ = ConfigExporterTarget.FILE
     40                 d = os.getcwd()
     41                 self.target = os.path.join(d, target)
     42 
     43         if self.make_doc:
     44             from confini.doc import ConfigDoc
     45             if isinstance(doc, ConfigDoc):
     46                 self.doc = doc
     47             else:
     48                 try:
     49                     self.doc = ConfigDoc.from_config(config)
     50                 except FileNotFoundError as e:
     51                     logg.warning('doc set but no doc file found: {}'.format(e))
     52                     self.make_doc = False
     53 
     54 
     55     def scan(self):
     56         for k in self.config.all():
     57             (s, v) = k.split('_', maxsplit=1)
     58             if s == '':
     59                 continue
     60             s = s.lower()
     61             v = v.lower()
     62             if self.sections.get(s) == None:
     63                 self.sections[s] = {}
     64             self.sections[s][v] = self.config.get(k)
     65 
     66 
     67     def export_section(self, ks, w):
     68         if self.make_doc:
     69             try:
     70                 v = self.doc.get(ks, '_')
     71                 w.write("# " + v + "\n")
     72             except KeyError:
     73                 logg.warning('doc missing for section {}'.format(ks))
     74                 pass
     75 
     76         w.write("[" + ks + "]\n")
     77         for ko in self.sections[ks].keys():
     78             if self.make_doc:
     79                 try:
     80                     v = self.doc.get(ks, ko)
     81                     w.write("# " + v + "\n")
     82                 except KeyError:
     83                     logg.warning('doc missing for section {} option {}'.format(ks, ko))
     84                     pass
     85             v = self.sections[ks][ko]
     86             if v == None:
     87                 v = ''
     88             w.write('{} = {}\n'.format(ko, v))
     89         w.write("\n")
     90 
     91 
     92     def export(self, exclude_sections=[]):
     93         self.scan()
     94 
     95         w = None
     96         if self.target_typ == ConfigExporterTarget.HANDLE:
     97             w = self.target
     98 
     99         for i in range(len(exclude_sections)):
    100             exclude_sections[i] = exclude_sections[i].lower()
    101 
    102         for k in self.sections:
    103             if k in exclude_sections:
    104                 logg.debug('explicit skip section {} in export'.format(k))
    105                 continue
    106 
    107             if w != None:
    108                 self.export_section(k, w)
    109                 continue
    110 
    111             if self.target_typ == ConfigExporterTarget.FILE:
    112                 w = open(self.target, 'a')
    113             elif self.target_typ == ConfigExporterTarget.DIR:
    114                 if self.target_split:
    115                     fn = k + '.ini'
    116                 else:
    117                     fn = 'config.ini'
    118                 fp = os.path.join(self.target, fn)
    119                 w = open(fp, 'a')
    120 
    121             self.export_section(k, w)
    122 
    123             w.close()
    124             w = None