Passed
Pull Request — master (#79)
by torrua
01:15
created

app.site.routes.proxy()   A

Complexity

Conditions 3

Size

Total Lines 18
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 15
dl 0
loc 18
rs 9.65
c 0
b 0
f 0
cc 3
nop 2
1
import os
2
3
from flask import Blueprint, redirect, url_for, render_template, request, jsonify
4
from loglan_core import WordSelector
5
from loglan_core.addons.definition_selector import DefinitionSelector
6
from app.site.compose.english_item import EnglishItem
7
from app.site.compose.loglan_item import Composer
8
from app.site.functions import get_data
9
from app.engine import Session
10
11
site_blueprint = Blueprint(
12
    "site",
13
    __name__,
14
    template_folder="site/templates",
15
)
16
DEFAULT_SEARCH_LANGUAGE = os.getenv("DEFAULT_SEARCH_LANGUAGE", "log")
17
DEFAULT_HTML_STYLE = os.getenv("DEFAULT_HTML_STYLE", "normal")
18
MAIN_SITE = "http://www.loglan.org/"
19
20
21
@site_blueprint.route("/Articles/")
22
def redirect_articles():
23
    return redirect(url_for("articles"))
24
25
26
@site_blueprint.route("/Texts/")
27
def redirect_texts():
28
    return redirect(url_for("texts"))
29
30
31
@site_blueprint.route("/Sanpa/")
32
@site_blueprint.route("/Lodtua/")
33
def redirect_columns():
34
    return redirect(url_for("columns"))
35
36
37
@site_blueprint.route("/")
38
@site_blueprint.route("/home")
39
def home():
40
    article = get_data(MAIN_SITE).body.find("div", {"id": "content"})
41
    for bq in article.findAll("blockquote"):
42
        bq["class"] = "blockquote"
43
44
    for img in article.findAll("img"):
45
        img["src"] = MAIN_SITE + img["src"]
46
47
    return render_template(
48
        "home.html",
49
        article="",
50
    )
51
52
53 View Code Duplication
@site_blueprint.route("/articles")
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
54
def articles():
55
    article_block = get_data(MAIN_SITE)
56
    title = article_block.find("a", {"name": "articles"}).find_parent("h2")
57
    content = title.find_next("ol")
58
    return render_template(
59
        "articles.html",
60
        articles=content,
61
        title=title.get_text(),
62
    )
63
64
65 View Code Duplication
@site_blueprint.route("/texts")
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
66
def texts():
67
    article_block = get_data(MAIN_SITE)
68
    title = article_block.find("a", {"name": "texts"}).find_parent("h2")
69
    content = title.find_next("ol")
70
    return render_template(
71
        "articles.html",
72
        articles=content,
73
        title=title.get_text(),
74
    )
75
76
77 View Code Duplication
@site_blueprint.route("/columns")
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
78
def columns():
79
    article_block = get_data(MAIN_SITE)
80
    title = article_block.find("a", {"name": "columns"}).find_parent("h2")
81
    content = title.find_next("ul")
82
    return render_template(
83
        "articles.html",
84
        articles=content,
85
        title=title.get_text(),
86
    )
87
88
89
@site_blueprint.route("/dictionary")
90
@site_blueprint.route("/dictionary/")
91
def dictionary():
92
    with Session() as session:
93
        events = session.query(Event).all()
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable Event does not seem to be defined.
Loading history...
94
    events = {event.id: event.name for event in reversed(events)}
95
    content = generate_content(request.args)
96
    return render_template(
97
        "dictionary.html",
98
        content=content,
99
        events=events,
100
    )
101
102
103
@site_blueprint.route("/how_to_read")
104
def how_to_read():
105
    return render_template("reading.html")
106
107
108
@site_blueprint.route("/submit_search", methods=["POST"])
109
def submit_search():
110
    return generate_content(request.form)
111
112
113
def strtobool(val):
114
    val = val.lower()
115
    if val in ("yes", "true", "t", "y", "1"):
116
        return True
117
    if val in ("no", "false", "f", "n", "0"):
118
        return False
119
    raise ValueError("Invalid boolean value")
120
121
122
def generate_content(data):
123
    word = data.get("word", str())
124
    search_language = data.get("language_id", DEFAULT_SEARCH_LANGUAGE)
125
    event_id = data.get("event_id", 1)
126
    is_case_sensitive = data.get("case_sensitive", False)
127
128
    if not word or not data:
129
        return jsonify(result="<div></div>")
130
131
    nothing = """
132
<div class="alert alert-secondary" role="alert" style="text-align: center;">
133
  %s
134
</div>
135
    """
136
137
    if isinstance(is_case_sensitive, str):
138
        is_case_sensitive = strtobool(is_case_sensitive)
139
140
    result = search_all(search_language, word, event_id, is_case_sensitive, nothing)
141
    return jsonify(result=result)
142
143
144
def search_all(search_language, word, event_id, is_case_sensitive, nothing):
145
    if search_language == "log":
146
        result = search_log(word, event_id, is_case_sensitive, nothing)
147
148
    elif search_language == "eng":
149
        result = search_eng(word, event_id, is_case_sensitive, nothing)
150
    else:
151
        result = nothing % f"Sorry, but nothing was found for <b>{word}</b>."
152
    return result
153
154
155
def search_eng(word, event_id, is_case_sensitive, nothing):
156
157
    with Session() as session:
158
        definitions_result = (
159
            DefinitionSelector(case_sensitive=is_case_sensitive)
160
            .with_relationships("source_word")
161
            .by_key(key=word)
162
            .by_event(event_id=event_id)
163
            .all(session)
164
        )
165
166
        result = EnglishItem(
167
            definitions=definitions_result, key=word, style=DEFAULT_HTML_STYLE
168
        ).export_as_html()
169
170
    if not result:
171
        result = (
172
            nothing
173
            % f"There is no word <b>{word}</b> in English. Try switching to Loglan"
174
            f"{' or disable Case sensitive search' if is_case_sensitive else ''}."
175
        )
176
    return result
177
178
179
def search_log(word, event_id, is_case_sensitive, nothing):
180
181
    with Session() as session:
182
        word_result = (
183
            WordSelector(case_sensitive=is_case_sensitive)
184
            .by_name(name=word)
185
            .by_event(event_id=event_id)
186
            .all(session)
187
        )
188
        result = Composer(words=word_result, style=DEFAULT_HTML_STYLE).export_as_html()
189
    if not result:
190
        result = (
191
            nothing
192
            % f"There is no word <b>{word}</b> in Loglan. Try switching to English"
193
            f"{' or disable Case sensitive search' if is_case_sensitive else ''}."
194
        )
195
    return result
196
197
198
@site_blueprint.route("/<string:section>/", methods=["GET"])
199
@site_blueprint.route("/<string:section>/<string:article>", methods=["GET"])
200
def proxy(section: str = "", article: str = ""):
201
    url = f"{MAIN_SITE}{section}/{article}"
202
    content = get_data(url).body
203
204
    for bq in content.findAll("blockquote"):
205
        bq["class"] = "blockquote"
206
207
    for img in content.findAll("img"):
208
        img["src"] = MAIN_SITE + section + "/" + img["src"]
209
210
    name_of_article = content.h1.extract().get_text()
211
    return render_template(
212
        "article.html",
213
        name_of_article=name_of_article,
214
        article=content,
215
        title=section,
216
    )
217