Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

build.py 5.0 KiB

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