/
dictfiles.py
256 lines (205 loc) · 7.95 KB
/
dictfiles.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
""" dictfiles.py
version 0.3
Reads key/value pairs to and from being embedded within
normal text files.
Leaves all non key:value text alone / preserves comments and non key:value pairs.
Processes multiple key:value formats.
by Jaysen Naidoo
2014.06.28
ChangeLog:
2014.06.28: v0.3 starts with fixes:
- leaves comments and non key pairs alone.
- only replaces a line if it contains a keypair and the value has changed
2006.08.21: fixed update - to properly update the file when a keyword is changed
TODO: Handle Key:Values in the following formats:
- [key:value]
- [key=value]
TODO: handle multi-line key:value pairs (?)
TODO: Allow the reading of multiple key:value formats
TODO: change dictionary to component instead of parent (?)
# Copyright (C) 2014 Jaysen
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import os
from UserDict import UserDict
import fileutils as fu
DEFAULTSEPERATOR = ':'
class FileDict(UserDict):
""" A class that reads and writes dictionary key:values from text files
Ignores & Preserves comments and non key:value pairs
"""
filename = './test.txt'
seperator = DEFAULTSEPERATOR
raiseErrors = False
def __init__(self, fname=None, sep=DEFAULTSEPERATOR):
""" inits the class - by checking filename and reading in dict values
arguments:
fname = filename to work with
sep : (optional) the separator used in the file (default = ':')
raiseErrors : (optional) whether or not to raise exceptions (default = False)
"""
UserDict.__init__(self)
self.filename = fname
self.seperator = sep
self.fileRead()
def isDictPair(self, fileline):
""" returns true if
the line passed in contains (even in part) a Dictionary Key:Value Pair
false otherwise.
"""
templine = fileline
splitline = templine.split(self.seperator)
if len(splitline) > 1:
tempkey = splitline[0].strip()
tempval = splitline[1].strip()
if tempkey in self.data:
if tempdict[tempkey] == tempval:
def isPairChanged(self, fileline):
""" Returns true - if the fileline contains a pair
and - pair has changed since it was last read.
either changed by external write to file
or
change by updating dictionary
"""
pass
def fileRead(self):
""" reads from file into FileDict
returns 1 if file exists - else returns 0
"""
if os.path.exists(self.filename):
for line in open(self.filename, 'r'):
splitline = line.split(self.seperator)
if len(splitline) > 1:
self.data[splitline[0].strip()] = splitline[1].strip()
return 1
# doesn't exist - so create empty file:
else:
f = open(self.filename, 'w')
f.close()
return 0
def fileUpdate(self, keepbackups=True):
""" updates the file with the contents of the dictionary
Preserves comments and non key:value pairs
returns 1 it if succeeds, otherwise 0
"""
if os.path.exists(self.filename):
fu.backup(self.filename)
tempdict = self.data
templines = []
for line in fu.readlines(self.filename):
templine = line
splitline = templine.split(self.seperator)
if len(splitline) > 1:
tempkey = splitline[0].strip()
tempval = splitline[1].strip()
if tempkey in self.data:
if tempdict[tempkey] == tempval:
templines.append(line.strip())
else:
templines.append('%-20s : %s'.strip() % (tempkey, tempdict[tempkey]))
# del existing pairs from tempdict - so you dont repeat them when u append tempdict
del tempdict[tempkey]
else:
templines.append(line.strip())
for k in sorted(tempdict.iterkeys()):
templines.append('%-20s : %s'.strip() % (k, tempdict[k]))
fu.writelines(self.filename, templines, True)
if not keepbackups:
fu.delete(self.filename + '.bak')
# self.fileRead()
# -----------------------------------------------------------------------------
def getValue(self, key, raw=False):
""" Returns the value associated with the key
Returns NULL if not found
If Raw=true: get from file.
"""
if key in self:
return self.data[key]
def printDict(self):
for k, v in sorted(fd.iteritems()):
print '%-20s : %s' % (k, v)
def printDictFile(self):
print("")
if os.path.exists(self.filename):
# log('print fd file contents:')
for l in (fu.readlines(self.filename)):
print l,
def log(string):
""" debug/log output """
print ("****** %s" % string)
if __name__ == "__main__":
testfile = './test2.txt'
# TEMP DEBUG - DELETE BEFORE:
# fu.delete(testfile)
fd = FileDict(testfile)
fd.fileRead()
try:
if ('read-count' in fd.data.keys() and int(fd.data['read-count']) > 5):
log("DELETING!!!")
fu.delete(testfile)
fd.data.clear()
except:
log("readcount failed!!!!!")
if not os.path.exists(testfile):
log("create a new dict file")
newlines = ["TESTING DICTFILES.PY",
"- A Script to read and handle Key:Value Pairs embedded files with normal text",
"",
"read-count :0:fldsjfal",
"greetings friendly tester.",
"",
"c:0",
"DD:09",
"varA:1",
"testWord : the WORD : a comment ... and another",
"and YET another comment",
"",
"then the END OF FREE TEXT!!!!!!!"]
fu.writelines(testfile, newlines, True)
fd.fileRead()
# log("===================================")
# log("print the dict file first time!")
# fd.printDictFile()
# log("read dict from the file")
# fd.fileRead()
log("===================================")
log("Print the dictionary:")
fd.printDict()
log("===================================")
log("Then change the dict in code ...")
fd.data['testWord'] = 'the WORD'
fd['testSentence'] = 'a whole SENTENCE'
varA, varB = '1', '5'
readcount = '0'
try:
varA = str(int(fd.data['varA']) + 1)
varB = str(int(fd.data['varB']) + 5)
readcount = str(int(fd.data['read-count']) + 1)
except:
pass
finally:
fd.data['varA'] = varA
fd.data['varB'] = varB
fd.data['read-count'] = readcount
fd['DD'] = '10'
fd['DE'] = '10'
fd['DD'] = '11'
# log("print the dictionary BEFORE update:")
# fd.printDict()
log("===================================")
log('now update file from new fd.data:')
fd.fileUpdate()
log("print the dictionary AFTER update:")
fd.printDict()
print("")
log('then reprint the FileDict file:')
fd.printDictFile()