chgksuite 0.24.3__py3-none-any.whl → 0.25.0__py3-none-any.whl
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/common.py +4 -0
- chgksuite/composer/pptx.py +95 -33
- chgksuite/version.py +1 -1
- {chgksuite-0.24.3.dist-info → chgksuite-0.25.0.dist-info}/METADATA +1 -1
- {chgksuite-0.24.3.dist-info → chgksuite-0.25.0.dist-info}/RECORD +9 -9
- {chgksuite-0.24.3.dist-info → chgksuite-0.25.0.dist-info}/WHEEL +1 -1
- {chgksuite-0.24.3.dist-info → chgksuite-0.25.0.dist-info}/entry_points.txt +0 -0
- {chgksuite-0.24.3.dist-info → chgksuite-0.25.0.dist-info}/licenses/LICENSE +0 -0
- {chgksuite-0.24.3.dist-info → chgksuite-0.25.0.dist-info}/top_level.txt +0 -0
chgksuite/common.py
CHANGED
|
@@ -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]
|
chgksuite/composer/pptx.py
CHANGED
|
@@ -5,10 +5,11 @@ import re
|
|
|
5
5
|
import toml
|
|
6
6
|
from pptx import Presentation
|
|
7
7
|
from pptx.dml.color import RGBColor
|
|
8
|
+
from pptx.enum.text import MSO_AUTO_SIZE, MSO_VERTICAL_ANCHOR, PP_ALIGN
|
|
8
9
|
from pptx.util import Inches as PptxInches
|
|
9
10
|
from pptx.util import Pt as PptxPt
|
|
10
11
|
|
|
11
|
-
from chgksuite.common import log_wrap, replace_escaped
|
|
12
|
+
from chgksuite.common import log_wrap, replace_escaped, tryint
|
|
12
13
|
from chgksuite.composer.composer_common import BaseExporter, backtick_replace, parseimg
|
|
13
14
|
|
|
14
15
|
|
|
@@ -130,6 +131,14 @@ class PptxExporter(BaseExporter):
|
|
|
130
131
|
s = s.strip()
|
|
131
132
|
return s
|
|
132
133
|
|
|
134
|
+
def apply_vertical_alignment_if_needed(self, text_frame):
|
|
135
|
+
align = self.c["textbox"].get("vertical_align")
|
|
136
|
+
if align:
|
|
137
|
+
text_frame.auto_size = MSO_AUTO_SIZE.NONE
|
|
138
|
+
text_frame.margin_top = 0
|
|
139
|
+
text_frame.margin_bottom = 0
|
|
140
|
+
text_frame.vertical_anchor = getattr(MSO_VERTICAL_ANCHOR, align.upper())
|
|
141
|
+
|
|
133
142
|
def _process_block(self, block):
|
|
134
143
|
section = [x for x in block if x[0] == "section"]
|
|
135
144
|
editor = [x for x in block if x[0] == "editor"]
|
|
@@ -139,6 +148,7 @@ class PptxExporter(BaseExporter):
|
|
|
139
148
|
slide = self.prs.slides.add_slide(self.BLANK_SLIDE)
|
|
140
149
|
textbox = self.get_textbox(slide)
|
|
141
150
|
tf = textbox.text_frame
|
|
151
|
+
self.apply_vertical_alignment_if_needed(tf)
|
|
142
152
|
tf.word_wrap = True
|
|
143
153
|
text_for_size = (
|
|
144
154
|
(self.recursive_join([x[1] for x in section]) or "")
|
|
@@ -150,10 +160,16 @@ class PptxExporter(BaseExporter):
|
|
|
150
160
|
p = self.init_paragraph(tf, text=text_for_size)
|
|
151
161
|
add_line_break = False
|
|
152
162
|
if section:
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
163
|
+
if self.c.get("tour_as_question_number"):
|
|
164
|
+
txt = self.pptx_process_text(section[0][1])
|
|
165
|
+
if self.c.get("tour_as_question_number") == "caps":
|
|
166
|
+
txt = txt.upper()
|
|
167
|
+
self.set_question_number(slide, number=txt)
|
|
168
|
+
else:
|
|
169
|
+
r = p.add_run()
|
|
170
|
+
r.text = self._replace_no_break(self.pptx_process_text(section[0][1]))
|
|
171
|
+
r.font.size = PptxPt(self.c["text_size_grid"]["section"])
|
|
172
|
+
add_line_break = True
|
|
157
173
|
if editor:
|
|
158
174
|
r = p.add_run()
|
|
159
175
|
r.text = self._replace_no_break(
|
|
@@ -206,10 +222,18 @@ class PptxExporter(BaseExporter):
|
|
|
206
222
|
qntextbox = self.get_textbox_qnumber(slide)
|
|
207
223
|
qtf = qntextbox.text_frame
|
|
208
224
|
qtf_p = self.init_paragraph(qtf)
|
|
225
|
+
if self.c["number_textbox"].get("align"):
|
|
226
|
+
qtf_p.alignment = getattr(PP_ALIGN, self.c["number_textbox"]["align"].upper())
|
|
209
227
|
qtf_r = qtf_p.add_run()
|
|
228
|
+
if self.c.get("question_number_format") == "caps" and tryint(number):
|
|
229
|
+
number = f"ВОПРОС {number}"
|
|
210
230
|
qtf_r.text = number
|
|
231
|
+
if self.c["number_textbox"].get("bold"):
|
|
232
|
+
qtf_r.font.bold = True
|
|
211
233
|
if self.c["number_textbox"].get("color"):
|
|
212
234
|
qtf_r.font.color.rgb = RGBColor(*self.c["number_textbox"]["color"])
|
|
235
|
+
if self.c["number_textbox"].get("font_size"):
|
|
236
|
+
qtf_r.font.size = PptxPt(self.c["number_textbox"]["font_size"])
|
|
213
237
|
|
|
214
238
|
def _get_handout_from_4s(self, text):
|
|
215
239
|
if isinstance(text, list):
|
|
@@ -336,10 +360,14 @@ class PptxExporter(BaseExporter):
|
|
|
336
360
|
image, slide, allowbigimage=allowbigimage
|
|
337
361
|
)
|
|
338
362
|
tf = textbox.text_frame
|
|
363
|
+
self.apply_vertical_alignment_if_needed(tf)
|
|
339
364
|
tf.word_wrap = True
|
|
340
365
|
self.set_question_number(slide, self.number)
|
|
341
366
|
question_text = self.pptx_process_text(q["question"], image=image)
|
|
342
|
-
|
|
367
|
+
if self.c.get("force_text_size_question"):
|
|
368
|
+
p = self.init_paragraph(tf, size=self.c["force_text_size_question"])
|
|
369
|
+
else:
|
|
370
|
+
p = self.init_paragraph(tf, text=question_text, coeff=coeff)
|
|
343
371
|
self.pptx_format(question_text, p, tf, slide)
|
|
344
372
|
|
|
345
373
|
def recursive_join(self, s):
|
|
@@ -352,13 +380,12 @@ class PptxExporter(BaseExporter):
|
|
|
352
380
|
slide = self.prs.slides.add_slide(self.BLANK_SLIDE)
|
|
353
381
|
textbox = self.get_textbox(slide)
|
|
354
382
|
tf = textbox.text_frame
|
|
383
|
+
self.apply_vertical_alignment_if_needed(tf)
|
|
355
384
|
tf.word_wrap = True
|
|
356
385
|
if number is not None:
|
|
357
386
|
self.set_question_number(slide, number)
|
|
358
387
|
p = self.init_paragraph(tf, text=handout)
|
|
359
|
-
self.pptx_format(
|
|
360
|
-
self.pptx_process_text(handout), p, tf, slide
|
|
361
|
-
)
|
|
388
|
+
self.pptx_format(self.pptx_process_text(handout), p, tf, slide)
|
|
362
389
|
|
|
363
390
|
def process_question_text(self, q):
|
|
364
391
|
image = self._get_image_from_4s(q["question"])
|
|
@@ -375,31 +402,19 @@ class PptxExporter(BaseExporter):
|
|
|
375
402
|
if image and image["big"] and text_is_duplicated:
|
|
376
403
|
self.add_slide_with_image(image, number=self.number)
|
|
377
404
|
|
|
378
|
-
def
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
self.qcount = int(q["setcounter"])
|
|
383
|
-
self.number = str(self.qcount if "number" not in q else q["number"])
|
|
384
|
-
|
|
385
|
-
if isinstance(q["question"], list):
|
|
386
|
-
for i in range(len(q["question"][1])):
|
|
387
|
-
qn = copy.deepcopy(q)
|
|
388
|
-
qn["question"][1] = q["question"][1][: i + 1]
|
|
389
|
-
self.process_question_text(qn)
|
|
405
|
+
def add_answer_slide(self, q):
|
|
406
|
+
slide = self.prs.slides.add_slide(self.BLANK_SLIDE)
|
|
407
|
+
if self.c.get("override_answer_caption"):
|
|
408
|
+
self.set_question_number(slide, self.c["override_answer_caption"])
|
|
390
409
|
else:
|
|
391
|
-
self.process_question_text(q)
|
|
392
|
-
|
|
393
|
-
if self.c["add_plug"]:
|
|
394
|
-
slide = self.prs.slides.add_slide(self.BLANK_SLIDE)
|
|
395
410
|
self.set_question_number(slide, self.number)
|
|
396
|
-
slide = self.prs.slides.add_slide(self.BLANK_SLIDE)
|
|
397
|
-
self.set_question_number(slide, self.number)
|
|
398
411
|
fields = ["answer"]
|
|
399
412
|
if q.get("zachet") and self.c.get("add_zachet"):
|
|
400
413
|
fields.append("zachet")
|
|
401
414
|
if self.c["add_comment"] and "comment" in q:
|
|
402
415
|
fields.append("comment")
|
|
416
|
+
if self.c["add_source"] and "source" in q:
|
|
417
|
+
fields.append("source")
|
|
403
418
|
textbox = None
|
|
404
419
|
coeff = 1
|
|
405
420
|
for field in fields:
|
|
@@ -410,6 +425,7 @@ class PptxExporter(BaseExporter):
|
|
|
410
425
|
if not textbox:
|
|
411
426
|
textbox = self.get_textbox(slide)
|
|
412
427
|
tf = textbox.text_frame
|
|
428
|
+
self.apply_vertical_alignment_if_needed(tf)
|
|
413
429
|
tf.word_wrap = True
|
|
414
430
|
|
|
415
431
|
text_for_size = self.recursive_join(
|
|
@@ -423,7 +439,18 @@ class PptxExporter(BaseExporter):
|
|
|
423
439
|
text_for_size += "\n" + self.recursive_join(
|
|
424
440
|
self.pptx_process_text(q["comment"])
|
|
425
441
|
)
|
|
426
|
-
|
|
442
|
+
if q.get("source") and self.c.get("add_source"):
|
|
443
|
+
text_for_size += "\n" + self.recursive_join(
|
|
444
|
+
self.pptx_process_text(q["source"])
|
|
445
|
+
)
|
|
446
|
+
if q.get("author") and self.c.get("add_author"):
|
|
447
|
+
text_for_size += "\n" + self.recursive_join(
|
|
448
|
+
self.pptx_process_text(q["author"])
|
|
449
|
+
)
|
|
450
|
+
if self.c.get("force_text_size_answer"):
|
|
451
|
+
p = self.init_paragraph(tf, size=self.c["force_text_size_answer"])
|
|
452
|
+
else:
|
|
453
|
+
p = self.init_paragraph(tf, text=text_for_size, coeff=coeff)
|
|
427
454
|
r = p.add_run()
|
|
428
455
|
r.text = f"{self.get_label(q, 'answer')}: "
|
|
429
456
|
r.font.bold = True
|
|
@@ -442,6 +469,38 @@ class PptxExporter(BaseExporter):
|
|
|
442
469
|
r.text = f"\n{self.get_label(q, 'comment')}: "
|
|
443
470
|
r.font.bold = True
|
|
444
471
|
self.pptx_format(comment_text, p, tf, slide)
|
|
472
|
+
if self.c["add_source"] and "source" in q:
|
|
473
|
+
source_text = self.pptx_process_text(q["source"])
|
|
474
|
+
r = p.add_run()
|
|
475
|
+
r.text = f"\n{self.get_label(q, 'source')}: "
|
|
476
|
+
r.font.bold = True
|
|
477
|
+
self.pptx_format(source_text, p, tf, slide)
|
|
478
|
+
if self.c["add_author"] and "author" in q:
|
|
479
|
+
author_text = self.pptx_process_text(q["author"])
|
|
480
|
+
r = p.add_run()
|
|
481
|
+
r.text = f"\n{self.get_label(q, 'author')}: "
|
|
482
|
+
r.font.bold = True
|
|
483
|
+
self.pptx_format(author_text, p, tf, slide)
|
|
484
|
+
|
|
485
|
+
def process_question(self, q):
|
|
486
|
+
if "number" not in q:
|
|
487
|
+
self.qcount += 1
|
|
488
|
+
if "setcounter" in q:
|
|
489
|
+
self.qcount = int(q["setcounter"])
|
|
490
|
+
self.number = str(self.qcount if "number" not in q else q["number"])
|
|
491
|
+
|
|
492
|
+
if isinstance(q["question"], list):
|
|
493
|
+
for i in range(len(q["question"][1])):
|
|
494
|
+
qn = copy.deepcopy(q)
|
|
495
|
+
qn["question"][1] = q["question"][1][: i + 1]
|
|
496
|
+
self.process_question_text(qn)
|
|
497
|
+
else:
|
|
498
|
+
self.process_question_text(q)
|
|
499
|
+
|
|
500
|
+
if self.c["add_plug"]:
|
|
501
|
+
slide = self.prs.slides.add_slide(self.BLANK_SLIDE)
|
|
502
|
+
self.set_question_number(slide, self.number)
|
|
503
|
+
self.add_answer_slide(q)
|
|
445
504
|
|
|
446
505
|
def determine_size(self, text, coeff=1):
|
|
447
506
|
text = self.recursive_join(text)
|
|
@@ -451,13 +510,16 @@ class PptxExporter(BaseExporter):
|
|
|
451
510
|
return element["size"]
|
|
452
511
|
return self.c["text_size_grid"]["smallest"]
|
|
453
512
|
|
|
454
|
-
def init_paragraph(self, text_frame, text=None, coeff=1):
|
|
513
|
+
def init_paragraph(self, text_frame, text=None, coeff=1, size=None):
|
|
455
514
|
p = text_frame.paragraphs[0]
|
|
456
515
|
p.font.name = self.c["font"]["name"]
|
|
457
|
-
size
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
516
|
+
if size:
|
|
517
|
+
_size = size
|
|
518
|
+
else:
|
|
519
|
+
_size = self.c["text_size_grid"]["default"]
|
|
520
|
+
if text:
|
|
521
|
+
_size = self.determine_size(text, coeff=coeff)
|
|
522
|
+
p.font.size = PptxPt(_size)
|
|
461
523
|
return p
|
|
462
524
|
|
|
463
525
|
def export(self, outfilename):
|
chgksuite/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.
|
|
1
|
+
__version__ = "0.25.0"
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
chgksuite/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
2
|
chgksuite/__main__.py,sha256=0-_jfloveTW3SZYW5XEagbyaHKGCiDhGNgcLxsT_dMs,140
|
|
3
3
|
chgksuite/cli.py,sha256=8YoHWfc-wv6gdYMPH3X8HxV9SG70S7M6IQqavJaBXV4,31990
|
|
4
|
-
chgksuite/common.py,sha256=
|
|
4
|
+
chgksuite/common.py,sha256=VkOhoBA_P3qY5VgtvfrBjOsm5uVNL2s2Th2AhGB2pg8,11207
|
|
5
5
|
chgksuite/parser.py,sha256=AVNeTUgv0aGHsxWunV_7bM4Ul2hbDslkzqg0dU49lic,37285
|
|
6
6
|
chgksuite/parser_db.py,sha256=W1--OcDnx18mehH1T2ISHu3Saeq-9mqHo-xJopNySXI,11135
|
|
7
7
|
chgksuite/trello.py,sha256=BG1Qb_W7Uu4o3Mfc_tK71ElU8ysdSplGlj_sAKfvUn4,14730
|
|
8
8
|
chgksuite/typotools.py,sha256=Jdk65Wn_bXqpQtOT7PkBZyD2ZG1MBeeZFPMzcHEPkf4,12771
|
|
9
|
-
chgksuite/version.py,sha256=
|
|
9
|
+
chgksuite/version.py,sha256=Mu4JbSLl5nr-J2figk5hmW2mrw4skf_oeIzxbnpcgwY,23
|
|
10
10
|
chgksuite/vulture_whitelist.py,sha256=P__p_X0zt10ivddIf81uyxsobV14vFg8uS2lt4foYpc,3582
|
|
11
11
|
chgksuite/composer/__init__.py,sha256=MAOVZIYXmZmD6nNQSo9DueV6b5RgxF7_HGeLvsAhMJs,6490
|
|
12
12
|
chgksuite/composer/chgksuite_parser.py,sha256=MFcLUWbccMqo3OYEuaAIA0loEvWM_PNS9vR7c1z_c60,8843
|
|
@@ -16,7 +16,7 @@ chgksuite/composer/docx.py,sha256=5MASXACM-ztWrr3VdO8HZ-W-hWWQ5TY1jXMsCQIufGc,18
|
|
|
16
16
|
chgksuite/composer/latex.py,sha256=WtLdUICxeX4_5vHEJRF0YhFLpTsOUwBkQFunQS488FA,9248
|
|
17
17
|
chgksuite/composer/lj.py,sha256=nty3Zs3N1H0gNK378U04aAHo71_5cABhCM1Mm9jiUEA,15213
|
|
18
18
|
chgksuite/composer/openquiz.py,sha256=4adZewvRXpZhKrh9H4epKoMMDhmki9US55-Q0LcpZW0,7019
|
|
19
|
-
chgksuite/composer/pptx.py,sha256=
|
|
19
|
+
chgksuite/composer/pptx.py,sha256=P4BewZj7TCiTM5atXxD1qvgW6GDWArp3NfwBN-7ytjg,22143
|
|
20
20
|
chgksuite/composer/reddit.py,sha256=-Eg4CqMHhyGGfCteVwdQdtE1pfUXQ42XcP5OYUrBXmo,3878
|
|
21
21
|
chgksuite/composer/stats.py,sha256=GbraSrjaZ8Mc2URs5aGAsI4ekboAKzlJJOqsbe96ELA,3995
|
|
22
22
|
chgksuite/composer/telegram.py,sha256=H65LS79JZ3aCcqeq_SrnUU4E4yro1f-EZxCM3IrIyyQ,46526
|
|
@@ -45,9 +45,9 @@ chgksuite/resources/template.docx,sha256=Do29TAsg3YbH0rRSaXhVzKEoh4pwXkklW_idWA3
|
|
|
45
45
|
chgksuite/resources/template.pptx,sha256=hEFWqE-yYpwZ8ejrMCJIPEyoMT3eDqaqtiEeQ7I4fyk,29777
|
|
46
46
|
chgksuite/resources/template_shorin.pptx,sha256=hEFWqE-yYpwZ8ejrMCJIPEyoMT3eDqaqtiEeQ7I4fyk,29777
|
|
47
47
|
chgksuite/resources/trello.json,sha256=M5Q9JR-AAJF1u16YtNAxDX-7c7VoVTXuq4POTqYvq8o,555
|
|
48
|
-
chgksuite-0.
|
|
49
|
-
chgksuite-0.
|
|
50
|
-
chgksuite-0.
|
|
51
|
-
chgksuite-0.
|
|
52
|
-
chgksuite-0.
|
|
53
|
-
chgksuite-0.
|
|
48
|
+
chgksuite-0.25.0.dist-info/licenses/LICENSE,sha256=_a1yfntuPmctLsuiE_08xMSORuCfGS8X5hQph2U_PUw,1081
|
|
49
|
+
chgksuite-0.25.0.dist-info/METADATA,sha256=ueTN4kr6BEoh8PvfvlbFTRfaWY5Lf7QBYvJQmONLZ3M,1294
|
|
50
|
+
chgksuite-0.25.0.dist-info/WHEEL,sha256=ck4Vq1_RXyvS4Jt6SI0Vz6fyVs4GWg7AINwpsaGEgPE,91
|
|
51
|
+
chgksuite-0.25.0.dist-info/entry_points.txt,sha256=lqjX6ULQZGDt0rgouTXBuwEPiwKkDQkSiNsT877A_Jg,54
|
|
52
|
+
chgksuite-0.25.0.dist-info/top_level.txt,sha256=cSWiRBOGZW9nIO6Rv1IrEfwPgV2ZWs87QV9wPXeBGqM,10
|
|
53
|
+
chgksuite-0.25.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|