~fabrixxm/lesanaweb

ref: b3d356ddc8bea2011667d5b40918117cf8938ece lesanaweb/app.py -rw-r--r-- 3.2 KiB
b3d356dd — fabrixxm Listing pages use default order 7 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import os

import jinja2
from flask import Flask
from flask import render_template, request, abort

try:
    from docutils.core import publish_parts
    import docutils.io
except ImportError:
    publish_parts = None

from lesana.collection import Collection


class ConfigurationError(Exception):
    pass


COLLECTIONPATH = os.environ.get('LW_COLLECTION_PATH', None)
PAGESIZE = int(os.environ.get('LW_PAGE_SIZE', 20))

if COLLECTIONPATH is None:
    raise ConfigurationError("LW_COLLECTION_PATH env var is not set")

if not os.path.isdir(COLLECTIONPATH) or \
   not os.path.isfile(os.path.join(COLLECTIONPATH, "settings.yaml")):
    raise ConfigurationError("'{} is not a valid collection".format(COLLECTIONPATH))

collection = Collection(COLLECTIONPATH)

app = Flask("lesanaweb")

# set template search paths
# first, search in collection templates, then use defaults.
my_loader = jinja2.ChoiceLoader([
    jinja2.FileSystemLoader(
        os.path.join(collection.basedir, "templates", "web")
    ),
    jinja2.FileSystemLoader(
        os.path.join(os.path.dirname(__file__), "templates")
    ),
])
app.jinja_loader = my_loader


def _render_text_only(fname):
    with open(fname) as fp:
        res = fp.read()
    return "<pre>" + res + "</pre>"

@app.route('/about.html')
def about():
    base_fname = os.path.join(COLLECTIONPATH, 'README')
    readme = None
    print("Looking for", base_fname)
    if os.path.isfile(base_fname + '.rst'):
        if publish_parts:
            parts = publish_parts(
                source=None,
                source_path=base_fname + '.rst',
                source_class=docutils.io.FileInput,
                writer=None, writer_name='html5'
            )
            readme = parts['fragment']
        else:
            readme = _render_text_only(base_fname + '.rst')
    if os.path.isfile(base_fname + '.md'):
        # TODO: render also md files
        readme = _render_text_only(base_fname + '.md')
    elif os.path.isfile(base_fname):
        readme = _render_text_only(base_fname)
    elif os.path.isfile(base_fname + '.txt'):
        readme = _render_text_only(base_fname + '.txt')
    return render_template(
        'about.html',
        settings=collection.settings,
        readme=readme,
    )

@app.route('/search.html')
def search():
    q = request.args.get('q', ' ')
    return _list_search(q)

@app.route('/<eid>.html')
def entry(eid):
    entries = collection.entries_from_short_eid(eid)
    if len(entries) > 1:
        abort(400, "{} is not an unique eid".format(eid))
    if not entries:
        abort(404, "Could not find an entry with eid starting with: {}".format(
            eid
        ))
    entry = entries[0]

    return render_template('entry.html', entry=entry, settings=collection.settings)

@app.route('/', methods=['GET'])
def index():
    return _list_search()


def _list_search(q=None):
    page = int(request.args.get('p', 1))
    if (page < 1):
        page = 1

    pagestart = (page - 1) * PAGESIZE
    pageend = pagestart + PAGESIZE
    
    if q is None:
        collection.start_search('*')
    else:
        collection.start_search(q)
    entries = list(collection.get_search_results(pagestart, pageend))
    return render_template('index.html', q=q, page=page, entries=entries, settings=collection.settings)