@@ -33,3 +33,5 @@ nosetests.xml | |||||
.mr.developer.cfg | .mr.developer.cfg | ||||
.project | .project | ||||
.pydevproject | .pydevproject | ||||
GoogleIssues2CSV.py |
@@ -1,74 +0,0 @@ | |||||
#!/usr/bin/python | |||||
# -*- coding: utf-8 -*- | |||||
''' | |||||
Advanced Text Generator module for a KaiSD Text Tools. | |||||
(c) 2013 Ivan "Kai SD" Korystin | |||||
License: GPLv3 | |||||
''' | |||||
from os.path import join, exists | |||||
from os import makedirs | |||||
class ATG: | |||||
''' | |||||
Advanced Text Generator is a class, created to generate multiple | |||||
text files from table data. | |||||
''' | |||||
def __init__(self, data, template): | |||||
''' | |||||
Constructor. | |||||
data - an instance of the data.Data class (i.e. CSVData) | |||||
template - an instance of the template.Template class (i.e. TemplateV2) | |||||
''' | |||||
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='.'): | |||||
''' | |||||
Write generated files to the given directory. | |||||
''' | |||||
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): | |||||
''' | |||||
Print information | |||||
''' | |||||
pass |
@@ -1,168 +0,0 @@ | |||||
#!/usr/bin/python | |||||
# -*- coding: utf-8 -*- | |||||
''' | |||||
Advanced Text Replacer module for a KaiSD Text Tools. | |||||
(c) 2013 Ivan "Kai SD" Korystin | |||||
License: GPLv3 | |||||
''' | |||||
import re | |||||
class ATR: | |||||
''' | |||||
Advanced Text Replacer - is a class, created to make multiple replacements | |||||
in the content or names of text file. | |||||
It can make plain replacements, or use ATG templates to do something more complex. | |||||
''' | |||||
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): | |||||
''' | |||||
Print information | |||||
''' | |||||
pass |
@@ -1,191 +0,0 @@ | |||||
#!/usr/bin/python | |||||
# -*- coding: utf-8 -*- | |||||
''' | |||||
Data module for a KaiSD Text Tools. | |||||
(c) 2013 Ivan "Kai SD" Korystin | |||||
License: GPLv3 | |||||
''' | |||||
import csv, codecs | |||||
class Data: | |||||
''' | |||||
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): | |||||
''' | |||||
Returns a column by header's name | |||||
''' | |||||
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): | |||||
''' | |||||
Returns a row by index. | |||||
''' | |||||
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): | |||||
''' | |||||
Constructor. | |||||
filename - CSV table filename | |||||
encoding - CSV table encoding | |||||
delimiter - CSV table delimiter | |||||
quotechar - CSV table quotechar | |||||
transpose=True - transpose the table | |||||
''' | |||||
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 |
@@ -1,47 +0,0 @@ | |||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> | |||||
<html><head><title>Python: module atg</title> | |||||
</head><body bgcolor="#f0f0f8"> | |||||
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading"> | |||||
<tr bgcolor="#7799ee"> | |||||
<td valign=bottom> <br> | |||||
<font color="#ffffff" face="helvetica, arial"> <br><big><big><strong>atg</strong></big></big></font></td | |||||
><td align=right valign=bottom | |||||
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:///C:/users/kaisd/documents/workbench/programming/ktt/src/atg.py">c:\users\kaisd\documents\workbench\programming\ktt\src\atg.py</a></font></td></tr></table> | |||||
<p><tt>Advanced Text Generator module for a KaiSD Text Tools.<br> | |||||
<br> | |||||
(c) 2013 Ivan "Kai SD" Korystin <br> | |||||
<br> | |||||
License: GPLv3</tt></p> | |||||
<p> | |||||
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section"> | |||||
<tr bgcolor="#ee77aa"> | |||||
<td colspan=3 valign=bottom> <br> | |||||
<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr> | |||||
<tr><td bgcolor="#ee77aa"><tt> </tt></td><td> </td> | |||||
<td width="100%"><dl> | |||||
<dt><font face="helvetica, arial"><a href="atg.html#ATG">ATG</a> | |||||
</font></dt></dl> | |||||
<p> | |||||
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section"> | |||||
<tr bgcolor="#ffc8d8"> | |||||
<td colspan=3 valign=bottom> <br> | |||||
<font color="#000000" face="helvetica, arial"><a name="ATG">class <strong>ATG</strong></a></font></td></tr> | |||||
<tr bgcolor="#ffc8d8"><td rowspan=2><tt> </tt></td> | |||||
<td colspan=2><tt>Advanced Text Generator is a class, created to generate multiple<br> | |||||
text files from table data.<br> </tt></td></tr> | |||||
<tr><td> </td> | |||||
<td width="100%">Methods defined here:<br> | |||||
<dl><dt><a name="ATG-__init__"><strong>__init__</strong></a>(self, data, template)</dt><dd><tt>Constructor.<br> | |||||
data - an instance of the data.Data class (i.e. CSVData)<br> | |||||
template - an instance of the template.Template class (i.e. TemplateV2)</tt></dd></dl> | |||||
<dl><dt><a name="ATG-log"><strong>log</strong></a>(self, text)</dt><dd><tt>Print information</tt></dd></dl> | |||||
<dl><dt><a name="ATG-write_files"><strong>write_files</strong></a>(self, outputDir<font color="#909090">='.'</font>)</dt><dd><tt>Write generated files to the given directory.</tt></dd></dl> | |||||
</td></tr></table></td></tr></table> | |||||
</body></html> |
@@ -1,70 +0,0 @@ | |||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> | |||||
<html><head><title>Python: module atr</title> | |||||
</head><body bgcolor="#f0f0f8"> | |||||
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading"> | |||||
<tr bgcolor="#7799ee"> | |||||
<td valign=bottom> <br> | |||||
<font color="#ffffff" face="helvetica, arial"> <br><big><big><strong>atr</strong></big></big></font></td | |||||
><td align=right valign=bottom | |||||
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:///C:/users/kaisd/documents/workbench/programming/ktt/src/atr.py">c:\users\kaisd\documents\workbench\programming\ktt\src\atr.py</a></font></td></tr></table> | |||||
<p><tt>Advanced Text Replacer module for a KaiSD Text Tools.<br> | |||||
<br> | |||||
(c) 2013 Ivan "Kai SD" Korystin <br> | |||||
<br> | |||||
License: GPLv3</tt></p> | |||||
<p> | |||||
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section"> | |||||
<tr bgcolor="#aa55cc"> | |||||
<td colspan=3 valign=bottom> <br> | |||||
<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr> | |||||
<tr><td bgcolor="#aa55cc"><tt> </tt></td><td> </td> | |||||
<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="re.html">re</a><br> | |||||
</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p> | |||||
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section"> | |||||
<tr bgcolor="#ee77aa"> | |||||
<td colspan=3 valign=bottom> <br> | |||||
<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr> | |||||
<tr><td bgcolor="#ee77aa"><tt> </tt></td><td> </td> | |||||
<td width="100%"><dl> | |||||
<dt><font face="helvetica, arial"><a href="atr.html#ATR">ATR</a> | |||||
</font></dt></dl> | |||||
<p> | |||||
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section"> | |||||
<tr bgcolor="#ffc8d8"> | |||||
<td colspan=3 valign=bottom> <br> | |||||
<font color="#000000" face="helvetica, arial"><a name="ATR">class <strong>ATR</strong></a></font></td></tr> | |||||
<tr bgcolor="#ffc8d8"><td rowspan=2><tt> </tt></td> | |||||
<td colspan=2><tt>Advanced Text Replacer - is a class, created to make multiple replacements<br> | |||||
in the content or names of text file.<br> | |||||
It can make plain replacements, or use ATG templates to do something more complex.<br> </tt></td></tr> | |||||
<tr><td> </td> | |||||
<td width="100%">Methods defined here:<br> | |||||
<dl><dt><a name="ATR-__init__"><strong>__init__</strong></a>(self, files)</dt><dd><tt>Constructor</tt></dd></dl> | |||||
<dl><dt><a name="ATR-clear_replacements"><strong>clear_replacements</strong></a>(self)</dt><dd><tt>Removes all replacements.</tt></dd></dl> | |||||
<dl><dt><a name="ATR-log"><strong>log</strong></a>(self, string)</dt><dd><tt>Print information</tt></dd></dl> | |||||
<dl><dt><a name="ATR-plain_replace"><strong>plain_replace</strong></a>(self, pattern, string, regexp<font color="#909090">=False</font>)</dt><dd><tt>Replaces the given pattern with string in files.</tt></dd></dl> | |||||
<dl><dt><a name="ATR-replace_in_names"><strong>replace_in_names</strong></a>(self)</dt><dd><tt>Do replacement, but in file names instead of file content. Returns the list of new file names,<br> | |||||
you can use it with writeNewFiles() method.</tt></dd></dl> | |||||
<dl><dt><a name="ATR-templated_replace"><strong>templated_replace</strong></a>(self, pattern, template, data, keyFormat<font color="#909090">='filename'</font>, regexp<font color="#909090">=False</font>)</dt><dd><tt>Replaces the given pattern with data formated by template.<br> | |||||
Valid values for keyFormat:<br> | |||||
filename - take data rows by filename(path ignored), key value of the data row should store the filename.<br> | |||||
fullname - as filename, but with path.<br> | |||||
index - take data rows in order, key value of the data row should store the index. Indexes starts with 0.<br> | |||||
If filename or index cannot be found in data keys, pattern will not be replaced.</tt></dd></dl> | |||||
<dl><dt><a name="ATR-write_in_place"><strong>write_in_place</strong></a>(self)</dt><dd><tt>Do replacement and save the files</tt></dd></dl> | |||||
<dl><dt><a name="ATR-write_new_files"><strong>write_new_files</strong></a>(self, outfiles)</dt><dd><tt>Do replacement, but save to given files instead of the original ones.</tt></dd></dl> | |||||
</td></tr></table></td></tr></table> | |||||
</body></html> |
@@ -1,114 +0,0 @@ | |||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> | |||||
<html><head><title>Python: module data</title> | |||||
</head><body bgcolor="#f0f0f8"> | |||||
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading"> | |||||
<tr bgcolor="#7799ee"> | |||||
<td valign=bottom> <br> | |||||
<font color="#ffffff" face="helvetica, arial"> <br><big><big><strong>data</strong></big></big></font></td | |||||
><td align=right valign=bottom | |||||
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:///C:/users/kaisd/documents/workbench/programming/ktt/src/data.py">c:\users\kaisd\documents\workbench\programming\ktt\src\data.py</a></font></td></tr></table> | |||||
<p><tt><a href="#Data">Data</a> module for a KaiSD Text Tools.<br> | |||||
<br> | |||||
(c) 2013 Ivan "Kai SD" Korystin <br> | |||||
<br> | |||||
License: GPLv3</tt></p> | |||||
<p> | |||||
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section"> | |||||
<tr bgcolor="#aa55cc"> | |||||
<td colspan=3 valign=bottom> <br> | |||||
<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr> | |||||
<tr><td bgcolor="#aa55cc"><tt> </tt></td><td> </td> | |||||
<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="codecs.html">codecs</a><br> | |||||
</td><td width="25%" valign=top><a href="csv.html">csv</a><br> | |||||
</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p> | |||||
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section"> | |||||
<tr bgcolor="#ee77aa"> | |||||
<td colspan=3 valign=bottom> <br> | |||||
<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr> | |||||
<tr><td bgcolor="#ee77aa"><tt> </tt></td><td> </td> | |||||
<td width="100%"><dl> | |||||
<dt><font face="helvetica, arial"><a href="data.html#Data">Data</a> | |||||
</font></dt><dd> | |||||
<dl> | |||||
<dt><font face="helvetica, arial"><a href="data.html#CSVData">CSVData</a> | |||||
</font></dt></dl> | |||||
</dd> | |||||
</dl> | |||||
<p> | |||||
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section"> | |||||
<tr bgcolor="#ffc8d8"> | |||||
<td colspan=3 valign=bottom> <br> | |||||
<font color="#000000" face="helvetica, arial"><a name="CSVData">class <strong>CSVData</strong></a>(<a href="data.html#Data">Data</a>)</font></td></tr> | |||||
<tr bgcolor="#ffc8d8"><td rowspan=2><tt> </tt></td> | |||||
<td colspan=2><tt>Class for reading CSV files.<br> </tt></td></tr> | |||||
<tr><td> </td> | |||||
<td width="100%">Methods defined here:<br> | |||||
<dl><dt><a name="CSVData-__init__"><strong>__init__</strong></a>(self, filename, encoding<font color="#909090">='utf-8'</font>, delimiter<font color="#909090">=';'</font>, quotechar<font color="#909090">='"'</font>, **kwargs)</dt><dd><tt>Constructor.<br> | |||||
<br> | |||||
filename - CSV table filename<br> | |||||
encoding - CSV table encoding<br> | |||||
delimiter - CSV table delimiter<br> | |||||
quotechar - CSV table quotechar<br> | |||||
transpose=True - transpose the table</tt></dd></dl> | |||||
<hr> | |||||
Data and other attributes defined here:<br> | |||||
<dl><dt><strong>Reader</strong> = <class data.Reader></dl> | |||||
<hr> | |||||
Methods inherited from <a href="data.html#Data">Data</a>:<br> | |||||
<dl><dt><a name="CSVData-__getitem__"><strong>__getitem__</strong></a>(self, pair)</dt><dd><tt>Returns a value for given key and row.</tt></dd></dl> | |||||
<dl><dt><a name="CSVData-__repr__"><strong>__repr__</strong></a>(self)</dt></dl> | |||||
<dl><dt><a name="CSVData-__setitem__"><strong>__setitem__</strong></a>(self, pair, value)</dt><dd><tt>Sets a value for given key and row.</tt></dd></dl> | |||||
<dl><dt><a name="CSVData-__str__"><strong>__str__</strong></a>(self)</dt><dd><tt>Returns data as string.</tt></dd></dl> | |||||
<dl><dt><a name="CSVData-add_keys"><strong>add_keys</strong></a>(self, *h)</dt><dd><tt>Adds new keys to the data.</tt></dd></dl> | |||||
<dl><dt><a name="CSVData-add_rows"><strong>add_rows</strong></a>(self, n<font color="#909090">=1</font>)</dt><dd><tt>Adds some empty rows to the data.</tt></dd></dl> | |||||
<dl><dt><a name="CSVData-col_by_key"><strong>col_by_key</strong></a>(self, key)</dt><dd><tt>Returns a column by header's name</tt></dd></dl> | |||||
<dl><dt><a name="CSVData-has_key"><strong>has_key</strong></a>(self, key)</dt><dd><tt>Returns True if given key exists in data</tt></dd></dl> | |||||
<dl><dt><a name="CSVData-row_by_idx"><strong>row_by_idx</strong></a>(self, idx)</dt><dd><tt>Returns a row by index.</tt></dd></dl> | |||||
</td></tr></table> <p> | |||||
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section"> | |||||
<tr bgcolor="#ffc8d8"> | |||||
<td colspan=3 valign=bottom> <br> | |||||
<font color="#000000" face="helvetica, arial"><a name="Data">class <strong>Data</strong></a></font></td></tr> | |||||
<tr bgcolor="#ffc8d8"><td rowspan=2><tt> </tt></td> | |||||
<td colspan=2><tt>Empty data class. Can be used for a subclassing or procedural data creation.<br> </tt></td></tr> | |||||
<tr><td> </td> | |||||
<td width="100%">Methods defined here:<br> | |||||
<dl><dt><a name="Data-__getitem__"><strong>__getitem__</strong></a>(self, pair)</dt><dd><tt>Returns a value for given key and row.</tt></dd></dl> | |||||
<dl><dt><a name="Data-__init__"><strong>__init__</strong></a>(self, *args, **kwargs)</dt><dd><tt>Constructor</tt></dd></dl> | |||||
<dl><dt><a name="Data-__repr__"><strong>__repr__</strong></a>(self)</dt></dl> | |||||
<dl><dt><a name="Data-__setitem__"><strong>__setitem__</strong></a>(self, pair, value)</dt><dd><tt>Sets a value for given key and row.</tt></dd></dl> | |||||
<dl><dt><a name="Data-__str__"><strong>__str__</strong></a>(self)</dt><dd><tt>Returns data as string.</tt></dd></dl> | |||||
<dl><dt><a name="Data-add_keys"><strong>add_keys</strong></a>(self, *h)</dt><dd><tt>Adds new keys to the data.</tt></dd></dl> | |||||
<dl><dt><a name="Data-add_rows"><strong>add_rows</strong></a>(self, n<font color="#909090">=1</font>)</dt><dd><tt>Adds some empty rows to the data.</tt></dd></dl> | |||||
<dl><dt><a name="Data-col_by_key"><strong>col_by_key</strong></a>(self, key)</dt><dd><tt>Returns a column by header's name</tt></dd></dl> | |||||
<dl><dt><a name="Data-has_key"><strong>has_key</strong></a>(self, key)</dt><dd><tt>Returns True if given key exists in data</tt></dd></dl> | |||||
<dl><dt><a name="Data-row_by_idx"><strong>row_by_idx</strong></a>(self, idx)</dt><dd><tt>Returns a row by index.</tt></dd></dl> | |||||
</td></tr></table></td></tr></table> | |||||
</body></html> |
@@ -1,135 +0,0 @@ | |||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> | |||||
<html><head><title>Python: module template</title> | |||||
</head><body bgcolor="#f0f0f8"> | |||||
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading"> | |||||
<tr bgcolor="#7799ee"> | |||||
<td valign=bottom> <br> | |||||
<font color="#ffffff" face="helvetica, arial"> <br><big><big><strong>template</strong></big></big></font></td | |||||
><td align=right valign=bottom | |||||
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:///C:/users/kaisd/documents/workbench/programming/ktt/src/template.py">c:\users\kaisd\documents\workbench\programming\ktt\src\template.py</a></font></td></tr></table> | |||||
<p><tt><a href="#Template">Template</a> module for a KaiSD Text Tools.<br> | |||||
<br> | |||||
(c) 2013 Ivan "Kai SD" Korystin <br> | |||||
<br> | |||||
License: GPLv3</tt></p> | |||||
<p> | |||||
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section"> | |||||
<tr bgcolor="#aa55cc"> | |||||
<td colspan=3 valign=bottom> <br> | |||||
<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr> | |||||
<tr><td bgcolor="#aa55cc"><tt> </tt></td><td> </td> | |||||
<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="re.html">re</a><br> | |||||
</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p> | |||||
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section"> | |||||
<tr bgcolor="#ee77aa"> | |||||
<td colspan=3 valign=bottom> <br> | |||||
<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr> | |||||
<tr><td bgcolor="#ee77aa"><tt> </tt></td><td> </td> | |||||
<td width="100%"><dl> | |||||
<dt><font face="helvetica, arial"><a href="template.html#Template">Template</a> | |||||
</font></dt><dd> | |||||
<dl> | |||||
<dt><font face="helvetica, arial"><a href="template.html#TemplateV2">TemplateV2</a> | |||||
</font></dt></dl> | |||||
</dd> | |||||
</dl> | |||||
<p> | |||||
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section"> | |||||
<tr bgcolor="#ffc8d8"> | |||||
<td colspan=3 valign=bottom> <br> | |||||
<font color="#000000" face="helvetica, arial"><a name="Template">class <strong>Template</strong></a></font></td></tr> | |||||
<tr bgcolor="#ffc8d8"><td rowspan=2><tt> </tt></td> | |||||
<td colspan=2><tt>Empty template class. Generates empty text.<br> </tt></td></tr> | |||||
<tr><td> </td> | |||||
<td width="100%">Methods defined here:<br> | |||||
<dl><dt><a name="Template-log"><strong>log</strong></a>(self, text)</dt><dd><tt>Print information</tt></dd></dl> | |||||
<dl><dt><a name="Template-process"><strong>process</strong></a>(self, data)</dt><dd><tt>Replace this method in subclasses.</tt></dd></dl> | |||||
<dl><dt><a name="Template-warning"><strong>warning</strong></a>(self, text)</dt><dd><tt>Prints a warning</tt></dd></dl> | |||||
</td></tr></table> <p> | |||||
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section"> | |||||
<tr bgcolor="#ffc8d8"> | |||||
<td colspan=3 valign=bottom> <br> | |||||
<font color="#000000" face="helvetica, arial"><a name="TemplateV2">class <strong>TemplateV2</strong></a>(<a href="template.html#Template">Template</a>)</font></td></tr> | |||||
<tr bgcolor="#ffc8d8"><td rowspan=2><tt> </tt></td> | |||||
<td colspan=2><tt>Class for reading ATGv2 templates.<br> | |||||
<br> | |||||
ATGv2 template file should be a plain text file, starting with the line<br> | |||||
ATGV2<br> | |||||
followed by the info line:<br> | |||||
[$KeyField$Extension$Prefix$Encoding$]<br> | |||||
where<br> | |||||
KeyField - is a name of a data column, that contains an identifier.<br> | |||||
Extension - is the desired extension for the generated files.<br> | |||||
Prefix - is the desired filename prefix for the generated files<br> | |||||
Encoding - is the desired encoding for the generated files.<br> | |||||
The line may also have some optional keywords before the closing bracket:<br> | |||||
oneFile$ - place all generated text into a single file instead of<br> | |||||
generating a file for each table row.<br> | |||||
After the info line, you can put your text.<br> | |||||
You can use following commands to handle the data:<br> | |||||
* [$Name$], where Name is the column header,<br> | |||||
will be replaced with value from the current row.<br> | |||||
* [$ATGLINDEX$] will be replaced with the number of a current row.<br> | |||||
* [$ATGHEADER$Text$] and [$ATGFOOTER$Text$] will place the given text<br> | |||||
at the begining or at the end of the file. You can't use other<br> | |||||
commands in this text.<br> | |||||
* [$ATGLIST$Name$Text$], where Name is a multi-column header<br> | |||||
(i.e. 'Col' will represent 'Col1', 'Col2', 'Col3' etc)<br> | |||||
will repeat the given text for each non-empty value.<br> | |||||
You can use other commands in Text. Also [$Name$] inside the list<br> | |||||
will be replaced with the value for the current row and column.<br> | |||||
* [$ATGLINDEX$] can be used only inside the ATGLIST text,<br> | |||||
will be replaced with the current column index.<br> | |||||
* [$ATGLISTCUT$Name$Text$] - same as ATGLIST, but the last symbol<br> | |||||
will be removed. Useful for removing unnecessary newlines.<br> | |||||
* [$ATGIF$Name$Value$Text$] will be replaced with the given text<br> | |||||
only if the the given column's value is the same as the given one.<br> | |||||
Will be replaced with the empty text otherwise. You can use other<br> | |||||
commands in Text.<br> | |||||
* [$ATGIFNOT$Name$Value$Text$] - same as ATGIF, but the column's value<br> | |||||
should not be equal to the given one.<br> | |||||
* [$ATGGREATER$Name$Value$Text$] - same as ATGIF, but the value should<br> | |||||
be the number and it should be greater then the given one.<br> | |||||
* [$ATGGREATER$Name$Value$Text$] - same as ATGGREATER, but the value<br> | |||||
should be less then the given one.<br> | |||||
* [$ATGREPLACE$Text1$Text2$] - Will replace Text1 with Text2. Replacements<br> | |||||
will be done after all other commands. You can't use regular expressions or<br> | |||||
other commands in the text.<br> | |||||
* [$ATGPREFIX$Text$] - Will add the given text to the filename prefix.<br> | |||||
You can use other commands in text, but do it carefully.<br> | |||||
* [$ATGSKIP$] - Skip the current row. Use only in combination with the<br> | |||||
ATGIF/ATGIFNOT, or you will generate nothing.<br> | |||||
* [$ATGPREV$Name$], where Name is the column header,<br> | |||||
will be replaced with the with the value of the given header from the<br> | |||||
previous row. ATGSKIP will be used for the first row.<br> </tt></td></tr> | |||||
<tr><td> </td> | |||||
<td width="100%">Methods defined here:<br> | |||||
<dl><dt><a name="TemplateV2-__init__"><strong>__init__</strong></a>(self, filename<font color="#909090">=None</font>, encoding<font color="#909090">='utf-8'</font>, text<font color="#909090">=''</font>)</dt><dd><tt>Constructor.<br> | |||||
<br> | |||||
filename - name of the ATGv2 template file.<br> | |||||
encoding - encoding of the template file.<br> | |||||
text - text to use if no filename has been provided.</tt></dd></dl> | |||||
<dl><dt><a name="TemplateV2-process"><strong>process</strong></a>(self, data)</dt><dd><tt>Generate text for the given data.</tt></dd></dl> | |||||
<hr> | |||||
Static methods defined here:<br> | |||||
<dl><dt><a name="TemplateV2-express"><strong>express</strong></a>(cls, text, **kwargs)</dt></dl> | |||||
<hr> | |||||
Methods inherited from <a href="template.html#Template">Template</a>:<br> | |||||
<dl><dt><a name="TemplateV2-log"><strong>log</strong></a>(self, text)</dt><dd><tt>Print information</tt></dd></dl> | |||||
<dl><dt><a name="TemplateV2-warning"><strong>warning</strong></a>(self, text)</dt><dd><tt>Prints a warning</tt></dd></dl> | |||||
</td></tr></table></td></tr></table> | |||||
</body></html> |
@@ -10,10 +10,8 @@ Part of KaiSD Text Tools | |||||
License: GPLv3 | License: GPLv3 | ||||
''' | ''' | ||||
from sys import argv | from sys import argv | ||||
from atg import ATG | |||||
from data import CSVData | |||||
from template import TemplateV2 | |||||
from os.path import split | from os.path import split | ||||
from ktt import ATG, CSVData, TemplateV2 | |||||
if __name__ == '__main__': | if __name__ == '__main__': | ||||
if len(argv) == 3: | if len(argv) == 3: | ||||
@@ -1,482 +0,0 @@ | |||||
#!/usr/bin/python | |||||
# -*- coding: utf-8 -*- | |||||
''' | |||||
Template module for a KaiSD Text Tools. | |||||
(c) 2013 Ivan "Kai SD" Korystin | |||||
License: GPLv3 | |||||
''' | |||||
import re | |||||
class Template: | |||||
''' | |||||
Empty template class. Generates empty text. | |||||
''' | |||||
def process(self, data): | |||||
''' | |||||
Replace this method in subclasses. | |||||
''' | |||||
return '' | |||||
def warning(self, text): | |||||
''' | |||||
Prints a warning | |||||
''' | |||||
print text | |||||
def log(self, text): | |||||
''' | |||||
Print information | |||||
''' | |||||
pass | |||||
class TemplateV2(Template): | |||||
''' | |||||
Class for reading ATGv2 templates. | |||||
ATGv2 template file should be a plain text file, starting with the line | |||||
ATGV2 | |||||
followed by the info line: | |||||
[$KeyField$Extension$Prefix$Encoding$] | |||||
where | |||||
KeyField - is a name of a data column, that contains an identifier. | |||||
Extension - is the desired extension for the generated files. | |||||
Prefix - is the desired filename prefix for the generated files | |||||
Encoding - is the desired encoding for the generated files. | |||||
The line may also have some optional keywords before the closing bracket: | |||||
oneFile$ - place all generated text into a single file instead of | |||||
generating a file for each table row. | |||||
After the info line, you can put your text. | |||||
You can use following commands to handle the data: | |||||
* [$Name$], where Name is the column header, | |||||
will be replaced with value from the current row. | |||||
* [$ATGLINDEX$] will be replaced with the number of a current row. | |||||
* [$ATGHEADER$Text$] and [$ATGFOOTER$Text$] will place the given text | |||||
at the begining or at the end of the file. You can't use other | |||||
commands in this text. | |||||
* [$ATGLIST$Name$Text$], where Name is a multi-column header | |||||
(i.e. 'Col' will represent 'Col1', 'Col2', 'Col3' etc) | |||||
will repeat the given text for each non-empty value. | |||||
You can use other commands in Text. Also [$Name$] inside the list | |||||
will be replaced with the value for the current row and column. | |||||
* [$ATGLINDEX$] can be used only inside the ATGLIST text, | |||||
will be replaced with the current column index. | |||||
* [$ATGLISTCUT$Name$Text$] - same as ATGLIST, but the last symbol | |||||
will be removed. Useful for removing unnecessary newlines. | |||||
* [$ATGIF$Name$Value$Text$] will be replaced with the given text | |||||
only if the the given column's value is the same as the given one. | |||||
Will be replaced with the empty text otherwise. You can use other | |||||
commands in Text. | |||||
* [$ATGIFNOT$Name$Value$Text$] - same as ATGIF, but the column's value | |||||
should not be equal to the given one. | |||||
* [$ATGGREATER$Name$Value$Text$] - same as ATGIF, but the value should | |||||
be the number and it should be greater then the given one. | |||||
* [$ATGGREATER$Name$Value$Text$] - same as ATGGREATER, but the value | |||||
should be less then the given one. | |||||
* [$ATGREPLACE$Text1$Text2$] - Will replace Text1 with Text2. Replacements | |||||
will be done after all other commands. You can't use regular expressions or | |||||
other commands in the text. | |||||
* [$ATGPREFIX$Text$] - Will add the given text to the filename prefix. | |||||
You can use other commands in text, but do it carefully. | |||||
* [$ATGSKIP$] - Skip the current row. Use only in combination with the | |||||
ATGIF/ATGIFNOT, or you will generate nothing. | |||||
* [$ATGPREV$Name$], where Name is the column header, | |||||
will be replaced with the with the value of the given header from the | |||||
previous row. ATGSKIP will be used for the first row. | |||||
''' | |||||
def __init__(self, filename=None, encoding='utf-8', text=''): | |||||
''' | |||||
Constructor. | |||||
filename - name of the ATGv2 template file. | |||||
encoding - encoding of the template file. | |||||
text - text to use if no filename has been provided. | |||||
''' | |||||
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 | |||||
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.header = 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 addHeader(index, flow, text): | |||||
if self.header.find(text) < 0: | |||||
self.header += text | |||||
key = '[$ATGHEADER$' + text + '$]' | |||||
return flow.replace(key,'') | |||||
partCommands['ATGHEADER'] = addHeader | |||||
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): | |||||
''' | |||||
Generate text for the given 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] = self.header + text + self.footer | |||||
self.log('Created %s' % (element)) | |||||
if self.oneFile: | |||||
out = self.header + out + self.footer | |||||
return out | |||||
@staticmethod | |||||
def express(cls, text, **kwargs): | |||||
obj = cls() | |||||
obj.text = text | |||||
obj.keyField = kwargs.get('keyField', 'Index') | |||||
obj.extension = kwargs.get('extension', '') | |||||
obj.prefix = kwargs.get('prefix', '') | |||||
obj.encoding = kwargs.get('encoding', 'utf-8') | |||||
return obj |