Переглянути джерело

moved files, added CSV export to data.py

master
KaiSD 11 роки тому
джерело
коміт
0c7c6c0dda
10 змінених файлів з 3 додано та 1284 видалено
  1. +2
    -0
      .gitignore
  2. +0
    -74
      atg.py
  3. +0
    -168
      atr.py
  4. +0
    -191
      data.py
  5. +0
    -47
      docs/atg.html
  6. +0
    -70
      docs/atr.html
  7. +0
    -114
      docs/data.html
  8. +0
    -135
      docs/template.html
  9. +1
    -3
      ktt_atgcsv.py
  10. +0
    -482
      template.py

+ 2
- 0
.gitignore Переглянути файл

@@ -33,3 +33,5 @@ nosetests.xml
.mr.developer.cfg
.project
.pydevproject

GoogleIssues2CSV.py

+ 0
- 74
atg.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

+ 0
- 168
atr.py Переглянути файл

@@ -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

+ 0
- 191
data.py Переглянути файл

@@ -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

+ 0
- 47
docs/atg.html Переглянути файл

@@ -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>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<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&nbsp;Text&nbsp;Generator&nbsp;module&nbsp;for&nbsp;a&nbsp;KaiSD&nbsp;Text&nbsp;Tools.<br>
&nbsp;<br>
(c)&nbsp;2013&nbsp;Ivan&nbsp;"Kai&nbsp;SD"&nbsp;Korystin&nbsp;<br>
&nbsp;<br>
License:&nbsp;GPLv3</tt></p>
<p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#ee77aa">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</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>&nbsp;<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>&nbsp;&nbsp;&nbsp;</tt></td>
<td colspan=2><tt>Advanced&nbsp;Text&nbsp;Generator&nbsp;is&nbsp;a&nbsp;class,&nbsp;created&nbsp;to&nbsp;generate&nbsp;multiple<br>
text&nbsp;files&nbsp;from&nbsp;table&nbsp;data.<br>&nbsp;</tt></td></tr>
<tr><td>&nbsp;</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&nbsp;-&nbsp;an&nbsp;instance&nbsp;of&nbsp;the&nbsp;data.Data&nbsp;class&nbsp;(i.e.&nbsp;CSVData)<br>
template&nbsp;-&nbsp;an&nbsp;instance&nbsp;of&nbsp;the&nbsp;template.Template&nbsp;class&nbsp;(i.e.&nbsp;TemplateV2)</tt></dd></dl>

<dl><dt><a name="ATG-log"><strong>log</strong></a>(self, text)</dt><dd><tt>Print&nbsp;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&nbsp;generated&nbsp;files&nbsp;to&nbsp;the&nbsp;given&nbsp;directory.</tt></dd></dl>

</td></tr></table></td></tr></table>
</body></html>

+ 0
- 70
docs/atr.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>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<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&nbsp;Text&nbsp;Replacer&nbsp;module&nbsp;for&nbsp;a&nbsp;KaiSD&nbsp;Text&nbsp;Tools.<br>
&nbsp;<br>
(c)&nbsp;2013&nbsp;Ivan&nbsp;"Kai&nbsp;SD"&nbsp;Korystin&nbsp;<br>
&nbsp;<br>
License:&nbsp;GPLv3</tt></p>
<p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#aa55cc">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</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>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</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>&nbsp;<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>&nbsp;&nbsp;&nbsp;</tt></td>
<td colspan=2><tt>Advanced&nbsp;Text&nbsp;Replacer&nbsp;-&nbsp;is&nbsp;a&nbsp;class,&nbsp;created&nbsp;to&nbsp;make&nbsp;multiple&nbsp;replacements<br>
in&nbsp;the&nbsp;content&nbsp;or&nbsp;names&nbsp;of&nbsp;text&nbsp;file.<br>
It&nbsp;can&nbsp;make&nbsp;plain&nbsp;replacements,&nbsp;or&nbsp;use&nbsp;ATG&nbsp;templates&nbsp;to&nbsp;do&nbsp;something&nbsp;more&nbsp;complex.<br>&nbsp;</tt></td></tr>
<tr><td>&nbsp;</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&nbsp;all&nbsp;replacements.</tt></dd></dl>

<dl><dt><a name="ATR-log"><strong>log</strong></a>(self, string)</dt><dd><tt>Print&nbsp;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&nbsp;the&nbsp;given&nbsp;pattern&nbsp;with&nbsp;string&nbsp;in&nbsp;files.</tt></dd></dl>

<dl><dt><a name="ATR-replace_in_names"><strong>replace_in_names</strong></a>(self)</dt><dd><tt>Do&nbsp;replacement,&nbsp;but&nbsp;in&nbsp;file&nbsp;names&nbsp;instead&nbsp;of&nbsp;file&nbsp;content.&nbsp;Returns&nbsp;the&nbsp;list&nbsp;of&nbsp;new&nbsp;file&nbsp;names,<br>
you&nbsp;can&nbsp;use&nbsp;it&nbsp;with&nbsp;writeNewFiles()&nbsp;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&nbsp;the&nbsp;given&nbsp;pattern&nbsp;with&nbsp;data&nbsp;formated&nbsp;by&nbsp;template.<br>
Valid&nbsp;values&nbsp;for&nbsp;keyFormat:<br>
filename&nbsp;-&nbsp;take&nbsp;data&nbsp;rows&nbsp;by&nbsp;filename(path&nbsp;ignored),&nbsp;key&nbsp;value&nbsp;of&nbsp;the&nbsp;data&nbsp;row&nbsp;should&nbsp;store&nbsp;the&nbsp;filename.<br>
fullname&nbsp;-&nbsp;as&nbsp;filename,&nbsp;but&nbsp;with&nbsp;path.<br>
index&nbsp;-&nbsp;take&nbsp;data&nbsp;rows&nbsp;in&nbsp;order,&nbsp;key&nbsp;value&nbsp;of&nbsp;the&nbsp;data&nbsp;row&nbsp;should&nbsp;store&nbsp;the&nbsp;index.&nbsp;Indexes&nbsp;starts&nbsp;with&nbsp;0.<br>
If&nbsp;filename&nbsp;or&nbsp;index&nbsp;cannot&nbsp;be&nbsp;found&nbsp;in&nbsp;data&nbsp;keys,&nbsp;pattern&nbsp;will&nbsp;not&nbsp;be&nbsp;replaced.</tt></dd></dl>

<dl><dt><a name="ATR-write_in_place"><strong>write_in_place</strong></a>(self)</dt><dd><tt>Do&nbsp;replacement&nbsp;and&nbsp;save&nbsp;the&nbsp;files</tt></dd></dl>

<dl><dt><a name="ATR-write_new_files"><strong>write_new_files</strong></a>(self, outfiles)</dt><dd><tt>Do&nbsp;replacement,&nbsp;but&nbsp;save&nbsp;to&nbsp;given&nbsp;files&nbsp;instead&nbsp;of&nbsp;the&nbsp;original&nbsp;ones.</tt></dd></dl>

</td></tr></table></td></tr></table>
</body></html>

+ 0
- 114
docs/data.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>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<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>&nbsp;module&nbsp;for&nbsp;a&nbsp;KaiSD&nbsp;Text&nbsp;Tools.<br>
&nbsp;<br>
(c)&nbsp;2013&nbsp;Ivan&nbsp;"Kai&nbsp;SD"&nbsp;Korystin&nbsp;<br>
&nbsp;<br>
License:&nbsp;GPLv3</tt></p>
<p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#aa55cc">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</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>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</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>&nbsp;<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>&nbsp;&nbsp;&nbsp;</tt></td>
<td colspan=2><tt>Class&nbsp;for&nbsp;reading&nbsp;CSV&nbsp;files.<br>&nbsp;</tt></td></tr>
<tr><td>&nbsp;</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>
&nbsp;<br>
filename&nbsp;-&nbsp;CSV&nbsp;table&nbsp;filename<br>
encoding&nbsp;-&nbsp;CSV&nbsp;table&nbsp;encoding<br>
delimiter&nbsp;-&nbsp;CSV&nbsp;table&nbsp;delimiter<br>
quotechar&nbsp;-&nbsp;CSV&nbsp;table&nbsp;quotechar<br>
transpose=True&nbsp;-&nbsp;transpose&nbsp;the&nbsp;table</tt></dd></dl>

<hr>
Data and other attributes defined here:<br>
<dl><dt><strong>Reader</strong> = &lt;class data.Reader&gt;</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&nbsp;a&nbsp;value&nbsp;for&nbsp;given&nbsp;key&nbsp;and&nbsp;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&nbsp;a&nbsp;value&nbsp;for&nbsp;given&nbsp;key&nbsp;and&nbsp;row.</tt></dd></dl>

<dl><dt><a name="CSVData-__str__"><strong>__str__</strong></a>(self)</dt><dd><tt>Returns&nbsp;data&nbsp;as&nbsp;string.</tt></dd></dl>

<dl><dt><a name="CSVData-add_keys"><strong>add_keys</strong></a>(self, *h)</dt><dd><tt>Adds&nbsp;new&nbsp;keys&nbsp;to&nbsp;the&nbsp;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&nbsp;some&nbsp;empty&nbsp;rows&nbsp;to&nbsp;the&nbsp;data.</tt></dd></dl>

<dl><dt><a name="CSVData-col_by_key"><strong>col_by_key</strong></a>(self, key)</dt><dd><tt>Returns&nbsp;a&nbsp;column&nbsp;by&nbsp;header's&nbsp;name</tt></dd></dl>

<dl><dt><a name="CSVData-has_key"><strong>has_key</strong></a>(self, key)</dt><dd><tt>Returns&nbsp;True&nbsp;if&nbsp;given&nbsp;key&nbsp;exists&nbsp;in&nbsp;data</tt></dd></dl>

<dl><dt><a name="CSVData-row_by_idx"><strong>row_by_idx</strong></a>(self, idx)</dt><dd><tt>Returns&nbsp;a&nbsp;row&nbsp;by&nbsp;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>&nbsp;<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>&nbsp;&nbsp;&nbsp;</tt></td>
<td colspan=2><tt>Empty&nbsp;data&nbsp;class.&nbsp;Can&nbsp;be&nbsp;used&nbsp;for&nbsp;a&nbsp;subclassing&nbsp;or&nbsp;procedural&nbsp;data&nbsp;creation.<br>&nbsp;</tt></td></tr>
<tr><td>&nbsp;</td>
<td width="100%">Methods defined here:<br>
<dl><dt><a name="Data-__getitem__"><strong>__getitem__</strong></a>(self, pair)</dt><dd><tt>Returns&nbsp;a&nbsp;value&nbsp;for&nbsp;given&nbsp;key&nbsp;and&nbsp;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&nbsp;a&nbsp;value&nbsp;for&nbsp;given&nbsp;key&nbsp;and&nbsp;row.</tt></dd></dl>

<dl><dt><a name="Data-__str__"><strong>__str__</strong></a>(self)</dt><dd><tt>Returns&nbsp;data&nbsp;as&nbsp;string.</tt></dd></dl>

<dl><dt><a name="Data-add_keys"><strong>add_keys</strong></a>(self, *h)</dt><dd><tt>Adds&nbsp;new&nbsp;keys&nbsp;to&nbsp;the&nbsp;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&nbsp;some&nbsp;empty&nbsp;rows&nbsp;to&nbsp;the&nbsp;data.</tt></dd></dl>

<dl><dt><a name="Data-col_by_key"><strong>col_by_key</strong></a>(self, key)</dt><dd><tt>Returns&nbsp;a&nbsp;column&nbsp;by&nbsp;header's&nbsp;name</tt></dd></dl>

<dl><dt><a name="Data-has_key"><strong>has_key</strong></a>(self, key)</dt><dd><tt>Returns&nbsp;True&nbsp;if&nbsp;given&nbsp;key&nbsp;exists&nbsp;in&nbsp;data</tt></dd></dl>

<dl><dt><a name="Data-row_by_idx"><strong>row_by_idx</strong></a>(self, idx)</dt><dd><tt>Returns&nbsp;a&nbsp;row&nbsp;by&nbsp;index.</tt></dd></dl>

</td></tr></table></td></tr></table>
</body></html>

+ 0
- 135
docs/template.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>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<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>&nbsp;module&nbsp;for&nbsp;a&nbsp;KaiSD&nbsp;Text&nbsp;Tools.<br>
&nbsp;<br>
(c)&nbsp;2013&nbsp;Ivan&nbsp;"Kai&nbsp;SD"&nbsp;Korystin&nbsp;<br>
&nbsp;<br>
License:&nbsp;GPLv3</tt></p>
<p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#aa55cc">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</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>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</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>&nbsp;<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>&nbsp;&nbsp;&nbsp;</tt></td>
<td colspan=2><tt>Empty&nbsp;template&nbsp;class.&nbsp;Generates&nbsp;empty&nbsp;text.<br>&nbsp;</tt></td></tr>
<tr><td>&nbsp;</td>
<td width="100%">Methods defined here:<br>
<dl><dt><a name="Template-log"><strong>log</strong></a>(self, text)</dt><dd><tt>Print&nbsp;information</tt></dd></dl>

<dl><dt><a name="Template-process"><strong>process</strong></a>(self, data)</dt><dd><tt>Replace&nbsp;this&nbsp;method&nbsp;in&nbsp;subclasses.</tt></dd></dl>

<dl><dt><a name="Template-warning"><strong>warning</strong></a>(self, text)</dt><dd><tt>Prints&nbsp;a&nbsp;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>&nbsp;<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>&nbsp;&nbsp;&nbsp;</tt></td>
<td colspan=2><tt>Class&nbsp;for&nbsp;reading&nbsp;ATGv2&nbsp;templates.<br>
&nbsp;<br>
ATGv2&nbsp;template&nbsp;file&nbsp;should&nbsp;be&nbsp;a&nbsp;plain&nbsp;text&nbsp;file,&nbsp;starting&nbsp;with&nbsp;the&nbsp;line<br>
ATGV2<br>
followed&nbsp;by&nbsp;the&nbsp;info&nbsp;line:<br>
[$KeyField$Extension$Prefix$Encoding$]<br>
where<br>
KeyField&nbsp;-&nbsp;is&nbsp;a&nbsp;name&nbsp;of&nbsp;a&nbsp;data&nbsp;column,&nbsp;that&nbsp;contains&nbsp;an&nbsp;identifier.<br>
Extension&nbsp;-&nbsp;is&nbsp;the&nbsp;desired&nbsp;extension&nbsp;for&nbsp;the&nbsp;generated&nbsp;files.<br>
Prefix&nbsp;-&nbsp;is&nbsp;the&nbsp;desired&nbsp;filename&nbsp;prefix&nbsp;for&nbsp;the&nbsp;generated&nbsp;files<br>
Encoding&nbsp;-&nbsp;is&nbsp;the&nbsp;desired&nbsp;encoding&nbsp;for&nbsp;the&nbsp;generated&nbsp;files.<br>
The&nbsp;line&nbsp;may&nbsp;also&nbsp;have&nbsp;some&nbsp;optional&nbsp;keywords&nbsp;before&nbsp;the&nbsp;closing&nbsp;bracket:<br>
oneFile$&nbsp;-&nbsp;place&nbsp;all&nbsp;generated&nbsp;text&nbsp;into&nbsp;a&nbsp;single&nbsp;file&nbsp;instead&nbsp;of<br>
generating&nbsp;a&nbsp;file&nbsp;for&nbsp;each&nbsp;table&nbsp;row.<br>
After&nbsp;the&nbsp;info&nbsp;line,&nbsp;you&nbsp;can&nbsp;put&nbsp;your&nbsp;text.<br>
You&nbsp;can&nbsp;use&nbsp;following&nbsp;commands&nbsp;to&nbsp;handle&nbsp;the&nbsp;data:<br>
*&nbsp;[$Name$],&nbsp;where&nbsp;Name&nbsp;is&nbsp;the&nbsp;column&nbsp;header,<br>
will&nbsp;be&nbsp;replaced&nbsp;with&nbsp;value&nbsp;from&nbsp;the&nbsp;current&nbsp;row.<br>
*&nbsp;[$ATGLINDEX$]&nbsp;will&nbsp;be&nbsp;replaced&nbsp;with&nbsp;the&nbsp;number&nbsp;of&nbsp;a&nbsp;current&nbsp;row.<br>
*&nbsp;[$ATGHEADER$Text$]&nbsp;and&nbsp;[$ATGFOOTER$Text$]&nbsp;will&nbsp;place&nbsp;the&nbsp;given&nbsp;text<br>
at&nbsp;the&nbsp;begining&nbsp;or&nbsp;at&nbsp;the&nbsp;end&nbsp;of&nbsp;the&nbsp;file.&nbsp;You&nbsp;can't&nbsp;use&nbsp;other<br>
commands&nbsp;in&nbsp;this&nbsp;text.<br>
*&nbsp;[$ATGLIST$Name$Text$],&nbsp;where&nbsp;Name&nbsp;is&nbsp;a&nbsp;multi-column&nbsp;header<br>
(i.e.&nbsp;'Col'&nbsp;will&nbsp;represent&nbsp;'Col1',&nbsp;'Col2',&nbsp;'Col3'&nbsp;etc)<br>
will&nbsp;repeat&nbsp;the&nbsp;given&nbsp;text&nbsp;for&nbsp;each&nbsp;non-empty&nbsp;value.<br>
You&nbsp;can&nbsp;use&nbsp;other&nbsp;commands&nbsp;in&nbsp;Text.&nbsp;Also&nbsp;[$Name$]&nbsp;inside&nbsp;the&nbsp;list<br>
will&nbsp;be&nbsp;replaced&nbsp;with&nbsp;the&nbsp;value&nbsp;for&nbsp;the&nbsp;current&nbsp;row&nbsp;and&nbsp;column.<br>
*&nbsp;[$ATGLINDEX$]&nbsp;can&nbsp;be&nbsp;used&nbsp;only&nbsp;inside&nbsp;the&nbsp;ATGLIST&nbsp;text,<br>
will&nbsp;be&nbsp;replaced&nbsp;with&nbsp;the&nbsp;current&nbsp;column&nbsp;index.<br>
*&nbsp;[$ATGLISTCUT$Name$Text$]&nbsp;-&nbsp;same&nbsp;as&nbsp;ATGLIST,&nbsp;but&nbsp;the&nbsp;last&nbsp;symbol<br>
will&nbsp;be&nbsp;removed.&nbsp;Useful&nbsp;for&nbsp;removing&nbsp;unnecessary&nbsp;newlines.<br>
*&nbsp;[$ATGIF$Name$Value$Text$]&nbsp;will&nbsp;be&nbsp;replaced&nbsp;with&nbsp;the&nbsp;given&nbsp;text<br>
only&nbsp;if&nbsp;the&nbsp;the&nbsp;given&nbsp;column's&nbsp;value&nbsp;is&nbsp;the&nbsp;same&nbsp;as&nbsp;the&nbsp;given&nbsp;one.<br>
Will&nbsp;be&nbsp;replaced&nbsp;with&nbsp;the&nbsp;empty&nbsp;text&nbsp;otherwise.&nbsp;You&nbsp;can&nbsp;use&nbsp;other<br>
commands&nbsp;in&nbsp;Text.<br>
*&nbsp;[$ATGIFNOT$Name$Value$Text$]&nbsp;-&nbsp;same&nbsp;as&nbsp;ATGIF,&nbsp;but&nbsp;the&nbsp;column's&nbsp;value<br>
should&nbsp;not&nbsp;be&nbsp;equal&nbsp;to&nbsp;the&nbsp;given&nbsp;one.<br>
*&nbsp;[$ATGGREATER$Name$Value$Text$]&nbsp;-&nbsp;same&nbsp;as&nbsp;ATGIF,&nbsp;but&nbsp;the&nbsp;value&nbsp;should<br>
be&nbsp;the&nbsp;number&nbsp;and&nbsp;it&nbsp;should&nbsp;be&nbsp;greater&nbsp;then&nbsp;the&nbsp;given&nbsp;one.<br>
*&nbsp;[$ATGGREATER$Name$Value$Text$]&nbsp;-&nbsp;same&nbsp;as&nbsp;ATGGREATER,&nbsp;but&nbsp;the&nbsp;value<br>
should&nbsp;be&nbsp;less&nbsp;then&nbsp;the&nbsp;given&nbsp;one.<br>
*&nbsp;[$ATGREPLACE$Text1$Text2$]&nbsp;-&nbsp;Will&nbsp;replace&nbsp;Text1&nbsp;with&nbsp;Text2.&nbsp;Replacements<br>
will&nbsp;be&nbsp;done&nbsp;after&nbsp;all&nbsp;other&nbsp;commands.&nbsp;You&nbsp;can't&nbsp;use&nbsp;regular&nbsp;expressions&nbsp;or<br>
other&nbsp;commands&nbsp;in&nbsp;the&nbsp;text.<br>
*&nbsp;[$ATGPREFIX$Text$]&nbsp;-&nbsp;Will&nbsp;add&nbsp;the&nbsp;given&nbsp;text&nbsp;to&nbsp;the&nbsp;filename&nbsp;prefix.<br>
You&nbsp;can&nbsp;use&nbsp;other&nbsp;commands&nbsp;in&nbsp;text,&nbsp;but&nbsp;do&nbsp;it&nbsp;carefully.<br>
*&nbsp;[$ATGSKIP$]&nbsp;-&nbsp;Skip&nbsp;the&nbsp;current&nbsp;row.&nbsp;Use&nbsp;only&nbsp;in&nbsp;combination&nbsp;with&nbsp;the<br>
ATGIF/ATGIFNOT,&nbsp;or&nbsp;you&nbsp;will&nbsp;generate&nbsp;nothing.<br>
*&nbsp;[$ATGPREV$Name$],&nbsp;where&nbsp;Name&nbsp;is&nbsp;the&nbsp;column&nbsp;header,<br>
will&nbsp;be&nbsp;replaced&nbsp;with&nbsp;the&nbsp;with&nbsp;the&nbsp;value&nbsp;of&nbsp;the&nbsp;given&nbsp;header&nbsp;from&nbsp;the<br>
previous&nbsp;row.&nbsp;ATGSKIP&nbsp;will&nbsp;be&nbsp;used&nbsp;for&nbsp;the&nbsp;first&nbsp;row.<br>&nbsp;</tt></td></tr>
<tr><td>&nbsp;</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>
&nbsp;<br>
filename&nbsp;-&nbsp;name&nbsp;of&nbsp;the&nbsp;ATGv2&nbsp;template&nbsp;file.<br>
encoding&nbsp;-&nbsp;encoding&nbsp;of&nbsp;the&nbsp;template&nbsp;file.<br>
text&nbsp;-&nbsp;text&nbsp;to&nbsp;use&nbsp;if&nbsp;no&nbsp;filename&nbsp;has&nbsp;been&nbsp;provided.</tt></dd></dl>

<dl><dt><a name="TemplateV2-process"><strong>process</strong></a>(self, data)</dt><dd><tt>Generate&nbsp;text&nbsp;for&nbsp;the&nbsp;given&nbsp;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&nbsp;information</tt></dd></dl>

<dl><dt><a name="TemplateV2-warning"><strong>warning</strong></a>(self, text)</dt><dd><tt>Prints&nbsp;a&nbsp;warning</tt></dd></dl>

</td></tr></table></td></tr></table>
</body></html>

+ 1
- 3
ktt_atgcsv.py Переглянути файл

@@ -10,10 +10,8 @@ Part of KaiSD Text Tools
License: GPLv3
'''
from sys import argv
from atg import ATG
from data import CSVData
from template import TemplateV2
from os.path import split
from ktt import ATG, CSVData, TemplateV2

if __name__ == '__main__':
if len(argv) == 3:


+ 0
- 482
template.py Переглянути файл

@@ -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