forked from idolpx/mobile-rr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
www_proc.py
217 lines (174 loc) · 6.67 KB
/
www_proc.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
#
# Clone files from "www" to "data" folder
# Then compress and embed resources
#
from distutils import dir_util
from shutil import copyfileobj, move, rmtree
import base64, gzip, os, sys, re
try:
import configparser
except ImportError:
import ConfigParser as configparser
def gzFile(file):
with open(file, 'rb') as f_in, gzip.open(file + '.gz', 'wb') as f_out:
copyfileobj(f_in, f_out)
os.remove(file)
def read_file(file):
with open(file, 'r') as myfile:
content = myfile.read()
return content.strip()
def read_media(file):
with open(file, 'rb') as myfile:
content = base64.b64encode(myfile.read())
return content
def get_mimetype(file):
filename, file_extension = os.path.splitext(file)
return {
'.gif': 'image/gif',
'.png': 'image/png',
'.jpg': 'image/jpg',
'.svg': 'image/svg+xml',
'.mp3': 'audio/mp3'
}[file_extension]
def minify_css(css):
# 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 )
# shorten collapsable colors: #aabbcc to #abc
css = re.sub( r'#([0-9a-f])\1([0-9a-f])\2([0-9a-f])\3(\s|;)', r'#\1\2\3\4', css )
# fragment values can loose zeros
css = re.sub( r':\s*0(\.\d+([cm]m|e[mx]|in|p[ctx]))\s*;', r':\1;', css )
for rule in re.findall( r'([^{]+){([^}]*)}', css ):
# we don't need spaces around operators
selectors = [re.sub( r'(?<=[\[\(>+=])\s+|\s+(?=[=~^$*|>+\]\)])', r'', selector.strip() ) for selector in rule[0].split( ',' )]
# order is important, but we still want to discard repetitions
properties = {}
porder = []
for prop in re.findall( '(.*?):(.*?)(;|$)', rule[1] ):
key = prop[0].strip().lower()
if key not in porder: porder.append( key )
properties[ key ] = prop[1].strip()
# output rule if it contains any declarations
if properties:
print("%s{%s}" % ( ','.join( selectors ), ''.join(['%s:%s;' % (key, properties[key]) for key in porder])[:-1] ))
return css
def embed_css(content):
pattern = re.compile(u'<link.*href=[\'"](.*?)[\'"].*/>')
# Combine CSS
matches = re.findall(pattern, content)
css_content = ''
for match in matches:
css_content = css_content + '<style>\n' + read_file(data + match) + '\n</style>\n'
os.remove(data + match)
print(match)
if len(css_content.strip()):
# Remove CSS includes from Content
content = pattern.sub('', content)
css_content = minify_css(css_content)
pattern = re.compile(u'</head>')
content = pattern.sub(css_content + '\n</head>', content)
return content
def combine_js(content):
# Combine Javascript
pattern = re.compile(u'<script.*src=[\'"](.*?)[\'"].*?</script>')
matches = re.findall(pattern, content)
js_content = ''
for match in matches:
js_content = js_content + read_file(data + match) + '\n'
os.remove(data + match)
print(match)
# Save combined file
if len(js_content.strip()):
with open(data + "script.js", 'w') as new_file:
# Write out new line
new_file.write( js_content )
new_file.close()
if re.search(r'gz', options):
gzFile( data + "script.js" )
# Remove Javascript includes from Content
content = pattern.sub('', content)
# Update HTML Content
if len(js_content.strip()):
pattern = re.compile(u'</head>')
content = pattern.sub(u'<script src="script.js"></script>\n</head>', content)
return content
def embed_media(content):
pattern = re.compile(u'<(?:img|audio).*src=[\'"](.*?)[\'"].*>')
# Combine CSS
matches = re.findall(pattern, content)
media_content = ''
for match in matches:
media_content = read_media(data + match)
media_content = "data:" + get_mimetype(match) + ";base64," + media_content
os.remove(data + match)
print(match)
content = re.sub(match, media_content, content)
return content
# Build httpdocs for web server
def before_buildfs(source, target, env):
print("before_buildfs")
# SPIFFS Stats With Different Combinations of Processing
# Updated: 12.28.2016
# No Processing
# 20 Files, 1.46 MB of 2.81 MB Used
# custom_option = "gz"
# 19 Files, 898.84 KB of 2.81 MB Used
# custom_option = "gz|css"
# 17 Files, 896.88 KB of 2.81 MB Used
# custom_option = "gz|css|js"
# 13 Files, 893.94 KB of 2.81 MB Used
# custom_option = "gz|css|js|media"
# 8 Files, 898.60 KB of 2.81 MB Used
# clone 'www' folder to 'data' folder
files = dir_util.copy_tree(www, data, )
# embed Javascript, CSS & media into html files
if re.search(r'css|js|media', options):
for file in files:
if re.search(r'\.htm', file):
print(file)
content = read_file(file)
if re.search(r'css', options):
content = embed_css( content )
if re.search(r'js', options):
content = combine_js( content )
if re.search(r'media', options):
content = embed_media( content )
# Save New HTML File
with open(file, 'w') as new_file:
new_file.write( content )
new_file.close()
# gzip appropriate files
if re.search(r'gz', options):
pattern = re.compile(u'\.htm|\.css|\.js|\.map|\.svg|\.ico')
for file in files:
if re.search(pattern, file):
if os.path.exists(file):
print(file)
gzFile( file )
# remove 'data' folder after upload
def after_uploadfs(source, target, env):
print("after_uploadfs")
rmtree(data)
Import("env")
config = configparser.ConfigParser()
config.read("platformio.ini")
options = config.get("env:d1_mini_pro","custom_option")
print(config.sections())
# Set parameters from environment variables
data = env['PROJECT_DIR'] + "/data/"
www = env['PROJECT_DIR'] + "/www/"
# Show parameters
print(data)
print(www)
print(options)
# Only run when building & uploading SPIFFS image
#env.AddPreAction("buildfs", before_buildfs)
env.AddPreAction("$BUILD_DIR/spiffs.bin", before_buildfs)
env.AddPostAction("uploadfs", after_uploadfs)
#if 'SPIFFS_START' in env:
# before_buildfs("","buildfs",env)