chgksuite 0.25.0b3__tar.gz → 0.25.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {chgksuite-0.25.0b3/chgksuite.egg-info → chgksuite-0.25.1}/PKG-INFO +1 -1
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/common.py +4 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/composer/pptx.py +70 -47
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/composer/telegram.py +8 -5
- chgksuite-0.25.1/chgksuite/version.py +1 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1/chgksuite.egg-info}/PKG-INFO +1 -1
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/history.md +7 -0
- chgksuite-0.25.0b3/chgksuite/version.py +0 -1
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/LICENSE +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/MANIFEST.in +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/README.md +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/__init__.py +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/__main__.py +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/cli.py +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/composer/__init__.py +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/composer/chgksuite_parser.py +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/composer/composer_common.py +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/composer/db.py +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/composer/docx.py +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/composer/latex.py +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/composer/lj.py +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/composer/openquiz.py +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/composer/reddit.py +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/composer/stats.py +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/composer/telegram_bot.py +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/composer/telegram_parser.py +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/parser.py +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/parser_db.py +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/resources/cheader.tex +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/resources/fix-unnumbered-sections.sty +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/resources/labels_by.toml +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/resources/labels_by_tar.toml +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/resources/labels_en.toml +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/resources/labels_kz_cyr.toml +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/resources/labels_ru.toml +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/resources/labels_sr.toml +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/resources/labels_ua.toml +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/resources/labels_uz.toml +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/resources/labels_uz_cyr.toml +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/resources/pptx_config.toml +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/resources/regexes_by.json +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/resources/regexes_en.json +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/resources/regexes_kz_cyr.json +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/resources/regexes_ru.json +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/resources/regexes_sr.json +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/resources/regexes_ua.json +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/resources/regexes_uz_cyr.json +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/resources/template.docx +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/resources/template.pptx +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/resources/template_shorin.pptx +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/resources/trello.json +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/trello.py +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/typotools.py +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite/vulture_whitelist.py +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite.egg-info/SOURCES.txt +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite.egg-info/dependency_links.txt +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite.egg-info/entry_points.txt +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite.egg-info/requires.txt +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/chgksuite.egg-info/top_level.txt +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/setup.cfg +0 -0
- {chgksuite-0.25.0b3 → chgksuite-0.25.1}/setup.py +0 -0
|
@@ -224,6 +224,8 @@ def xlsx_to_results(xlsx_file_path):
|
|
|
224
224
|
res_by_tour = defaultdict(lambda: defaultdict(list))
|
|
225
225
|
tour_len = defaultdict(lambda: 0)
|
|
226
226
|
for row in sheet.iter_rows(values_only=True):
|
|
227
|
+
if not any(x for x in row):
|
|
228
|
+
continue
|
|
227
229
|
if first:
|
|
228
230
|
assert row[1] == "Название"
|
|
229
231
|
if row[3] == "Тур":
|
|
@@ -233,6 +235,8 @@ def xlsx_to_results(xlsx_file_path):
|
|
|
233
235
|
first = False
|
|
234
236
|
continue
|
|
235
237
|
team_id = row[0]
|
|
238
|
+
if not tryint(team_id):
|
|
239
|
+
continue
|
|
236
240
|
team_name = row[1]
|
|
237
241
|
if table_type == "tour":
|
|
238
242
|
tour = row[3]
|
|
@@ -3,15 +3,15 @@ import os
|
|
|
3
3
|
import re
|
|
4
4
|
|
|
5
5
|
import toml
|
|
6
|
+
|
|
7
|
+
from chgksuite.common import log_wrap, replace_escaped, tryint
|
|
8
|
+
from chgksuite.composer.composer_common import BaseExporter, backtick_replace, parseimg
|
|
6
9
|
from pptx import Presentation
|
|
7
10
|
from pptx.dml.color import RGBColor
|
|
8
11
|
from pptx.enum.text import MSO_AUTO_SIZE, MSO_VERTICAL_ANCHOR, PP_ALIGN
|
|
9
12
|
from pptx.util import Inches as PptxInches
|
|
10
13
|
from pptx.util import Pt as PptxPt
|
|
11
14
|
|
|
12
|
-
from chgksuite.common import log_wrap, replace_escaped, tryint
|
|
13
|
-
from chgksuite.composer.composer_common import BaseExporter, backtick_replace, parseimg
|
|
14
|
-
|
|
15
15
|
|
|
16
16
|
class PptxExporter(BaseExporter):
|
|
17
17
|
def __init__(self, *args, **kwargs):
|
|
@@ -48,6 +48,15 @@ class PptxExporter(BaseExporter):
|
|
|
48
48
|
textbox = slide.shapes.add_textbox(left, top, width, height)
|
|
49
49
|
return textbox
|
|
50
50
|
|
|
51
|
+
def add_run(self, para, text, color=None):
|
|
52
|
+
r = para.add_run()
|
|
53
|
+
r.text = text
|
|
54
|
+
if color is None:
|
|
55
|
+
color = self.c["textbox"].get("color")
|
|
56
|
+
if color:
|
|
57
|
+
r.font.color.rgb = RGBColor(*color)
|
|
58
|
+
return r
|
|
59
|
+
|
|
51
60
|
def pptx_format(self, el, para, tf, slide, replace_spaces=True):
|
|
52
61
|
def r_sp(text):
|
|
53
62
|
if replace_spaces:
|
|
@@ -60,15 +69,13 @@ class PptxExporter(BaseExporter):
|
|
|
60
69
|
licount = 0
|
|
61
70
|
for li in el[1]:
|
|
62
71
|
licount += 1
|
|
63
|
-
|
|
64
|
-
r.text = "\n{}. ".format(licount)
|
|
72
|
+
self.add_run(para, "\n{}. ".format(licount))
|
|
65
73
|
self.pptx_format(li, para, tf, slide)
|
|
66
74
|
else:
|
|
67
75
|
licount = 0
|
|
68
76
|
for li in el:
|
|
69
77
|
licount += 1
|
|
70
|
-
|
|
71
|
-
r.text = "\n{}. ".format(licount)
|
|
78
|
+
self.add_run(para, "\n{}. ".format(licount))
|
|
72
79
|
self.pptx_format(li, para, tf, slide)
|
|
73
80
|
|
|
74
81
|
if isinstance(el, str):
|
|
@@ -77,23 +84,20 @@ class PptxExporter(BaseExporter):
|
|
|
77
84
|
|
|
78
85
|
for run in self.parse_4s_elem(el):
|
|
79
86
|
if run[0] == "screen":
|
|
80
|
-
|
|
81
|
-
r.text = r_sp(run[1]["for_screen"])
|
|
87
|
+
self.add_run(para, r_sp(run[1]["for_screen"]))
|
|
82
88
|
|
|
83
89
|
elif run[0] == "linebreak":
|
|
84
|
-
|
|
90
|
+
self.add_run(para, "\n")
|
|
85
91
|
|
|
86
92
|
elif run[0] == "strike":
|
|
87
|
-
r =
|
|
88
|
-
r.text = r_sp(run[1])
|
|
93
|
+
r = self.add_run(para, r_sp(run[1]))
|
|
89
94
|
r.font.strike = True # TODO: doesn't work as of 2023-12-24, cf. https://github.com/scanny/python-pptx/issues/339
|
|
90
95
|
|
|
91
96
|
elif run[0] == "img":
|
|
92
97
|
pass # image processing is moved to other places
|
|
93
98
|
|
|
94
99
|
else:
|
|
95
|
-
r =
|
|
96
|
-
r.text = r_sp(run[1])
|
|
100
|
+
r = self.add_run(para, r_sp(run[1]))
|
|
97
101
|
if "italic" in run[0]:
|
|
98
102
|
r.font.italic = True
|
|
99
103
|
if "bold" in run[0]:
|
|
@@ -166,25 +170,30 @@ class PptxExporter(BaseExporter):
|
|
|
166
170
|
txt = txt.upper()
|
|
167
171
|
self.set_question_number(slide, number=txt)
|
|
168
172
|
else:
|
|
169
|
-
r =
|
|
170
|
-
|
|
173
|
+
r = self.add_run(
|
|
174
|
+
p, self._replace_no_break(self.pptx_process_text(section[0][1]))
|
|
175
|
+
)
|
|
171
176
|
r.font.size = PptxPt(self.c["text_size_grid"]["section"])
|
|
172
177
|
add_line_break = True
|
|
173
178
|
if editor:
|
|
174
|
-
r =
|
|
175
|
-
|
|
176
|
-
(
|
|
177
|
-
|
|
178
|
-
|
|
179
|
+
r = self.add_run(
|
|
180
|
+
p,
|
|
181
|
+
self._replace_no_break(
|
|
182
|
+
("\n" if add_line_break else "")
|
|
183
|
+
+ self.pptx_process_text(editor[0][1])
|
|
184
|
+
+ "\n"
|
|
185
|
+
),
|
|
179
186
|
)
|
|
180
187
|
add_line_break = True
|
|
181
188
|
if meta:
|
|
182
189
|
for element in meta:
|
|
183
|
-
r =
|
|
184
|
-
|
|
185
|
-
(
|
|
186
|
-
|
|
187
|
-
|
|
190
|
+
r = self.add_run(
|
|
191
|
+
p,
|
|
192
|
+
self._replace_no_break(
|
|
193
|
+
("\n" if add_line_break else "")
|
|
194
|
+
+ self.pptx_process_text(element[1])
|
|
195
|
+
+ "\n"
|
|
196
|
+
),
|
|
188
197
|
)
|
|
189
198
|
add_line_break = True
|
|
190
199
|
|
|
@@ -211,8 +220,11 @@ class PptxExporter(BaseExporter):
|
|
|
211
220
|
title = slide.shapes.title
|
|
212
221
|
title.text = title_text[0][1]
|
|
213
222
|
if date_text:
|
|
214
|
-
|
|
215
|
-
|
|
223
|
+
try:
|
|
224
|
+
subtitle = slide.placeholders[1]
|
|
225
|
+
subtitle.text = date_text[0][1]
|
|
226
|
+
except KeyError:
|
|
227
|
+
pass
|
|
216
228
|
for block in (editor_block, section_block):
|
|
217
229
|
self._process_block(block)
|
|
218
230
|
|
|
@@ -223,11 +235,14 @@ class PptxExporter(BaseExporter):
|
|
|
223
235
|
qtf = qntextbox.text_frame
|
|
224
236
|
qtf_p = self.init_paragraph(qtf)
|
|
225
237
|
if self.c["number_textbox"].get("align"):
|
|
226
|
-
qtf_p.alignment = getattr(
|
|
227
|
-
|
|
238
|
+
qtf_p.alignment = getattr(
|
|
239
|
+
PP_ALIGN, self.c["number_textbox"]["align"].upper()
|
|
240
|
+
)
|
|
228
241
|
if self.c.get("question_number_format") == "caps" and tryint(number):
|
|
229
242
|
number = f"ВОПРОС {number}"
|
|
230
|
-
qtf_r
|
|
243
|
+
qtf_r = self.add_run(qtf_p, number)
|
|
244
|
+
if self.c["number_textbox"].get("bold"):
|
|
245
|
+
qtf_r.font.bold = True
|
|
231
246
|
if self.c["number_textbox"].get("color"):
|
|
232
247
|
qtf_r.font.color.rgb = RGBColor(*self.c["number_textbox"]["color"])
|
|
233
248
|
if self.c["number_textbox"].get("font_size"):
|
|
@@ -276,6 +291,15 @@ class PptxExporter(BaseExporter):
|
|
|
276
291
|
base_top = PptxInches(self.c["textbox"]["top"])
|
|
277
292
|
base_width = PptxInches(self.c["textbox"]["width"])
|
|
278
293
|
base_height = PptxInches(self.c["textbox"]["height"])
|
|
294
|
+
if self.c.get("disable_autolayout"):
|
|
295
|
+
slide.shapes.add_picture(
|
|
296
|
+
image["imgfile"],
|
|
297
|
+
left=base_left,
|
|
298
|
+
top=base_top,
|
|
299
|
+
width=img_base_width,
|
|
300
|
+
height=img_base_height,
|
|
301
|
+
)
|
|
302
|
+
return self.get_textbox(slide), 1
|
|
279
303
|
big_mode = (
|
|
280
304
|
image["big"] and not self.c.get("text_is_duplicated") and allowbigimage
|
|
281
305
|
)
|
|
@@ -388,9 +412,13 @@ class PptxExporter(BaseExporter):
|
|
|
388
412
|
def process_question_text(self, q):
|
|
389
413
|
image = self._get_image_from_4s(q["question"])
|
|
390
414
|
handout = self._get_handout_from_4s(q["question"])
|
|
391
|
-
|
|
415
|
+
add_handout_on_separate_slide = self.c.get("add_handout_on_separate_slide")
|
|
416
|
+
add_handout_on_separate_slide = (
|
|
417
|
+
add_handout_on_separate_slide is None or add_handout_on_separate_slide
|
|
418
|
+
)
|
|
419
|
+
if image and add_handout_on_separate_slide:
|
|
392
420
|
self.add_slide_with_image(image, number=self.number)
|
|
393
|
-
elif handout:
|
|
421
|
+
elif handout and add_handout_on_separate_slide:
|
|
394
422
|
self.add_slide_with_handout(handout, number=self.number)
|
|
395
423
|
slide = self.prs.slides.add_slide(self.BLANK_SLIDE)
|
|
396
424
|
text_is_duplicated = bool(self.c.get("text_is_duplicated"))
|
|
@@ -411,7 +439,7 @@ class PptxExporter(BaseExporter):
|
|
|
411
439
|
fields.append("zachet")
|
|
412
440
|
if self.c["add_comment"] and "comment" in q:
|
|
413
441
|
fields.append("comment")
|
|
414
|
-
if self.c
|
|
442
|
+
if self.c.get("add_source") and "source" in q:
|
|
415
443
|
fields.append("source")
|
|
416
444
|
textbox = None
|
|
417
445
|
coeff = 1
|
|
@@ -449,34 +477,29 @@ class PptxExporter(BaseExporter):
|
|
|
449
477
|
p = self.init_paragraph(tf, size=self.c["force_text_size_answer"])
|
|
450
478
|
else:
|
|
451
479
|
p = self.init_paragraph(tf, text=text_for_size, coeff=coeff)
|
|
452
|
-
r =
|
|
453
|
-
r.text = f"{self.get_label(q, 'answer')}: "
|
|
480
|
+
r = self.add_run(p, f"{self.get_label(q, 'answer')}: ")
|
|
454
481
|
r.font.bold = True
|
|
455
482
|
self.pptx_format(
|
|
456
483
|
self.pptx_process_text(q["answer"], strip_brackets=False), p, tf, slide
|
|
457
484
|
)
|
|
458
485
|
if q.get("zachet") and self.c.get("add_zachet"):
|
|
459
486
|
zachet_text = self.pptx_process_text(q["zachet"], strip_brackets=False)
|
|
460
|
-
r =
|
|
461
|
-
r.text = f"\n{self.get_label(q, 'zachet')}: "
|
|
487
|
+
r = self.add_run(p, f"\n{self.get_label(q, 'zachet')}: ")
|
|
462
488
|
r.font.bold = True
|
|
463
489
|
self.pptx_format(zachet_text, p, tf, slide)
|
|
464
490
|
if self.c["add_comment"] and "comment" in q:
|
|
465
491
|
comment_text = self.pptx_process_text(q["comment"])
|
|
466
|
-
r =
|
|
467
|
-
r.text = f"\n{self.get_label(q, 'comment')}: "
|
|
492
|
+
r = self.add_run(p, f"\n{self.get_label(q, 'comment')}: ")
|
|
468
493
|
r.font.bold = True
|
|
469
494
|
self.pptx_format(comment_text, p, tf, slide)
|
|
470
|
-
if self.c
|
|
495
|
+
if self.c.get("add_source") and "source" in q:
|
|
471
496
|
source_text = self.pptx_process_text(q["source"])
|
|
472
|
-
r =
|
|
473
|
-
r.text = f"\n{self.get_label(q, 'source')}: "
|
|
497
|
+
r = self.add_run(p, f"\n{self.get_label(q, 'source')}: ")
|
|
474
498
|
r.font.bold = True
|
|
475
499
|
self.pptx_format(source_text, p, tf, slide)
|
|
476
|
-
if self.c
|
|
500
|
+
if self.c.get("add_author") and "author" in q:
|
|
477
501
|
author_text = self.pptx_process_text(q["author"])
|
|
478
|
-
r =
|
|
479
|
-
r.text = f"\n{self.get_label(q, 'author')}: "
|
|
502
|
+
r = self.add_run(p, f"\n{self.get_label(q, 'author')}: ")
|
|
480
503
|
r.font.bold = True
|
|
481
504
|
self.pptx_format(author_text, p, tf, slide)
|
|
482
505
|
|
|
@@ -508,7 +531,7 @@ class PptxExporter(BaseExporter):
|
|
|
508
531
|
return element["size"]
|
|
509
532
|
return self.c["text_size_grid"]["smallest"]
|
|
510
533
|
|
|
511
|
-
def init_paragraph(self, text_frame, text=None, coeff=1, size=None):
|
|
534
|
+
def init_paragraph(self, text_frame, text=None, coeff=1, size=None, color=None):
|
|
512
535
|
p = text_frame.paragraphs[0]
|
|
513
536
|
p.font.name = self.c["font"]["name"]
|
|
514
537
|
if size:
|
|
@@ -852,7 +852,7 @@ class TelegramExporter(BaseExporter):
|
|
|
852
852
|
|
|
853
853
|
# Wait for a forwarded message with channel information
|
|
854
854
|
channel_id = self.wait_for_forwarded_message(
|
|
855
|
-
entity_type="channel", check_type=True
|
|
855
|
+
entity_type="channel", check_type=True
|
|
856
856
|
)
|
|
857
857
|
if channel_id:
|
|
858
858
|
self.save_username(channel_result, channel_id)
|
|
@@ -875,7 +875,7 @@ class TelegramExporter(BaseExporter):
|
|
|
875
875
|
|
|
876
876
|
# Wait for a forwarded message with chat information
|
|
877
877
|
chat_id = self.wait_for_forwarded_message(
|
|
878
|
-
entity_type="chat", check_type=False
|
|
878
|
+
entity_type="chat", check_type=False
|
|
879
879
|
)
|
|
880
880
|
if not chat_id:
|
|
881
881
|
self.logger.error("Failed to get chat ID from forwarded message")
|
|
@@ -891,7 +891,6 @@ class TelegramExporter(BaseExporter):
|
|
|
891
891
|
entity_type="chat",
|
|
892
892
|
check_type=False,
|
|
893
893
|
add_msg=error_msg,
|
|
894
|
-
string_id=chat_result,
|
|
895
894
|
)
|
|
896
895
|
if chat_id:
|
|
897
896
|
self.save_username(chat_result, chat_id)
|
|
@@ -1117,11 +1116,15 @@ class TelegramExporter(BaseExporter):
|
|
|
1117
1116
|
|
|
1118
1117
|
# Look for a forwarded message in recent messages
|
|
1119
1118
|
cursor = self.db_conn.cursor()
|
|
1119
|
+
if self.created_at:
|
|
1120
|
+
threshold = "'" + self.created_at + "'"
|
|
1121
|
+
else:
|
|
1122
|
+
threshold = "datetime('now', '-2 minutes')"
|
|
1120
1123
|
cursor.execute(
|
|
1121
|
-
"""
|
|
1124
|
+
f"""
|
|
1122
1125
|
SELECT raw_data, created_at
|
|
1123
1126
|
FROM messages
|
|
1124
|
-
WHERE created_at >
|
|
1127
|
+
WHERE created_at > {threshold}
|
|
1125
1128
|
ORDER BY created_at DESC
|
|
1126
1129
|
"""
|
|
1127
1130
|
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.25.1"
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# What’s new
|
|
2
2
|
|
|
3
|
+
## v0.25.1
|
|
4
|
+
- Исправлен баг выкладывания пакета в телеграм
|
|
5
|
+
|
|
6
|
+
## v0.25.0
|
|
7
|
+
- Адаптация к новому формату выходных таблиц турнирного сайта
|
|
8
|
+
- Улучшения выгрузки PPTX
|
|
9
|
+
|
|
3
10
|
## v0.24.0
|
|
4
11
|
- Постинг в телеграм теперь происходит не через клиент, а через бота (подробнее можно прочитать в документации: https://chgksuite.pecheny.me/telegram/)
|
|
5
12
|
- При невозможности распарсить табличку в вордовском файле теперь выдаётся предупреждение об этом (раньше программа просто падала)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.25.0b3"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|