# -*- coding: utf-8 -*- """Generate objectivka (spravka) for Бойко Кирилл Сергеевич in .md, .docx, .pdf.""" import os import sys sys.stdout.reconfigure(encoding="utf-8") from docx import Document from docx.shared import Pt, Cm, RGBColor from docx.enum.text import WD_ALIGN_PARAGRAPH from reportlab.lib.pagesizes import A4 from reportlab.lib.units import cm from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.lib.enums import TA_CENTER from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, Image from reportlab.pdfbase import pdfmetrics from reportlab.pdfbase.ttfonts import TTFont OUT_DIR = r"C:\python\resume" PHOTO = os.path.join(OUT_DIR, "dca7a868-65c0-422e-be26-06a5f2564cca.jfif") MD_OUT = os.path.join(OUT_DIR, "Объективка_Бойко_Кирилл_Сергеевич.md") DOCX_OUT = os.path.join(OUT_DIR, "Объективка_Бойко_Кирилл_Сергеевич.docx") PDF_OUT = os.path.join(OUT_DIR, "Объективка_Бойко_Кирилл_Сергеевич.pdf") FIO = "БОЙКО КИРИЛЛ СЕРГЕЕВИЧ" POSITION = ("Соучредитель IT-стартапа ITGuild; Председатель Комитета по предпринимательству " "и экономической грамотности молодежи Молодежного Парламента Донецкой Народной Республики") BIRTH_DATE = "18 декабря 1989 г." BIRTH_PLACE = "г. Донецк, Донецкая область." RESIDENCE = "г. Донецк, пр. Театральный, д. 5" EDUCATION = [ "Донецкий Национальный Технический Университет, экономический факультет, кафедра хозяйственного права, специальность «Менеджмент организаций» — бакалавр. Период обучения: 2008-2012 гг.", "Донецкий Национальный Технический Университет, экономический факультет, кафедра «Управления персоналом и Экономика труда», специальность «Управление персоналом и экономика труда» — магистр. Период обучения: 2012-2014 гг.", "Курсы, тренинги: «Старт бизнеса», «Школа предпринимательства 2.0. Перезагрузка»; обучение в «Школе 21» (в настоящее время).", ] DEGREE = "Магистр" AWARDS = [ "Благодарность Акселератора роста малого бизнеса (Луганская Народная Республика) — за высокий профессионализм, поддержку и наставничество;", "Благодарность Акселератора роста малого бизнеса — за активную поддержку молодежных инициатив и вклад в программу развития молодежных проектов Запорожской области;", "Сертификат члена Общероссийской общественной организации малого и среднего предпринимательства «ОПОРА РОССИИ» в Донецкой Народной Республике (№ 0002/2022);", "Сертификат за успешное прохождение заданий первого блока дистанционного этапа конкурса управленцев «Лидеры России» (2021 г.);", "Сертификат участника третьей флагманской встречи Клуба молодых предпринимателей Росмолодёжь.Бизнес (2024 г.);", "Сертификат о прохождении курса «Старт бизнеса» «Школы предпринимательства 2.0. Перезагрузка»;", "Сертификат Акселератора роста малого бизнеса об успешной защите итогового бизнес-проекта;", "Сертификат участника хакатона (Народная дружина В.А. Тараненко);", "Благодарственное письмо Росмолодёжь.Предпринимай — за активное участие и неоценимый вклад в развитие Сообщества молодых предпринимателей (Москва, 2025 г.);", "Благодарственное письмо Росмолодёжь.Предпринимай — члену региональной команды Донецкой Народной Республики Южного федерального округа (2025 г.);", "Благодарственное письмо за участие в качестве эксперта всероссийского форума «Амур»;", "Благодарственное письмо Министерства молодежной политики Донецкой Народной Республики — за высокий профессионализм, значительный личный вклад и добросовестный труд в области молодежной политики (2025 г.);", "Благодарственное письмо программы «Я в деле» — за поддержку и активное сотрудничество в повышении предпринимательской грамотности студентов (2026 г.);", "Награда за участие в полуфинале кадрового конкурса «Лидеры Возрождения. Донецкая Народная Республика».", ] PARTY = "не имеет" FAMILY = "женат, детей не имеет" WORK = [ ("2014 - н/вр.", "Предпринимательская деятельность в сфере информационных технологий"), ("2019 - н/вр.", "Владелец интернет-портала для поиска работы Rabota Today (rabota.today)"), ("2022 - н/вр.", "Соучредитель IT-стартапа ITGuild (itguild.info)"), ("2022 - н/вр.", "Председатель Комитета «Информационных Технологий и Автоматизации Бизнеса» в ОО «ОПОРА РОССИИ»"), ("2023 - 2025", "Лидер «Росмолодежь.Предпринимай» в Донецкой Народной Республике"), ("2025 - н/вр.", "Председатель Комитета по предпринимательству и экономической грамотности молодежи Молодежного Парламента Донецкой Народной Республики"), ("2025 - н/вр.", "Наставник проекта «Росмолодежь.Предпринимай»"), ("2026 - н/вр.", "Руководитель ИТ-сообщества Донбасса"), ] def build_md(): lines = [] lines.append("# СПРАВКА") lines.append("") lines.append(f"## {FIO}") lines.append("") lines.append('Фото') lines.append("") lines.append(f"**Должность:** {POSITION}") lines.append("") lines.append(f"**Дата рождения:** {BIRTH_DATE}") lines.append("") lines.append(f"**Место рождения:** {BIRTH_PLACE}") lines.append("") lines.append(f"**Место жительства:** {RESIDENCE}") lines.append("") lines.append("**Образование:** высшее:") for e in EDUCATION: lines.append(f"- {e}") lines.append("") lines.append(f"**Учёная степень:** {DEGREE}") lines.append("") lines.append("**Награды, поощрения:**") for i, a in enumerate(AWARDS, 1): lines.append(f"{i}. {a}") lines.append("") lines.append(f"**Партийная принадлежность:** {PARTY}") lines.append("") lines.append(f"**Семейное положение:** {FAMILY}") lines.append("") lines.append("## Трудовая деятельность") lines.append("") for period, pos in WORK: lines.append(f"- **{period}** — {pos}") with open(MD_OUT, "w", encoding="utf-8") as f: f.write("\n".join(lines) + "\n") print("MD saved:", MD_OUT) def build_docx(): doc = Document() style = doc.styles["Normal"] style.font.name = "Times New Roman" style.font.size = Pt(12) for section in doc.sections: section.top_margin = Cm(1.5) section.bottom_margin = Cm(1.5) section.left_margin = Cm(2) section.right_margin = Cm(1.5) # Header table: photo + info t = doc.add_table(rows=1, cols=2) t.autofit = False t.columns[0].width = Cm(4) t.columns[1].width = Cm(12.5) photo_cell = t.cell(0, 0) p = photo_cell.paragraphs[0] if os.path.exists(PHOTO): p.add_run().add_picture(PHOTO, width=Cm(3.2)) info_cell = t.cell(0, 1) def add_line(cell, text, bold=False, size=12, center=False, first=False): para = cell.paragraphs[0] if first else cell.add_paragraph() if center: para.alignment = WD_ALIGN_PARAGRAPH.CENTER r = para.add_run(text) r.bold = bold r.font.size = Pt(size) return para add_line(info_cell, "СПРАВКА", bold=True, size=14, center=True, first=True) add_line(info_cell, FIO, bold=True, size=14, center=True) add_line(info_cell, "") add_line(info_cell, f"Должность: {POSITION}") add_line(info_cell, f"Дата рождения: {BIRTH_DATE}") add_line(info_cell, f"Место рождения: {BIRTH_PLACE}") add_line(info_cell, f"Место жительства: {RESIDENCE}") doc.add_paragraph() # Fields table ft = doc.add_table(rows=5, cols=2) ft.autofit = False ft.columns[0].width = Cm(4.5) ft.columns[1].width = Cm(12) def set_cell(cell, text, bold=False, first=True): para = cell.paragraphs[0] r = para.add_run(text) r.bold = bold r.font.size = Pt(12) def set_cell_multi(cell, items, numbered=False): first = True for i, item in enumerate(items, 1): para = cell.paragraphs[0] if first else cell.add_paragraph() first = False txt = f"{i}. {item}" if numbered else f"— {item}" r = para.add_run(txt) r.font.size = Pt(11) set_cell(ft.cell(0, 0), "Образование:", bold=True) set_cell_multi(ft.cell(0, 1), EDUCATION) set_cell(ft.cell(1, 0), "Учёная степень:", bold=True) set_cell(ft.cell(1, 1), DEGREE) set_cell(ft.cell(2, 0), "Награды, поощрения:", bold=True) set_cell_multi(ft.cell(2, 1), AWARDS, numbered=True) set_cell(ft.cell(3, 0), "Партийная принадлежность:", bold=True) set_cell(ft.cell(3, 1), PARTY) set_cell(ft.cell(4, 0), "Семейное положение:", bold=True) set_cell(ft.cell(4, 1), FAMILY) # Work heading hp = doc.add_paragraph() hp.alignment = WD_ALIGN_PARAGRAPH.CENTER hr = hp.add_run("Трудовая деятельность") hr.bold = True hr.font.size = Pt(13) # Work table wt = doc.add_table(rows=len(WORK), cols=2) wt.autofit = False wt.columns[0].width = Cm(4) wt.columns[1].width = Cm(12.5) for i, (period, pos) in enumerate(WORK): r0 = wt.cell(i, 0).paragraphs[0].add_run(period) r0.font.size = Pt(11) r1 = wt.cell(i, 1).paragraphs[0].add_run(pos) r1.font.size = Pt(11) doc.save(DOCX_OUT) print("DOCX saved:", DOCX_OUT) def build_pdf(): pdfmetrics.registerFont(TTFont("DejaVuSans", r"C:\Windows\Fonts\DejaVuSans.ttf")) pdfmetrics.registerFont(TTFont("DejaVuSans-Bold", r"C:\Windows\Fonts\DejaVuSans-Bold.ttf")) pdfmetrics.registerFontFamily("DejaVuSans", normal="DejaVuSans", bold="DejaVuSans-Bold") styles = getSampleStyleSheet() title = ParagraphStyle("T", parent=styles["Normal"], fontName="DejaVuSans-Bold", fontSize=15, leading=19, alignment=TA_CENTER, spaceAfter=2) fio_st = ParagraphStyle("F", parent=styles["Normal"], fontName="DejaVuSans-Bold", fontSize=14, leading=18, alignment=TA_CENTER, spaceAfter=8) body = ParagraphStyle("B", parent=styles["Normal"], fontName="DejaVuSans", fontSize=10.5, leading=14, spaceAfter=3) lab = ParagraphStyle("L", parent=body, fontName="DejaVuSans-Bold") head = ParagraphStyle("H", parent=styles["Normal"], fontName="DejaVuSans-Bold", fontSize=13, leading=17, alignment=TA_CENTER, spaceBefore=8, spaceAfter=4) doc = SimpleDocTemplate(PDF_OUT, pagesize=A4, leftMargin=2 * cm, rightMargin=1.5 * cm, topMargin=1.5 * cm, bottomMargin=1.5 * cm, title="Справка — Бойко Кирилл Сергеевич") story = [] # Header table header_lines = [ Paragraph("СПРАВКА", title), Paragraph(FIO, fio_st), Paragraph(f"Должность: {POSITION}", body), Paragraph(f"Дата рождения: {BIRTH_DATE}", body), Paragraph(f"Место рождения: {BIRTH_PLACE}", body), Paragraph(f"Место жительства: {RESIDENCE}", body), ] photo = Image(PHOTO, width=3.2 * cm, height=4.3 * cm) if os.path.exists(PHOTO) else Paragraph("", body) header_tbl = Table([[photo, header_lines]], colWidths=[4 * cm, 13 * cm]) header_tbl.setStyle(TableStyle([ ("VALIGN", (0, 0), (-1, -1), "TOP"), ("LEFTPADDING", (0, 0), (-1, -1), 0), ("RIGHTPADDING", (0, 0), (-1, -1), 0), ])) story.append(header_tbl) story.append(Spacer(1, 10)) # Fields table rows edu_flow = [Paragraph(f"— {e}", ParagraphStyle("e", parent=body, fontSize=10)) for e in EDUCATION] awards_flow = [Paragraph(f"{i}. {a}", ParagraphStyle("a", parent=body, fontSize=10)) for i, a in enumerate(AWARDS, 1)] rows = [ [Paragraph("Образование:", lab), edu_flow], [Paragraph("Учёная степень:", lab), Paragraph(DEGREE, body)], [Paragraph("Награды, поощрения:", lab), awards_flow], [Paragraph("Партийная принадлежность:", lab), Paragraph(PARTY, body)], [Paragraph("Семейное положение:", lab), Paragraph(FAMILY, body)], ] fields_tbl = Table(rows, colWidths=[4.5 * cm, 12.5 * cm]) fields_tbl.setStyle(TableStyle([ ("VALIGN", (0, 0), (-1, -1), "TOP"), ("LEFTPADDING", (0, 0), (-1, -1), 2), ("RIGHTPADDING", (0, 0), (-1, -1), 2), ("TOPPADDING", (0, 0), (-1, -1), 3), ("BOTTOMPADDING", (0, 0), (-1, -1), 3), ])) story.append(fields_tbl) story.append(Paragraph("Трудовая деятельность", head)) work_rows = [[Paragraph(f"{p}", body), Paragraph(pos, body)] for p, pos in WORK] work_tbl = Table(work_rows, colWidths=[4 * cm, 13 * cm]) work_tbl.setStyle(TableStyle([ ("VALIGN", (0, 0), (-1, -1), "TOP"), ("LEFTPADDING", (0, 0), (-1, -1), 2), ("RIGHTPADDING", (0, 0), (-1, -1), 2), ("TOPPADDING", (0, 0), (-1, -1), 2), ("BOTTOMPADDING", (0, 0), (-1, -1), 2), ])) story.append(work_tbl) doc.build(story) print("PDF saved:", PDF_OUT) if __name__ == "__main__": build_md() build_docx() build_pdf()