pretty print of doclists
This commit is contained in:
parent
2c79cfda57
commit
034602dfd9
6 changed files with 183 additions and 67 deletions
|
|
@ -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):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue