Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 
 
 
 

226 řádky
6.0 KiB

  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. from webnotes.utils.minify import JavascriptMinify
  24. """
  25. Build the `public` folders and setup languages
  26. """
  27. import os, sys, webnotes
  28. def bundle(no_compress, cms_make=True):
  29. """concat / minify js files"""
  30. # build js files
  31. check_public()
  32. check_lang()
  33. bundle = Bundle()
  34. bundle.no_compress = no_compress
  35. bundle.make()
  36. if cms_make:
  37. # build index.html and app.html
  38. from website.helpers.make_web_include_files import make
  39. make()
  40. def watch(no_compress):
  41. """watch and rebuild if necessary"""
  42. import time
  43. bundle = Bundle()
  44. bundle.no_compress = no_compress
  45. while True:
  46. if bundle.dirty():
  47. bundle.make()
  48. time.sleep(3)
  49. def check_public():
  50. from webnotes.install_lib.setup_public_folder import make
  51. make()
  52. def check_lang():
  53. from webnotes.translate import update_translations
  54. update_translations()
  55. class Bundle:
  56. """
  57. Concatenate, compress and mix (if required) js+css files from build.json
  58. """
  59. no_compress = False
  60. timestamps = {}
  61. path = '.'
  62. def concat(self, filelist, outfile=None):
  63. """
  64. Concat css and js files into a bundle
  65. """
  66. from cStringIO import StringIO
  67. out_type = outfile and outfile.split('.')[-1] or 'js'
  68. outtxt = ''
  69. for f in filelist:
  70. suffix = None
  71. if ':' in f:
  72. f, suffix = f.split(':')
  73. if not os.path.exists(f) or os.path.isdir(f):
  74. continue
  75. self.timestamps[f] = os.path.getmtime(f)
  76. # get datas
  77. try:
  78. with open(f, 'r') as infile:
  79. # get file type
  80. ftype = f.split('.')[-1]
  81. data = unicode(infile.read(), 'utf-8', errors='ignore')
  82. outtxt += ('\n/*\n *\t%s\n */' % f)
  83. # append
  84. if suffix=='concat' or out_type != 'js' or self.no_compress or ('.min.' in f):
  85. outtxt += '\n' + data + '\n'
  86. else:
  87. jsm = JavascriptMinify()
  88. tmpin = StringIO(data.encode('utf-8'))
  89. tmpout = StringIO()
  90. jsm.minify(tmpin, tmpout)
  91. tmpmin = unicode(tmpout.getvalue() or '', 'utf-8')
  92. tmpmin.strip('\n')
  93. outtxt += tmpmin
  94. except Exception, e:
  95. print "--Error in:" + f + "--"
  96. print webnotes.getTraceback()
  97. with open(outfile, 'w') as f:
  98. f.write(outtxt.encode("utf-8"))
  99. print "Wrote %s - %sk" % (outfile, str(int(os.path.getsize(outfile)/1024)))
  100. def dirty(self):
  101. """check if build files are dirty"""
  102. self.make_build_data()
  103. for builddict in self.bdata:
  104. for f in self.get_infiles(builddict):
  105. if ':' in f:
  106. f, suffix = f.split(':')
  107. if not os.path.exists(f) or os.path.isdir(f):
  108. continue
  109. if os.path.getmtime(f) != self.timestamps.get(f):
  110. print f + ' dirty'
  111. return True
  112. else:
  113. return False
  114. def make(self):
  115. """Build (stitch + compress) the file defined in build.json"""
  116. print "Building js and css files..."
  117. self.make_build_data()
  118. for builddict in self.bdata:
  119. outfile = builddict.keys()[0]
  120. infiles = self.get_infiles(builddict)
  121. self.concat(infiles, os.path.relpath(os.path.join(self.path, outfile), os.curdir))
  122. self.reset_app_html()
  123. def reset_app_html(self):
  124. import webnotes
  125. if os.path.exists("public/app.html"):
  126. os.remove("public/app.html")
  127. splash = ""
  128. if os.path.exists("public/app/images/splash.svg"):
  129. with open("public/app/images/splash.svg") as splash_file:
  130. splash = splash_file.read()
  131. with open('lib/public/html/app.html', 'r') as app_html:
  132. data = app_html.read()
  133. data = data % {
  134. "_version_number": webnotes.generate_hash(),
  135. "splash": splash
  136. }
  137. with open('public/app.html', 'w') as new_app_html:
  138. new_app_html.write(data)
  139. def get_infiles(self, builddict):
  140. """make list of files to merge"""
  141. outfile = builddict.keys()[0]
  142. infiles = builddict[outfile]
  143. # add app js and css to the list
  144. if outfile in self.appfiles:
  145. for f in self.appfiles[outfile]:
  146. if f not in infiles:
  147. infiles.append(f)
  148. fl = []
  149. for f in infiles:
  150. ## load files from directory
  151. if f.endswith('/'):
  152. # add init js first
  153. fl += [os.path.relpath(os.path.join(f, 'init.js'), os.curdir)]
  154. # files other than init.js and beginning with "_"
  155. fl += [os.path.relpath(os.path.join(f, tmp), os.curdir) \
  156. for tmp in os.listdir(f) if (tmp != 'init.js' and not tmp.startswith('_'))]
  157. else:
  158. fl.append(os.path.relpath(os.path.join(self.path, f), os.curdir))
  159. return fl
  160. def make_build_data(self):
  161. """merge build.json and lib/build.json"""
  162. # framework js and css files
  163. with open('lib/public/build.json', 'r') as bfile:
  164. bdata = eval(bfile.read())
  165. # app js and css files
  166. if os.path.exists('app/public/build.json'):
  167. with open('app/public/build.json', 'r') as bfile:
  168. appfiles = eval(bfile.read())
  169. else:
  170. appfiles = {}
  171. # add additional app files in bdata
  172. buildfile_list = [builddict.keys()[0] for builddict in bdata]
  173. for f in appfiles:
  174. if f not in buildfile_list:
  175. bdata.append({f: appfiles[f]})
  176. self.appfiles = appfiles
  177. self.bdata = bdata