Switch to unified view

a/webui.py b/webui.py
1
#!env python
1
#!env python
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
7
6
try:
8
try:
7
    from recoll import recoll
9
    from recoll import recoll
10
    from recoll import rclextract
11
    hasrclextract = True
8
except:
12
except:
9
    import recoll
13
    import recoll
14
    hasrclextract = False
10
    
15
    
11
import datetime
16
import datetime
12
import glob
17
import glob
13
import hashlib
18
import hashlib
14
import json
19
import json
...
...
164
        qs += " date:%s/%s" % (q['after'], q['before'])
169
        qs += " date:%s/%s" % (q['after'], q['before'])
165
    if q['dir'] != '<all>':
170
    if q['dir'] != '<all>':
166
        qs += " dir:\"%s\" " % q['dir']
171
        qs += " dir:\"%s\" " % q['dir']
167
    return qs
172
    return qs
168
#}}}
173
#}}}
169
#{{{ recoll_search
174
#{{{ recoll_initsearch
170
def recoll_search(q):
175
def recoll_initsearch(q):
171
    config = get_config()
176
    config = get_config()
172
    tstart = datetime.datetime.now()
173
    results = []
174
    db = recoll.connect(config['confdir'])
177
    db = recoll.connect(config['confdir'])
175
    db.setAbstractParams(config['maxchars'], config['context'])
178
    db.setAbstractParams(config['maxchars'], config['context'])
176
    query = db.query()
179
    query = db.query()
177
    query.sortby(q['sort'], q['ascending'])
180
    query.sortby(q['sort'], q['ascending'])
178
    try:
181
    try:
179
        qs = query_to_recoll_string(q)
182
        qs = query_to_recoll_string(q)
180
        nres = query.execute(qs, config['stem'])
183
        query.execute(qs, config['stem'])
181
    except:
184
    except:
182
        nres = 0
185
        pass
186
    return query
187
#}}}
188
#{{{ recoll_search
189
def recoll_search(q):
190
    config = get_config()
191
    tstart = datetime.datetime.now()
192
    results = []
193
    query = recoll_initsearch(q)
194
    nres = query.rowcount
195
183
    if config['maxresults'] == 0:
196
    if config['maxresults'] == 0:
184
        config['maxresults'] = nres
197
        config['maxresults'] = nres
185
    if nres > config['maxresults']:
198
    if nres > config['maxresults']:
186
        nres = config['maxresults']
199
        nres = config['maxresults']
187
    if config['perpage'] == 0 or q['page'] == 0:
200
    if config['perpage'] == 0 or q['page'] == 0:
188
        config['perpage'] = nres
201
        config['perpage'] = nres
189
        q['page'] = 1
202
        q['page'] = 1
190
    offset = (q['page'] - 1) * config['perpage']
203
    offset = (q['page'] - 1) * config['perpage']
191
204
205
    if query.rowcount > 0:
192
    if type(query.next) == int:
206
        if type(query.next) == int:
193
        query.next = offset
207
            query.next = offset
194
    else:
208
        else:
195
        query.scroll(offset)
209
            query.scroll(offset, mode='absolute')
210
196
    for i in range(config['perpage']):
211
    for i in range(config['perpage']):
197
        try:
212
        try:
198
            doc = query.fetchone()
213
            doc = query.fetchone()
199
        except:
214
        except:
200
            break
215
            break
...
...
206
            else:
221
            else:
207
                d[f] = ''
222
                d[f] = ''
208
        d['label'] = select([d['title'], d['filename'], '?'], [None, ''])
223
        d['label'] = select([d['title'], d['filename'], '?'], [None, ''])
209
        d['sha'] = hashlib.sha1(d['url']+d['ipath']).hexdigest()
224
        d['sha'] = hashlib.sha1(d['url']+d['ipath']).hexdigest()
210
        d['time'] = timestr(d['mtime'], config['timefmt'])
225
        d['time'] = timestr(d['mtime'], config['timefmt'])
211
        d['snippet'] = db.makeDocAbstract(doc, query).encode('utf-8')
226
        d['snippet'] = query.makedocabstract(doc).encode('utf-8')
212
        results.append(d)
227
        results.append(d)
213
    tend = datetime.datetime.now()
228
    tend = datetime.datetime.now()
214
    return results, nres, tend - tstart
229
    return results, nres, tend - tstart
215
#}}}
230
#}}}
216
#}}}
231
#}}}
...
...
239
    if config['maxresults'] == 0:
254
    if config['maxresults'] == 0:
240
        config['maxresults'] = nres
255
        config['maxresults'] = nres
241
    if config['perpage'] == 0:
256
    if config['perpage'] == 0:
242
        config['perpage'] = nres
257
        config['perpage'] = nres
243
    return { 'res': res, 'time': timer, 'query': query, 'dirs':
258
    return { 'res': res, 'time': timer, 'query': query, 'dirs':
244
            get_dirs(config['dirs'], config['dirdepth']),'qs': qs, 'sorts': SORTS, 'config': config,
259
            get_dirs(config['dirs'], config['dirdepth']),
260
             'qs': qs, 'sorts': SORTS, 'config': config,
245
            'query_string': bottle.request.query_string, 'nres': nres  }
261
            'query_string': bottle.request.query_string, 'nres': nres,
262
             'hasrclextract': hasrclextract }
263
#}}}
264
#{{{ preview
265
@bottle.route('/preview/<resnum:int>')
266
def preview(resnum):
267
    if not hasrclextract:
268
        return 'Sorry, needs recoll version 1.19 or later'
269
    query = get_query()
270
    qs = query_to_recoll_string(query)
271
    rclq = recoll_initsearch(query)
272
    if resnum > rclq.rowcount - 1:
273
        return 'Bad result index %d' % resnum
274
    rclq.scroll(resnum)
275
    doc = rclq.fetchone()
276
    xt = rclextract.Extractor(doc)
277
    tdoc = xt.textextract(doc.ipath)
278
    if tdoc.mimetype == 'text/html':
279
        bottle.response.content_type = 'text/html; charset=utf-8'
280
    else:
281
        bottle.response.content_type = 'text/plain; charset=utf-8'
282
    return tdoc.text
283
#}}}
284
#{{{ edit
285
@bottle.route('/edit/<resnum:int>')
286
def edit(resnum):
287
    if not hasrclextract:
288
        return 'Sorry, needs recoll version 1.19 or later'
289
    query = get_query()
290
    qs = query_to_recoll_string(query)
291
    rclq = recoll_initsearch(query)
292
    if resnum > rclq.rowcount - 1:
293
        return 'Bad result index %d' % resnum
294
    rclq.scroll(resnum)
295
    doc = rclq.fetchone()
296
    bottle.response.content_type = doc.mimetype
297
    # If ipath is null, we can just return the file
298
    pathismine = False
299
    if doc.ipath == '':
300
        path = doc.url.replace('file://','')
301
    else:
302
        xt = rclextract.Extractor(doc)
303
        path = xt.idoctofile(doc.ipath, doc.mimetype)
304
        pathismine = True
305
    print >> sys.stderr, "Sending %s with mimetype %s" % (path, doc.mimetype)
306
    f = open(path, 'r')
307
    if pathismine:
308
        os.unlink(path)
309
    return f
246
#}}}
310
#}}}
247
#{{{ json
311
#{{{ json
248
@bottle.route('/json')
312
@bottle.route('/json')
249
def get_json():
313
def get_json():
250
    query = get_query()
314
    query = get_query()