342 # no extension, this is a precise value |
342 # no extension, this is a precise value |
343 return int(s) |
343 return int(s) |
344 except ValueError: |
344 except ValueError: |
345 raise error.ParseError(_("couldn't parse size: %s") % s) |
345 raise error.ParseError(_("couldn't parse size: %s") % s) |
346 |
346 |
347 @predicate('size(expression)', callexisting=True) |
347 def sizematcher(x): |
348 def size(mctx, x): |
348 """Return a function(size) -> bool from the ``size()`` expression""" |
349 """File size matches the given expression. Examples: |
|
350 |
|
351 - size('1k') - files from 1024 to 2047 bytes |
|
352 - size('< 20k') - files less than 20480 bytes |
|
353 - size('>= .5MB') - files at least 524288 bytes |
|
354 - size('4k - 1MB') - files from 4096 bytes to 1048576 bytes |
|
355 """ |
|
356 |
349 |
357 # i18n: "size" is a keyword |
350 # i18n: "size" is a keyword |
358 expr = getstring(x, _("size requires an expression")).strip() |
351 expr = getstring(x, _("size requires an expression")).strip() |
359 if '-' in expr: # do we have a range? |
352 if '-' in expr: # do we have a range? |
360 a, b = expr.split('-', 1) |
353 a, b = expr.split('-', 1) |
361 a = util.sizetoint(a) |
354 a = util.sizetoint(a) |
362 b = util.sizetoint(b) |
355 b = util.sizetoint(b) |
363 m = lambda x: x >= a and x <= b |
356 return lambda x: x >= a and x <= b |
364 elif expr.startswith("<="): |
357 elif expr.startswith("<="): |
365 a = util.sizetoint(expr[2:]) |
358 a = util.sizetoint(expr[2:]) |
366 m = lambda x: x <= a |
359 return lambda x: x <= a |
367 elif expr.startswith("<"): |
360 elif expr.startswith("<"): |
368 a = util.sizetoint(expr[1:]) |
361 a = util.sizetoint(expr[1:]) |
369 m = lambda x: x < a |
362 return lambda x: x < a |
370 elif expr.startswith(">="): |
363 elif expr.startswith(">="): |
371 a = util.sizetoint(expr[2:]) |
364 a = util.sizetoint(expr[2:]) |
372 m = lambda x: x >= a |
365 return lambda x: x >= a |
373 elif expr.startswith(">"): |
366 elif expr.startswith(">"): |
374 a = util.sizetoint(expr[1:]) |
367 a = util.sizetoint(expr[1:]) |
375 m = lambda x: x > a |
368 return lambda x: x > a |
376 elif expr[0].isdigit or expr[0] == '.': |
369 elif expr[0].isdigit or expr[0] == '.': |
377 a = util.sizetoint(expr) |
370 a = util.sizetoint(expr) |
378 b = _sizetomax(expr) |
371 b = _sizetomax(expr) |
379 m = lambda x: x >= a and x <= b |
372 return lambda x: x >= a and x <= b |
380 else: |
373 raise error.ParseError(_("couldn't parse size: %s") % expr) |
381 raise error.ParseError(_("couldn't parse size: %s") % expr) |
374 |
382 |
375 @predicate('size(expression)', callexisting=True) |
|
376 def size(mctx, x): |
|
377 """File size matches the given expression. Examples: |
|
378 |
|
379 - size('1k') - files from 1024 to 2047 bytes |
|
380 - size('< 20k') - files less than 20480 bytes |
|
381 - size('>= .5MB') - files at least 524288 bytes |
|
382 - size('4k - 1MB') - files from 4096 bytes to 1048576 bytes |
|
383 """ |
|
384 m = sizematcher(x) |
383 return [f for f in mctx.existing() if m(mctx.ctx[f].size())] |
385 return [f for f in mctx.existing() if m(mctx.ctx[f].size())] |
384 |
386 |
385 @predicate('encoding(name)', callexisting=True) |
387 @predicate('encoding(name)', callexisting=True) |
386 def encoding(mctx, x): |
388 def encoding(mctx, x): |
387 """File can be successfully decoded with the given character |
389 """File can be successfully decoded with the given character |