Last active
July 15, 2016 12:51
-
-
Save danielperezr88/0af32a4e6ac03d74f758407aac62cd8f to your computer and use it in GitHub Desktop.
ConfigParser applied to php.ini commented and uncommented option parsing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from configparser import ConfigParser | |
LOGDIR = '/etc/php5/apache2' | |
### Overload ConfigParser _read method to generate a comment parser | |
class CommentParser(ConfigParser): | |
def __init__(self,*args,**kwargs): | |
super(ConfigParser,self).__init__(*args,**kwargs) | |
def _read(self, fp, fpname): | |
from ConfigParser import DEFAULTSECT | |
from ConfigParser import MissingSectionHeaderError | |
from ConfigParser import ParsingError | |
cursect = None # None, or a dictionary | |
optname = None | |
lineno = 0 | |
e = None # None, or an exception | |
while True: | |
line = fp.readline() | |
if not line: | |
break | |
lineno = lineno + 1 | |
# comment or blank line? | |
if line.strip() == '' or line[0] not in '#;[': | |
continue | |
if line[0] != '[': | |
line = line[1:] | |
if re.match(r'^[^\=]*\=[^\=]+',line) == None: | |
continue | |
if line.split(None, 1)[0].lower() == 'rem' and line[0] in "rR": | |
# no leading whitespace | |
continue | |
# continuation line? | |
if line[0].isspace() and cursect is not None and optname: | |
value = line.strip() | |
if value: | |
cursect[optname].append(value) | |
# a section header or option header? | |
else: | |
# is it a section header? | |
mo = self.SECTCRE.match(line) | |
if mo: | |
sectname = mo.group('header') | |
if sectname in self._sections: | |
cursect = self._sections[sectname] | |
elif sectname == DEFAULTSECT: | |
cursect = self._defaults | |
else: | |
cursect = self._dict() | |
cursect['__name__'] = sectname | |
self._sections[sectname] = cursect | |
# So sections can't start with a continuation line | |
optname = None | |
# no section header in the file? | |
elif cursect is None: | |
raise MissingSectionHeaderError(fpname, lineno, line) | |
# an option line? | |
else: | |
mo = self._optcre.match(line) | |
if mo: | |
optname, vi, optval = mo.group('option', 'vi', 'value') | |
optname = self.optionxform(optname.rstrip()) | |
# This check is fine because the OPTCRE cannot | |
# match if it would set optval to None | |
if optval is not None: | |
if vi in ('=', ':') and ';' in optval: | |
# ';' is a comment delimiter only if it follows | |
# a spacing character | |
pos = optval.find(';') | |
if pos != -1 and optval[pos-1].isspace(): | |
optval = optval[:pos] | |
optval = optval.strip() | |
# allow empty values | |
if optval == '""': | |
optval = '' | |
cursect[optname] = [optval] | |
else: | |
# valueless option handling | |
cursect[optname] = optval | |
else: | |
# a non-fatal parsing error occurred. set up the | |
# exception but keep going. the exception will be | |
# raised at the end of the file and will contain a | |
# list of all bogus lines | |
if not e: | |
e = ParsingError(fpname) | |
e.append(lineno, repr(line)) | |
# if any parsing errors occurred, raise an exception | |
if e: | |
raise e | |
# join the multi-line values collected while reading | |
all_sections = [self._defaults] | |
all_sections.extend(self._sections.values()) | |
for options in all_sections: | |
for name, val in options.items(): | |
if isinstance(val, list): | |
options[name] = '\n'.join(val) | |
### Parse commented and uncommented options | |
with open(os.path.join(LOGDIR,'php.ini'),'r') as origfile: | |
orig = ConfigParser().read_file(origfile) | |
comm = CommentParser().read_file(origfile) | |
### Create dict from commented options | |
comm = dict( | |
[ | |
(str(name),str(value)) | |
if re.match(r'[\"\']',value[0]+value[-1]) == None | |
else (name,value[1:-1]) | |
for name, value in { | |
name:value | |
for name, value in comm._sections['PHP'].items() | |
if name != '__name__' | |
}.items() | |
] | |
) | |
### Set new php.ini from original with some changes | |
shutil.move(os.path.join(LOGDIR,'php.ini'),os.path.join(LOGDIR,'php.ini.old')) | |
orig.set('PHP','error_log','/var/log/php-scripts.log') | |
with open(os.path.join(LOGDIR,'php.ini'),'w') as newfile: | |
orig.write(newfile) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment