Files
server-tools/test_s/csv_to_ics.py
2026-05-23 18:40:41 +03:00

105 lines
5.1 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.
import csv
import hashlib
from datetime import datetime, timedelta
# test
def generate_uid(full_name: str, domain: str = "mupts.local") -> str:
"""
Генерирует стабильный уникальный идентификатор (UID) на основе ФИО.
"""
if not full_name:
return ""
# 1. Нормализация: нижний регистр и удаление двойных пробелов
clean_name = " ".join(full_name.strip().lower().split())
# 2. Хеширование: используем MD5 (он быстрый и короткий)
# Берем первые 16 символов хеша — этого более чем достаточно для избежания коллизий в рамках компании
name_hash = hashlib.md5(clean_name.encode('utf-8')).hexdigest()[:16]
# 3. Формирование формата UID (по стандарту RFC 5545 рекомендуется формат id@domain)
return f"{name_hash}@{domain}"
def csv_to_ics(csv_file_path, ics_file_path):
ics_content = [
"BEGIN:VCALENDAR",
"VERSION:2.0",
"PRODID:-//MUT_TS//Birthdays//RU",
"CALSCALE:GREGORIAN"
]
# with open(csv_file_path, mode='r', encoding='utf-8') as file:
with open(csv_file_path, mode='r', encoding='windows-1251') as file:
# Предполагаем, что разделитель - запятая. Если точка с запятой, измените на delimiter=';'
reader = csv.DictReader(file, delimiter=';')
for row in reader:
# Извлекаем данные (замените ключи на названия ваших колонок в CSV)
name = row.get('Subject', '').strip()
date_str = row.get('Start Date', '').strip().rstrip('.') # убираем случайные точки на конце
desckription = row.get('Description', '').strip()
location = row.get('Location', '').strip()
# phone = row.get('Телефон', '').strip()
# address = row.get('Адрес', '').strip()
if not name or not date_str:
continue
try:
# Парсим оригинальную дату (например, 18.06.1964)
start_date = datetime.strptime(date_str, "%d.%m.%Y")
# Для событий на весь день дата окончания должна быть следующим днем
end_date = start_date + timedelta(days=1)
dtstart = start_date.strftime("%Y%m%d")
dtend = end_date.strftime("%Y%m%d")
# Формируем блок события
ics_content.append("BEGIN:VEVENT")
ics_content.append(f"UID:{generate_uid(name)}")
ics_content.append(f"SUMMARY:День рождения: {name}")
ics_content.append(f"DTSTART;VALUE=DATE:{dtstart}")
ics_content.append(f"DTEND;VALUE=DATE:{dtend}")
ics_content.append("RRULE:FREQ=YEARLY")
ics_content.append(f"DESCRIPTION:{desckription}")
ics_content.append(f"LOCATION:{location}")
ics_content.append("TRANSP:TRANSPARENT")
ics_content.append("STATUS:CONFIRMED")
ics_content.append("CLASS:PUBLIC")
ics_content.append("CATEGORIES:Дни рождения,МУП ТС")
ics_content.append("CLASS:PUBLIC")
# Первое напоминание: за 1 день (в стандартное время календаря, обычно 09:00 или 18:00 предыдущего дня)
ics_content.append("BEGIN:VALARM")
ics_content.append("ACTION:DISPLAY")
ics_content.append("DESCRIPTION:Завтра день рождения коллеги!")
ics_content.append("TRIGGER:-P1D")
ics_content.append("END:VALARM")
# Второе напоминание: в сам день в 07:30 (через 7 часов 30 минут после полуночи)
ics_content.append("BEGIN:VALARM")
ics_content.append("ACTION:DISPLAY")
ics_content.append("DESCRIPTION:Сегодня день рождения!")
ics_content.append("TRIGGER:PT7H30M")
ics_content.append("END:VALARM")
ics_content.append("END:VEVENT")
except ValueError:
# Пропускаем строки с некорректным форматом даты
print(f"Ошибка парсинга даты для: {name} ({date_str})")
continue
ics_content.append("END:VCALENDAR")
# Записываем всё в .ics файл
with open(ics_file_path, mode='w', encoding='utf-8', newline='') as ics_file:
ics_file.write("\n".join(ics_content))
# Запуск конвертации
csv_to_ics('1.csv', 'birthdays.ics')
print("Файл birthdays.ics успешно создан!")