Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Jean-Francois Dockes
upmpdcli
Commits
7ebbdb17
Commit
7ebbdb17
authored
Feb 01, 2017
by
Jean-Francois Dockes
Browse files
none
parent
e7698b09
Changes
3
Hide whitespace changes
Inline
Side-by-side
src/mediaserver/cdplugins/uprcl/uprcl-app.py
View file @
7ebbdb17
...
...
@@ -23,17 +23,22 @@ import posixpath
import
re
import
conftree
import
cmdtalkplugin
import
folders
import
uprclfolders
import
uprclsearch
from
uprclutils
import
*
from
recoll
import
recoll
from
recoll
import
rclconfig
g_myprefix
=
'0$uprcl$folders'
# Func name to method mapper
dispatcher
=
cmdtalkplugin
.
Dispatch
()
# Pipe message handler
msgproc
=
cmdtalkplugin
.
Processor
(
dispatcher
)
def
module_init
():
global
httphp
global
pathprefix
def
uprcl_init
():
global
httphp
,
pathprefix
,
uprclhost
,
pathmap
if
"UPMPD_HTTPHOSTPORT"
not
in
os
.
environ
:
raise
Exception
(
"No UPMPD_HTTPHOSTPORT in environment"
)
...
...
@@ -45,24 +50,26 @@ def module_init():
raise
Exception
(
"No UPMPD_CONFIG in environment"
)
upconfig
=
conftree
.
ConfSimple
(
os
.
environ
[
"UPMPD_CONFIG"
])
global
uprclhost
,
pathmap
uprclhost
=
upconfig
.
get
(
"uprclhost"
)
if
uprclhost
is
None
:
msgproc
.
log
(
"uprcl init: no uprclhost in config file"
)
return
False
raise
Exception
(
"uprclhost not in config"
)
pthstr
=
upconfig
.
get
(
"uprclpaths"
)
if
pthstr
is
None
:
msgproc
.
log
(
"uprcl init: no uprclpaths in config file"
)
return
False
raise
Exception
(
"uprclpaths not in config"
)
lpth
=
pthstr
.
split
(
','
)
pathmap
=
{}
for
ptt
in
lpth
:
l
=
ptt
.
split
(
':'
)
pathmap
[
l
[
0
]]
=
l
[
1
]
return
True
global
rclconfdir
rclconfdir
=
upconfig
.
get
(
"uprclconfdir"
)
if
rclconfdir
is
None
:
raise
Exception
(
"uprclconfdir not in config"
)
uprclfolders
.
inittree
(
rclconfdir
)
@
dispatcher
.
record
(
'trackuri'
)
def
trackuri
(
a
):
...
...
@@ -105,7 +112,7 @@ def browse(a):
entries
.
append
(
rcldirentry
(
'0$uprcl$'
+
'folders'
,
'0$uprcl$'
,
'[folders]'
))
elif
idpath
.
startswith
(
"folders"
):
entries
=
folders
.
browse
(
objid
,
bflg
,
httphp
,
pathprefix
)
entries
=
uprcl
folders
.
browse
(
objid
,
bflg
,
httphp
,
pathprefix
)
else
:
pass
...
...
@@ -119,37 +126,36 @@ def browse(a):
def
search
(
a
):
msgproc
.
log
(
"search: [%s]"
%
a
)
objid
=
a
[
'objid'
]
field
=
a
[
'field'
]
if
'field'
in
a
else
None
value
=
a
[
'value'
]
objkind
=
a
[
'objkind'
]
if
'objkind'
in
a
else
None
if
re
.
match
(
'0\$uprcl\$'
,
objid
)
is
None
:
raise
Exception
(
"bad objid [%s]"
%
objid
)
upnps
=
a
[
'origsearch'
]
rcls
=
uprclsearch
.
upnpsearchtorecoll
(
upnps
)
uplog
(
"Search: recoll search: %s"
%
rcls
)
searchresults
=
session
.
search
(
value
)
if
objkind
and
objkind
not
in
[
'artist'
,
'album'
,
'playlist'
,
'track'
]:
msgproc
.
log
(
'Unknown objkind
\'
%s
\'
'
%
objkind
)
objkind
=
None
if
objkind
is
None
or
objkind
==
'artist'
:
view
(
searchresults
.
artists
,
urls_from_id
(
artist_view
,
searchresults
.
artists
),
end
=
False
)
if
objkind
is
None
or
objkind
==
'album'
:
view
(
searchresults
.
albums
,
urls_from_id
(
album_view
,
searchresults
.
albums
),
end
=
False
)
if
objkind
is
None
or
objkind
==
'playlist'
:
view
(
searchresults
.
playlists
,
urls_from_id
(
playlist_view
,
searchresults
.
playlists
),
end
=
False
)
if
objkind
is
None
or
objkind
==
'track'
:
track_list
(
searchresults
.
tracks
)
#msgproc.log("%s" % xbmcplugin.entries)
encoded
=
json
.
dumps
(
xbmcplugin
.
entries
)
rcldb
=
recoll
.
connect
(
confdir
=
rclconfdir
)
rclq
=
rcldb
.
query
()
rclq
.
execute
(
rcls
)
uplog
(
"Estimated query results: %d"
%
(
rclq
.
rowcount
))
entries
=
[]
maxcnt
=
0
totcnt
=
0
while
True
:
docs
=
rclq
.
fetchmany
()
for
doc
in
docs
:
id
=
g_myprefix
+
'$'
+
'seeyoulater'
e
=
rcldoctoentry
(
id
,
objid
,
httphp
,
pathprefix
,
doc
)
entries
.
append
(
e
)
totcnt
+=
1
if
(
maxcnt
>
0
and
totcnt
>=
maxcnt
)
or
len
(
docs
)
!=
rclq
.
arraysize
:
break
uplog
(
"Search retrieved %d docs"
%
(
totcnt
,))
encoded
=
json
.
dumps
(
entries
)
return
{
"entries"
:
encoded
}
if
not
module_init
():
msgproc
.
log
(
"Uprcl init failed"
)
sys
.
exit
(
1
)
uprcl_init
()
msgproc
.
log
(
"Uprcl running"
)
msgproc
.
mainloop
()
src/mediaserver/cdplugins/uprcl/folders.py
→
src/mediaserver/cdplugins/uprcl/
uprcl
folders.py
View file @
7ebbdb17
...
...
@@ -25,7 +25,7 @@ g_myprefix = '0$uprcl$folders'
# configuration. The entries are paths instead of simple names, and
# the doc index (j) is 0. The dir index points normally to a dirvec
# entry.
def
rcl2folders
(
docs
,
confdir
):
def
_
rcl2folders
(
docs
,
confdir
):
global
dirvec
dirvec
=
[]
...
...
@@ -113,7 +113,7 @@ def rcl2folders(docs, confdir):
# which is guaranteed to match every doc without overflowing the query
# size (because the number of mime types is limited). Something like
# title:* would overflow.
def
fetchalldocs
(
confdir
):
def
_
fetchalldocs
(
confdir
):
allthedocs
=
[]
rcldb
=
recoll
.
connect
(
confdir
=
confdir
)
...
...
@@ -134,37 +134,33 @@ def fetchalldocs(confdir):
return
allthedocs
# In
ternal init
# In
itialize (read recoll data and build tree)
def
inittree
(
confdir
):
global
g_alldocs
,
g_dirvec
g_alldocs
=
fetchalldocs
(
confdir
)
g_dirvec
=
rcl2folders
(
g_alldocs
,
confdir
)
g_alldocs
=
_
fetchalldocs
(
confdir
)
g_dirvec
=
_
rcl2folders
(
g_alldocs
,
confdir
)
## This needs to come from upmpdcli.conf
confdir
=
"/home/dockes/.recoll-mp3"
inittree
(
confdir
)
def
cmpentries
(
e1
,
e2
):
#uplog("cmpentries: %s %s" % (e1['tt'], e2['tt']))
def
_cmpentries
(
e1
,
e2
):
tp1
=
e1
[
'tp'
]
tp2
=
e2
[
'tp'
]
isct1
=
tp1
==
'ct'
isct2
=
tp2
==
'ct'
# Containers come before items, and are sorted in alphabetic order
if
tp1
==
'ct'
and
tp2
!=
'
ct
'
:
if
isct1
and
not
is
ct
2
:
return
1
elif
tp1
!=
'
ct
'
and
tp2
==
'
ct
'
:
elif
not
is
ct
1
and
is
ct
2
:
return
-
1
elif
tp1
==
'ct'
and
tp2
==
'ct'
:
if
tp1
<
tp2
:
elif
isct1
and
isct2
:
tt1
=
e1
[
'tt'
]
tt2
=
e2
[
'tt'
]
if
tt1
<
tt2
:
return
-
1
elif
t
p
1
>
t
p
2
:
elif
t
t
1
>
t
t
2
:
return
1
else
:
return
0
# 2 tracks. Sort by album then track number
k
=
'upnp:album'
a1
=
e1
[
k
]
if
k
in
e1
else
""
...
...
@@ -179,6 +175,8 @@ def cmpentries(e1, e2):
a2
=
e2
[
k
]
if
k
in
e2
else
"0"
return
int
(
a1
)
-
int
(
a2
)
# Browse method
# objid is like folders$index
# flag is meta or children.
def
browse
(
pid
,
flag
,
httphp
,
pathprefix
):
...
...
@@ -224,4 +222,4 @@ def browse(pid, flag, httphp, pathprefix):
entries
.
append
(
e
)
#return entries
return
sorted
(
entries
,
cmp
=
cmpentries
)
return
sorted
(
entries
,
cmp
=
_
cmpentries
)
src/mediaserver/cdplugins/uprcl/uprclsearch.py
0 → 100644
View file @
7ebbdb17
#!/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
)
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment