262 lines
10 KiB
Python
Executable file
262 lines
10 KiB
Python
Executable file
#!/usr/bin/env python
|
|
#vim: et:ts=4:sw=4:sts=4
|
|
|
|
import base64
|
|
import json
|
|
import os
|
|
import ox
|
|
import re
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
import tarfile
|
|
import time
|
|
|
|
def build_oxjs(downloads=False, geo=False):
|
|
|
|
base_path = os.path.dirname(__file__)
|
|
if base_path:
|
|
os.chdir(base_path)
|
|
|
|
root_path = '../../'
|
|
source_path = root_path + 'source/'
|
|
build_path = root_path + 'build/'
|
|
dev_path = root_path + 'dev/'
|
|
|
|
version = '0.1.%s' % subprocess.Popen(
|
|
['bzr', 'revno'],
|
|
stdout=subprocess.PIPE
|
|
).communicate()[0].strip()
|
|
year = time.strftime('%Y', time.gmtime())
|
|
comment = ' OxJS %s (c) %s 0x2620, dual-licensed GPL/MIT, see https://oxjs.org for details ' % (version, year)
|
|
|
|
# SVGs
|
|
path = source_path + 'Ox.UI/themes/classic/svg/'
|
|
for filename in os.listdir(path):
|
|
svg = read_file(path + filename)
|
|
svg = svg.replace('#000000', '#XXXXXX').replace('#404040', '#C0C0C0').replace('#FFFFFF', '#000000').replace('#XXXXXX', '#FFFFFF')
|
|
write_file(path.replace('/classic/', '/modern/') + filename, svg)
|
|
imageURLs = {}
|
|
imageDataURLs = {}
|
|
for theme in ['classic', 'modern']:
|
|
path = source_path + 'Ox.UI/themes/' + theme + '/svg/'
|
|
for filename in os.listdir(path):
|
|
if not filename[0] in '._' and not filename.endswith('~'):
|
|
key = theme + '/' + filename[:-4]
|
|
imageURLs[key] = os.path.join(path, filename).replace(source_path, '')
|
|
data = re.sub('\n\s+', '', read_file(path + filename))
|
|
imageDataURLs[key] = 'data:image/svg+xml;base64,' + base64.b64encode(data)
|
|
write_file(build_path + 'Ox.UI/json/Ox.UI.imageURLs.json', json.dumps(imageURLs, sort_keys=True))
|
|
write_file(build_path + 'Ox.UI/json/Ox.UI.imageDataURLs.json', json.dumps(imageDataURLs, sort_keys=True))
|
|
write_file(dev_path + 'Ox.UI/json/Ox.UI.imageURLs.json', json.dumps(imageURLs, indent=4, sort_keys=True))
|
|
write_file(dev_path + 'Ox.UI/json/Ox.UI.imageDataURLs.json', json.dumps(imageDataURLs, indent=4, sort_keys=True))
|
|
|
|
# copy & link
|
|
ui_files = {'build': [], 'dev': []}
|
|
for path, dirnames, filenames in os.walk(source_path):
|
|
for filename in filenames:
|
|
if not '_' in path and not filename[0] in '._' \
|
|
and not filename.endswith('~') \
|
|
and (geo or not '/Ox.Geo/' in path):
|
|
# write copies in build path
|
|
source = os.path.join(path, filename)
|
|
is_jquery = re.match('^jquery-[\d\.]+\.js$', filename)
|
|
is_jquery_min = re.match('^jquery-[\d\.]+\.min\.js$', filename)
|
|
is_jquery_plugin = re.match('^jquery\..*?\.js$', filename)
|
|
if is_jquery or is_jquery_min:
|
|
target = os.path.join(path.replace(source_path, build_path), 'jquery.js')
|
|
else:
|
|
target = os.path.join(path.replace(source_path, build_path), filename)
|
|
if is_jquery_plugin:
|
|
ui_files['build'].append(target.replace(build_path, ''))
|
|
ui_files['dev'].append(target.replace(build_path, ''))
|
|
if not '/Ox/js' in source and not '/Ox.UI/js/' in source and not is_jquery:
|
|
if re.match('^Ox\..+\.js$', filename):
|
|
js = read_file(source)
|
|
write_file(target, ox.js.minify(js, comment))
|
|
else:
|
|
copy_file(source, target)
|
|
# write links in dev path
|
|
parts = os.path.join(path.replace(source_path, ''), filename).split('/')
|
|
for i, part in enumerate(parts):
|
|
if i < len(parts) - 1:
|
|
parts[i] = '..'
|
|
link_source = '/'.join(parts).replace(filename, os.path.join(path, filename))[3:]
|
|
link_target = target.replace(build_path, dev_path)
|
|
if not is_jquery_min:
|
|
write_link(link_source, link_target)
|
|
# remove dangling links from dev tree that might
|
|
# be left over from renames or removed files
|
|
for path, dirnames, filenames in os.walk(dev_path):
|
|
for f in filenames:
|
|
f = os.path.join(path, f)
|
|
if os.path.islink(f) and not os.path.exists(f):
|
|
os.unlink(f)
|
|
# Ox.js
|
|
filenames = [
|
|
[
|
|
'Core.js' # has to run first so that Ox is defined
|
|
],
|
|
[
|
|
'Array.js', # Ox.PATH depends on Ox.toArray
|
|
'Collection.js', # Ox.toArray depends on Ox.slice
|
|
'Polyfill.js', # FIXME: not clear if needed here
|
|
'Math.js', # Ox.MAX_LATITUDE depends on Ox.sinh
|
|
'Object.js', # Ox.typeOf depends on Ox.hasOwn
|
|
'String.js', # HTML.js depends on Ox.char
|
|
'Type.js' # Ox.slice may depend on Ox.typeOf
|
|
]
|
|
]
|
|
js = ''
|
|
js_dir = 'Ox/js/'
|
|
ox_files = [[], [], []]
|
|
for filename in filenames[0]:
|
|
ox_files[0].append(js_dir + filename)
|
|
for filename in filenames[1]:
|
|
ox_files[1].append(js_dir + filename)
|
|
filenames = filenames[0] + filenames[1]
|
|
for filename in sorted(os.listdir(source_path + js_dir)):
|
|
if not filename in filenames \
|
|
and not filename.startswith('.') \
|
|
and not filename.endswith('~'):
|
|
filenames.append(filename)
|
|
for filename in filenames:
|
|
js += read_file(source_path + js_dir + filename) + '\n'
|
|
if not js_dir + filename in ox_files[0] + ox_files[1]:
|
|
ox_files[2].append(js_dir + filename)
|
|
js = re.sub("Ox.VERSION = '([\d\.]+)'", "Ox.VERSION = '%s'" % version, js)
|
|
write_file(build_path + 'Ox.js', ox.js.minify(js, comment))
|
|
write_file(dev_path + '/Ox/json/' + 'Ox.json', json.dumps({
|
|
'files': ox_files,
|
|
'version': version
|
|
}, indent=4))
|
|
|
|
# Ox.UI
|
|
js = ''
|
|
root = source_path + 'Ox.UI/'
|
|
for path, dirnames, filenames in os.walk(root):
|
|
for filename in sorted(filenames):
|
|
# jquery gets included by Ox.UI loader
|
|
# theme css files get included by main css
|
|
# svgs are loaded as URLs or dataURLs
|
|
# browser images appear before load
|
|
if path != root and not '_' in path and not filename[0] in '._'\
|
|
and not filename.endswith('~')\
|
|
and not 'jquery' in filename\
|
|
and not ('/themes/' in path and filename.endswith('.css'))\
|
|
and not filename.endswith('.svg')\
|
|
and not filename.startswith('browser'):
|
|
ui_files['dev'].append(os.path.join(path.replace(source_path, ''), filename))
|
|
if not '/js/' in path:
|
|
ui_files['build'].append(os.path.join(path.replace(source_path, ''), filename))
|
|
if filename.endswith('.js'):
|
|
js += read_file(os.path.join(path, filename)) + '\n'
|
|
filename = build_path + 'Ox.UI/js/Ox.UI.js'
|
|
write_file(filename, ox.js.minify(js, comment))
|
|
ui_files['build'].append(filename.replace(build_path, ''))
|
|
files = json.dumps(sorted(ui_files['build']))
|
|
write_file(build_path + 'Ox.UI/json/Ox.UI.files.json', files)
|
|
files = json.dumps(sorted(ui_files['dev']), indent=4)
|
|
write_file(dev_path + 'Ox.UI/json/Ox.UI.files.json', files)
|
|
|
|
ui_files['dev'].append('Ox.UI/Ox.UI.js')
|
|
# index
|
|
data = {
|
|
# sum(list, []) is flatten
|
|
'documentation': sorted(sum(ox_files, [])) + sorted(filter(
|
|
lambda x: re.search('\.js$', x),
|
|
ui_files['dev']
|
|
) + map(
|
|
lambda x: 'Ox.%s/Ox.%s.js' % (x, x),
|
|
['Geo', 'Image', 'Unicode']
|
|
)),
|
|
'examples': filter(
|
|
lambda x: not re.search('^[\._]', x),
|
|
os.listdir(root_path + 'examples/')
|
|
),
|
|
'readme': map(
|
|
lambda x: {
|
|
'date': time.strftime(
|
|
'%Y-%m-%d %H:%M:%S',
|
|
time.gmtime(os.path.getmtime(root_path + 'readme/html/' + x))
|
|
),
|
|
'id': x.split('.')[0],
|
|
'title': get_title(root_path + 'readme/html/' + x)
|
|
},
|
|
filter(
|
|
lambda x: not re.search('^[\._]', x),
|
|
os.listdir(root_path + 'readme/html/')
|
|
)
|
|
)
|
|
}
|
|
write_file(root_path + 'index.json', json.dumps(data, indent=4, sort_keys=True))
|
|
|
|
# downloads
|
|
if downloads:
|
|
download_path = root_path + 'downloads/'
|
|
# source
|
|
source_file = 'OxJS.%s.source.tar.gz' % version
|
|
source_tar = tarfile.open(download_path + source_file, 'w:gz')
|
|
source_tar.add(root_path, arcname='OxJS', filter=filter_source)
|
|
source_tar.close()
|
|
write_link(source_file, root_path + 'downloads/OxJS.latest.source.tar.gz')
|
|
# build
|
|
build_file = 'OxJS.%s.build.tar.gz' % version
|
|
build_tar = tarfile.open(download_path + build_file, 'w:gz')
|
|
build_tar.add(root_path, arcname='OxJS', filter=filter_build)
|
|
build_tar.close()
|
|
write_link(build_file, root_path + 'downloads/OxJS.latest.build.tar.gz')
|
|
|
|
|
|
def copy_file(source, target):
|
|
print 'copying', source, 'to', target
|
|
write_file(target, read_file(source))
|
|
|
|
def filter_build(tarinfo):
|
|
if tarinfo.name == 'OxJS':
|
|
return tarinfo
|
|
if re.search('^OxJS/build', tarinfo.name):
|
|
return tarinfo
|
|
return None
|
|
|
|
def filter_source(tarinfo):
|
|
if re.search('^OxJS/(demos|downloads/|tools/geo/png/icons/)', tarinfo.name):
|
|
return None
|
|
if re.search('/\.', tarinfo.name) or re.search('(\.gz|[~])$', tarinfo.name):
|
|
return None
|
|
return tarinfo
|
|
|
|
def get_title(file):
|
|
match = re.search('<h1>(.+)</h1>', read_file(file))
|
|
return match.groups()[0] if match else 'Untitled'
|
|
|
|
def read_file(file):
|
|
print 'reading', file
|
|
f = open(file)
|
|
data = f.read()
|
|
f.close()
|
|
return data
|
|
|
|
def write_file(file, data):
|
|
print 'writing', file
|
|
write_path(file)
|
|
f = open(file, 'w')
|
|
f.write(data)
|
|
f.close()
|
|
return len(data)
|
|
|
|
def write_link(source, target):
|
|
print 'linking', source, 'to', target
|
|
write_path(target)
|
|
if os.path.exists(target):
|
|
os.unlink(target)
|
|
os.symlink(source, target)
|
|
|
|
def write_path(file):
|
|
path = os.path.split(file)[0]
|
|
if path and not os.path.exists(path):
|
|
os.makedirs(path)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
build_oxjs(downloads='-downloads' in sys.argv, geo=not '-nogeo' in sys.argv)
|