You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

utils.py 5.0 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. # Copyright (c) 2012 Web Notes Technologies Pvt Ltd (http://erpnext.com)
  2. #
  3. # MIT License (MIT)
  4. #
  5. # Permission is hereby granted, free of charge, to any person obtaining a
  6. # copy of this software and associated documentation files (the "Software"),
  7. # to deal in the Software without restriction, including without limitation
  8. # the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9. # and/or sell copies of the Software, and to permit persons to whom the
  10. # Software is furnished to do so, subject to the following conditions:
  11. #
  12. # The above copyright notice and this permission notice shall be included in
  13. # all copies or substantial portions of the Software.
  14. #
  15. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  16. # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  17. # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  18. # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
  19. # CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
  20. # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  21. #
  22. from __future__ import unicode_literals
  23. def listfolders(path, only_name=0):
  24. """
  25. Returns the list of folders (with paths) in the given path,
  26. If only_name is set, it returns only the folder names
  27. """
  28. import os
  29. out = []
  30. for each in os.listdir(path):
  31. dirname = each.split(os.path.sep)[-1]
  32. fullpath = os.path.join(path, dirname)
  33. if os.path.isdir(fullpath) and not dirname.startswith('.'):
  34. out.append(only_name and dirname or fullname)
  35. return out
  36. def switch_module(dt, dn, to, frm=None, export=None):
  37. """
  38. Change the module of the given doctype, if export is true, then also export txt and copy
  39. code files from src
  40. """
  41. import os
  42. webnotes.conn.sql("update `tab"+dt+"` set module=%s where name=%s", (to, dn))
  43. if export:
  44. export_doc(dt, dn)
  45. # copy code files
  46. if dt in ('DocType', 'Page', 'Search Criteria', 'Report'):
  47. from_path = os.path.join(get_module_path(frm), scrub(dt), scrub(dn), scrub(dn))
  48. to_path = os.path.join(get_module_path(to), scrub(dt), scrub(dn), scrub(dn))
  49. # make dire if exists
  50. os.system('mkdir -p %s' % os.path.join(get_module_path(to), scrub(dt), scrub(dn)))
  51. for ext in ('py','js','html','css'):
  52. os.system('cp %s %s')
  53. def commonify_doclist(doclist, with_comments=1):
  54. """
  55. Makes a doclist more readable by extracting common properties.
  56. This is used for printing Documents in files
  57. """
  58. from webnotes.utils import get_common_dict, get_diff_dict
  59. def make_common(doclist):
  60. c = {}
  61. if with_comments:
  62. c['##comment'] = 'These values are common in all dictionaries'
  63. for k in common_keys:
  64. c[k] = doclist[0][k]
  65. return c
  66. def strip_common_and_idx(d):
  67. for k in common_keys:
  68. if k in d: del d[k]
  69. if 'idx' in d: del d['idx']
  70. return d
  71. def make_common_dicts(doclist):
  72. common_dict = {} # one per doctype
  73. # make common dicts for all records
  74. for d in doclist:
  75. if not d['doctype'] in common_dict:
  76. d1 = d.copy()
  77. del d1['name']
  78. common_dict[d['doctype']] = d1
  79. else:
  80. common_dict[d['doctype']] = get_common_dict(common_dict[d['doctype']], d)
  81. return common_dict
  82. common_keys = ['owner','docstatus','creation','modified','modified_by']
  83. common_dict = make_common_dicts(doclist)
  84. # make docs
  85. final = []
  86. for d in doclist:
  87. f = strip_common_and_idx(get_diff_dict(common_dict[d['doctype']], d))
  88. f['doctype'] = d['doctype'] # keep doctype!
  89. # strip name for child records (only an auto generated number!)
  90. if f['doctype'] != doclist[0]['doctype']:
  91. del f['name']
  92. if with_comments:
  93. f['##comment'] = d['doctype'] + ('name' in f and (', ' + f['name']) or '')
  94. final.append(f)
  95. # add commons
  96. commons = []
  97. for d in common_dict.values():
  98. d['name']='__common__'
  99. if with_comments:
  100. d['##comment'] = 'These values are common for all ' + d['doctype']
  101. commons.append(strip_common_and_idx(d))
  102. common_values = make_common(doclist)
  103. return [common_values]+commons+final
  104. def uncommonify_doclist(dl):
  105. """
  106. Expands an commonified doclist
  107. """
  108. # first one has common values
  109. common_values = dl[0]
  110. common_dict = {}
  111. final = []
  112. idx_dict = {}
  113. for d in dl[1:]:
  114. if 'name' in d and d['name']=='__common__':
  115. # common for a doctype -
  116. del d['name']
  117. common_dict[d['doctype']] = d
  118. else:
  119. dt = d['doctype']
  120. if not dt in idx_dict: idx_dict[dt] = 1;
  121. d1 = common_values.copy()
  122. # update from common and global
  123. d1.update(common_dict[dt])
  124. d1.update(d)
  125. # idx by sequence
  126. d1['idx'] = idx_dict[dt]
  127. # increment idx
  128. idx_dict[dt] += 1
  129. final.append(d1)
  130. return final
  131. def pprint_doclist(doclist, with_comments = 1):
  132. """
  133. Pretty Prints a doclist with common keys separated and comments
  134. """
  135. from json import dumps
  136. return dumps(commonify_doclist(doclist, False), indent=1)
  137. def peval_doclist(txt):
  138. """
  139. Restore a pretty printed doclist
  140. """
  141. from json import loads
  142. if txt.startswith("#"):
  143. return uncommonify_doclist(eval(txt))
  144. else:
  145. return uncommonify_doclist(loads(txt))