Switch to unified view

a/webui.py b/webui.py
1
#!/usr/bin/env python
1
from __future__ import print_function
2
#{{{ imports
2
#{{{ imports
3
import os
3
import os
4
import bottle
4
import bottle
5
import time
5
import time
6
import sys
6
import sys
7
import datetime
7
import datetime
8
import glob
8
import glob
9
import hashlib
9
import hashlib
10
import json
10
import json
11
import csv
11
import csv
12
import StringIO
12
import io
13
import ConfigParser
14
import string
13
import string
15
import shlex
14
import shlex
15
def msg(s):
16
    print("%s" % s, file=sys.stderr)
17
py3k = sys.version_info >= (3, 0, 0)
18
if py3k:
19
    from urllib.parse import urlencode, quote as urlquote
20
else: # 2.x
21
    from urllib import urlencode, quote as urlquote
22
16
import urllib
23
import urllib
17
# import recoll and rclextract
24
# import recoll and rclextract
18
try:
25
try:
19
    from recoll import recoll
26
    from recoll import recoll
20
    from recoll import rclextract
27
    from recoll import rclextract
21
    hasrclextract = True
28
    hasrclextract = True
22
except:
29
except Exception as err:
30
    msg("Import recoll because: %s" % err)
23
    import recoll
31
    import recoll
24
    hasrclextract = False
32
    hasrclextract = False
25
# import rclconfig system-wide or local copy
33
# Import rclconfig system-wide or local copy
26
try:
34
try:
27
    from recoll import rclconfig
35
    from recoll import rclconfig
28
except:
36
except:
29
    import rclconfig
37
    import rclconfig
30
#}}}
38
#}}}
...
...
120
    config['csvfields'] = ' '.join(ncf)
128
    config['csvfields'] = ' '.join(ncf)
121
    config['fields'] = ' '.join(FIELDS)
129
    config['fields'] = ' '.join(FIELDS)
122
    # get mountpoints
130
    # get mountpoints
123
    config['mounts'] = {}
131
    config['mounts'] = {}
124
    for d in config['dirs']:
132
    for d in config['dirs']:
125
        name = 'mount_%s' % urllib.quote(d,'')
133
        name = 'mount_%s' % urlquote(d,'')
126
        config['mounts'][d] = select([bottle.request.get_cookie(name), 'file://%s' % d], [None, ''])
134
        config['mounts'][d] = select([bottle.request.get_cookie(name), 'file://%s' % d], [None, ''])
127
135
128
    # Parameters set by the admin in the recoll configuration
136
    # Parameters set by the admin in the recoll configuration
129
    # file. These override anything else, so read them last
137
    # file. These override anything else, so read them last
130
    val = rclconf.getConfParam('webui_nojsoncsv')
138
    val = rclconf.getConfParam('webui_nojsoncsv')
...
...
169
    }
177
    }
170
    return query
178
    return query
171
#}}}
179
#}}}
172
#{{{ query_to_recoll_string
180
#{{{ query_to_recoll_string
173
def query_to_recoll_string(q):
181
def query_to_recoll_string(q):
182
    if type(q['query']) == type(u''):
183
        qs = q['query']
184
    else:
174
    qs = q['query'].decode('utf-8')
185
        qs = q['query'].decode('utf-8')
175
    if len(q['after']) > 0 or len(q['before']) > 0:
186
    if len(q['after']) > 0 or len(q['before']) > 0:
176
        qs += " date:%s/%s" % (q['after'], q['before'])
187
        qs += " date:%s/%s" % (q['after'], q['before'])
188
    qdir = q['dir']
189
    if type(qdir) != type(u''):
190
        qdir = qdir.decode('utf-8')
177
    if q['dir'] != '<all>':
191
    if qdir != '<all>':
178
        qs += " dir:\"%s\" " % q['dir'].decode('utf-8')
192
        qs += " dir:\"%s\" " % qdir
179
    return qs
193
    return qs
180
#}}}
194
#}}}
181
#{{{ recoll_initsearch
195
#{{{ recoll_initsearch
182
def recoll_initsearch(q):
196
def recoll_initsearch(q):
183
    config = get_config()
197
    config = get_config()
...
...
232
        for f in FIELDS:
246
        for f in FIELDS:
233
            v = getattr(doc, f)
247
            v = getattr(doc, f)
234
            if v is not None:
248
            if v is not None:
235
                d[f] = v.encode('utf-8')
249
                d[f] = v.encode('utf-8')
236
            else:
250
            else:
237
                d[f] = ''
251
                d[f] = b''
238
        d['label'] = select([d['title'], d['filename'], '?'], [None, ''])
252
        d['label'] = select([d['title'], d['filename'], '?'], [None, ''])
239
        d['sha'] = hashlib.sha1(d['url']+d['ipath']).hexdigest()
253
        d['sha'] = hashlib.sha1(d['url']+d['ipath']).hexdigest().encode('utf-8')
240
        d['time'] = timestr(d['mtime'], config['timefmt'])
254
        d['time'] = timestr(d['mtime'], config['timefmt']).encode('utf-8')
241
        if dosnippets:
255
        if dosnippets:
242
            d['snippet'] = query.makedocabstract(doc, highlighter).encode('utf-8')
256
            d['snippet'] = query.makedocabstract(doc, highlighter).encode('utf-8')
257
        #for n,v in d.items():
258
        #    print("type(%s) is %s" % (n,type(v)))
243
        results.append(d)
259
        results.append(d)
244
    tend = datetime.datetime.now()
260
    tend = datetime.datetime.now()
245
    return results, nres, tend - tstart
261
    return results, nres, tend - tstart
246
#}}}
262
#}}}
247
#}}}
263
#}}}
...
...
349
    query['page'] = 0
365
    query['page'] = 0
350
    qs = query_to_recoll_string(query)
366
    qs = query_to_recoll_string(query)
351
    bottle.response.headers['Content-Type'] = 'text/csv'
367
    bottle.response.headers['Content-Type'] = 'text/csv'
352
    bottle.response.headers['Content-Disposition'] = 'attachment; filename=recoll-%s.csv' % normalise_filename(qs)
368
    bottle.response.headers['Content-Disposition'] = 'attachment; filename=recoll-%s.csv' % normalise_filename(qs)
353
    res, nres, timer = recoll_search(query, False)
369
    res, nres, timer = recoll_search(query, False)
354
    si = StringIO.StringIO()
370
    si = io.StringIO()
355
    cw = csv.writer(si)
371
    cw = csv.writer(si)
356
    fields = config['csvfields'].split()
372
    fields = config['csvfields'].split()
357
    cw.writerow(fields)
373
    cw.writerow(fields)
358
    for doc in res:
374
    for doc in res:
359
        row = []
375
        row = []
...
...
372
def set():
388
def set():
373
    config = get_config()
389
    config = get_config()
374
    for k, v in DEFAULTS.items():
390
    for k, v in DEFAULTS.items():
375
        bottle.response.set_cookie(k, str(bottle.request.query.get(k)), max_age=3153600000, expires=315360000)
391
        bottle.response.set_cookie(k, str(bottle.request.query.get(k)), max_age=3153600000, expires=315360000)
376
    for d in config['dirs']:
392
    for d in config['dirs']:
377
        cookie_name = 'mount_%s' % urllib.quote(d, '')
393
        cookie_name = 'mount_%s' % urlquote(d, '')
378
        bottle.response.set_cookie(cookie_name, str(bottle.request.query.get('mount_%s' % d)), max_age=3153600000, expires=315360000)
394
        bottle.response.set_cookie(cookie_name, str(bottle.request.query.get('mount_%s' % d)), max_age=3153600000, expires=315360000)
379
    bottle.redirect('./')
395
    bottle.redirect('./')
380
#}}}
396
#}}}
381
#{{{ osd
397
#{{{ osd
382
@bottle.route('/osd.xml')
398
@bottle.route('/osd.xml')