-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
239 lines (201 loc) · 7.09 KB
/
main.py
File metadata and controls
239 lines (201 loc) · 7.09 KB
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
# -*- coding: utf-8 -*-
# pylint: disable=logging-fstring-interpolation
"""
HTML Generator
"""
import os
import time
from datetime import datetime, timedelta
from itertools import groupby
from jinja2 import Environment, FileSystemLoader
from loglan_core import Event, Key, Setting, Definition
from loglan_core.addons.word_selector import WordSelector
from sqlalchemy import create_engine, select
from sqlalchemy.orm import sessionmaker, scoped_session, Session
from compose.english_item import EnglishItem
from compose.loglan_item import Meaning
from config import HTML_EXPORT_DIRECTORY_PATH_LOCAL as EXPORT_PATH
from config import log, DEFAULT_LANGUAGE, DEFAULT_STYLE
# TODO Add other languages support
SQLALCHEMY_DATABASE_URI = os.environ.get("LOD_DATABASE_URL", "sqlite://")
engine = create_engine(SQLALCHEMY_DATABASE_URI)
LOD_Session = scoped_session(sessionmaker(bind=engine, future=True))
def prepare_dictionary_l(
session: Session,
style: str = DEFAULT_STYLE,
lex_event: Event = None,
):
"""
:param session:
:param style:
:param lex_event:
:return:
"""
log.info("Start Loglan dictionary preparation")
if lex_event is None:
lex_event = session.execute(Event.latest()).scalar()
log.debug(f"Required Lexical Event is {lex_event.name}")
log.debug("Get data from Database")
select_words = WordSelector().by_event(event_id=lex_event.id) # [1350:1400]
all_words = session.execute(select_words).scalars().all()
log.debug(f"Grouping total {len(all_words)} words by name")
grouped_words = groupby(all_words, lambda ent: ent.name)
log.debug("Making dictionary with grouped words")
group_words = {k: list(g) for k, g in grouped_words}
log.debug(f"Grouping {len(group_words)} word groups by first letter")
grouped_letters = groupby(group_words, lambda ent: ent[0].upper())
log.debug("Making dictionary with grouped letters")
names_grouped_by_letter = {k: list(g) for k, g in grouped_letters}
log.debug(
f"Making main export dictionary with {len(names_grouped_by_letter)} letters"
)
dictionary = {}
for letter, names in names_grouped_by_letter.items():
log.debug(f"Current letter: {letter}")
dictionary[letter] = [
{
"name": group_words[name][0].name,
"meanings": [
Meaning(word=w, style=style).export_as_html()
for w in group_words[name]
],
}
for name in names
]
log.info(f"End Loglan dictionary preparation - {len(dictionary)} letters totally")
return dictionary
def prepare_dictionary_e(
session: Session,
style: str = DEFAULT_STYLE,
key_language: str = DEFAULT_LANGUAGE,
lex_event: Event = None,
):
"""
:param session:
:param style:
:param key_language:
:param lex_event:
:return:
"""
def check_events(definition: Definition, event_id: int):
if definition.source_word.event_start_id > event_id:
return False
if definition.source_word.event_end_id is None:
return True
if definition.source_word.event_end_id > event_id:
return True
return False
log.info(
f"Start {key_language.capitalize()} dictionary preparation",
)
if not lex_event:
lex_event = session.execute(Event.latest()).scalar()
log.debug("Get Key's data from Database")
select_keys = select(Key).order_by(Key.word).filter(Key.language == key_language)
all_keys = session.execute(select_keys).scalars().all() # [1600:1700]
all_keys_words = [key.word for key in all_keys]
log.debug(f"Grouping {len(all_keys)} keys by word")
grouped_keys = groupby(all_keys, lambda ent: ent.word)
log.debug("Making dictionary with grouped keys")
group_keys = {
k: [
EnglishItem.export_for_english(d, key=k, style=style)
for d in list(g)[0].definitions
if check_events(d, lex_event.id)
]
for k, g in grouped_keys
}
log.debug("Grouping keys by first letter")
grouped_letters = groupby(all_keys_words, lambda ent: ent[0].upper())
log.debug("Making dictionary with grouped letters")
key_names_grouped_by_letter = {k: list(g) for k, g in grouped_letters}
log.debug("Making main export dictionary")
dictionary = {
letter: {name: group_keys[name] for name in names}
for letter, names in key_names_grouped_by_letter.items()
}
log.info(
f"End {key_language.capitalize()} dictionary preparation - {len(dictionary)} items totally"
)
return dictionary
def prepare_technical_info(
session: Session,
lex_event: Event = None,
):
"""
:param session:
:param lex_event:
:return:
"""
generation_date = datetime.now().strftime("%d.%m.%Y")
db_release = (
session.execute(select(Setting).order_by(-Setting.id)).scalar().db_release
)
if not lex_event:
lex_event = session.execute(Event.latest()).scalar()
return {
"Generated": generation_date,
"Database": db_release,
"LexEvent": lex_event.annotation,
}
def generate_dictionary_file(
session: Session,
entities_language: str = "loglan",
style: str = DEFAULT_STYLE,
lex_event: Event = None,
timestamp: str = None,
):
"""
:param session:
:param entities_language: [ loglan, english ]
:param style: [ normal, ultra ]
:param lex_event:
:param timestamp:
"""
if not lex_event:
lex_event = session.execute(Event.latest()).scalar()
env = Environment(loader=FileSystemLoader("templates"))
if entities_language == "loglan":
data = prepare_dictionary_l(session=session, style=style, lex_event=lex_event)
else:
data = prepare_dictionary_e(session=session, style=style, lex_event=lex_event)
template = env.get_template(f"{entities_language}/words_{style}.html")
tech = prepare_technical_info(session=session, lex_event=lex_event)
render = template.render(dictionary=data, technical=tech)
name = "L-to-E" if entities_language == "loglan" else "E-to-L"
timestamp = datetime.now().strftime("%y%m%d%H%M") if not timestamp else timestamp
file = (
f"{EXPORT_PATH}{name}-"
f"{tech['Database']}-"
f"{timestamp}_{lex_event.suffix}_"
f"{style[0].lower()}.html"
)
with open(file, "w", encoding="utf-8") as text_file:
text_file.write(render)
def generate_dictionaries(
session: Session,
):
"""
:return:
"""
log.info("START DICTIONARY HTML CREATION")
start_time = time.monotonic()
timestamp = datetime.now().strftime("%y%m%d%H%M")
generate_dictionary_file(
session=session,
style="normal",
entities_language="loglan",
timestamp=timestamp,
)
generate_dictionary_file(
session=session,
style="normal",
entities_language="english",
timestamp=timestamp,
)
log.info(
"ELAPSED TIME IN MINUTES: %s\n",
timedelta(minutes=time.monotonic() - start_time),
)
if __name__ == "__main__":
generate_dictionaries(LOD_Session())