mirror of
https://github.com/koniu/recoll-webui.git
synced 2025-10-03 09:49:25 +02:00
added preview and open links using rclextract when available
This commit is contained in:
parent
1f91a59af6
commit
933529b479
4 changed files with 86 additions and 15 deletions
|
@ -75,6 +75,7 @@ body { margin: 0; font-family: sans-serif }
|
||||||
}
|
}
|
||||||
.search-result-url { clear:left; }
|
.search-result-url { clear:left; }
|
||||||
.search-result-url a { color: #5a5; font-size: 8pt; float: left; margin-right: 1em;}
|
.search-result-url a { color: #5a5; font-size: 8pt; float: left; margin-right: 1em;}
|
||||||
|
.search-result-links {color: #aaf; font-size: 8pt; float: left; margin-right: 1em}
|
||||||
.search-result-date { color: #777; font-size: 8pt; float: right; margin-bottom: 7px; }
|
.search-result-date { color: #777; font-size: 8pt; float: right; margin-bottom: 7px; }
|
||||||
.search-result-size { color: #777; font-size: 8pt; float: right; display: none; }
|
.search-result-size { color: #777; font-size: 8pt; float: right; display: none; }
|
||||||
.search-result-highlight { color: #7E1212; font-weight: bold; }
|
.search-result-highlight { color: #7E1212; font-weight: bold; }
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
%if len(d['ipath']) > 0:
|
%if len(d['ipath']) > 0:
|
||||||
<div class="search-result-ipath">[{{d['ipath']}}]</div>
|
<div class="search-result-ipath">[{{d['ipath']}}]</div>
|
||||||
%end
|
%end
|
||||||
%if d.has_key('author') and len(d['author']) > 0:
|
%if d.has_key('author') and len(d['author']) > 0:
|
||||||
<div class="search-result-author">{{d['author']}}</div>
|
<div class="search-result-author">{{d['author']}}</div>
|
||||||
%end
|
%end
|
||||||
<div class="search-result-url">
|
<div class="search-result-url">
|
||||||
|
@ -21,6 +21,12 @@
|
||||||
%end
|
%end
|
||||||
<a href="{{url.replace('/'+d['filename'],'')}}">{{urllabel}}</a>
|
<a href="{{url.replace('/'+d['filename'],'')}}">{{urllabel}}</a>
|
||||||
</div>
|
</div>
|
||||||
|
%if hasrclextract:
|
||||||
|
<div class="search-result-links">
|
||||||
|
<a href="/preview/{{number-1}}?{{query_string}}" target="_blank">Preview</a>
|
||||||
|
<a href="/edit/{{number-1}}?{{query_string}}">Open</a>
|
||||||
|
</div>
|
||||||
|
%end
|
||||||
<div class="search-result-date">{{d['time']}}</div>
|
<div class="search-result-date">{{d['time']}}</div>
|
||||||
%for q in shlex.split(query['query'].replace("'","\\'")):
|
%for q in shlex.split(query['query'].replace("'","\\'")):
|
||||||
%if not q == "OR":
|
%if not q == "OR":
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
%include pages query=query, config=config, nres=nres
|
%include pages query=query, config=config, nres=nres
|
||||||
<div id="results">
|
<div id="results">
|
||||||
%for i in range(0, len(res)):
|
%for i in range(0, len(res)):
|
||||||
%include result d=res[i], i=i, query=query, config=config,
|
%include result d=res[i], i=i, query=query, config=config, query_string=query_string, hasrclextract=hasrclextract
|
||||||
%end
|
%end
|
||||||
</div>
|
</div>
|
||||||
%include pages query=query, config=config, nres=nres
|
%include pages query=query, config=config, nres=nres
|
||||||
|
|
90
webui.py
90
webui.py
|
@ -3,10 +3,15 @@
|
||||||
import os
|
import os
|
||||||
import bottle
|
import bottle
|
||||||
import time
|
import time
|
||||||
|
import sys
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from recoll import recoll
|
from recoll import recoll
|
||||||
|
from recoll import rclextract
|
||||||
|
hasrclextract = True
|
||||||
except:
|
except:
|
||||||
import recoll
|
import recoll
|
||||||
|
hasrclextract = False
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
import glob
|
import glob
|
||||||
|
@ -166,20 +171,28 @@ def query_to_recoll_string(q):
|
||||||
qs += " dir:\"%s\" " % q['dir']
|
qs += " dir:\"%s\" " % q['dir']
|
||||||
return qs
|
return qs
|
||||||
#}}}
|
#}}}
|
||||||
#{{{ recoll_search
|
#{{{ recoll_initsearch
|
||||||
def recoll_search(q):
|
def recoll_initsearch(q):
|
||||||
config = get_config()
|
config = get_config()
|
||||||
tstart = datetime.datetime.now()
|
|
||||||
results = []
|
|
||||||
db = recoll.connect(config['confdir'])
|
db = recoll.connect(config['confdir'])
|
||||||
db.setAbstractParams(config['maxchars'], config['context'])
|
db.setAbstractParams(config['maxchars'], config['context'])
|
||||||
query = db.query()
|
query = db.query()
|
||||||
query.sortby(q['sort'], q['ascending'])
|
query.sortby(q['sort'], q['ascending'])
|
||||||
try:
|
try:
|
||||||
qs = query_to_recoll_string(q)
|
qs = query_to_recoll_string(q)
|
||||||
nres = query.execute(qs, config['stem'])
|
query.execute(qs, config['stem'])
|
||||||
except:
|
except:
|
||||||
nres = 0
|
pass
|
||||||
|
return query
|
||||||
|
#}}}
|
||||||
|
#{{{ recoll_search
|
||||||
|
def recoll_search(q):
|
||||||
|
config = get_config()
|
||||||
|
tstart = datetime.datetime.now()
|
||||||
|
results = []
|
||||||
|
query = recoll_initsearch(q)
|
||||||
|
nres = query.rowcount
|
||||||
|
|
||||||
if config['maxresults'] == 0:
|
if config['maxresults'] == 0:
|
||||||
config['maxresults'] = nres
|
config['maxresults'] = nres
|
||||||
if nres > config['maxresults']:
|
if nres > config['maxresults']:
|
||||||
|
@ -189,10 +202,12 @@ def recoll_search(q):
|
||||||
q['page'] = 1
|
q['page'] = 1
|
||||||
offset = (q['page'] - 1) * config['perpage']
|
offset = (q['page'] - 1) * config['perpage']
|
||||||
|
|
||||||
if type(query.next) == int:
|
if query.rowcount > 0:
|
||||||
query.next = offset
|
if type(query.next) == int:
|
||||||
else:
|
query.next = offset
|
||||||
query.scroll(offset)
|
else:
|
||||||
|
query.scroll(offset, mode='absolute')
|
||||||
|
|
||||||
for i in range(config['perpage']):
|
for i in range(config['perpage']):
|
||||||
try:
|
try:
|
||||||
doc = query.fetchone()
|
doc = query.fetchone()
|
||||||
|
@ -208,7 +223,7 @@ def recoll_search(q):
|
||||||
d['label'] = select([d['title'], d['filename'], '?'], [None, ''])
|
d['label'] = select([d['title'], d['filename'], '?'], [None, ''])
|
||||||
d['sha'] = hashlib.sha1(d['url']+d['ipath']).hexdigest()
|
d['sha'] = hashlib.sha1(d['url']+d['ipath']).hexdigest()
|
||||||
d['time'] = timestr(d['mtime'], config['timefmt'])
|
d['time'] = timestr(d['mtime'], config['timefmt'])
|
||||||
d['snippet'] = db.makeDocAbstract(doc, query).encode('utf-8')
|
d['snippet'] = query.makedocabstract(doc).encode('utf-8')
|
||||||
results.append(d)
|
results.append(d)
|
||||||
tend = datetime.datetime.now()
|
tend = datetime.datetime.now()
|
||||||
return results, nres, tend - tstart
|
return results, nres, tend - tstart
|
||||||
|
@ -241,8 +256,57 @@ def results():
|
||||||
if config['perpage'] == 0:
|
if config['perpage'] == 0:
|
||||||
config['perpage'] = nres
|
config['perpage'] = nres
|
||||||
return { 'res': res, 'time': timer, 'query': query, 'dirs':
|
return { 'res': res, 'time': timer, 'query': query, 'dirs':
|
||||||
get_dirs(config['dirs'], config['dirdepth']),'qs': qs, 'sorts': SORTS, 'config': config,
|
get_dirs(config['dirs'], config['dirdepth']),
|
||||||
'query_string': bottle.request.query_string, 'nres': nres }
|
'qs': qs, 'sorts': SORTS, 'config': config,
|
||||||
|
'query_string': bottle.request.query_string, 'nres': nres,
|
||||||
|
'hasrclextract': hasrclextract }
|
||||||
|
#}}}
|
||||||
|
#{{{ preview
|
||||||
|
@bottle.route('/preview/<resnum:int>')
|
||||||
|
def preview(resnum):
|
||||||
|
if not hasrclextract:
|
||||||
|
return 'Sorry, needs recoll version 1.19 or later'
|
||||||
|
query = get_query()
|
||||||
|
qs = query_to_recoll_string(query)
|
||||||
|
rclq = recoll_initsearch(query)
|
||||||
|
if resnum > rclq.rowcount - 1:
|
||||||
|
return 'Bad result index %d' % resnum
|
||||||
|
rclq.scroll(resnum)
|
||||||
|
doc = rclq.fetchone()
|
||||||
|
xt = rclextract.Extractor(doc)
|
||||||
|
tdoc = xt.textextract(doc.ipath)
|
||||||
|
if tdoc.mimetype == 'text/html':
|
||||||
|
bottle.response.content_type = 'text/html; charset=utf-8'
|
||||||
|
else:
|
||||||
|
bottle.response.content_type = 'text/plain; charset=utf-8'
|
||||||
|
return tdoc.text
|
||||||
|
#}}}
|
||||||
|
#{{{ edit
|
||||||
|
@bottle.route('/edit/<resnum:int>')
|
||||||
|
def edit(resnum):
|
||||||
|
if not hasrclextract:
|
||||||
|
return 'Sorry, needs recoll version 1.19 or later'
|
||||||
|
query = get_query()
|
||||||
|
qs = query_to_recoll_string(query)
|
||||||
|
rclq = recoll_initsearch(query)
|
||||||
|
if resnum > rclq.rowcount - 1:
|
||||||
|
return 'Bad result index %d' % resnum
|
||||||
|
rclq.scroll(resnum)
|
||||||
|
doc = rclq.fetchone()
|
||||||
|
bottle.response.content_type = doc.mimetype
|
||||||
|
# If ipath is null, we can just return the file
|
||||||
|
pathismine = False
|
||||||
|
if doc.ipath == '':
|
||||||
|
path = doc.url.replace('file://','')
|
||||||
|
else:
|
||||||
|
xt = rclextract.Extractor(doc)
|
||||||
|
path = xt.idoctofile(doc.ipath, doc.mimetype)
|
||||||
|
pathismine = True
|
||||||
|
print >> sys.stderr, "Sending %s with mimetype %s" % (path, doc.mimetype)
|
||||||
|
f = open(path, 'r')
|
||||||
|
if pathismine:
|
||||||
|
os.unlink(path)
|
||||||
|
return f
|
||||||
#}}}
|
#}}}
|
||||||
#{{{ json
|
#{{{ json
|
||||||
@bottle.route('/json')
|
@bottle.route('/json')
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue