Diffstat (limited to 'scripts/builder/frontendBuilder.py') (more/less context) (ignore whitespace changes)
-rw-r--r-- | scripts/builder/frontendBuilder.py | 73 |
1 files changed, 17 insertions, 56 deletions
diff --git a/scripts/builder/frontendBuilder.py b/scripts/builder/frontendBuilder.py index e52c31e..b72179f 100644 --- a/scripts/builder/frontendBuilder.py +++ b/scripts/builder/frontendBuilder.py @@ -1,146 +1,150 @@ #!/usr/bin/env python # -*- coding: UTF-8 -*- import sys, os, re import cssmin import jsmin import codecs import shutil import StringIO import urllib import main #=============================================================================== class FrontendBuilder(object): def __init__ (self, frontend, settings, repositoryVersion): if '.' in frontend: moduleComponents = frontend.split('.') self.module = moduleComponents[0] self.submodule = moduleComponents[1] else: self.module = frontend self.submodule = frontend self.settings = settings self.projectDir = main.projectBaseDir() # self.repository = repository.repositoryWithPath(self.projectDir) self.repositoryVersion = repositoryVersion self.processedFiles = {} #--------------------------------------------------------------------------- def name (self): raise NotImplementedError() + def projectResourceTypes (self): + raise NotImplementedError() def copyStaticResources (self, targetFolder): raise NotImplementedError() #--------------------------------------------------------------------------- def log (self, message): module = self.module if (self.module != self.submodule): module = module + "." + self.submodule print "frontend [" + module + "]: " + message def absolutePathForSources (self): return os.path.join(self.projectDir, 'frontend', self.module) def absolutePathForSourceFile (self, basePath, file): return os.path.join(self.absolutePathForSources(), basePath, file) def absolutePathForTargetFile (self, folder, basePath, file): return os.path.join(folder, self.module, basePath, file) def filterFiles (self, files): result = [] for file in files: if file.startswith('--'): pass else: result.append(file) return result def copyResources (self, sourceFolder, destinationFolder, fileType): if fileType in self.settings: for file in self.filterFiles(self.settings[fileType]): src = self.absolutePathForSourceFile(fileType, file) dst = self.absolutePathForTargetFile(destinationFolder, fileType, file) main.createFolder(os.path.dirname(dst)) shutil.copy2(src, dst) else: srcFolder = os.path.join(self.absolutePathForSources(), fileType) dstFolder = os.path.join(destinationFolder, self.module, fileType) if not(os.path.exists(dstFolder)): shutil.copytree(srcFolder, dstFolder) # try: # shutil.copytree(srcFolder, dstFolder) # except: # pass def copyResourcesToFolder (self, targetFolder): - self.copyResources(self.projectDir, targetFolder, 'css') - self.copyResources(self.projectDir, targetFolder, 'js') - self.copyResources(self.projectDir, targetFolder, 'images') +# self.copyResources(self.projectDir, targetFolder, 'css') +# self.copyResources(self.projectDir, targetFolder, 'js') +# self.copyResources(self.projectDir, targetFolder, 'images') + for resoureceType in self.projectResourceTypes(): + self.copyResources(self.projectDir, targetFolder, resoureceType) self.copyStaticResources(targetFolder) def loadFilesContent (self, basePath, files): result = "" for file in self.filterFiles(files): try: fileHandler = codecs.open(self.absolutePathForSourceFile(basePath, file), 'r', 'utf-8') except: print "FILE: " + file result += fileHandler.read() + '\n' fileHandler.close() return result def template (self): processedFile = 'html_template' if not self.processedFiles.has_key(processedFile): # self.processedFiles[processedFile] = self.loadFilesContent('html', ['index_template.html']) self.processedFiles[processedFile] = self.loadFilesContent('html', [self.settings['html.template']]) return self.processedFiles[processedFile] def cssminCompressor (self, css): # package found here: # - http://stackoverflow.com/questions/222581/python-script-for-minifying-css/2396777#2396777 # actual downloaded version: http://pypi.python.org/pypi/cssmin/0.1.4 return cssmin.cssmin(css) def regexCssCompressor (self, css): # http://stackoverflow.com/questions/222581/python-script-for-minifying-css/223689#223689 # remove comments - this will break a lot of hacks :-P css = re.sub( r'\s*/\*\s*\*/', "$$HACK1$$", css ) # preserve IE<6 comment hack css = re.sub( r'/\*[\s\S]*?\*/', "", css ) css = css.replace( "$$HACK1$$", '/**/' ) # preserve IE<6 comment hack # url() doesn't need quotes css = re.sub( r'url\((["\'])([^)]*)\1\)', r'url(\2)', css ) # spaces may be safely collapsed as generated content will collapse them anyway css = re.sub( r'\s+', ' ', css ) @@ -198,223 +202,180 @@ class FrontendBuilder(object): # java -jar compiler.jar --js=in1.js --js=in2.js ... --js_output_file=out.js result = js return result def compressJS (self, js, description): return self.compressJS_jsmin(js, description) #return self.compressJS_closureCompiler(js, description) #========================================================================== def packBookmarklet (self, bookmakeletCode, version): replacers = [ ('isLoginForm', 'ilf'), ('findLoginForm', 'flf'), ('findLoginForm', 'flf'), ('formParameters', 'fp' ), ('pageParameters', 'pp' ), ('serializeJSON', 'sj' ), ('reprString', 'rs' ), ('logFormParameters', 'lfp'), ('loadClipperzBookmarklet', 'lcb'), ('loginForm', 'lf' ), ('parameters', 'p' ), ('inputElementValues', 'iev'), ] result = self.compressJS(bookmakeletCode, version + " bookmarklet") result = re.sub('\n', ' ', result) # Fit all in a single line # result = re.sub('\s+', ' ', result) # Collapse "redundant" spaces. WARNING: this could have some evil side effects on constant strings used inside to code!! # result = re.sub('\s?([,\+=\(\)\{\};])\s?', '\\1', result) for replacer in replacers: result = re.sub(replacer[0], replacer[1], result) # <!-- escaping required to handle the bookmarklet code within the javascript code --> result = re.sub('\://', '%3a%2f%2f', result) result = re.sub('/', '%2f', result) # result = re.sub('"', '%22', result) result = re.sub('"', '\\"', result) result = re.sub('\"', '%22', result) result = re.sub('\'', '%22', result) result = re.sub('\\\\', '%5c', result) result = result.strip() result = 'javascript:' + result - -# replacers = [ -# ('aForm', '_1' ), -# ('inputFields', '_2' ), -# ('passwordFieldsFound', '_3' ), -# ('aDocument', '_6' ), -# ('aLevel', '_7' ), -# # ('result', '_8' ), -# ('documentForms', '_9' ), -# ('iFrames', '_c' ), -# ('anInputElement', '_d' ), -# ('options', '_f' ), -# ('option', '_12'), -# ('aLoginForm', '_13'), -# # ('action', '_17'), -# ('radioValues', '_18'), -# ('radioValueName', '_19'), -# ('inputElement', '_1a'), -# ('elementValues', '_1b'), -# ('radioValue', '_1c'), -# ('values', '_1d'), -# ('objtype', '_21'), -# ('useKey', '_27'), -# ('bookmarkletDiv', '_28'), -# ('someParameters', '_29'), -# ('anException', '_2a'), -# ('newDiv', '_2b'), -# ('base_url', '_2c'), -# ('help_url', '_2d'), -# ('logo_image_url', '_2e'), -# ('background_image_url','_2f'), -# ('close_image_url', '_30'), -# # ('bookmarklet_textarea','_31'), -# ('innerHTML', '_32'), -# ] -# for replacer in replacers: -# result = re.sub('([^\.])' + replacer[0], '\\1' + replacer[1], result) - -# replacers = [ -# ('headNode', '_1' ), -# ('clipperzScriptNode', '_2' ), -# ] -# for replacer in replacers: -# result = re.sub('([^\.])' + replacer[0], '\\1' + replacer[1], result) - -# result = re.sub(';', ';\n', result) return result - def bookmarklet (self): cacheKey = 'bookmarklet' if not self.processedFiles.has_key(cacheKey): result = 'bookmarklet="' + self.packBookmarklet(self.loadFilesContent('js', ['Bookmarklet.js']), "regular") + '";bookmarklet_ie="' + self.packBookmarklet(self.loadFilesContent('js', ['Bookmarklet_IE.js']), "IE") + '";' self.processedFiles[cacheKey] = result else: result = self.processedFiles[cacheKey] return result def replaceTemplatePlaceholders (self, pageTitle, copyright, css, code, jsLoadMode, version, versionType): result = self.template() result = result.replace('@page.title@', pageTitle) result = result.replace('@copyright@', copyright) result = result.replace('@css@', css) #result = result.replace('@bookmarklet@', bookmarklet) result = result.replace('@application.version@', version) result = result.replace('@application.version.type@', versionType) result = result.replace('@js_' + jsLoadMode + '@', code) result = re.sub('@js_[^@]+@', '', result) return result def assembleCopyrightHeader (self): processedFile = 'copyright' if not self.processedFiles.has_key(processedFile): #self.log("assembling copyright header") copyrightValues = self.settings['copyright.values'] license = self.loadFilesContent('../../properties', ['license.txt']) result = self.loadFilesContent('properties', ['creditsAndCopyrights.txt']) result = re.sub('@clipperz.license@', license, result) for key in copyrightValues: result = re.sub('@'+key+'@', copyrightValues[key], result) self.processedFiles[processedFile] = result return self.processedFiles[processedFile] def cssTagsForFiles (self, basePath, files): #<link rel="stylesheet" type="text/css" href="./css/reset-min.css" /> return '\n'.join(map(lambda file: '<link rel="stylesheet" type="text/css" href="' + basePath + '/' + file + '" />', files)) def cssTagForContent (self, content): return '<style type="text/css">' + content + '</style>' def scriptTagsForFiles (self, basePath, files): #<script type='text/javascript' src='./js/src/bookmarklet.js'></script> return '\n'.join(map(lambda file: '<script type="text/javascript" src="' + basePath + '/' + file + '" charset="utf-8"></script>', files)) def scriptTagForContent (self, content): return '<script>' + content + '</script>' def assembleVersion (self, pageTitle, copyright, css, js, jsLoadMode, version, versionType): cacheKey = version + "-" + versionType if not self.processedFiles.has_key(cacheKey): result = self.replaceTemplatePlaceholders(pageTitle, copyright, css, js, jsLoadMode, version, versionType) self.processedFiles[cacheKey] = result else: result = self.processedFiles[cacheKey] #self.log("# cacheKey:\n" + result) return result def assemble (self, assemblyMode='INSTALL', versionType='LIVE'): if versionType == 'LIVE': pageTitle = "Clipperz - " + self.module else: pageTitle = "Clipperz - " + self.module + " [" + versionType + " - " + assemblyMode +"]" if assemblyMode == 'INSTALL': copyright = self.assembleCopyrightHeader() css = self.cssTagForContent(self.compressCSS(self.loadFilesContent('css', self.settings['css']))) js = self.scriptTagForContent( self.bookmarklet() + '\n' + self.compressJS(self.loadFilesContent('js', self.settings['js']), "application") ) jsLoadMode = 'EMBEDDED' elif assemblyMode == 'DEBUG': copyright = self.assembleCopyrightHeader() css = self.cssTagsForFiles('./css', self.filterFiles(self.settings['css'])) - js = self.scriptTagForContent(self.bookmarklet()) + \ - '\n' + \ - self.scriptTagsForFiles('./js', self.filterFiles(self.settings['js'])) + js = self.scriptTagForContent( + self.bookmarklet()) + \ + '\n' + \ + self.scriptTagsForFiles('./js', self.filterFiles(self.settings['js']) + ) jsLoadMode = 'LINKED' elif assemblyMode == 'DEVELOPMENT': copyright = "" css = self.cssTagsForFiles('file://' + str(os.path.join(self.absolutePathForSources(), 'css')), self.filterFiles(self.settings['css'])) - js = self.scriptTagForContent(self.bookmarklet()) + \ - '\n' + \ - self.scriptTagsForFiles('file://' + str(os.path.join(self.absolutePathForSources(), 'js')), self.filterFiles(self.settings['js'])) + js = self.scriptTagForContent( + self.bookmarklet()) + \ + '\n' + \ + self.scriptTagsForFiles('file://' + str(os.path.join(self.absolutePathForSources(), 'js')), self.filterFiles(self.settings['js']) + ) jsLoadMode = 'LINKED' versionType = 'development' else: raise NotImplementedError() return self.assembleVersion( pageTitle = pageTitle, copyright = copyright, css = css, js = js, jsLoadMode = jsLoadMode, version = self.repositoryVersion, versionType = versionType ) |