app.site.routes.articles()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 9
Code Lines 9

Duplication

Lines 9
Ratio 100 %

Importance

Changes 0
Metric Value
eloc 9
dl 9
loc 9
rs 9.95
c 0
b 0
f 0
cc 1
nop 0
1
import os
2
3
from quart import Blueprint, redirect, url_for, render_template, request, jsonify
4
from loglan_core import WordSelector, Event, BaseSelector, DefinitionSelector
5
6
from app.engine import async_session_maker
7
from app.site.compose.english_item import EnglishItem
8
from app.site.compose.loglan_item import Composer
9
from app.site.functions import get_data
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
async 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 await 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
async 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 await 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
async 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 await 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
async 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 await 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
async def dictionary():
92
    async with async_session_maker() as session:
93
        events = await BaseSelector(model=Event).all_async(session)
94
    events = {int(event.id): event.name for event in reversed(events)}
95
    content = await generate_content(request.args)
96
    return await render_template(
97
        "dictionary.html",
98
        content=content,
99
        events=events,
100
    )
101
102
103
@site_blueprint.route("/how_to_read")
104
async def how_to_read():
105
    return await render_template("reading.html")
106
107
108
@site_blueprint.route("/submit_search", methods=["POST"])
109
async def submit_search():
110
111
    res = await request.form
112
    return await generate_content(res)
113
114
115
def strtobool(val):
116
    val = val.lower()
117
    if val in ("yes", "true", "t", "y", "1"):
118
        return True
119
    if val in ("no", "false", "f", "n", "0"):
120
        return False
121
    raise ValueError("Invalid boolean value")
122
123
124
async def generate_content(data):
125
    word = data.get("word", str())
126
    search_language = data.get("language_id", DEFAULT_SEARCH_LANGUAGE)
127
    event_id = int(data.get("event_id", 1))
128
    is_case_sensitive = data.get("case_sensitive", False)
129
130
    if not word or not data:
131
        return jsonify(result="<div></div>")
132
133
    nothing = """
134
<div class="alert alert-secondary" role="alert" style="text-align: center;">
135
  %s
136
</div>
137
    """
138
139
    if isinstance(is_case_sensitive, str):
140
        is_case_sensitive = strtobool(is_case_sensitive)
141
142
    result = await search_all(
143
        search_language, word, event_id, is_case_sensitive, nothing
144
    )
145
    return jsonify(result=result)
146
147
148
async def search_all(search_language, word, event_id, is_case_sensitive, nothing):
149
    if search_language == "log":
150
        result = await search_log(word, event_id, is_case_sensitive, nothing)
151
152
    elif search_language == "eng":
153
        result = await search_eng(word, event_id, is_case_sensitive, nothing)
154
    else:
155
        result = nothing % f"Sorry, but nothing was found for <b>{word}</b>."
156
    return result
157
158
159
async def search_eng(word, event_id, is_case_sensitive, nothing):
160
161
    async with async_session_maker() as session:
162
        definitions = await (
163
            DefinitionSelector(case_sensitive=is_case_sensitive)
164
            .with_relationships("source_word")
165
            .by_key(key=word)
166
            .by_event(event_id=int(event_id))
167
            .all_async(session, unique=True)
168
        )
169
        result = EnglishItem(
170
            definitions=definitions, key=word, style=DEFAULT_HTML_STYLE
171
        ).export_as_html()
172
173
    if not result:
174
        result = (
175
            nothing
176
            % f"There is no word <b>{word}</b> in English. Try switching to Loglan"
177
            f"{' or disable Case sensitive search' if is_case_sensitive else ''}."
178
        )
179
    return result
180
181
182
async def search_log(word: str, event_id: int, is_case_sensitive: bool, nothing):
183
184
    async with async_session_maker() as session:
185
        word_result = await (
186
            WordSelector(case_sensitive=bool(is_case_sensitive))
187
            .with_relationships()
188
            .by_name(name=str(word))
189
            .by_event(event_id=int(event_id))
190
            .all_async(session, unique=True)
191
        )
192
        result = Composer(words=word_result, style=DEFAULT_HTML_STYLE).export_as_html()
193
    if not result:
194
        result = (
195
            nothing
196
            % f"There is no word <b>{word}</b> in Loglan. Try switching to English"
197
            f"{' or disable Case sensitive search' if is_case_sensitive else ''}."
198
        )
199
    return result
200
201
202
@site_blueprint.route("/<string:section>/", methods=["GET"])
203
@site_blueprint.route("/<string:section>/<string:article>", methods=["GET"])
204
async def proxy(section: str = "", article: str = ""):
205
    url = f"{MAIN_SITE}{section}/{article}"
206
    content = get_data(url).body
207
208
    for bq in content.findAll("blockquote"):
209
        bq["class"] = "blockquote"
210
211
    for img in content.findAll("img"):
212
        img["src"] = MAIN_SITE + section + "/" + img["src"]
213
214
    name_of_article = content.h1.extract().get_text()
215
    return await render_template(
216
        "article.html",
217
        name_of_article=name_of_article,
218
        article=content,
219
        title=section,
220
    )
221