def chain_modules_js(files): # we could create a lock for each hash instead of a global lock here # but the savings of potentially generating/checking different module groups concurrently # probably isn't worth managing a dictionary of locks with _chain_modules_js_lock: logger.debug('Chaining and minifying modules JS') try: locale = lib.i18n.current_lang(True) modules = libmodule.moduleMapper.getInstalledModules() hash = generate_file_list_hash(files) cache_filename = make_absolute(os.path.join(lib.i18n.CACHE_PATH, '%s-%s-%s.cache' % (MODULE_JS_FILE_PREFIX, hash, locale))) if os.path.exists(cache_filename) and os.path.getsize(cache_filename) != 0: cache_mtime = os.path.getmtime(cache_filename) # check if root directory was modified (app installed, etc., where indiv. timestamps may be well in the past) if cache_mtime < os.path.getmtime(os.path.join(MRSPARKLE, 'modules')) or cache_mtime < os.path.getmtime(make_absolute(os.path.join('etc', 'apps'))): os.unlink(cache_filename) else: # check individual files, so if they've been touched we'll poison the cache for input_filename in files: parts = os.path.normpath(input_filename.strip('/')).replace(os.path.sep, '/').split('/') if len(parts) == 2: input_path = os.path.join(MRSPARKLE, *parts) else: module_path = local_apps.getModulePath(parts[1]) input_path = os.path.join(module_path, *parts[2:]) if cache_mtime < os.path.getmtime(input_path): os.unlink(cache_filename) break if os.path.exists(cache_filename) and os.path.getsize(cache_filename) != 0: return cache_filename output_fh = file(cache_filename, 'wb') # many duplicate JS translation blocks blocks = [] js = '' wrap_try_catch = splunk.util.normalizeBoolean(cherrypy.config.get('trap_module_exceptions', True)) for input_filename in files: parts = os.path.normpath(input_filename.strip('/')).replace(os.path.sep, '/').split('/') if len(parts) == 2: input_path = os.path.join(MRSPARKLE, *parts) # since we don't have the module name from something like /modules/AbstractModule.js, try # to figure it out from the module list for key in modules: if modules[key]['js'].endswith(os.path.join(*parts)): moduleName = key break else: module_path = local_apps.getModulePath(parts[1]) input_path = os.path.join(module_path, *parts[2:]) for key in modules: if modules[key]['js'].endswith(os.path.join(*parts)): moduleName = key break block = lib.i18n.generate_wrapped_js(input_path, locale) if block: if block not in blocks: blocks.append(block) if wrap_try_catch: js += 'try{' + block else: js += block input_temp_fh = file(input_path, 'r') js += input_temp_fh.read() + ';' input_temp_fh.close() if wrap_try_catch: js += '}catch(e){var err="The module \'%s\' in the \'%s\' app has thrown an unexpected error and may not function properly. Contact the app author or disable the app to remove this message. ";if(window.console){window.console.log(err);}$(function(){Splunk.Messenger.System.getInstance().send("error","%s",err);});}' % (moduleName, modules[moduleName]['appName'], moduleName) minifier = Popen([PATH_TO_JSMIN], stdin = subprocess.PIPE, stderr = subprocess.STDOUT, stdout = subprocess.PIPE, close_fds = True) (data, err) = minifier.communicate(js) if minifier.returncode != 0: logger.error('While minifying modules JavaScript, jsmin (pid %d) returned code %d' % (minifier.pid, minifier.returncode)) logger.error('Disabling minification of JavaScript and CSS') cherrypy.config['minify_js'] = False cherrypy.config['minify_css'] = False else: output_fh.write(data) output_fh.close() return cache_filename except IOError: logger.error('While minifying modules JavaScript, the following exception was thrown: %s Stack: %s' % (traceback.format_exc(), traceback.format_stack())) logger.error('Disabling minification of JavaScript and CSS') cherrypy.config['minify_js'] = False cherrypy.config['minify_css'] = False try: if os.path.exists(cache_filename): os.unlink(cache_filename) except: pass finally: try: input_temp_fh.close() except: pass try: output_fh.close() except: pass
def chain_modules_js(files): # we could create a lock for each hash instead of a global lock here # but the savings of potentially generating/checking different module groups concurrently # probably isn't worth managing a dictionary of locks with _chain_modules_js_lock: logger.debug('Chaining and minifying modules JS') try: locale = lib.i18n.current_lang(True) modules = libmodule.moduleMapper.getInstalledModules() hash = generate_file_list_hash(files) cache_filename = make_absolute( os.path.join( lib.i18n.CACHE_PATH, '%s-%s-%s.cache' % (MODULE_JS_FILE_PREFIX, hash, locale))) if os.path.exists( cache_filename) and os.path.getsize(cache_filename) != 0: cache_mtime = os.path.getmtime(cache_filename) # check if root directory was modified (app installed, etc., where indiv. timestamps may be well in the past) if cache_mtime < os.path.getmtime( os.path.join( MRSPARKLE, 'modules')) or cache_mtime < os.path.getmtime( make_absolute(os.path.join('etc', 'apps'))): os.unlink(cache_filename) else: # check individual files, so if they've been touched we'll poison the cache for input_filename in files: parts = os.path.normpath( input_filename.strip('/')).replace( os.path.sep, '/').split('/') if len(parts) == 2: input_path = os.path.join(MRSPARKLE, *parts) else: module_path = local_apps.getModulePath(parts[1]) input_path = os.path.join(module_path, *parts[2:]) if cache_mtime < os.path.getmtime(input_path): os.unlink(cache_filename) break if os.path.exists(cache_filename ) and os.path.getsize(cache_filename) != 0: return cache_filename output_fh = file(cache_filename, 'wb') # many duplicate JS translation blocks blocks = [] js = '' wrap_try_catch = splunk.util.normalizeBoolean( cherrypy.config.get('trap_module_exceptions', True)) for input_filename in files: parts = os.path.normpath(input_filename.strip('/')).replace( os.path.sep, '/').split('/') if len(parts) == 2: input_path = os.path.join(MRSPARKLE, *parts) # since we don't have the module name from something like /modules/AbstractModule.js, try # to figure it out from the module list for key in modules: if modules[key]['js'].endswith(os.path.join(*parts)): moduleName = key break else: module_path = local_apps.getModulePath(parts[1]) input_path = os.path.join(module_path, *parts[2:]) for key in modules: if modules[key]['js'].endswith(os.path.join(*parts)): moduleName = key break block = lib.i18n.generate_wrapped_js(input_path, locale) if block: if block not in blocks: blocks.append(block) if wrap_try_catch: js += 'try{' + block else: js += block input_temp_fh = file(input_path, 'r') js += input_temp_fh.read() + ';' input_temp_fh.close() if wrap_try_catch: js += '}catch(e){var err="The module \'%s\' in the \'%s\' app has thrown an unexpected error and may not function properly. Contact the app author or disable the app to remove this message. ";if(window.console){window.console.log(err);}$(function(){Splunk.Messenger.System.getInstance().send("error","%s",err);});}' % ( moduleName, modules[moduleName]['appName'], moduleName) minifier = Popen([PATH_TO_JSMIN], stdin=subprocess.PIPE, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, close_fds=True) (data, err) = minifier.communicate(js) if minifier.returncode != 0: logger.error( 'While minifying modules JavaScript, jsmin (pid %d) returned code %d' % (minifier.pid, minifier.returncode)) logger.error('Disabling minification of JavaScript and CSS') cherrypy.config['minify_js'] = False cherrypy.config['minify_css'] = False else: output_fh.write(data) output_fh.close() return cache_filename except IOError: logger.error( 'While minifying modules JavaScript, the following exception was thrown: %s Stack: %s' % (traceback.format_exc(), traceback.format_stack())) logger.error('Disabling minification of JavaScript and CSS') cherrypy.config['minify_js'] = False cherrypy.config['minify_css'] = False try: if os.path.exists(cache_filename): os.unlink(cache_filename) except: pass finally: try: input_temp_fh.close() except: pass try: output_fh.close() except: pass
def chain_common_js(): ''' Add translations to the common JS in share/splunk/search_mrsparkle/exposed/js, EXCLUDING anything in contrib/, which does not need translations ''' with _chain_common_js_lock: logger.debug('Chaining and minifying common JS') try: locale = cherrypy.request.lang # defaults to en_US, handy for precaching in root.py js_root = os.path.join(MRSPARKLE, 'exposed', 'js') cache_filename = make_absolute(os.path.join(lib.i18n.CACHE_PATH, '%s-%s-%s.cache' % ('common.min.js', hashlib.md5('common.min.js').hexdigest(), locale))) js_filenames = startup.generateJSManifest(True) if os.path.exists(cache_filename) and os.path.getsize(cache_filename) != 0: cache_mtime = os.path.getmtime(cache_filename) # if any .js files were touched, one of js_root or js_root/contrib will have the bumped timestamp if cache_mtime < os.path.getmtime(js_root) or cache_mtime < os.path.getmtime(js_root + os.sep + 'contrib'): os.unlink(cache_filename) elif cache_mtime < os.path.getmtime(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'startup.py')): os.unlink(cache_filename) else: return cache_filename output_fh = file(cache_filename, 'wb') # many duplicate JS translation snippets blocks = [] js = '' for js_filename in js_filenames: if js_filename == 'i18n.js': path = lib.i18n.dispatch_i18n_js(os.path.join(js_root, 'i18n.js')) input_temp_fh = file(path, 'rb') js += input_temp_fh.read() input_temp_fh.close() else: path = os.path.join(js_root, js_filename) if os.sep + 'contrib' + os.sep not in path: block = lib.i18n.generate_wrapped_js(path, locale) if block and block not in blocks: blocks.append(block) js += block input_temp_fh = file(path, 'r') js += input_temp_fh.read() + ';' input_temp_fh.close() minifier = Popen([PATH_TO_JSMIN], stdin = subprocess.PIPE, stderr = subprocess.STDOUT, stdout = subprocess.PIPE, close_fds = True) (data, err) = minifier.communicate(js) if minifier.returncode != 0: logger.error('While minifying common JavaScript, jsmin (pid %d) returned code %d' % (minifier.pid, minifier.returncode)) logger.error('Disabling minification of JavaScript and CSS') cherrypy.config['minify_js'] = False cherrypy.config['minify_css'] = False else: output_fh.write(data) output_fh.close() return cache_filename except IOError: logger.error('While minifying common JavaScript, the following exception was thrown: %s Stack: %s' % (traceback.format_exc(), traceback.format_stack())) logger.error('Disabling minification of JavaScript and CSS') cherrypy.config['minify_js'] = False cherrypy.config['minify_css'] = False try: if os.path.exists(cache_filename): os.unlink(cache_filename) except: pass finally: try: input_temp_fh.close() except: pass try: output_fh.close() except: pass
def chain_common_js(): ''' Add translations to the common JS in share/splunk/search_mrsparkle/exposed/js, EXCLUDING anything in contrib/, which does not need translations ''' with _chain_common_js_lock: logger.debug('Chaining and minifying common JS') try: locale = cherrypy.request.lang # defaults to en_US, handy for precaching in root.py js_root = os.path.join(MRSPARKLE, 'exposed', 'js') cache_filename = make_absolute( os.path.join( lib.i18n.CACHE_PATH, '%s-%s-%s.cache' % ('common.min.js', hashlib.md5('common.min.js').hexdigest(), locale))) js_filenames = startup.generateJSManifest(True) if os.path.exists( cache_filename) and os.path.getsize(cache_filename) != 0: cache_mtime = os.path.getmtime(cache_filename) # if any .js files were touched, one of js_root or js_root/contrib will have the bumped timestamp if cache_mtime < os.path.getmtime( js_root) or cache_mtime < os.path.getmtime(js_root + os.sep + 'contrib'): os.unlink(cache_filename) elif cache_mtime < os.path.getmtime( os.path.join( os.path.dirname(os.path.abspath(__file__)), 'startup.py')): os.unlink(cache_filename) else: return cache_filename output_fh = file(cache_filename, 'wb') # many duplicate JS translation snippets blocks = [] js = '' for js_filename in js_filenames: if js_filename == 'i18n.js': path = lib.i18n.dispatch_i18n_js( os.path.join(js_root, 'i18n.js')) input_temp_fh = file(path, 'rb') js += input_temp_fh.read() input_temp_fh.close() else: path = os.path.join(js_root, js_filename) if os.sep + 'contrib' + os.sep not in path: block = lib.i18n.generate_wrapped_js(path, locale) if block and block not in blocks: blocks.append(block) js += block input_temp_fh = file(path, 'r') js += input_temp_fh.read() + ';' input_temp_fh.close() minifier = Popen([PATH_TO_JSMIN], stdin=subprocess.PIPE, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, close_fds=True) (data, err) = minifier.communicate(js) if minifier.returncode != 0: logger.error( 'While minifying common JavaScript, jsmin (pid %d) returned code %d' % (minifier.pid, minifier.returncode)) logger.error('Disabling minification of JavaScript and CSS') cherrypy.config['minify_js'] = False cherrypy.config['minify_css'] = False else: output_fh.write(data) output_fh.close() return cache_filename except IOError: logger.error( 'While minifying common JavaScript, the following exception was thrown: %s Stack: %s' % (traceback.format_exc(), traceback.format_stack())) logger.error('Disabling minification of JavaScript and CSS') cherrypy.config['minify_js'] = False cherrypy.config['minify_css'] = False try: if os.path.exists(cache_filename): os.unlink(cache_filename) except: pass finally: try: input_temp_fh.close() except: pass try: output_fh.close() except: pass