# -*- 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()