Repository navigation
Expand file tree
/
Copy path0watch.py
More file actions
74 lines (62 loc) · 2.96 KB
/
Copy path0watch.py
File metadata and controls
74 lines (62 loc) · 2.96 KB
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
# Copyright (C) 2017, Bastian Eicher
# See the README file for details, or visit http://0install.net.
from __future__ import print_function
import argparse
import sys
import subprocess
from os import path
from xml.dom import minidom
from zeroinstall.injector import model
XMLNS_IFACE= 'http://zero-install.sourceforge.net/2004/injector/interface'
def die(msg):
print(msg, file=sys.stderr)
sys.exit(1)
def load(name, path):
if sys.version_info >= (3, 5):
import importlib.util
from importlib.machinery import SourceFileLoader
loader = SourceFileLoader(name, path)
spec = importlib.util.spec_from_file_location(name, path, loader=loader)
module = importlib.util.module_from_spec(spec)
sys.modules[name] = module
loader.exec_module(module)
return module
elif sys.version_info >= (3,):
from importlib.machinery import SourceFileLoader
return SourceFileLoader(name, path).load_module()
else:
import imp
return imp.load_source(name, path)
parser = argparse.ArgumentParser(description='Scan a website for new releases and trigger 0template if required.')
parser.add_argument('watch_file', help='Python script that pulls a list of releases from a website')
parser.add_argument('-o', '--output', help='output directory')
args = parser.parse_args()
watch_file = path.abspath(args.watch_file)
if not watch_file.endswith('.watch.py'):
die("Watch file must be named *.watch.py, not '{watch_file}'".format(watch_file = watch_file))
if not path.exists(watch_file):
die("Watch file '{watch_file}' must exist".format(watch_file = watch_file))
watch_file_stem = watch_file[:-9]
template_file = watch_file_stem + '.xml.template'
if not path.exists(template_file):
die("Template file '{template_file}' must exist".format(template_file = template_file))
output_stem = watch_file_stem if args.output is None else path.join(args.output, path.basename(watch_file_stem))
feed_file = watch_file_stem + '.xml'
def output_file(version): return output_stem + '-' + model.format_version(version) + '.xml'
watch_module = load('watch', watch_file)
releases = getattr(watch_module, 'releases', None)
if not releases:
die("Watch file must set array of dicts 'releases'")
def already_known(version):
if path.exists(output_file(version)): return True
if path.exists(feed_file):
doc = minidom.parse(feed_file)
for elem in doc.getElementsByTagNameNS(XMLNS_IFACE, 'implementation') + doc.getElementsByTagNameNS(XMLNS_IFACE, 'group'):
v = elem.getAttribute('version')
if v != '' and model.parse_version(v) == version: return True
return False
for release in releases:
version = model.parse_version(release['version'])
if already_known(version): continue
retval = subprocess.call(['0template', '--force-download', '--output', output_file(version), template_file] + [key + '=' + value for (key, value) in release.items()])
if retval != 0: sys.exit(retval)