pretty print of doclists

This commit is contained in:
Rushabh Mehta 2011-06-30 17:08:24 +05:30
parent 2c79cfda57
commit 034602dfd9
6 changed files with 183 additions and 67 deletions

View file

@ -32,19 +32,23 @@ class DocList:
self.docs = expand(data)
self.objectify(docname)
def objectify(self, docname):
def objectify(self, docname=None):
"""
Converts self.docs from a list of dicts to list of Documents
"""
from webnotes.model.doc import Document
self.docs = [Document(fielddata=d) for d in self.docs]
self.children = []
for d in self.docs:
if d.name == docname:
self.doc = d
else:
self.children.append(d)
if not docname:
self.doc, self.children = self.docs[0], self.docs[1:]
else:
self.children = []
for d in self.docs:
if d.name == docname:
self.doc = d
else:
self.children.append(d)
def make_obj(self):
"""

View file

@ -167,3 +167,101 @@ def to_html(doclist):
out += _make_html(d, link_lists[d.doctype])
return out
def commonify_doclist(doclist):
"""
Makes a doclist more readable by extracting common properties.
This is used for printing Documents in files
"""
from webnotes.utils import get_common_dict, get_diff_dict
def make_common(doclist):
c = {}
if with_comments:
c['##comment'] = 'These values are common in all dictionaries'
for k in common_keys:
c[k] = doclist[0][k]
return c
def strip_common(d):
for k in common_keys:
if k in d: del d[k]
return d
def make_common_dicts(doclist):
common_dict = {} # one per doctype
# make common dicts for all records
for d in doclist:
if not d['doctype'] in common_dict:
d1 = d.copy()
del d1['name']
common_dict[d['doctype']] = d1
else:
common_dict[d['doctype']] = get_common_dict(common_dict[d['doctype']], d)
return common_dict
common_keys = ['owner','docstatus','creation','modified','modified_by']
common_dict = make_common_dicts(doclist)
# make docs
final = []
for d in doclist:
f = strip_common(get_diff_dict(common_dict[d['doctype']], d))
f['doctype'] = d['doctype'] # keep doctype!
# strip name for child records (only an auto generated number!)
if f['doctype'] != doclist[0]['doctype']:
del f['name']
if with_comments:
f['##comment'] = d['doctype'] + ('name' in f and (', ' + f['name']) or '')
final.append(f)
# add commons
commons = []
for d in common_dict.values():
d['name']='__common__'
if with_comments:
d['##comment'] = 'These values are common for all ' + d['doctype']
commons.append(strip_common(d))
common_values = make_common(doclist)
return [common_values]+commons+final
def uncommonify_doclist(dl):
"""
Expands an commonified doclist
"""
common_values = dl[0]
common_dict = {}
final = []
for d in dl[1:]:
if d['name']=='__common__':
del d['name']
common_dict[d['doctype']] = d
else:
d1 = common_values.copy()
d1.update(common_dict[d['doctype']])
d1.update(d)
final.append(d1)
return final
def pprint_doclist(doclist, with_comments = 1):
"""
Pretty Prints a doclist with common keys separated and comments
"""
from webnotes.utils import pprint_dict
dictlist =[pprint_dict(d) for d in commonify_doclist(doclist, with_comments)]
title = '# '+doclist[0]['doctype']+', '+doclist[0]['name']
return title + '\n[\n' + ',\n'.join(dictlist) + '\n]'
def peval_doclist(txt):
"""
Restore a pretty printed doclist
"""
return uncommonify_doclist(eval(txt))

View file

@ -69,7 +69,7 @@ def write_document_file(doclist, record_module=None):
Write a doclist to file, can optionally specify module name
"""
import os
from webnotes.utils import pprint_dict
from webnotes.utils import pprint_doclist
module = get_module_name(doclist, record_module)
@ -84,10 +84,11 @@ def write_document_file(doclist, record_module=None):
# write the data file
fname = (code_type and scrub(doclist[0]['name'])) or doclist[0]['name']
dict_list = [pprint_dict(d) for d in doclist]
txtfile = open(os.path.join(folder, fname +'.txt'),'w+')
txtfile.write('[\n' + ',\n'.join(dict_list) + '\n]')
txtfile = open(os.path.join(folder, fname +'.txt'),'w+')
txtfile.write(pprint_doclist(doclist))
#dict_list = [pprint_dict(d) for d in doclist]
#txtfile.write('[\n' + ',\n'.join(dict_list) + '\n]')
txtfile.close()
def clear_code_fields(doclist, folder, code_type):

View file

@ -37,12 +37,14 @@ def import_module(module, verbose=0):
def get_doclist(path, doctype, docname):
"returns a doclist (list of dictionaries) of multiple records for the given parameters"
import os
from webnotes.utils import peval_doclist
do_not_import = ('control_panel')
fname = os.path.join(path,doctype,docname,docname+'.txt')
if os.path.exists(fname) and (doctype not in do_not_import):
f = open(fname,'r')
dl = eval(f.read())
dl = peval_doclist(f.read())
f.close()
return dl
else:

View file

@ -532,78 +532,89 @@ def send_error_report():
''' % (m, form.getvalue('msg') or '', form.getvalue('err_msg'))
sendmail([webnotes.conn.get_value('Control Panel',None,'support_email_id') or 'support@iwebnotes.com'], sender=webnotes.session['user'], msg=err_msg, subject='Error Report '+m)
# pretty print a dict
# Dictionary utils
# ==============================================================================
def remove_blanks(d):
"""
Returns d with empty ('' or None) values stripped
"""
empty_keys = []
for key in d:
if d[key]=='' or d[key]==None:
# del d[key] raises runtime exception, using a workaround
empty_keys.append(key)
for key in empty_keys:
del d[key]
return d
def pprint_dict(d, level=1, no_blanks=True):
"""
Pretty print a dictionary with indents
"""
if no_blanks:
empty_keys = []
for key in d:
if d[key]=='' or d[key]==None:
# del d[key] raises runtime exception, using a workaround
empty_keys.append(key)
for key in empty_keys:
del d[key]
indent = ''
for i in range(0,level):
indent += '\t'
lines = []
remove_blanks(d)
# make indent
indent, ret = '', ''
for i in range(0,level): indent += '\t'
# add lines
comment, lines = '', []
kl = d.keys()
kl.sort()
# make lines
for key in kl:
tmp = {key: d[key]}
lines.append(indent + str(tmp)[1:-1] )
return indent + '{\n' \
+ indent + ',\n\t'.join(lines) \
+ '\n' + indent + '}'
if key != '##comment':
tmp = {key: d[key]}
lines.append(indent + str(tmp)[1:-1] )
# add comment string
if '##comment' in kl:
ret = ('\n' + indent) + '# ' + d['##comment'] + '\n'
# open
ret += indent + '{\n'
# lines
ret += indent + ',\n\t'.join(lines)
# close
ret += '\n' + indent + '}'
return ret
def get_common(d1,d2):
"""
returns (list of keys) the common part of two dicts
"""
return [p for p in d1 if p in d2 and d1[p]==d2[p]]
def min_lod(listt):
def get_common_dict(d1, d2):
"""
minimized a list of dictionaries using '_from_prev'
return common dictionary of d1 and d2
"""
import copy
l = copy.deepcopy(listt)
prev = {}
for dic in l:
common = get_common(prev,dic)
prev = dic
for i in common : del dic[i]
if not common==[] : dic['_from_prev']= ','.join(str(p) for p in common)
return l
ret = {}
for key in d1:
if key in d2 and d2[key]==d1[key]:
ret[key] = d1[key]
return ret
def max_lod(listt):
def get_diff_dict(d1, d2):
"""
maximizes a list of dictionaries using '_from_prev'
return common dictionary of d1 and d2
"""
import copy
l = copy.deepcopy(listt)
prev = {}
for dic in l:
if '_from_prev' in dic:
prevs = dic['_from_prev'].split(',')
for p in prevs : dic[p] = prev[p]
del dic['_from_prev']
prev = dic
return l
diff_keys = set(d2.keys()).difference(set(d1.keys()))
ret = {}
for d in diff_keys: ret[d] = d2[d]
return ret
def pprint_lod(l, level=1, no_blanks=True):
"""
returns pretty print string for list of dictionaries
"""
l = min_lod(l)
dictlist = [pprint_dict(d) for d in l]
return '[\n' + ',\n'.join(dictlist) + '\n]'
def peval_lod(string):
"""
pretty eval a pretty printed list of dictionaries (using )
"""
strdict = eval(string)
strdict = max_lod(strdict)
return strdict

View file

@ -195,7 +195,7 @@ def runserverobj():
else:
doclist = DocList()
doclist.from_compressed(form.getvalue('docs'), form.getvalue('docname'))
doclist.from_compressed(form.getvalue('docs'), dn)
so = doclist.make_obj()
check_guest_access(so.doc)