Skip to content

Commit 27913b8

Browse files
committed
Separate functions from main script.
1 parent 4d22d05 commit 27913b8

2 files changed

Lines changed: 239 additions & 228 deletions

File tree

syrup/__main__.py

Lines changed: 10 additions & 228 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,16 @@
1-
import hashlib
2-
import urllib
31
import os
4-
import sys
5-
import subprocess
6-
import shutil
7-
import stat
82
from collections import namedtuple
9-
import fnmatch
103

11-
from PIL import Image
12-
import requests
134
import click
145

15-
CHECKSUM_TYPE = "sha256"
16-
17-
ICON_SIZES = [16, 32, 48, 64, 96, 128, 256]
18-
19-
TEMP_DIR = "tmp"
20-
21-
TOOLS_7ZIP = "./tools/7z"
22-
TOOLS_NSIS = "D:/Software/NSIS/Bin/makensis.exe"
6+
from .functions import (
7+
cleanArtifacts,
8+
cleanBuild,
9+
copySrc,
10+
makeIco,
11+
compileNSISTemplate,
12+
NSISBuildInstaller,
13+
)
2314

2415
Version = namedtuple('Version', ['major', 'minor', 'build'])
2516
Version.__str__ = lambda self: "{self.major}.{self.minor}.{self.build}".format(self=self)
@@ -29,216 +20,6 @@
2920
def cli():
3021
pass
3122

32-
33-
def download_file(url, target=None, verbose=False):
34-
# https://stackoverflow.com/a/16696317
35-
# NOTE the stream=True parameter
36-
cs = hashlib.new(CHECKSUM_TYPE)
37-
req = requests.get(url, stream=True)
38-
39-
url_fn = os.path.basename(urllib.parse.urlparse(req.url).path)
40-
41-
if target is None:
42-
outpath = os.path.realpath(url_fn)
43-
elif os.path.isdir(target) or target[-1] in ['/', '\\']:
44-
outpath = os.path.join(target, url_fn)
45-
else:
46-
outpath = target
47-
48-
os.makedirs(os.path.dirname(outpath), exist_ok=True)
49-
50-
with open(outpath, 'wb') as fh:
51-
for chunk in req.iter_content(chunk_size=None):
52-
if chunk: # filter out keep-alive new chunks
53-
fh.write(chunk)
54-
cs.update(chunk)
55-
fh.flush()
56-
return (outpath, cs.hexdigest())
57-
58-
def parse_checksum_file(content):
59-
result = {}
60-
for line in content.split('\n'):
61-
if not line.strip(): continue
62-
hex, fn = line.split(maxsplit=1)
63-
result[fn] = hex
64-
return result
65-
66-
def cmd(args, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, encoding=None):
67-
#print(args)
68-
p = subprocess.Popen(args, stdout=stdout, stderr=stderr)
69-
if p.stdout is not None:
70-
if encoding is not None:
71-
p.stdout.read().decode(encoding)
72-
return p.stdout.read()
73-
else:
74-
p.wait()
75-
return p.returncode
76-
77-
def p7zip_list(fn):
78-
data = cmd([TOOLS_7ZIP, "l", "-slt", "-sccUTF-8", fn]).decode("utf-8")
79-
80-
files = []
81-
82-
data = data.replace('\r\n', '\n')
83-
84-
_crap, archivedata = data.split('\n--\n', 1)
85-
_headers, filedata = archivedata.split('\n----------\n', 1)
86-
filelist = filedata.split('\n\n\n')[0].split('\n\n')
87-
88-
for fileinfo in filelist:
89-
if not fileinfo.strip(): continue
90-
91-
fi = dict([[y.strip() for y in x.split('=', 1)] for x in fileinfo.strip().split('\n')])
92-
93-
if fi.get('Attributes') == 'D': continue # Directory
94-
95-
files.append({
96-
'name': fi.get('Path'),
97-
'size': int(fi.get('Size')),
98-
'crc': fi.get('CRC'),
99-
})
100-
101-
return files
102-
103-
def p7zip_open_file(fn, name):
104-
p = subprocess.Popen(
105-
[TOOLS_7ZIP, "e", "-so", fn],
106-
stdout=subprocess.PIPE,
107-
stderr=subprocess.DEVNULL
108-
)
109-
return p.stdout
110-
111-
def p7zip_extract_file(fn, name, target=None):
112-
with p7zip_open_file(fn, name) as zfh:
113-
if target is None:
114-
outpath = os.path.realpath(name)
115-
elif os.path.isdir(target) or target[-1] in ['/', '\\']:
116-
outpath = os.path.join(target, os.path.basename(name))
117-
else:
118-
outpath = target
119-
120-
os.makedirs(os.path.dirname(outpath), exist_ok=True)
121-
with open(outpath, "wb") as ofh:
122-
ofh.write(zfh.read())
123-
124-
return outpath
125-
126-
def p7zip_extract(fn, target=None):
127-
if target is None:
128-
outpath = "."
129-
else:
130-
outpath = target
131-
os.makedirs(target, exist_ok=True)
132-
133-
p = subprocess.Popen(
134-
[TOOLS_7ZIP, "x", "-o{}".format(outpath), fn],
135-
stdout=subprocess.DEVNULL,
136-
stderr=subprocess.DEVNULL
137-
)
138-
p.wait()
139-
return outpath
140-
141-
142-
143-
def checksum_file(path, checksum_type=CHECKSUM_TYPE):
144-
cs = hashlib.new(checksum_type)
145-
with open(path, "rb") as fh:
146-
data = fh.read(1_048_576)
147-
while data:
148-
cs.update(data)
149-
data = fh.read(1_048_576)
150-
return cs.hexdigest()
151-
152-
def cleanBuild(builddir):
153-
print("Cleaning build directory...")
154-
if os.path.exists(builddir):
155-
for path, _dirs, files in os.walk(builddir):
156-
for name in files:
157-
pathname = os.path.join(path, name)
158-
# Silly git readonly files.
159-
os.chmod(pathname, stat.S_IWRITE)
160-
os.unlink(pathname)
161-
shutil.rmtree(builddir, onerror=lambda func, path, exec_info: print("WARNING: Failed to delete ", path, exec_info))
162-
163-
def cleanArtifacts(artifactdir):
164-
print("Cleaning artifact directory...")
165-
if os.path.exists(artifactdir):
166-
shutil.rmtree(artifactdir, onerror=lambda func, path, exec_info: print("WARNING: Failed to delete ", path, exec_info))
167-
168-
def copySrc(src_dir, build_dir):
169-
print("Copying src/*...")
170-
for name in os.listdir(src_dir):
171-
src = os.path.join(src_dir, name)
172-
if os.path.isdir(src):
173-
shutil.copytree(src, os.path.join(build_dir, name))
174-
else:
175-
shutil.copy(src, build_dir)
176-
177-
def makeIco(icon, name, build_dir):
178-
"Generates .ico file from .png"
179-
print("Generating .ico file...")
180-
im = Image.open(icon)
181-
fn = "{name}.ico".format(name)
182-
im.save(os.path.join(build_dir, fn), sizes=[(x,x) for x in ICON_SIZES])
183-
return fn
184-
185-
def compileNSISTemplate(build_dir, artifact_dir, executables, **kwargs):
186-
"Generates NSIS script from jinja2 template"
187-
print("Generating NSIS script...")
188-
import jinja2
189-
loader = jinja2.PackageLoader(__package__)
190-
env = jinja2.Environment(loader=loader, autoescape=False, undefined=jinja2.StrictUndefined)
191-
192-
template = env.get_template("generic.nsi.j2")
193-
194-
install_files = []
195-
install_dirs = []
196-
install_size = 0
197-
install_executables = []
198-
for path, dirs, files in os.walk(build_dir):
199-
for name in files:
200-
itempath = os.path.join(path, name)
201-
outpath = os.path.relpath(itempath, build_dir)
202-
203-
install_files.append(dict(
204-
input = itempath,
205-
output = outpath,
206-
))
207-
208-
install_size += os.stat(itempath).st_size
209-
210-
for pat in executables:
211-
if fnmatch.fnmatch(outpath, pat) and outpath not in install_executables:
212-
install_executables.append(outpath)
213-
214-
for name in dirs:
215-
itempath = os.path.join(path, name)
216-
relitempath = os.path.relpath(itempath, build_dir)
217-
install_dirs.append(relitempath)
218-
219-
template_variables = {
220-
'files': install_files,
221-
'dirs': install_dirs,
222-
'outfile': os.path.join(artifact_dir, "${APPNAME}-${VERSIONMAJOR}.${VERSIONMINOR}.${VERSIONBUILD}-setup.exe"),
223-
'size': install_size,
224-
'executables': install_executables,
225-
}
226-
template_variables.update(kwargs)
227-
228-
nsis_script = os.path.join(build_dir, "generic.nsi")
229-
with open(nsis_script, "w") as fh: # TODO: Temp file name.
230-
template.stream(**template_variables).dump(fh)
231-
return nsis_script
232-
233-
def NSISBuildInstaller(nsi_script, artifact_dir):
234-
print("Building NSIS installer...")
235-
236-
os.makedirs(artifact_dir, exist_ok=True)
237-
238-
# http://nsis.sourceforge.net/Docs/Chapter3.html#usage
239-
command = [TOOLS_NSIS, "/NOCD", "/INPUTCHARSET", "UTF8", "/P3", "/V3", nsi_script]
240-
print(cmd(command, stdout=sys.stdout, stderr=sys.stderr, encoding="utf8"))
241-
24223
@cli.command()
24324
@click.option('--build-dir', default="build", type=click.Path(file_okay=False))
24425
@click.option('--artifact-dir', default="artifacts", type=click.Path(file_okay=False))
@@ -308,4 +89,5 @@ def build(ctx, do_clean, version, name, company, description, license, icon, bui
30889
NSISBuildInstaller(nsi_script=nsi_script, artifact_dir=artifact_dir)
30990

31091
if __name__ == "__main__":
311-
cli(auto_envvar_prefix='SYRUP')
92+
# pylint:disable=unexpected-keyword-arg
93+
cli(auto_envvar_prefix='SYRUP')

0 commit comments

Comments
 (0)