--- a
+++ b/src/mediaserver/cdplugins/uprcl/uprclsearch.py
@@ -0,0 +1,121 @@
+#!/usr/bin/env python
+from __future__ import print_function
+
+def _getchar(s, i):
+ if i < len(s):
+ return i+1,s[i]
+ else:
+ return i,None
+
+def _readword(s, i):
+ w = ''
+ for j in range(i, len(s)):
+ if s[j].isspace():
+ return j,w
+ w += s[j]
+ return j,w
+
+# Called with '"' already read:
+def _readstring(s, i):
+ str = '"'
+ escape = False
+ for j in range(i, len(s)):
+ #print("s[j] [%s] out now [%s]" % (s[j],out))
+ if s[j] == '\\':
+ if not escape:
+ escape = True
+ str += '\\'
+ continue
+
+ if s[j] == '"':
+ str += '"'
+ if not escape:
+ return j+1, str
+ else:
+ str += s[j]
+
+ escape = False
+
+ return len(s), str
+
+def upnpsearchtorecoll(s):
+ s = s.replace('\t', ' ')
+ s = s.replace('\n', ' ')
+ s = s.replace('\r', ' ')
+ s = s.replace('\f', ' ')
+
+ out = []
+ hadDerived = False
+ i = 0
+ while True:
+ i,c = _getchar(s, i)
+ if not c:
+ break
+
+ if c.isspace():
+ continue
+
+ if c == "*":
+ if (len(out) > 1 or (len(out) == 1 and not out[-1].isspace())) or \
+ (len(s[i:]) and not s[i:].isspace()):
+ raise Exception("If * is used it must be the only input")
+ out = ["mime:*"]
+ break
+
+ if c == '(' or c == ')' or c == '>' or c == '<' or c == '=':
+ out.append(c)
+ else:
+ if c == '"':
+ i,w = _readstring(s, i)
+ if not w.endswith('"'):
+ raise Exception("Unterminated string in [%s]" % out)
+ else:
+ i -= 1
+ i,w = _readword(s, i)
+
+ #print("Got word [%s]" % w)
+ if w == 'contains':
+ out.append(':')
+ elif w == 'doesNotContain':
+ if len(out) < 1:
+ raise Exception("doesNotContain can't be the first word")
+ out.insert(-1, "-")
+ out.append(':')
+ elif w == 'derivedFrom':
+ hadDerived = True
+ out.append(':')
+ elif w == 'true':
+ out.append('*')
+ elif w == 'false':
+ out.append('xxxjanzocsduochterrrrm')
+ elif w == 'exists':
+ out.append(':')
+ elif w == 'and':
+ # Recoll has implied AND, but see next
+ pass
+ elif w == 'or':
+ # Does not work because OR/AND priorities are reversed
+ # between recoll and upnp. This would be very
+ # difficult to correct, let's hope that the callers
+ # use parenthesese
+ out.append('OR')
+ else:
+ if hadDerived:
+ hadDerived = False
+ if len(w) >= 1 and w[-1] == '"':
+ w = w[:-1] + '*' + '"'
+ else:
+ w += '*'
+ out.append(w)
+
+ ostr = ""
+ for tok in out:
+ ostr += tok + " "
+ return ostr
+
+
+if __name__ == '__main__':
+ s = '(upnp:artist derivedFrom "abc\\"def\\g") or (dc:title:xxx) '
+ print("INPUT: %s" % s)
+ o = upnpsearchtorecoll(s)
+ print("OUTPUT: %s" % o)