3
# client showing use of command_hook_mirror
5
from simplestreams import mirrors
6
from simplestreams import log
7
from simplestreams import util
17
sys.stderr.write("WARN: %s" % msg)
20
class ItemFilter(object):
21
def __init__(self, content, noneval=""):
22
rparsefmt="(\w+)[ ]*([!]{0,1}[=~])[ ]*(.*)[ ]*$"
23
parsed = re.match(rparsefmt, content)
26
raise ValueError("Unable to parse expression %s" % content)
28
(key, op, val) = parsed.groups()
31
self._matches = val.__eq__
32
elif op in ("!~", "~"):
33
self._matches = re.compile(val).search
35
raise ValueError("Bad parsing of %s" % content)
37
self.negator = (op[0] != "!")
41
self.content = content
42
self.noneval = noneval
46
return "%s %s %s [none=%s]" % (self.key, self.op,
47
self.value, self.noneval)
52
def matches(self, item):
53
val = str(item.get(self.key, self.noneval))
54
return (self.negator == bool(self._matches(val)))
57
def get_filters(filters, noneval=""):
60
flist.append(ItemFilter(f, noneval=noneval))
64
class FilterMirror(mirrors.BasicMirrorWriter):
65
def __init__(self, config=None):
66
super(FilterMirror, self).__init__(config=config)
70
self.filters = config.get('filters', [])
71
outfmt = config.get('output_format')
74
self.output_format = outfmt
77
def load_products(self, path=None, content_id=None):
78
return {'content_id': content_id, 'products': {}}
80
def filter_item(self, data, src, target, pedigree):
81
# src and target are top level products:1.0
82
# data is src['products'][ped[0]]['versions'][ped[1]]['items'][ped[2]]
83
data = util.products_exdata(src, pedigree)
84
for f in self.filters:
85
if not f.matches(data):
89
def insert_item(self, data, src, target, pedigree, contentsource):
90
# src and target are top level products:1.0
91
# data is src['products'][ped[0]]['versions'][ped[1]]['items'][ped[2]]
92
# contentsource is a ContentSource if 'path' exists in data or None
93
data = util.products_exdata(src, pedigree)
95
data.update({'item_url': contentsource.url})
98
print(self.output_format % (data))
100
sys.stderr.write("output format failed. Missing %s\n" % e.args)
101
sys.stderr.write("item: %s\n" % data)
105
parser = argparse.ArgumentParser()
107
parser.add_argument('--max', type=int, default=None, dest='max_items',
108
help='store at most MAX items in the target')
110
parser.add_argument('--path', default=None,
111
help='sync from index or products file in mirror')
113
parser.add_argument('--output-format', '-o', action='store', default=None)
114
parser.add_argument('--verbose', '-v', action='count', default=0)
115
parser.add_argument('--log-file', default=sys.stderr,
116
type=argparse.FileType('w'))
118
parser.add_argument('mirror_url')
119
parser.add_argument('filters', nargs='*', default=[])
121
cmdargs = parser.parse_args()
123
(mirror_url, path) = util.path_from_mirror_url(cmdargs.mirror_url,
126
level = (log.ERROR, log.INFO, log.DEBUG)[min(cmdargs.verbose, 2)]
127
log.basicConfig(stream=cmdargs.log_file, level=level)
129
smirror = mirrors.UrlMirrorReader(mirror_url)
131
filters = get_filters(cmdargs.filters)
132
cfg = {'max_items': cmdargs.max_items,
134
'output_format': cmdargs.output_format}
136
tmirror = FilterMirror(config=cfg)
137
tmirror.sync(smirror.reader, path)
139
if __name__ == '__main__':
142
# vi: ts=4 expandtab syntax=python