Files
resume/build_objectivka.py
T

274 lines
16 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- 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('<img src="dca7a868-65c0-422e-be26-06a5f2564cca.jfif" alt="Фото" width="120">')
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"<b>Должность:</b> {POSITION}", body),
Paragraph(f"<b>Дата рождения:</b> {BIRTH_DATE}", body),
Paragraph(f"<b>Место рождения:</b> {BIRTH_PLACE}", body),
Paragraph(f"<b>Место жительства:</b> {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"<b>{p}</b>", 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()