Browse Source

implement searching by metadata modified date...

main
John-Mark Gurney 2 months ago
parent
commit
50c006a3ce
2 changed files with 65 additions and 9 deletions
  1. +22
    -2
      ui/fixtures/cmd.search.json
  2. +43
    -7
      ui/medashare/cli.py

+ 22
- 2
ui/fixtures/cmd.search.json View File

@@ -24,6 +24,9 @@
"title": "add tag a",
"cmd": [ "modify", "+tag=foo", "+dc:creator=John-Mark Gurney", "newfile.txt" ]
},
{
"special": "store now"
},
{
"title": "add tag b",
"cmd": [ "modify", "+tag=bar", "+dc:creator=John-Mark Gurney", "+other=baz", "test.txt" ]
@@ -34,8 +37,25 @@
"count": 6
},
{
"title": "search tag foo",
"cmd": [ "search", "file", "+tag=foo" ],
"title": "invalid meta:",
"cmd": [ "search", "file", "+meta:modified" ],
"stderr": "invalid meta: specification: 'meta:modified'\n",
"exit": 1
},
{
"special": "format next cmd"
},
{
"title": "search on meta:modified",
"cmd": [ "search", "file", "+meta:modified>{nowiso}" ],
"stdout_re": "/test.txt\n$"
},
{
"special": "format next cmd"
},
{
"title": "search on meta:modified",
"cmd": [ "search", "file", "+meta:modified<{nowiso}" ],
"stdout_re": "/newfile.txt\n$"
},
{


+ 43
- 7
ui/medashare/cli.py View File

@@ -50,6 +50,7 @@ import itertools
import json
import libarchive
import magic
import operator
import os.path
import pathlib
import pasn1
@@ -96,6 +97,16 @@ def _iterdictlist(obj, **kwargs):
else:
yield k, v

_metaopre = re.compile('meta:(?P<key>[a-zA-Z]+)(?P<op>=|<|>|!=|<=|>=)(?P<val>.*)')
_metaoplookup = {
'=': operator.eq, '!=': operator.ne,
'<': operator.lt, '>': operator.gt,
'<=': operator.le, '>=': operator.ge
}
_metavalueconv = {
'modified': datetime.datetime.fromisoformat,
}

from .utils import _makeuuid, _makedatetime, _asn1coder

from .mdb import MDBase
@@ -1631,19 +1642,37 @@ def cmd_search(options, persona, objstr, cache):
skeymap = aliased(orm.StringTable)
svaluemap = aliased(orm.StringTable)

origvalue = '='.join(i[1:])

try:
op, key, value = i
except ValueError:
op, key = i
value = None

subq = select(propmapsub.obj).where(
# that match the key
propmapsub.keyid == skeymap.id, skeymap.str == key)
# handle meta tree
if key.startswith('meta:'):
mat = _metaopre.match(origvalue)
if not mat:
print('invalid meta: specification: %s' % repr(origvalue),
file=sys.stderr)
sys.exit(1)

#print(repr(mat), repr(mat.groups()), file=_real_stderr)

mdo = aliased(orm.MetaDataObject)
metavalue = _metavalueconv[mat.group('key')](mat.group('val'))
subq = select(propmapsub.obj).where(propmapsub.obj == mdo.uuid,
_metaoplookup[mat.group('op')](mdo.modified, metavalue))

else:
subq = select(propmapsub.obj).where(
# that match the key
propmapsub.keyid == skeymap.id, skeymap.str == key)

if value is not None:
subq = subq.where(propmapsub.valueid == svaluemap.id,
svaluemap.str == value)
if value is not None:
subq = subq.where(propmapsub.valueid == svaluemap.id,
svaluemap.str == value)

#subq = subq.subquery()

@@ -1719,6 +1748,7 @@ def cmd_search(options, persona, objstr, cache):
sel = sel.execution_options(yield_per=10)

#_debprint('sel:', _getquery(sel, objstr))
#print('sel:', _getquery(sel, objstr), file=_real_stderr)

with objstr._ses() as session:
r = ( x[0] for x in session.execute(sel) )
@@ -2508,7 +2538,7 @@ class _TestCases(unittest.TestCase):

patches = []

for cmd in cmds:
for idx, cmd in enumerate(cmds):
try:
if cmd['skip']: # pragma: no cover
continue
@@ -2583,6 +2613,12 @@ class _TestCases(unittest.TestCase):
elif special == 'setup tar file':
shutil.copy(self.fixtures /
'testfile.tar.gz', self.tempdir)
elif special == 'store now':
storednow = datetime.datetime.now(datetime.timezone.utc)
elif special == 'format next cmd':
modcmd = cmds[idx + 1]
formatkwargs = dict(nowiso=storednow.isoformat())
modcmd['cmd'] = [ x.format(**formatkwargs) for x in modcmd['cmd'] ]
else: # pragma: no cover
raise ValueError('unhandled special: %s' % repr(special))



Loading…
Cancel
Save