#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Class for read and modify files with key value content.
Last versión:
http://lwp-l.com/s5436
Samples:
Read key for file with separation is "="
sample fileConfig content:
# comment
key1=value1
code:
from keyValueFile import KeyValueFile
kv=KeyValueFile("fileConfig", "=")
kv.getValue("key1") # return value1
Read key commented for file with separation is "=" and comment line started with "#"
sample fileConfig content:
# comment
key1=value1
#key2=value2
code:
from keyValueFile import KeyValueFile
kv=KeyValueFile("fileConfig", "=")
kv.getValue("key2", True) # return value2
Read key commented for file with separation is "=" and comment line started with ";"
sample fileConfig content:
; comment
key1=value1
;key2=value2
code:
from keyValueFile import KeyValueFile
kv=KeyValueFile("fileConfig", "=", ";")
kv.getValue("key2", True) # return value2
Read key for file with separation is one space " "
sample fileConfig content:
# comment
key2 value2
code:
from keyValueFile import KeyValueFile
kv=KeyValueFile("fileConfig", " ")
kv.getValue("key2") # return value2
Update value for file with separation is "="
sample fileConfig content:
# comment
key1=value1
code:
from keyValueFile import KeyValueFile
kv=KeyValueFile("fileConfig", "=")
kv.setValue("key1", "new value")
kv.save()
Get commented value for a file with separation is "=" and comment line started with ";"
sample fileConfig content:
; comment
key1=value1
;key2=value2
code:
from keyValueFile import KeyValueFile
kv=KeyValueFile("fileConfig", "=", ";")
kv.getValue("key2") # return None
kv.getValue("key2", True) # return value2
Set commented for a key value pairs
sample fileConfig content:
; comment
key1=value1
key2=value2
code:
from keyValueFile import KeyValueFile
kv=KeyValueFile("fileConfig", "=", ";")
kv.setValue("key2", kv.getValue("key2"), True)
kv.save()
Remove commented for a key value pairs
sample fileConfig content:
; comment
key1=value1
;key2=value2
code:
from keyValueFile import KeyValueFile
kv=KeyValueFile("fileConfig", "=", ";")
kv.setValue("key2", kv.getValue("key2", True))
kv.save()
Remove key value pairs from file
sample fileConfig content:
# comment
key1=value1
key2=value2
code:
from keyValueFile import KeyValueFile
kv=KeyValueFile("fileConfig")
kv.removeKey("key2") # remove the line key2=value2
kv.save()
"""
import os
from tempfile import mkstemp
from shutil import move
__ver__="0.1"
class KeyValueFile():
file=""
separationKeyValue=""
commentCharacterStart=""
keyValues={}
keyRemove=[]
def __init__(self, file="", separationKeyValue="=", commentCharacterStart="#"):
"""
Parameters:
file string - file to read and save
separation string - separation between key and value
"""
self.setFile(file)
self.separationKeyValue=separationKeyValue
self.commentCharacterStart=commentCharacterStart
def setFile(self, file, separationKeyValue="="):
"""
Function that receive a filename to update.
Parameters
string file
string separationKeyValue (default =)
Return
boolean
"""
if os.path.exists(file) and separationKeyValue:
self.file=file
self.separationKeyValue=separationKeyValue
return True
return False
def setValue(self, key, value="", comment=False):
"""
Function to save key value in a var for update or insert when save data.
Parameters:
string key
string value (optional)
boolean comment - define if the value has to be commented
Return:
boolean
"""
if not key:
return False
if key in self.keyRemove:
self.keyRemove.remove(key)
self.keyValues[key.strip()]=[value.strip(), comment]
return True
def removeKey(self, key):
"""
Function to save key value for remove this line with key when save data.
Parameters:
string key
"""
if not key:
return False
if key in self.keyValues:
del self.keyValues[key]
self.keyRemove.append(key)
return True
def getValue(self, key, commented=False):
"""
Function that find a key into file and return a value if finded key.
Parameters:
key string
commented boolean - define if search key in commented lines
Return:
string - value for a key or None
"""
with open(self.file, "r") as f:
for line in f:
kv=line.split(self.separationKeyValue, 1)
# the line doesn't have a separation key value
if len(kv)==1:
continue
k,v=kv
k=k.strip()
v=v.strip()
k=k[1:].strip() if commented and k[0]==self.commentCharacterStart else k
if k==key:
return v
return None
def save(self):
"""
Function to save the content of vars in a file.
Return:
int - number of lines + added or updated - removed
"""
count=0
if os.path.exists(self.file) and os.access(self.file, os.W_OK) and self.separationKeyValue:
fh, abs_path = mkstemp()
with os.fdopen(fh, 'w') as new_file:
with open(self.file, "r") as old_file:
for line in old_file:
kv=line.split(self.separationKeyValue, 1)
if len(kv)==1:
# the line doesn't have a separation key value
new_file.write(line)
continue
k,v=kv
k=k.strip()
v=v.strip()
k=k[1:] if k[0]==self.commentCharacterStart else k
if k and k in self.keyRemove:
# this key if market as remove
count-=1
self.keyRemove.remove(k)
continue
if k and k in self.keyValues:
# this key will update from file
count+=1
if self.keyValues[k][1]==True:
# write as commented
new_file.write(self.commentCharacterStart+k+self.separationKeyValue+self.keyValues[k][0]+"\n")
else:
new_file.write(k+self.separationKeyValue+self.keyValues[k][0]+"\n")
del self.keyValues[k]
else:
new_file.write(line)
# Add elements not updated
for k,v in self.keyValues.items():
count+=1
new_file.write(k+self.separationKeyValue+v[0]+"\n")
self.keyValues={}
self.keyRemove=[]
# Remove original file
os.remove(self.file)
# Move new file
move(abs_path, self.file)
return count
Samples
Read key for file with separation is "="
# comment
key1=value1
Read key commented for file with separation is "=" and comment line started with "#"
# comment
key1=value1
#key2=value2
Read key commented for file with separation is "=" and comment line started with ";"
key1=value1
;key2=value2
Read key for file with separation is one space " "
# comment
Update value for file with separation is "="
# comment
key1=value1
Get commented value for a file with separation is "=" and comment line started with ";"
key1=value1
;key2=value2
Set commented for a key value pairs
key1=value1
key2=value2
Remove commented for a key value pairs
key1=value1
;key2=value2
Remove key value pairs from file
# comment
key1=value1
key2=value2