initial
This commit is contained in:
11
README.md
11
README.md
@@ -1,4 +1,13 @@
|
||||
ktt
|
||||
===
|
||||
|
||||
Kai's text tools
|
||||
Kai's text tools
|
||||
|
||||
Contains following python modules:
|
||||
atg - Advanced Text Generator. Created to generate large numbers of files, using a template and a data stored in table.
|
||||
atr - Advanced Text Replacer. Created to handle various ways of replacements in text files.
|
||||
template - template class for ATG and ATR.
|
||||
data - data class for ATG and ATR.
|
||||
|
||||
Scripts:
|
||||
ktt_atgcsv.py - generates files from CSV table and ATGv2 template file.
|
||||
62
atg.py
Normal file
62
atg.py
Normal file
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Advanced Text Generator module for a Kai's Text Tools.
|
||||
|
||||
(c) 2013 Ivan "Kai SD" Korystin
|
||||
|
||||
License: GPLv3
|
||||
'''
|
||||
from os.path import join, split, exists
|
||||
from os import makedirs
|
||||
|
||||
class ATG(object):
|
||||
'''
|
||||
Advanced Text Generator is a class, created to generate multiple text files from table data.
|
||||
'''
|
||||
def __init__(self, data, template):
|
||||
self.data = data
|
||||
self.template = template
|
||||
self.out = template.process(data)
|
||||
|
||||
if type(self.out) == dict:
|
||||
self.multiple = True
|
||||
else:
|
||||
self.multiple = False
|
||||
|
||||
def write_files(self, outputDir='.'):
|
||||
encoding = self.template.encoding
|
||||
extension = self.template.extension
|
||||
out = self.out
|
||||
if self.multiple:
|
||||
for name in out.keys():
|
||||
namepath = name.replace('\\', '/').split('/')
|
||||
newpath = u''
|
||||
for i in namepath[:-1]:
|
||||
newpath = join(newpath, i)
|
||||
if not exists(join(unicode(outputDir),newpath)):
|
||||
makedirs(join(unicode(outputDir),newpath))
|
||||
fname = join(unicode(outputDir),name+'.'+extension)
|
||||
if fname.endswith('.'):
|
||||
fname = fname[:-1]
|
||||
f = open(fname, 'w')
|
||||
f.write(out[name].encode(encoding))
|
||||
self.log(' Saved %s' % (name+'.'+extension))
|
||||
f.close()
|
||||
else:
|
||||
name = self.template.bonusPrefix + '.' + extension
|
||||
if name == '.':
|
||||
name = self.template.keyField
|
||||
namepath = name.replace('\\', '/').split('/')
|
||||
newpath = u''
|
||||
for i in namepath[:-1]:
|
||||
newpath = join(newpath, i)
|
||||
if not exists(join(unicode(outputDir),newpath)):
|
||||
makedirs(join(unicode(outputDir),newpath))
|
||||
f = open(join(unicode(outputDir),name+'.'+extension), 'w')
|
||||
f.write(out.encode(encoding))
|
||||
self.log(' Saved %s' % (name+'.'+extension))
|
||||
f.close()
|
||||
|
||||
def log(self, text):
|
||||
pass
|
||||
163
atr.py
Normal file
163
atr.py
Normal file
@@ -0,0 +1,163 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Advanced Text Replacer module for a Kai's Text Tools.
|
||||
|
||||
(c) 2013 Ivan "Kai SD" Korystin
|
||||
|
||||
License: GPLv3
|
||||
'''
|
||||
import re
|
||||
class ATR(object):
|
||||
'''
|
||||
classdocs
|
||||
'''
|
||||
|
||||
def __init__(self, files):
|
||||
'''
|
||||
Constructor
|
||||
'''
|
||||
self.files = files
|
||||
self.replacements = []
|
||||
|
||||
def plain_replace(self, pattern, string, regexp=False):
|
||||
'''
|
||||
Replaces the given pattern with string in files.
|
||||
'''
|
||||
if regexp:
|
||||
pattern = re.compile(pattern)
|
||||
self.replacements.append((pattern, string))
|
||||
|
||||
|
||||
def templated_replace(self, pattern, template, data, keyFormat='filename', regexp=False):
|
||||
'''
|
||||
Replaces the given pattern with data formated by template.
|
||||
Valid values for keyFormat:
|
||||
filename - take data rows by filename(path ignored), key value of the data row should store the filename.
|
||||
fullname - as filename, but with path.
|
||||
index - take data rows in order, key value of the data row should store the index. Indexes starts with 0.
|
||||
If filename or index cannot be found in data keys, pattern will not be replaced.
|
||||
'''
|
||||
if regexp:
|
||||
pattern = re.compile(pattern)
|
||||
strings = template.process(data)
|
||||
self.replacements.append((pattern, strings, keyFormat))
|
||||
|
||||
|
||||
def write_in_place(self):
|
||||
'''
|
||||
Do replacement and save the files
|
||||
'''
|
||||
for f in self.files:
|
||||
out = u''
|
||||
with open(f, 'rb') as file:
|
||||
out = file.read()
|
||||
|
||||
idx = 0
|
||||
for r in self.replacements:
|
||||
if type(r[0]) in (str, unicode):
|
||||
pattern = re.compile(re.escape(r[0]))
|
||||
string = r[1]
|
||||
elif type(r[0]) is dict and len(r) == 3:
|
||||
if r[2] == 'filename':
|
||||
fname = f.replace('\\', '/').split('/')[-1]
|
||||
string = f[1].get(fname, None)
|
||||
elif r[2] == 'fullname':
|
||||
string = f[1].get(f, None)
|
||||
elif r[2] == 'index':
|
||||
fname = f.replace('\\', '/').split('/')[-1]
|
||||
string = f[1].get(idx, None)
|
||||
else:
|
||||
raise BaseException('Unknown data key format.')
|
||||
elif hasattr(r[0], 'match'):
|
||||
pattern = r[0]
|
||||
string = r[1]
|
||||
else:
|
||||
raise BaseException('Unknown pattern type.')
|
||||
if string:
|
||||
out = re.sub(pattern, string, out)
|
||||
|
||||
with open(f, 'wb') as outfile:
|
||||
outfile.write(out)
|
||||
|
||||
def write_new_files(self, outfiles):
|
||||
'''
|
||||
Do replacement, but save to given files instead of the original ones.
|
||||
'''
|
||||
if not len(outfiles) == len(self.files):
|
||||
raise BaseException('Lists of original and new files has different length.')
|
||||
|
||||
for f in self.files:
|
||||
out = u''
|
||||
with open(f, 'rb') as file:
|
||||
out = file.read()
|
||||
|
||||
idx = 0
|
||||
for r in self.replacements:
|
||||
if type(r[0]) in (str, unicode):
|
||||
pattern = re.compile(re.escape(r[0]))
|
||||
string = r[1]
|
||||
elif type(r[0]) is dict and len(r) == 3:
|
||||
if r[2] == 'filename':
|
||||
fname = f.replace('\\', '/').split('/')[-1]
|
||||
string = f[1].get(fname, None)
|
||||
elif r[2] == 'fullname':
|
||||
string = f[1].get(f, None)
|
||||
elif r[2] == 'index':
|
||||
fname = f.replace('\\', '/').split('/')[-1]
|
||||
string = f[1].get(idx, None)
|
||||
else:
|
||||
raise BaseException('Unknown data key format.')
|
||||
elif hasattr(r[0], 'match'):
|
||||
pattern = r[0]
|
||||
string = r[1]
|
||||
else:
|
||||
raise BaseException('Unknown pattern type.')
|
||||
if string:
|
||||
out = re.sub(pattern, string, out)
|
||||
|
||||
with open(outfiles[self.files.index(f)], 'wb') as outfile:
|
||||
outfile.write(out)
|
||||
|
||||
def replace_in_names(self):
|
||||
'''
|
||||
Do replacement, but in file names instead of file content. Returns the list of new file names,
|
||||
you can use it with writeNewFiles() method.
|
||||
'''
|
||||
out = []
|
||||
for f in self.files:
|
||||
new = f
|
||||
idx = 0
|
||||
for r in self.replacements:
|
||||
if type(r[0]) in (str, unicode):
|
||||
pattern = re.compile(re.escape(r[0]))
|
||||
string = r[1]
|
||||
elif type(r[0]) is dict and len(r) == 3:
|
||||
if r[2] == 'filename':
|
||||
fname = f.replace('\\', '/').split('/')[-1]
|
||||
string = f[1].get(fname, None)
|
||||
elif r[2] == 'fullname':
|
||||
string = f[1].get(f, None)
|
||||
elif r[2] == 'index':
|
||||
fname = f.replace('\\', '/').split('/')[-1]
|
||||
string = f[1].get(idx, None)
|
||||
else:
|
||||
raise BaseException('Unknown data key format.')
|
||||
elif hasattr(r[0], 'match'):
|
||||
pattern = r[0]
|
||||
string = r[1]
|
||||
else:
|
||||
raise BaseException('Unknown pattern type.')
|
||||
if string:
|
||||
new = re.sub(pattern, string, new)
|
||||
out.append(new)
|
||||
return out
|
||||
|
||||
def clear_replacements(self):
|
||||
'''
|
||||
Removes all replacements.
|
||||
'''
|
||||
self.replacements = []
|
||||
|
||||
def log(self, string):
|
||||
pass
|
||||
176
data.py
Normal file
176
data.py
Normal file
@@ -0,0 +1,176 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Data module for a Kai's Text Tools.
|
||||
|
||||
(c) 2013 Ivan "Kai SD" Korystin
|
||||
|
||||
License: GPLv3
|
||||
'''
|
||||
|
||||
import csv, codecs
|
||||
|
||||
class Data(object):
|
||||
'''
|
||||
Empty data class. Can be used for a subclassing or procedural data creation.
|
||||
'''
|
||||
def __init__(self, *args, **kwargs):
|
||||
'''
|
||||
Constructor
|
||||
'''
|
||||
self.keys = []
|
||||
self.rows = []
|
||||
|
||||
def __getitem__(self, pair):
|
||||
'''
|
||||
Returns a value for given key and row.
|
||||
'''
|
||||
key = pair[0]
|
||||
row = pair[1]
|
||||
|
||||
keys = self.keys
|
||||
rows = self.rows
|
||||
if key in keys:
|
||||
if len(rows) > row:
|
||||
return rows[row][keys.index(key)]
|
||||
else:
|
||||
raise BaseException('Row %i not found in data' % (row))
|
||||
else:
|
||||
raise BaseException('Named value %s not found in data' % (key))
|
||||
|
||||
def __setitem__(self, pair, value):
|
||||
'''
|
||||
Sets a value for given key and row.
|
||||
'''
|
||||
key = pair[0]
|
||||
row = pair[1]
|
||||
|
||||
keys = self.keys
|
||||
rows = self.rows
|
||||
if key in keys:
|
||||
if len(rows) > row:
|
||||
rows[row][keys.index(key)] = value
|
||||
else:
|
||||
raise BaseException('Row %i not found in data' % (row))
|
||||
else:
|
||||
raise BaseException('Named value %s not found in data' % (key))
|
||||
|
||||
def __str__(self):
|
||||
'''
|
||||
Returns data as string.
|
||||
'''
|
||||
return str((self.keys, self.rows))
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
def has_key(self, key):
|
||||
'''
|
||||
Returns True if given key exists in data
|
||||
'''
|
||||
return key in self.keys
|
||||
|
||||
def add_rows(self, n=1):
|
||||
'''
|
||||
Adds some empty rows to the data.
|
||||
'''
|
||||
keys = self.keys
|
||||
rows = self.rows
|
||||
|
||||
for n in xrange(0, n):
|
||||
row = []
|
||||
for k in keys:
|
||||
row.append('')
|
||||
rows.append(row)
|
||||
|
||||
def add_keys(self, *h):
|
||||
'''
|
||||
Adds new keys to the data.
|
||||
'''
|
||||
keys = self.keys
|
||||
rows = self.rows
|
||||
|
||||
for i in h:
|
||||
keys.append(i)
|
||||
for r in rows:
|
||||
for i in h:
|
||||
r.append('')
|
||||
|
||||
def col_by_key(self, key):
|
||||
cols = []
|
||||
keys = self.keys
|
||||
rows = self.rows
|
||||
if key in keys:
|
||||
idx = keys.index(key)
|
||||
for r in rows:
|
||||
cols.append(r[idx])
|
||||
else:
|
||||
raise BaseException('Named value %s not found in data' % (key))
|
||||
return tuple(cols)
|
||||
|
||||
def row_by_idx(self, idx):
|
||||
return tuple(self.rows[idx])
|
||||
|
||||
class CSVData(Data):
|
||||
'''
|
||||
Class for reading CSV files.
|
||||
'''
|
||||
class Reader:
|
||||
class Recoder:
|
||||
def __init__(self, f, encoding):
|
||||
self.reader = codecs.getreader(encoding)(f)
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def next(self):
|
||||
return self.reader.next().encode("utf-8")
|
||||
|
||||
def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
|
||||
f = self.Recoder(f, encoding)
|
||||
self.reader = csv.reader(f, dialect=dialect, **kwds)
|
||||
|
||||
def next(self):
|
||||
row = self.reader.next()
|
||||
return [unicode(s, "utf-8") for s in row]
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def __init__(self, filename, encoding='utf-8', delimiter=';', quotechar='"', **kwargs):
|
||||
csvfile = self.Reader(open(filename), encoding=encoding, delimiter=delimiter, quotechar=quotechar)
|
||||
sourceData = []
|
||||
sourcekeys = None
|
||||
|
||||
if kwargs.get('transpose', False):
|
||||
sourcekeys = []
|
||||
rowData = []
|
||||
for i in csvfile:
|
||||
sourcekeys.append(i[0])
|
||||
for k in xrange(1, len(i)):
|
||||
sourceData.append([])
|
||||
try:
|
||||
i[k] = int(i[k])
|
||||
except:
|
||||
try:
|
||||
i[k] = float(i[k])
|
||||
except:
|
||||
i[k] = i[k]
|
||||
rowData.append(i[1:])
|
||||
sourceData = list(map(lambda *x:x, *rowData))
|
||||
else:
|
||||
for i in csvfile:
|
||||
if sourcekeys is None:
|
||||
sourcekeys = i
|
||||
else:
|
||||
for k in xrange(0, len(i)):
|
||||
try:
|
||||
i[k] = int(i[k])
|
||||
except:
|
||||
try:
|
||||
i[k] = float(i[k])
|
||||
except:
|
||||
i[k] = i[k]
|
||||
sourceData.append(i)
|
||||
self.keys = sourcekeys
|
||||
self.rows = sourceData
|
||||
27
ktt_atgcsv.py
Executable file
27
ktt_atgcsv.py
Executable file
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Generates files from csv table.
|
||||
|
||||
Part of Kai's Text Tools
|
||||
|
||||
(c) 2013 Ivan "Kai SD" Korystin
|
||||
|
||||
License: GPLv3
|
||||
'''
|
||||
from sys import argv
|
||||
from atg import ATG
|
||||
from data import CSVData
|
||||
from template import TemplateV2
|
||||
from os.path import split
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(argv) == 3:
|
||||
generator = ATG(CSVData(argv[1]), TemplateV2(argv[2]))
|
||||
generator.write_files()
|
||||
elif len(argv) == 4:
|
||||
generator = ATG(CSVData(argv[1]), TemplateV2(argv[2]))
|
||||
generator.write_files(argv[3])
|
||||
else:
|
||||
print 'Usage:', split(argv[0])[-1], '<CSV file>', '<Template file>', '[Output directory]'
|
||||
print '(c)2013 Ivan "Kai SD" Korystin'
|
||||
419
template.py
Normal file
419
template.py
Normal file
@@ -0,0 +1,419 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Template module for a Kai's Text Tools.
|
||||
|
||||
(c) 2013 Ivan "Kai SD" Korystin
|
||||
|
||||
License: GPLv3
|
||||
'''
|
||||
|
||||
import re
|
||||
class TemplateV3(object):
|
||||
'''
|
||||
Class for reading ATGv3 templates.
|
||||
'''
|
||||
pass
|
||||
|
||||
class TemplateV2(object):
|
||||
'''
|
||||
Class for reading ATGv2 templates.
|
||||
'''
|
||||
|
||||
def __init__(self, filename=None, encoding='utf-8', text=''):
|
||||
'''
|
||||
Constructor
|
||||
'''
|
||||
if filename:
|
||||
with open(filename, 'r') as templateFile:
|
||||
topline = templateFile.readline().decode(encoding)
|
||||
if not topline.startswith('ATGV2'):
|
||||
raise BaseException('%s is not an ATGv2 template' % (filename))
|
||||
|
||||
key = templateFile.readline().decode(encoding)
|
||||
if key[:2] == '[$' and key[-3:-1] == '$]':
|
||||
keyInfo = key[2:-2].split('$')
|
||||
if len(keyInfo) < 4:
|
||||
raise BaseException('%s has bad ATGv2 key' % (filename))
|
||||
self.keyField = keyInfo[0]
|
||||
self.extension = keyInfo[1]
|
||||
self.prefix = keyInfo[2]
|
||||
self.encoding = keyInfo[3]
|
||||
if 'oneFile' in keyInfo[4:]:
|
||||
self.oneFile = True
|
||||
else:
|
||||
self.oneFile = False
|
||||
if 'transpose' in keyInfo[4:]:
|
||||
self.transpose = True
|
||||
else:
|
||||
self.transpose = False
|
||||
self.text = u''
|
||||
else:
|
||||
raise BaseException('%s has bad ATGv2 key' % (filename))
|
||||
|
||||
for i in templateFile.readlines():
|
||||
self.text += i.decode(encoding)
|
||||
else:
|
||||
self.text = text
|
||||
|
||||
self.key = u''
|
||||
self.footer = u''
|
||||
self.replacement = {}
|
||||
self._data = None
|
||||
self._multiWords = None
|
||||
|
||||
def parse(text):
|
||||
topParts = []
|
||||
matches = {}
|
||||
|
||||
openers = re.finditer('\[\$.*?\$', text)
|
||||
closers = re.finditer('\$\]', text)
|
||||
ops = []
|
||||
try:
|
||||
cl = closers.next()
|
||||
while not cl is None:
|
||||
try:
|
||||
op = openers.next()
|
||||
if op.start() < cl.start():
|
||||
ops.append(op)
|
||||
else:
|
||||
idx = -1
|
||||
try:
|
||||
while ops[idx].start() > cl.start():
|
||||
idx -= 1
|
||||
except:
|
||||
raise BaseException('Template parsing error: can not find the opener for '+str(cl.start()))
|
||||
matches[ops[idx]] = cl
|
||||
if len(ops) == 1 or idx == -len(ops):
|
||||
topParts.append(ops[idx])
|
||||
del ops[idx]
|
||||
ops.append(op)
|
||||
try:
|
||||
cl = closers.next()
|
||||
except StopIteration:
|
||||
cl = None
|
||||
except StopIteration:
|
||||
idx = -1
|
||||
try:
|
||||
while ops[idx].start() > cl.start():
|
||||
idx -= 1
|
||||
except:
|
||||
raise BaseException('Template parsing error: can not find the opener for '+str(cl.start()))
|
||||
matches[ops[idx]] = cl
|
||||
if len(ops) == 1 or idx == -len(ops):
|
||||
topParts.append(ops[idx])
|
||||
del ops[idx]
|
||||
try:
|
||||
cl = closers.next()
|
||||
except StopIteration:
|
||||
cl = None
|
||||
except StopIteration:
|
||||
pass
|
||||
parts = []
|
||||
for i in topParts:
|
||||
startPoint = i.end()
|
||||
endPoint = matches[i].start()
|
||||
p = (i.group()[2:-1], text[startPoint:endPoint])
|
||||
if p[0].startswith('ATG'):
|
||||
parts.insert(0, p)
|
||||
else:
|
||||
parts.append(p)
|
||||
return parts
|
||||
|
||||
partCommands = {}
|
||||
|
||||
def plain(index, flow, keytag):
|
||||
if not keytag in self._data.keys:
|
||||
self.warning('WARNING: keyword not found in table - %s' % (keytag))
|
||||
return flow
|
||||
return flow.replace('[$%s$]' % (keytag), unicode(self._data[keytag, index]))
|
||||
partCommands['_ATGPLAIN'] = plain
|
||||
|
||||
def nPlain(index, flow, keytag, number):
|
||||
if not keytag+str(number) in self._data.keys:
|
||||
self.warning('WARNING: keyword not found in table - %s' % (keytag+str(number)))
|
||||
return flow
|
||||
return flow.replace('[$%s$]' % (keytag), unicode(self._data[keytag+str(number), index]))
|
||||
|
||||
def lIndex(index, flow, keytag, number):
|
||||
return flow.replace('[$ATGLINDEX$]', str(number))
|
||||
|
||||
def addkey(index, flow, text):
|
||||
if self.key.find(text) < 0:
|
||||
self.key += text
|
||||
key = '[$ATGkey$' + text + '$]'
|
||||
return flow.replace(key,'')
|
||||
partCommands['ATGkey'] = addkey
|
||||
|
||||
def addFooter(index, flow, text):
|
||||
if self.footer.find(text) < 0:
|
||||
self.footer += text
|
||||
key = '[$ATGFOOTER$' + text + '$]'
|
||||
return flow.replace(key,'')
|
||||
partCommands['ATGFOOTER'] = addFooter
|
||||
|
||||
def addList(index, flow, string):
|
||||
key = '[$ATGLIST$%s$%s$]' % (string.split('$')[0], string[len(string.split('$')[0])+1:])
|
||||
sub = string[len(string.split('$')[0])+1:]
|
||||
keyTag = string.split('$')[0]
|
||||
subparts = parse(sub)
|
||||
myText = u''
|
||||
if not keyTag in self._multiWords:
|
||||
self.warning('Keytag %s is not multiple!' % (keyTag))
|
||||
return flow
|
||||
for j in xrange(1, self._multiWords[keyTag]+1):
|
||||
subText = sub
|
||||
for sp in subparts:
|
||||
if sp[0] in self._multiWords:
|
||||
subText = nPlain(index, subText, sp[0], j)
|
||||
elif sp[0] == 'ATGLINDEX':
|
||||
subText = lIndex(index, subText, sp[0], j)
|
||||
elif sp[0] in partCommands:
|
||||
subText = partCommands[sp[0]](index, subText, sp[1])
|
||||
elif sp[1] == '':
|
||||
subText = plain(index, subText, sp[0])
|
||||
else:
|
||||
self.warning('Warning: unknown command '+sp[0])
|
||||
if not self._data[keyTag+str(j), index] == u'':
|
||||
myText += subText
|
||||
return flow.replace(key, myText)
|
||||
partCommands['ATGLIST'] = addList
|
||||
|
||||
def addListCut(index, flow, string):
|
||||
key = '[$ATGLISTCUT$%s$%s$]' % (string.split('$')[0], string[len(string.split('$')[0])+1:])
|
||||
sub = string[len(string.split('$')[0])+1:]
|
||||
keyTag = string.split('$')[0]
|
||||
subparts = parse(sub)
|
||||
myText = u''
|
||||
if not keyTag in self._multiWords:
|
||||
self.warning('Keytag %s is not multiple!' % (keyTag))
|
||||
return flow
|
||||
for j in xrange(1, self._multiWords[keyTag]+1):
|
||||
subText = sub
|
||||
for sp in subparts:
|
||||
if sp[0] in self._multiWords:
|
||||
subText = nPlain(index, subText, sp[0], j)
|
||||
elif sp[0] == 'ATGLINDEX':
|
||||
subText = lIndex(index, subText, sp[0], j)
|
||||
elif sp[0] in partCommands:
|
||||
subText = partCommands[sp[0]](index, subText, sp[1])
|
||||
elif sp[1] == '':
|
||||
subText = plain(index, subText, sp[0])
|
||||
else:
|
||||
self.warning('Warning: unknown command '+sp[0])
|
||||
if not self._data[keyTag+str(j), index] == u'':
|
||||
myText += subText
|
||||
return flow.replace(key, myText[:-1])
|
||||
partCommands['ATGLISTCUT'] = addListCut
|
||||
|
||||
def addIf(index, flow, string):
|
||||
key = '[$ATGIF$%s$%s$]' % (string.split('$')[0], string[len(string.split('$')[0])+1:])
|
||||
sub = string[len(string.split('$')[0])+len(string.split('$')[1])+2:]
|
||||
keyTag = string.split('$')[0]
|
||||
targetValue = string.split('$')[1]
|
||||
subparts = parse(sub)
|
||||
myText = u''
|
||||
if self._data[keyTag, 0] == []:
|
||||
self.warning('WARNING: keyword not found in table - %s' % (keyTag))
|
||||
return flow
|
||||
if unicode(self._data[keyTag, index]) == unicode(targetValue):
|
||||
subText = sub
|
||||
for sp in subparts:
|
||||
if sp[0] in partCommands:
|
||||
subText = partCommands[sp[0]](index, subText, sp[1])
|
||||
elif sp[1] == '':
|
||||
subText = plain(index, subText, sp[0])
|
||||
else:
|
||||
self.warning('Warning: unknown command '+sp[0])
|
||||
myText += subText
|
||||
return flow.replace(key, myText)
|
||||
partCommands['ATGIF'] = addIf
|
||||
|
||||
def addIfNot(index, flow, string):
|
||||
key = '[$ATGIFNOT$%s$%s$]' % (string.split('$')[0], string[len(string.split('$')[0])+1:])
|
||||
sub = string[len(string.split('$')[0])+len(string.split('$')[1])+2:]
|
||||
keyTag = string.split('$')[0]
|
||||
targetValue = string.split('$')[1]
|
||||
subparts = parse(sub)
|
||||
myText = u''
|
||||
if self._data[keyTag, 0] == []:
|
||||
self.warning('WARNING: keyword not found in table - %s' % (keyTag))
|
||||
return flow
|
||||
if not unicode(self._data[keyTag, index]) == unicode(targetValue):
|
||||
subText = sub
|
||||
for sp in subparts:
|
||||
if sp[0] in partCommands:
|
||||
subText = partCommands[sp[0]](index, subText, sp[1])
|
||||
elif sp[1] == '':
|
||||
subText = plain(index, subText, sp[0])
|
||||
else:
|
||||
self.warning('Warning: unknown command '+sp[0])
|
||||
myText += subText
|
||||
return flow.replace(key, myText)
|
||||
partCommands['ATGIFNOT'] = addIfNot
|
||||
|
||||
def addGreater(index, flow, string):
|
||||
key = '[$ATGGREATER$%s$%s$]' % (string.split('$')[0], string[len(string.split('$')[0])+1:])
|
||||
sub = string[len(string.split('$')[0])+len(string.split('$')[1])+2:]
|
||||
keyTag = string.split('$')[0]
|
||||
targetValue = string.split('$')[1]
|
||||
subparts = parse(sub)
|
||||
myText = u''
|
||||
if self._data[keyTag, 0] == []:
|
||||
self.warning('WARNING: keyword not found in table - %s' % (keyTag))
|
||||
return flow
|
||||
try:
|
||||
if float(self._data[keyTag, index]) > float(targetValue):
|
||||
subText = sub
|
||||
for sp in subparts:
|
||||
if sp[0] in partCommands:
|
||||
subText = partCommands[sp[0]](index, subText, sp[1])
|
||||
elif sp[1] == '':
|
||||
subText = plain(index, subText, sp[0])
|
||||
else:
|
||||
self.warning('Warning: unknown command '+sp[0])
|
||||
myText += subText
|
||||
except:
|
||||
self.warning('ERROR: trying to compare uncomparable values!')
|
||||
return flow.replace(key, myText)
|
||||
partCommands['ATGGREATER'] = addGreater
|
||||
|
||||
def addLess(index, flow, string):
|
||||
key = '[$ATGLESS$%s$%s$]' % (string.split('$')[0], string[len(string.split('$')[0])+1:])
|
||||
sub = string[len(string.split('$')[0])+len(string.split('$')[1])+2:]
|
||||
keyTag = string.split('$')[0]
|
||||
targetValue = string.split('$')[1]
|
||||
subparts = parse(sub)
|
||||
myText = u''
|
||||
if self._data[keyTag, 0] == []:
|
||||
self.warning('WARNING: keyword not found in table - %s' % (keyTag))
|
||||
return flow
|
||||
try:
|
||||
if float(self._data[keyTag, index]) < float(targetValue):
|
||||
subText = sub
|
||||
for sp in subparts:
|
||||
if sp[0] in partCommands:
|
||||
subText = partCommands[sp[0]](index, subText, sp[1])
|
||||
elif sp[1] == '':
|
||||
subText = plain(index, subText, sp[0])
|
||||
else:
|
||||
self.warning('Warning: unknown command '+sp[0])
|
||||
myText += subText
|
||||
except:
|
||||
self.warning('ERROR: trying to compare uncomparable values!')
|
||||
return flow.replace(key, myText)
|
||||
partCommands['ATGLESS'] = addLess
|
||||
|
||||
def addReplace(index, flow, string):
|
||||
key = '[$ATGREPLACE$%s$%s$]' % (string.split('$')[0], string[len(string.split('$')[0])+1:])
|
||||
targetString = string[len(string.split('$')[0])+1:]
|
||||
srcString = string.split('$')[0]
|
||||
self.replacement[srcString] = targetString
|
||||
key = '[$ATGREPLACE$' + string + '$]'
|
||||
return flow.replace(key,'')
|
||||
partCommands['ATGREPLACE'] = addReplace
|
||||
|
||||
def addPrefix(index, flow, string):
|
||||
key = '[$ATGPREFIX$%s$%s$]' % (string.split('$')[0], string[len(string.split('$')[0])+1:])
|
||||
sub = string
|
||||
subparts = parse(sub)
|
||||
for sp in subparts:
|
||||
if sp[0] in partCommands:
|
||||
sub = partCommands[sp[0]](index, sub, sp[1])
|
||||
elif sp[1] == '':
|
||||
sub = plain(index, sub, sp[0])
|
||||
else:
|
||||
self.warning('Warning: unknown command '+sp[0])
|
||||
self.bonusPrefix += sub
|
||||
key = '[$ATGPREFIX$' + string + '$]'
|
||||
return flow.replace(key,'')
|
||||
partCommands['ATGPREFIX'] = addPrefix
|
||||
|
||||
def skip(index, flow, string):
|
||||
return u'[$ATGSKIP_DO$]'
|
||||
partCommands['ATGSKIP'] = skip
|
||||
|
||||
def prev(index, flow, string):
|
||||
key = '[$ATGPREV$%s$]' % (string.split('$')[0])
|
||||
keytag = string.split('$')[0]
|
||||
if self._data[keytag, 0] == []:
|
||||
self.warning('WARNING: keyword not found in table - %s' % (keytag))
|
||||
return flow
|
||||
if index == 0:
|
||||
self.log('INFORMATION: Skipping ATGPREV tag for entry with index = 0')
|
||||
return u'[$ATGSKIP_DO$]'
|
||||
return flow.replace('[$ATGPREV$%s$]' % (keytag), unicode(self._data.col_by_key(keytag)[index-1]))
|
||||
partCommands['ATGPREV'] = prev
|
||||
|
||||
self.commands = partCommands
|
||||
self.parts = parse(self.text)
|
||||
|
||||
def process(self, data):
|
||||
self._data = data
|
||||
|
||||
multiWords = {}
|
||||
numbs = ('1','2','3','4','5','6','7','8','9','0')
|
||||
|
||||
for i in data.keys:
|
||||
multi = False
|
||||
while i[-1] in numbs:
|
||||
i = i[:-1]
|
||||
multi = True
|
||||
if multi:
|
||||
if i in multiWords:
|
||||
multiWords[i] += 1
|
||||
else:
|
||||
multiWords[i] = 1
|
||||
self._multiWords = multiWords
|
||||
|
||||
if self.oneFile:
|
||||
out = ''
|
||||
else:
|
||||
out = {}
|
||||
index = 0
|
||||
partCommands = self.commands
|
||||
for element in data.col_by_key(self.keyField):
|
||||
self.bonusPrefix = self.prefix
|
||||
text = self.text
|
||||
for i in self.parts:
|
||||
if i[0] in partCommands:
|
||||
text = partCommands[i[0]](index, text, i[1])
|
||||
elif i[1] == u'':
|
||||
text = partCommands['_ATGPLAIN'](index, text, i[0])
|
||||
else:
|
||||
self.warning('Warning: unknown command '+i[0])
|
||||
for i in self.replacement:
|
||||
text = text.replace(i, self.replacement[i])
|
||||
self.replacement = {}
|
||||
index += 1
|
||||
|
||||
if u'[$ATGSKIP_DO$]' in text:
|
||||
self.log('ATGSKIP Tag found. Skipping ' + unicode(element) + '.')
|
||||
else:
|
||||
if self.oneFile:
|
||||
out += text
|
||||
else:
|
||||
name = self.bonusPrefix + unicode(element)
|
||||
out[name] = text
|
||||
self.log('Created %s' % (element))
|
||||
|
||||
if self.oneFile:
|
||||
out = self.key + out + self.footer
|
||||
|
||||
return out
|
||||
|
||||
def warning(self, text):
|
||||
print text
|
||||
|
||||
def log(self, text):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def express(cls, text, **kwargs):
|
||||
obj = cls()
|
||||
obj.text = text
|
||||
self.keyField = kwargs.get('keyField', 'Index')
|
||||
self.extension = kwargs.get('extension', '')
|
||||
self.prefix = kwargs.get('prefix', '')
|
||||
self.encoding = kwargs.get('encoding', 'utf-8')
|
||||
return obj
|
||||
Reference in New Issue
Block a user