274 lines
16 KiB
Python
274 lines
16 KiB
Python
# -*- 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() |