summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--scripts/builder/backendBuilder.py37
-rw-r--r--scripts/builder/backends/devBuilder.py56
-rw-r--r--scripts/builder/frontendBuilder.py44
-rw-r--r--scripts/builder/frontends/betaBuilder.py14
-rw-r--r--scripts/builder/frontends/gammaBuilder.py26
-rw-r--r--scripts/builder/frontends/gamma_mobileBuilder.py9
-rwxr-xr-xscripts/builder/main.py26
-rw-r--r--scripts/builder/repository.py11
-rwxr-xr-xscripts/dev-proxy7
-rwxr-xr-xscripts/proxy/main.py95
10 files changed, 293 insertions, 32 deletions
diff --git a/scripts/builder/backendBuilder.py b/scripts/builder/backendBuilder.py
index 5b91678..36b28ca 100644
--- a/scripts/builder/backendBuilder.py
+++ b/scripts/builder/backendBuilder.py
@@ -1,131 +1,134 @@
1#!/usr/bin/env python 1#!/usr/bin/env python
2# -*- coding: UTF-8 -*- 2# -*- coding: UTF-8 -*-
3 3
4import sys, os, json 4import sys, os, json
5import shutil 5import shutil
6import hashlib 6import hashlib
7 7
8import main 8import main
9 9
10#=================================================================== 10#===================================================================
11 11
12
13class BackendBuilder(object): 12class BackendBuilder(object):
14 13
15 def __init__ (self, projectTargetDir, frontends, versions, settings): 14 def __init__ (self, projectTargetDir, frontends, versions, settings):
16 self.projectTargetDir = projectTargetDir 15 self.projectTargetDir = projectTargetDir
17 self.frontends = frontends 16 self.frontends = frontends
18 self.versions = versions 17 self.versions = versions
19 self.settings = settings 18 self.settings = settings
20 19
21 # -------------------------------------------------------------------------- 20 # --------------------------------------------------------------------------
22 21
23 def name (self): 22 def name (self):
24 raise NotImplementedError() 23 raise NotImplementedError()
25 24
26 25
27 def relativePath (self): 26 def relativePath (self):
28 raise NotImplementedError() 27 raise NotImplementedError()
29 28
30 29
31 def compileCode (self): 30 def compileCode (self):
32 raise NotImplementedError() 31 raise NotImplementedError()
33 32
34 33
35 def createPackage (self): 34 def createPackage (self):
36 raise NotImplementedError() 35 raise NotImplementedError()
37 36
38 # -------------------------------------------------------------------------- 37 # --------------------------------------------------------------------------
39 38
40 def sourceFolder (self): 39 def sourceFolder (self):
41 return os.path.join(main.projectBaseDir() , 'backend', self.relativePath(), 'src') 40 return os.path.join(main.projectBaseDir() , 'backend', self.relativePath(), 'src')
42 41
43 42
44 def tempFolder (self): 43 def tempFolder (self):
45 return os.path.join(self.projectTargetDir, '.tmp', self.relativePath()) 44 return os.path.join(self.projectTargetDir, '.tmp', self.relativePath())
46 45
47 46
48 def frontEndTempFolder (self): 47 def frontEndTempFolder (self):
49 return self.tempFolder() 48 return self.tempFolder()
50 49
51 50
52 def developmentTargetFolder (self): 51 def developmentTargetFolder (self):
53 return os.path.join(self.projectTargetDir, 'development', self.relativePath()) 52 return os.path.join(self.projectTargetDir, 'development')
53
54 54
55 def targetFolder (self): 55 def targetFolder (self):
56 return os.path.join(self.projectTargetDir, self.relativePath()) 56 return os.path.join(self.projectTargetDir, self.relativePath())
57
57 58
58 # -------------------------------------------------------------------------- 59 # --------------------------------------------------------------------------
59 60
60 def writeToFolder (self, folder, filename, content): 61 def writeToFolder (self, folder, filename, content):
61 file = open(os.path.join(folder, filename), 'w') 62 file = open(os.path.join(folder, filename), 'w')
62 file.write(content.encode('utf-8')) 63 file.write(content.encode('utf-8'))
63 file.close() 64 file.close()
64 65
65 66
66 def configureIndexContent (self, indexContent, requestPathPrefix = ".."): 67 def configureIndexContent (self, indexContent, requestPathPrefix = ".."):
67 result = indexContent 68 result = indexContent
68 result = result.replace( '@request.path@', requestPathPrefix + '/' + self.settings['request.path'] ) 69 result = result.replace( '@request.path@', requestPathPrefix + '/' + self.settings['request.path'] )
69 result = result.replace( '@should.pay.toll@', self.settings['should.pay.toll'] ) 70 result = result.replace( '@should.pay.toll@', self.settings['should.pay.toll'] )
70 71
71 return result 72 return result
72 73
73 74
74 def logChecksums (self, content, message): 75 def logChecksums (self, content, message):
75 md5Digest = hashlib.md5(content.encode('utf-8')).hexdigest() 76 md5Digest = hashlib.md5(content.encode('utf-8')).hexdigest()
76 shaDigest = hashlib.sha1(content.encode('utf-8')).hexdigest() 77 shaDigest = hashlib.sha1(content.encode('utf-8')).hexdigest()
77 sha256Digest= hashlib.sha256(content.encode('utf-8')).hexdigest() 78 sha256Digest= hashlib.sha256(content.encode('utf-8')).hexdigest()
78 print message + ": " + md5Digest + " (md5)" 79 print message + ": " + md5Digest + " (md5)"
79 print message + ": " + shaDigest + " (sha1)" 80 print message + ": " + shaDigest + " (sha1)"
80 print message + ": " + sha256Digest + " (sha256)" 81 print message + ": " + sha256Digest + " (sha256)"
81 82
82 83
83 def shouldCompileCode (self): 84 def shouldCompileCode (self):
84 return ('debug' in self.versions) or ('install' in self.versions) 85 return ('debug' in self.versions) or ('install' in self.versions)
85 86
86 87
87 def run (self): 88 def run (self):
88 print self.name() + " - RUN" 89 print self.name() + " - RUN"
89 90
90 if self.shouldCompileCode(): 91 if self.shouldCompileCode():
91 self.compileCode() 92 self.compileCode()
92 93
93 for frontend in self.frontends: 94 for frontend in self.frontends:
94 if (frontend.module == frontend.submodule): 95 if (frontend.module == frontend.submodule):
95 submoduleExtension = '' 96 submoduleExtension = ''
96 else: 97 else:
97 submoduleExtension = '.' + frontend.submodule 98 submoduleExtension = '.' + frontend.submodule
98 99
99 main.createFolder(os.path.join(self.frontEndTempFolder(), frontend.module)) 100 main.createFolder(os.path.join(self.frontEndTempFolder(), frontend.module))
100 101
101 if 'debug' in self.versions: 102 if 'debug' in self.versions:
102 frontend.copyResourcesToFolder(self.frontEndTempFolder()) 103 frontend.copyResourcesToFolder(self.frontEndTempFolder())
103 104
104 index = self.configureIndexContent(frontend.assemble(assemblyMode='DEBUG', versionType='DEBUG')) 105 index = self.configureIndexContent(frontend.assemble(assemblyMode='DEBUG', versionType='DEBUG'))
105 self.writeToFolder(self.frontEndTempFolder(), os.path.join(frontend.module, 'index_debug' + submoduleExtension + '.html'), index) 106 self.writeToFolder(self.frontEndTempFolder(), os.path.join(frontend.module, 'index_debug' + submoduleExtension + '.html'), index)
106 107
107 if 'install' in self.versions: 108 if 'install' in self.versions:
108 index = self.configureIndexContent(frontend.assemble()) 109 index = self.configureIndexContent(frontend.assemble())
109 self.writeToFolder(self.frontEndTempFolder(), os.path.join(frontend.module, 'index' + submoduleExtension + '.html'), index) 110 self.writeToFolder(self.frontEndTempFolder(), os.path.join(frontend.module, 'index' + submoduleExtension + '.html'), index)
110 111
111 self.logChecksums(index, "[" + self.name() + " - " + frontend.module + "] index" + submoduleExtension + ".html checksum") 112 self.logChecksums(index, "[" + self.name() + " - " + frontend.module + "] index" + submoduleExtension + ".html checksum")
112 113
113 self.createPackage() 114 self.createPackage()
114 115
115 if 'development' in self.versions: 116 # if 'development' in self.versions:
116 for frontend in self.frontends: 117 # for frontend in self.frontends:
117 if (frontend.module == frontend.submodule): 118 # if (frontend.module == frontend.submodule):
118 submoduleExtension = '' 119 # submoduleExtension = ''
119 else: 120 # else:
120 submoduleExtension = '.' + frontend.submodule 121 # submoduleExtension = '.' + frontend.submodule
121 122#
122 print "FRONTEND module: " + frontend.module 123 # print "FRONTEND module: " + frontend.module
123 print "FRONTEND submodule: " + frontend.submodule 124 # print "FRONTEND submodule: " + frontend.submodule
124 125#
125 main.createFolder(os.path.join(self.developmentTargetFolder(), frontend.module)) 126 ## main.createFolder(os.path.join(self.developmentTargetFolder(), frontend.module))
126 127 # main.createFolder(self.developmentTargetFolder())
127 index = self.configureIndexContent(frontend.assemble(assemblyMode='DEVELOPMENT', versionType='DEBUG'), self.settings['development.settings']['url']) 128#
128 self.writeToFolder(self.developmentTargetFolder(), os.path.join(frontend.module, 'index' + submoduleExtension + '.html'), index) 129 # index = self.configureIndexContent(frontend.assemble(assemblyMode='DEVELOPMENT', versionType='DEBUG'), self.settings['development.settings']['url'])
130 ## self.writeToFolder(self.developmentTargetFolder(), os.path.join(frontend.module, 'index_development' + submoduleExtension + '.html'), index)
131 # self.writeToFolder(self.developmentTargetFolder(), os.path.join(frontend.module + submoduleExtension + '.html'), index)
129 132
130 133
131#=================================================================== 134#===================================================================
diff --git a/scripts/builder/backends/devBuilder.py b/scripts/builder/backends/devBuilder.py
new file mode 100644
index 0000000..671765e
--- a/dev/null
+++ b/scripts/builder/backends/devBuilder.py
@@ -0,0 +1,56 @@
1#!/usr/bin/env python
2# -*- coding: UTF-8 -*-
3
4import os
5import shutil
6import subprocess
7import main
8
9from backendBuilder import BackendBuilder
10
11class DevBuilder(BackendBuilder):
12
13 def name(self):
14 return "Dev builder"
15
16
17 def relativePath(self):
18 return 'dev'
19
20
21 #def frontEndTempFolder (self):
22 # return os.path.join(self.tempFolder(), 'src', 'main', 'webapp')
23
24
25 #def targetFolder (self):
26 # return self.projectTargetDir
27
28
29 def compileCode (self):
30 pass
31
32
33 def createPackage (self):
34 src = self.tempFolder()
35 dst = self.targetFolder()
36
37 shutil.copytree(src, dst)
38
39
40 def run (self):
41 print self.name() + " - RUN (dev)"
42
43 for frontend in self.frontends:
44 if (frontend.module == frontend.submodule):
45 submoduleExtension = ''
46 else:
47 submoduleExtension = '.' + frontend.submodule
48
49 main.createFolder(os.path.join(self.frontEndTempFolder(), frontend.module))
50
51 index = self.configureIndexContent(frontend.assemble(assemblyMode='DEBUG', versionType='DEBUG'))
52 self.writeToFolder(self.frontEndTempFolder(), os.path.join(frontend.module, 'index' + submoduleExtension + '.html'), index)
53
54 self.createPackage()
55
56
diff --git a/scripts/builder/frontendBuilder.py b/scripts/builder/frontendBuilder.py
index 1f0f92f..fc603c4 100644
--- a/scripts/builder/frontendBuilder.py
+++ b/scripts/builder/frontendBuilder.py
@@ -1,118 +1,147 @@
1#!/usr/bin/env python 1#!/usr/bin/env python
2# -*- coding: UTF-8 -*- 2# -*- coding: UTF-8 -*-
3 3
4import sys, os, re 4import sys, os, re
5import cssmin 5import cssmin
6import jsmin 6import jsmin
7import codecs 7import codecs
8import shutil 8import shutil
9import StringIO 9import StringIO
10import urllib 10import urllib
11 11
12import main 12import main
13 13
14#===============================================================================
15
14class FrontendBuilder(object): 16class FrontendBuilder(object):
15 17
16 def __init__ (self, frontend, settings, repositoryVersion): 18 def __init__ (self, frontend, settings, repositoryVersion):
17 if '.' in frontend: 19 if '.' in frontend:
18 moduleComponents = frontend.split('.') 20 moduleComponents = frontend.split('.')
19 self.module = moduleComponents[0] 21 self.module = moduleComponents[0]
20 self.submodule = moduleComponents[1] 22 self.submodule = moduleComponents[1]
21 else: 23 else:
22 self.module = frontend 24 self.module = frontend
23 self.submodule = frontend 25 self.submodule = frontend
24 26
25 self.settings = settings 27 self.settings = settings
26 self.projectDir = main.projectBaseDir() 28 self.projectDir = main.projectBaseDir()
27 # self.repository = repository.repositoryWithPath(self.projectDir) 29 # self.repository = repository.repositoryWithPath(self.projectDir)
28 self.repositoryVersion = repositoryVersion 30 self.repositoryVersion = repositoryVersion
29 self.processedFiles = {} 31 self.processedFiles = {}
30 32
33 #---------------------------------------------------------------------------
34
35 def name (self):
36 raise NotImplementedError()
37
38
39 def copyStaticResources (self, targetFolder):
40 raise NotImplementedError()
41
42 #---------------------------------------------------------------------------
31 43
32 def log (self, message): 44 def log (self, message):
33 print "frontend [" + self.module + "]: " + message 45 module = self.module
46 if (self.module != self.submodule):
47 module = module + "." + self.submodule
48 print "frontend [" + module + "]: " + message
34 49
35 50
36 def absolutePathForSources (self): 51 def absolutePathForSources (self):
37 return os.path.join(self.projectDir, 'frontend', self.module) 52 return os.path.join(self.projectDir, 'frontend', self.module)
38 53
39 54
40 def absolutePathForSourceFile (self, basePath, file): 55 def absolutePathForSourceFile (self, basePath, file):
41 return os.path.join(self.absolutePathForSources(), basePath, file) 56 return os.path.join(self.absolutePathForSources(), basePath, file)
42 57
43 58
44 def absolutePathForTargetFile (self, folder, basePath, file): 59 def absolutePathForTargetFile (self, folder, basePath, file):
45 return os.path.join(folder, self.module, basePath, file) 60 return os.path.join(folder, self.module, basePath, file)
46 61
47 62
48 def filterFiles (self, files): 63 def filterFiles (self, files):
49 result = [] 64 result = []
50 65
51 for file in files: 66 for file in files:
52 if file.startswith('--'): 67 if file.startswith('--'):
53 pass 68 pass
54 else: 69 else:
55 result.append(file) 70 result.append(file)
56 71
57 return result 72 return result
58 73
59 74
60 def copyResources (self, sourceFolder, destinationFolder, fileType): 75 def copyResources (self, sourceFolder, destinationFolder, fileType):
61 for file in self.filterFiles(self.settings[fileType]): 76 if fileType in self.settings:
62 src = self.absolutePathForSourceFile(fileType, file) 77 for file in self.filterFiles(self.settings[fileType]):
63 dst = self.absolutePathForTargetFile(destinationFolder, fileType, file) 78 src = self.absolutePathForSourceFile(fileType, file)
64 main.createFolder(os.path.dirname(dst)) 79 dst = self.absolutePathForTargetFile(destinationFolder, fileType, file)
65 shutil.copy2(src, dst) 80 main.createFolder(os.path.dirname(dst))
81 shutil.copy2(src, dst)
82 else:
83 srcFolder = os.path.join(self.absolutePathForSources(), fileType)
84 dstFolder = os.path.join(destinationFolder, self.module, fileType)
85 if not(os.path.exists(dstFolder)):
86 shutil.copytree(srcFolder, dstFolder)
87
88 # try:
89 # shutil.copytree(srcFolder, dstFolder)
90 # except:
91 # pass
92
66 93
67 94
68 def copyResourcesToFolder (self, targetFolder): 95 def copyResourcesToFolder (self, targetFolder):
69 self.copyResources(self.projectDir, targetFolder, 'css') 96 self.copyResources(self.projectDir, targetFolder, 'css')
70 self.copyResources(self.projectDir, targetFolder, 'js') 97 self.copyResources(self.projectDir, targetFolder, 'js')
98 self.copyResources(self.projectDir, targetFolder, 'images')
99 self.copyStaticResources(targetFolder)
71 100
72 101
73 def loadFilesContent (self, basePath, files): 102 def loadFilesContent (self, basePath, files):
74 result = "" 103 result = ""
75 104
76 for file in self.filterFiles(files): 105 for file in self.filterFiles(files):
77 try: 106 try:
78 fileHandler = codecs.open(self.absolutePathForSourceFile(basePath, file), 'r', 'utf-8') 107 fileHandler = codecs.open(self.absolutePathForSourceFile(basePath, file), 'r', 'utf-8')
79 except: 108 except:
80 print "FILE: " + file 109 print "FILE: " + file
81 110
82 result += fileHandler.read() + '\n' 111 result += fileHandler.read() + '\n'
83 fileHandler.close() 112 fileHandler.close()
84 113
85 return result 114 return result
86 115
87 116
88 def template (self): 117 def template (self):
89 processedFile = 'html_template' 118 processedFile = 'html_template'
90 if not self.processedFiles.has_key(processedFile): 119 if not self.processedFiles.has_key(processedFile):
91 #self.processedFiles[processedFile] = self.loadFilesContent('html', ['index_template.html']) 120 #self.processedFiles[processedFile] = self.loadFilesContent('html', ['index_template.html'])
92 self.processedFiles[processedFile] = self.loadFilesContent('html', [self.settings['html.template']]) 121 self.processedFiles[processedFile] = self.loadFilesContent('html', [self.settings['html.template']])
93 122
94 return self.processedFiles[processedFile] 123 return self.processedFiles[processedFile]
95 124
96 125
97 def cssminCompressor (self, css): 126 def cssminCompressor (self, css):
98 # package found here: 127 # package found here:
99 # - http://stackoverflow.com/questions/222581/python-script-for-minifying-css/2396777#2396777 128 # - http://stackoverflow.com/questions/222581/python-script-for-minifying-css/2396777#2396777
100 # actual downloaded version: http://pypi.python.org/pypi/cssmin/0.1.4 129 # actual downloaded version: http://pypi.python.org/pypi/cssmin/0.1.4
101 return cssmin.cssmin(css) 130 return cssmin.cssmin(css)
102 131
103 132
104 def regexCssCompressor (self, css): 133 def regexCssCompressor (self, css):
105 # http://stackoverflow.com/questions/222581/python-script-for-minifying-css/223689#223689 134 # http://stackoverflow.com/questions/222581/python-script-for-minifying-css/223689#223689
106 135
107 # remove comments - this will break a lot of hacks :-P 136 # remove comments - this will break a lot of hacks :-P
108 css = re.sub( r'\s*/\*\s*\*/', "$$HACK1$$", css ) # preserve IE<6 comment hack 137 css = re.sub( r'\s*/\*\s*\*/', "$$HACK1$$", css ) # preserve IE<6 comment hack
109 css = re.sub( r'/\*[\s\S]*?\*/', "", css ) 138 css = re.sub( r'/\*[\s\S]*?\*/', "", css )
110 css = css.replace( "$$HACK1$$", '/**/' ) # preserve IE<6 comment hack 139 css = css.replace( "$$HACK1$$", '/**/' ) # preserve IE<6 comment hack
111 140
112 # url() doesn't need quotes 141 # url() doesn't need quotes
113 css = re.sub( r'url\((["\'])([^)]*)\1\)', r'url(\2)', css ) 142 css = re.sub( r'url\((["\'])([^)]*)\1\)', r'url(\2)', css )
114 143
115 # spaces may be safely collapsed as generated content will collapse them anyway 144 # spaces may be safely collapsed as generated content will collapse them anyway
116 css = re.sub( r'\s+', ' ', css ) 145 css = re.sub( r'\s+', ' ', css )
117 146
118 # shorten collapsable colors: #aabbcc to #abc 147 # shorten collapsable colors: #aabbcc to #abc
@@ -326,65 +355,66 @@ class FrontendBuilder(object):
326 def scriptTagForContent (self, content): 355 def scriptTagForContent (self, content):
327 return '<script>' + content + '</script>' 356 return '<script>' + content + '</script>'
328 357
329 358
330 def assembleVersion (self, pageTitle, copyright, css, js, jsLoadMode, version, versionType): 359 def assembleVersion (self, pageTitle, copyright, css, js, jsLoadMode, version, versionType):
331 cacheKey = version + "-" + versionType 360 cacheKey = version + "-" + versionType
332 if not self.processedFiles.has_key(cacheKey): 361 if not self.processedFiles.has_key(cacheKey):
333 result = self.replaceTemplatePlaceholders(pageTitle, copyright, css, js, jsLoadMode, version, versionType) 362 result = self.replaceTemplatePlaceholders(pageTitle, copyright, css, js, jsLoadMode, version, versionType)
334 self.processedFiles[cacheKey] = result 363 self.processedFiles[cacheKey] = result
335 else: 364 else:
336 result = self.processedFiles[cacheKey] 365 result = self.processedFiles[cacheKey]
337 366
338 #self.log("# cacheKey:\n" + result) 367 #self.log("# cacheKey:\n" + result)
339 return result 368 return result
340 369
341 370
342 def assemble (self, assemblyMode='INSTALL', versionType='LIVE'): 371 def assemble (self, assemblyMode='INSTALL', versionType='LIVE'):
343 372
344 if versionType == 'LIVE': 373 if versionType == 'LIVE':
345 pageTitle = "Clipperz - " + self.module 374 pageTitle = "Clipperz - " + self.module
346 else: 375 else:
347 pageTitle = "Clipperz - " + self.module + " [" + versionType + " - " + assemblyMode +"]" 376 pageTitle = "Clipperz - " + self.module + " [" + versionType + " - " + assemblyMode +"]"
348 377
349 if assemblyMode == 'INSTALL': 378 if assemblyMode == 'INSTALL':
350 copyright = self.assembleCopyrightHeader() 379 copyright = self.assembleCopyrightHeader()
351 css =self.cssTagForContent(self.compressCSS(self.loadFilesContent('css', self.settings['css']))) 380 css =self.cssTagForContent(self.compressCSS(self.loadFilesContent('css', self.settings['css'])))
352 js =self.scriptTagForContent( 381 js =self.scriptTagForContent(
353 self.bookmarklet() + 382 self.bookmarklet() +
354 '\n' + 383 '\n' +
355 self.compressJS(self.loadFilesContent('js', self.settings['js']), "application") 384 self.compressJS(self.loadFilesContent('js', self.settings['js']), "application")
356 ) 385 )
357 jsLoadMode = 'EMBEDDED' 386 jsLoadMode = 'EMBEDDED'
358 387
359 elif assemblyMode == 'DEBUG': 388 elif assemblyMode == 'DEBUG':
360 copyright = self.assembleCopyrightHeader() 389 copyright = self.assembleCopyrightHeader()
361 css =self.cssTagsForFiles('./css', self.filterFiles(self.settings['css'])) 390 css =self.cssTagsForFiles('./css', self.filterFiles(self.settings['css']))
362 js =self.scriptTagForContent(self.bookmarklet()) + \ 391 js =self.scriptTagForContent(self.bookmarklet()) + \
363 '\n' + \ 392 '\n' + \
364 self.scriptTagsForFiles('./js', self.filterFiles(self.settings['js'])) 393 self.scriptTagsForFiles('./js', self.filterFiles(self.settings['js']))
365 jsLoadMode = 'LINKED' 394 jsLoadMode = 'LINKED'
366 395
367 elif assemblyMode == 'DEVELOPMENT': 396 elif assemblyMode == 'DEVELOPMENT':
368 copyright = "" 397 copyright = ""
369 css =self.cssTagsForFiles('file://' + str(os.path.join(self.absolutePathForSources(), 'css')), self.filterFiles(self.settings['css'])) 398 css =self.cssTagsForFiles('file://' + str(os.path.join(self.absolutePathForSources(), 'css')), self.filterFiles(self.settings['css']))
370 js =self.scriptTagForContent(self.bookmarklet()) + \ 399 js =self.scriptTagForContent(self.bookmarklet()) + \
371 '\n' + \ 400 '\n' + \
372 self.scriptTagsForFiles('file://' + str(os.path.join(self.absolutePathForSources(), 'js')), self.filterFiles(self.settings['js'])) 401 self.scriptTagsForFiles('file://' + str(os.path.join(self.absolutePathForSources(), 'js')), self.filterFiles(self.settings['js']))
373 jsLoadMode = 'LINKED' 402 jsLoadMode = 'LINKED'
403 versionType = 'development'
374 404
375 else: 405 else:
376 raise NotImplementedError() 406 raise NotImplementedError()
377 407
378 return self.assembleVersion( 408 return self.assembleVersion(
379 pageTitle = pageTitle, 409 pageTitle = pageTitle,
380 copyright = copyright, 410 copyright = copyright,
381 css = css, 411 css = css,
382 js = js, 412 js = js,
383 jsLoadMode = jsLoadMode, 413 jsLoadMode = jsLoadMode,
384 version = self.repositoryVersion, 414 version = self.repositoryVersion,
385 versionType = versionType 415 versionType = versionType
386 ) 416 )
387 417
388 418
389 419
390 420
diff --git a/scripts/builder/frontends/betaBuilder.py b/scripts/builder/frontends/betaBuilder.py
new file mode 100644
index 0000000..c5a3e76
--- a/dev/null
+++ b/scripts/builder/frontends/betaBuilder.py
@@ -0,0 +1,14 @@
1from frontendBuilder import FrontendBuilder
2import shutil
3
4class BetaBuilder(FrontendBuilder):
5
6 def name(self):
7 return "/beta builder"
8
9 def copyStaticResources (self, targetFolder):
10 for file in self.filterFiles(self.settings['staticResources']):
11 src = self.absolutePathForSourceFile('staticResources', file)
12 dst = self.absolutePathForTargetFile(targetFolder, '', file)
13 shutil.copy2(src, dst)
14
diff --git a/scripts/builder/frontends/gammaBuilder.py b/scripts/builder/frontends/gammaBuilder.py
new file mode 100644
index 0000000..35fa68b
--- a/dev/null
+++ b/scripts/builder/frontends/gammaBuilder.py
@@ -0,0 +1,26 @@
1from frontendBuilder import FrontendBuilder
2import shutil
3
4class GammaBuilder(FrontendBuilder):
5
6 def name(self):
7 return "/gamma builder"
8
9 def copyStaticResources (self, targetFolder):
10 resourcesToCopy = [
11 {'folder': 'html', 'source': 'exit_template.html','target': 'exit.html'},
12 {'folder': 'css', 'source': 'static.css', 'target': 'static.css'}
13 ]
14
15 for resource in resourcesToCopy:
16 src = self.absolutePathForSourceFile(resource['folder'], resource['source'])
17 dst = self.absolutePathForTargetFile(targetFolder, '', resource['target'])
18 shutil.copy2(src, dst)
19
20 # src = self.absolutePathForSourceFile('html', 'exit_template.html')
21 # dst = self.absolutePathForTargetFile(targetFolder, '', 'exit.html')
22 # shutil.copy2(src, dst)
23
24 # src = self.absolutePathForSourceFile('css', 'static.css')
25 # dst = self.absolutePathForTargetFile(targetFolder, '', 'static.css')
26 # shutil.copy2(src, dst)
diff --git a/scripts/builder/frontends/gamma_mobileBuilder.py b/scripts/builder/frontends/gamma_mobileBuilder.py
new file mode 100644
index 0000000..f2e80c9
--- a/dev/null
+++ b/scripts/builder/frontends/gamma_mobileBuilder.py
@@ -0,0 +1,9 @@
1from frontendBuilder import FrontendBuilder
2
3class Gamma_MobileBuilder(FrontendBuilder):
4
5 def name(self):
6 return "/gamma.mobile builder"
7
8 def copyStaticResources (self, targetFolder):
9 pass
diff --git a/scripts/builder/main.py b/scripts/builder/main.py
index 6fce65d..b9fe04a 100755
--- a/scripts/builder/main.py
+++ b/scripts/builder/main.py
@@ -1,177 +1,191 @@
1#!/usr/bin/env python 1#!/usr/bin/env python
2# -*- coding: UTF-8 -*- 2# -*- coding: UTF-8 -*-
3 3
4import sys 4import sys
5import os 5import os
6import json 6import json
7import shutil 7import shutil
8import pprint 8import pprint
9import codecs 9import codecs
10import itertools 10import itertools
11from collections import deque 11from collections import deque
12 12
13import frontendBuilder 13#import frontendBuilder
14import repository 14import repository
15 15
16pp = pprint.PrettyPrinter(indent=4, depth=4) 16pp = pprint.PrettyPrinter(indent=4, depth=4)
17 17
18#-------------------------------------------------------------------- 18#--------------------------------------------------------------------
19 19
20def scriptDir (): 20def scriptDir ():
21 return os.path.dirname(sys.argv[0]) 21 return os.path.dirname(sys.argv[0])
22 22
23def projectBaseDir (): 23def projectBaseDir ():
24 return os.path.abspath(scriptDir() + '/../..') 24 return os.path.abspath(scriptDir() + '/../..')
25 25
26def projectTargetDir(): 26def projectTargetDir():
27 return projectBaseDir() + '/target/' 27 return projectBaseDir() + '/target/'
28 28
29#-------------------------------------------------------------------- 29#--------------------------------------------------------------------
30 30
31def createFolder (path): 31def createFolder (path):
32 if not os.path.exists(path): 32 if not os.path.exists(path):
33 os.makedirs(path) 33 os.makedirs(path)
34 34
35#-------------------------------------------------------------------- 35#--------------------------------------------------------------------
36 36
37def loadSettings (component, module): 37def loadSettings (component, module):
38 # print "MODULE: " + module 38 # print "MODULE: " + module
39 39
40 if '.' in module: 40 if '.' in module:
41 moduleComponents = module.split('.') 41 moduleComponents = module.split('.')
42 module = moduleComponents[0] 42 module = moduleComponents[0]
43 submodule = moduleComponents[1] 43 submodule = moduleComponents[1]
44 else: 44 else:
45 submodule = module 45 submodule = module
46 46
47 #settings = codecs.open(projectBaseDir() + os.sep + component + os.sep + module + os.sep + 'properties' + os.sep + submodule + '.properties.json', 'r', 'utf-8') 47 #settings = codecs.open(projectBaseDir() + os.sep + component + os.sep + module + os.sep + 'properties' + os.sep + submodule + '.properties.json', 'r', 'utf-8')
48 settings = codecs.open(os.path.join(projectBaseDir(), component, module, 'properties', submodule + '.properties.json'), 'r', 'utf-8') 48 settings = codecs.open(os.path.join(projectBaseDir(), component, module, 'properties', submodule + '.properties.json'), 'r', 'utf-8')
49 result = json.load(settings) 49 result = json.load(settings)
50 settings.close 50 settings.close
51 51
52 return result 52 return result
53 53
54#==================================================================== 54#====================================================================
55# 55#
56# def assembleFrontend (frontend, versions): 56# def assembleFrontend (frontend, versions):
57 # result = {} 57 # result = {}
58 # settings = loadSettings('frontend', frontend) 58 # settings = loadSettings('frontend', frontend)
59 # builder = frontendBuilder.FrontendBuilder(frontend, settings, projectBaseDir()) 59 # builder = frontendBuilder.FrontendBuilder(frontend, settings, projectBaseDir())
60 # 60 #
61 # for version in versions: 61 # for version in versions:
62 # if version == 'install': 62 # if version == 'install':
63 # result[version] = builder.assembleInstallVersion() 63 # result[version] = builder.assembleInstallVersion()
64 # elif version == 'debug': 64 # elif version == 'debug':
65 # result[version] = builder.assembleDebugVersion() 65 # result[version] = builder.assembleDebugVersion()
66 # else: 66 # else:
67 # raise Exception('unrecognized version: ' + version) 67 # raise Exception('unrecognized version: ' + version)
68 # 68 #
69 # return result 69 # return result
70# 70#
71#==================================================================== 71#====================================================================
72 72
73def assembleBackend (backend, frontends, versions): 73def assembleBackend (backend, frontends, versions):
74 settings = loadSettings('backend', backend) 74 settings = loadSettings('backend', backend)
75 75
76 builderModuleName = backend + 'Builder' 76 builderModuleName = backend + 'Builder'
77 builderClassName = backend.capitalize() + 'Builder' 77 builderClassName = backend.capitalize() + 'Builder'
78 78 #print ("BUILD BACKENDS - module: " + builderModuleName + " , class: " + builderClassName)
79 builderModule = __import__(builderModuleName) 79 builderModule = __import__(builderModuleName)
80 builderClass = getattr(builderModule, builderClassName) 80 builderClass = getattr(builderModule, builderClassName)
81 81
82 backendBuilder = builderClass(projectTargetDir(), frontends, versions, settings) 82 backendBuilder = builderClass(projectTargetDir(), frontends, versions, settings)
83 backendBuilder.run() 83 backendBuilder.run()
84 84
85#==================================================================== 85#====================================================================
86 86
87def build (settings, repository): 87def build (settings, repository):
88 frontends = [] 88 frontends = []
89 89
90 if repository.areTherePendingChanges(): 90 if repository.areTherePendingChanges():
91 print "\nWARNING: repository has pending changes\n" 91 if 'install' in settings['versions']:
92 raise Exception("repository has pending changes, can't 'install'")
93 else:
94 print "\nWARNING: repository has pending changes\n"
92 95
93 for frontend in settings['frontends']: 96 for frontend in settings['frontends']:
94 frontends.append(frontendBuilder.FrontendBuilder(frontend, loadSettings('frontend', frontend), repository.version())) 97 normalizedFrontendName = frontend.replace(".", "_")
98 builderModuleName = normalizedFrontendName + 'Builder'
99 builderClassName = normalizedFrontendName.title() + 'Builder'
100
101 #print ("BUILD FRONTEND - module: " + builderModuleName + " , class: " + builderClassName)
102 builderModule = __import__(builderModuleName)
103 builderClass = getattr(builderModule, builderClassName)
104 builder = builderClass(frontend, loadSettings('frontend', frontend), repository.version())
105 #builder = frontendBuilder.FrontendBuilder(frontend, loadSettings('frontend', frontend), repository.version())
106 frontends.append(builder)
95 107
96 for backend in settings['backends']: 108 for backend in settings['backends']:
97 assembleBackend(backend, frontends, settings['versions']) 109 assembleBackend(backend, frontends, settings['versions'])
98 110
99#-------------------------------------------------------------------- 111#--------------------------------------------------------------------
100 112
101def clean (): 113def clean ():
102 # print "cleaning up …" 114 # print "cleaning up …"
103 if os.path.exists(projectTargetDir()): 115 if os.path.exists(projectTargetDir()):
104 shutil.rmtree(projectTargetDir()) 116 shutil.rmtree(projectTargetDir())
105 117
106#-------------------------------------------------------------------- 118#--------------------------------------------------------------------
107 119
108def usage (message): 120def usage (message):
109 if message != None: 121 if message != None:
110 print "ERROR: " + message 122 print "ERROR: " + message
111 123
112 print 124 print
113 # print "build clean" 125 # print "build clean"
114 # print "build clean install" 126 # print "build clean install"
115 print "build install --ALL" 127 print "build install --ALL"
116 print "build install debug --ALL" 128 print "build install debug --ALL"
129 print "build install debug development --ALL"
117 # print "build clean install debug --ALL" 130 # print "build clean install debug --ALL"
118 print "build install debug --backends php python --frontends beta gamma" 131 print "build install debug --backends php python --frontends beta gamma"
119 print "build install debug development --backends php python --frontends beta gamma gamma.mobile" 132 print "build install debug development --backends php python --frontends beta gamma gamma.mobile"
120 exit(1) 133 exit(1)
121 134
122#-------------------------------------------------------------------- 135#--------------------------------------------------------------------
123 136
124def allFrontends (): 137def allFrontends ():
125 return ['beta', 'gamma', 'mobile'] 138 return ['beta', 'gamma', 'gamma.mobile']
126 139
127def allBackends (): 140def allBackends ():
128 return ['php', 'python'] 141 return ['php', 'python']
129 142
130#-------------------------------------------------------------------- 143#--------------------------------------------------------------------
131 144
132def main (): 145def main ():
133 settings = {} 146 settings = {}
134 parameters = list(itertools.islice(sys.argv, 1, None)) 147 parameters = list(itertools.islice(sys.argv, 1, None))
135 148
136 sys.path.append(os.path.join(scriptDir(), 'backends')) 149 sys.path.append(os.path.join(scriptDir(), 'backends'))
150 sys.path.append(os.path.join(scriptDir(), 'frontends'))
137 currentRepository = repository.repositoryWithPath(projectBaseDir()) 151 currentRepository = repository.repositoryWithPath(projectBaseDir())
138 152
139 clean() 153 clean()
140 versions = list(itertools.takewhile(lambda x: not x.startswith('--'), parameters)) 154 versions = list(itertools.takewhile(lambda x: not x.startswith('--'), parameters))
141 settings['versions'] = versions; #['debug', 'install', 'development'] 155 settings['versions'] = versions; #['debug', 'install', 'development']
142 parameters = deque(itertools.dropwhile(lambda x: not x.startswith('--'), parameters)) 156 parameters = deque(itertools.dropwhile(lambda x: not x.startswith('--'), parameters))
143 157
144 if len(parameters) > 0: 158 if len(parameters) > 0:
145 parameter = parameters.popleft() 159 parameter = parameters.popleft()
146 if parameter == "--ALL": 160 if parameter == "--ALL":
147 settings['frontends'] = allFrontends() 161 settings['frontends'] = allFrontends()
148 settings['backends'] = allBackends() 162 settings['backends'] = allBackends()
149 else: 163 else:
150 while parameter != None: 164 while parameter != None:
151 values = list(itertools.takewhile(lambda x: not x.startswith('--'), parameters)) 165 values = list(itertools.takewhile(lambda x: not x.startswith('--'), parameters))
152 166
153 if parameter == "--backends": 167 if parameter == "--backends":
154 settings['backends'] = values 168 settings['backends'] = values
155 elif parameter == "--frontends": 169 elif parameter == "--frontends":
156 settings['frontends'] = values 170 settings['frontends'] = values
157 171
158 parameters = deque(itertools.dropwhile(lambda x: not x.startswith('--'), parameters)) 172 parameters = deque(itertools.dropwhile(lambda x: not x.startswith('--'), parameters))
159 if parameters: 173 if parameters:
160 parameter = parameters.popleft() 174 parameter = parameters.popleft()
161 else: 175 else:
162 parameter = None 176 parameter = None
163 177
164 if (not settings.has_key('versions')): 178 if (not settings.has_key('versions')):
165 usage("missing 'versions'") 179 usage("missing 'versions'")
166 if (not settings.has_key('frontends')): 180 if (not settings.has_key('frontends')):
167 usage("missing 'frontends'") 181 usage("missing 'frontends'")
168 if (not settings.has_key('backends')): 182 if (not settings.has_key('backends')):
169 usage("missing 'backends'") 183 usage("missing 'backends'")
170 184
171 build(settings, currentRepository) 185 build(settings, currentRepository)
172 else: 186 else:
173 usage("Suggestions on how to call the 'build' script:") 187 usage("Suggestions on how to call the 'build' script:")
174 188
175 189
176if __name__ == "__main__": 190if __name__ == "__main__":
177 main() 191 main()
diff --git a/scripts/builder/repository.py b/scripts/builder/repository.py
index 0045de7..a47e249 100644
--- a/scripts/builder/repository.py
+++ b/scripts/builder/repository.py
@@ -11,71 +11,78 @@ def repositoryWithPath (path):
11 except: 11 except:
12 try: 12 try:
13 from git import Repo 13 from git import Repo
14 14
15 repo = Repo(path) 15 repo = Repo(path)
16 result = GitRepository(repo, path) 16 result = GitRepository(repo, path)
17 except ImportError, exception: 17 except ImportError, exception:
18 print "Failed to import git, please install http://gitorious.org/git-python" 18 print "Failed to import git, please install http://gitorious.org/git-python"
19 raise exception 19 raise exception
20 20
21 21
22 return result 22 return result
23 23
24 24
25#=================================================================== 25#===================================================================
26 26
27 27
28class Repository(object): 28class Repository(object):
29 29
30 def __init__ (self, repository, path): 30 def __init__ (self, repository, path):
31 self.repository = repository 31 self.repository = repository
32 self.path = path 32 self.path = path
33 33
34 34
35 def revision (self): 35 def revision (self):
36 raise NotImplementedError() 36 raise NotImplementedError()
37 37
38 38
39 def areTherePendingChanges (self): 39 def areTherePendingChanges (self):
40 raise NotImplementedError() 40 raise NotImplementedError()
41 41
42 42
43 def version (self): 43 def version (self):
44 result = self.revision() 44 result = self.revision()
45 if self.areTherePendingChanges(): 45 if self.areTherePendingChanges():
46 result = '>>> ' + result + ' <<<' 46 result = '>>> ' + result + ' <<<'
47 47
48 # print "VERSION: " + result 48 # print "VERSION: " + result
49 return result 49 return result
50 50
51 51
52#=================================================================== 52#===================================================================
53 53
54 54
55class GitRepository(Repository): 55class GitRepository(Repository):
56 #http://gitorious.org/git-python 56 #http://gitorious.org/git-python
57 57
58 def revision (self): 58 def revision (self):
59 return self.repository.head.commit.hexsha 59 try:
60 return self.repository.head.commit.hexsha
61 except:
62 return self.repository.commits()[0].id
60 63
61 64
62 def areTherePendingChanges (self): 65 def areTherePendingChanges (self):
63 return self.repository.is_dirty() 66 try:
67 return self.repository.is_dirty()
68 except TypeError, te:
69 return self.repository.is_dirty
70
64 71
65 72
66#=================================================================== 73#===================================================================
67 74
68 75
69class HgRepository(Repository): 76class HgRepository(Repository):
70 #http://mercurial.selenic.com/wiki/MercurialApi 77 #http://mercurial.selenic.com/wiki/MercurialApi
71 78
72 def revision (self): 79 def revision (self):
73 return 'hg:' + str(self.repository['tip']) 80 return 'hg:' + str(self.repository['tip'])
74 81
75 82
76 def areTherePendingChanges (self): 83 def areTherePendingChanges (self):
77 # TODO: FIXME: repository.status() does not report 'unknown(?)' files. :( 84 # TODO: FIXME: repository.status() does not report 'unknown(?)' files. :(
78 return not all(map(lambda fileList: len(fileList) == 0, self.repository.status())) 85 return not all(map(lambda fileList: len(fileList) == 0, self.repository.status()))
79 86
80 87
81#=================================================================== 88#===================================================================
diff --git a/scripts/dev-proxy b/scripts/dev-proxy
new file mode 100755
index 0000000..e5980e3
--- a/dev/null
+++ b/scripts/dev-proxy
@@ -0,0 +1,7 @@
1#!/bin/bash
2
3readonly CURR_DIR=$(cd "$(dirname "$0")"; pwd -P)
4
5#${CURR_DIR}/proxy/main.py $@
6python ${CURR_DIR}/proxy/main.py $@
7#twistd -y ${CURR_DIR}/proxy/main.py --pidfile=${CURR_DIR}/../target/proxy/proxy.pid --logfile=${CURR_DIR}/../target/proxy/logs/proxy.log \ No newline at end of file
diff --git a/scripts/proxy/main.py b/scripts/proxy/main.py
new file mode 100755
index 0000000..107ba16
--- a/dev/null
+++ b/scripts/proxy/main.py
@@ -0,0 +1,95 @@
1from twisted.internet import reactor
2from twisted.web import proxy, server, http, resource, static
3from posixpath import basename, dirname
4
5import copy
6import sys
7import os
8import pprint
9
10#--------------------------------------------------------------------
11
12def scriptDir ():
13 return os.path.dirname(sys.argv[0])
14
15def projectBaseDir ():
16 return os.path.abspath(scriptDir() + '/../..')
17
18def projectTargetDir():
19 return projectBaseDir() + '/target/'
20
21#--------------------------------------------------------------------
22
23class ClipperzTestSite(server.Site):
24
25 def __init__(self, resource, logPath=None, timeout=60 * 60 * 12):
26 server.Site.__init__(self, resource, logPath, timeout)
27
28
29 def getResourceFor(self, request):
30 if request.uri.startswith('/json') or request.uri.startswith('/dump'):
31 request.site = self
32 request.sitepath = copy.copy(request.prepath)
33 result = resource.getChildForRequest(self.resource, request)
34
35 else:
36 pathParts = request.uri.split('/')
37 version = pathParts[1]
38
39 if pathParts[2].startswith('index.'):
40 contentType = 'text/html'
41 absoluteFilePath = os.path.join(projectTargetDir(), 'dev', version, pathParts[2])
42 result = static.File(absoluteFilePath, contentType)
43
44 else:
45 #http://homer.local:8888/beta/css/clipperz/images/loginInfoBackground.png
46 #pathParts: ['', 'beta', 'css', 'clipperz', 'images', 'loginInfoBackground.png']
47 try:
48 imagePathIndex = pathParts.index('images')
49 resourceType = 'images'
50 for _ in range(2, imagePathIndex):
51 del pathParts[2]
52 except:
53 resourceType = pathParts[2]
54
55 basePath = projectBaseDir() + '/frontend'
56 if resourceType == 'images':
57 fileExtension = os.path.splitext(request.uri)[1]
58 if fileExtension == '.png':
59 contentType = 'image/png'
60 elif fileExtension == '.jpg':
61 contentType = 'image/jpeg'
62 elif fileExtension == '.gif':
63 contentType = 'image/gif'
64 else:
65 print "ERROR - unknown image extension: " + fileExtension
66
67 absoluteFilePath = basePath + '/'.join(pathParts)
68 else:
69 resourceType = pathParts[2]
70
71 if resourceType == 'css':
72 contentType = 'text/css'
73 elif resourceType == 'js':
74 contentType = 'text/javascript'
75 else:
76 contentType = 'text/html'
77
78 absoluteFilePath = basePath + request.uri
79
80 result = static.File(absoluteFilePath, contentType)
81
82
83 return result
84
85
86
87def main ():
88 site = ClipperzTestSite(proxy.ReverseProxyResource('localhost', 8084, '/java-backend'))
89 reactor.listenTCP(8888, site)
90 reactor.run()
91
92
93if __name__ == "__main__":
94 main()
95