العمل مع iCalendar في بايثون

في هذه المقالة، سنناقش كيفية العمل مع iCalendar في بايثون، وكتابة وقراءة ملفات iCal، وتحليل تقويم من عنوان URL مثل Google Calendar.

لكن أولاً، ما هو ملف iCal؟

يتيح تنسيق ICALENDAR (مواصفات الكائنات الأساسية للتقويم والجدولة عبر الإنترنت) للمستخدمين تخزين وتبادل معلومات التقويم والجدولة مثل الأحداث والمهام. تستخدم العديد من المنتجات بما في ذلك تقويم Google وتقويم Apple هذا التنسيق.

دعونا نلقي نظرة على وحدتي بايثون المشهورتين اللتين تعملان على تبسيط العمل مع ملفات ics.

كيفية قراءة وكتابة ملفات iCalendar في بايثون

icalendar هي مكتبة شعبية ومريحة لمعالجة التقويمات في بايثون. تحتاج إلى تثبيته من حزمة pip:

pip install icalendar

لمزيد من المعلوامت حول هذه الوحدة يمكنك زيارة الوثائق من هنا

بعد ذلك، دعونا نكتب الكود لإنشاء حدث جديد وتخزينه على القرص.

نبدأ بإستدعاء المكتبات و الوحدات. بالإضافة إلى icalendar، نحتاج إلى datetime وpytz وpathlib.

from icalendar import Calendar, Event, vCalAddress, vText
from datetime import datetime
from pathlib import Path
import os
import pytz
 
# init the calendar
cal = Calendar()

يتبع iCalendar مواصفات RFC5545، مما يعني أننا بحاجة إلى تضمين بعض الخصائص مثل PRODID والإصدار. يحدد PRODID المعرف الذي قام بإنشاء كائن iCalendar.

cal.add('prodid', '-//My calendar product//example.com//')
cal.add('version', '2.0')

بعد ذلك، نضيف الحدث بالاسم والوصف والبداية والنهاية.

# Add subcomponents
event = Event()
event.add('name', 'Awesome Meeting')
event.add('description', 'Define the roadmap of our awesome project')
event.add('dtstart', datetime(2022, 1, 25, 8, 0, 0, tzinfo=pytz.utc))
event.add('dtend', datetime(2022, 1, 25, 10, 0, 0, tzinfo=pytz.utc))
 
# Add the organizer
organizer = vCalAddress('MAILTO:jdoe@example.com')
 
# Add parameters of the event
organizer.params['name'] = vText('John Doe')
organizer.params['role'] = vText('CEO')
event['organizer'] = organizer
event['location'] = vText('New York, USA')
 
event['uid'] = '2022125T111010/272356262376@example.com'
event.add('priority', 5)
attendee = vCalAddress('MAILTO:rdoe@example.com')
attendee.params['name'] = vText('Richard Roe')
attendee.params['role'] = vText('REQ-PARTICIPANT')
event.add('attendee', attendee, encode=0)
 
attendee = vCalAddress('MAILTO:jsmith@example.com')
attendee.params['name'] = vText('John Smith')
attendee.params['role'] = vText('REQ-PARTICIPANT')
event.add('attendee', attendee, encode=0)
 
# Add the event to the calendar
cal.add_component(event)

وأخيرًا، نقوم بتخزين الحدث على القرص باسم example.ics ثم نقوم بإنشاء دليل يسمى MyCalendar باستخدام pathlib، ثم نكتب الحدث في ملف. يمكنك قراءة إحدى مقالاتي السابقة هنا لمعرفة المزيد حول الكتابة إلى ملف في بايثون.

# Write to disk
directory = Path.cwd() / 'MyCalendar'
try:
   directory.mkdir(parents=True, exist_ok=False)
except FileExistsError:
   print("Folder already exists")
else:
   print("Folder was created")
 
f = open(os.path.join(directory, 'example.ics'), 'wb')
f.write(cal.to_ical())
f.close()

الآن بعد أن أنشأنا حدثًا، فلنقرأه.

e = open('MyCalendar/example.ics', 'rb')
ecal = icalendar.Calendar.from_ical(e.read())
for component in ecal.walk():
   print(component.name)
e.close()

يظهر الإخراج مكونين:

VCALENDAR
VEVENT

يتم تخزين الأحداث في VEVENT. للحصول على التفاصيل، نحن بحاجة للوصول إلى مكوناته الفرعية. لاحظ أنك تحتاج إلى استدعاء التابع decoded() بدلاً من get() لإخراج قيم التاريخ والوقت.

e = open('MyCalendar/example.ics', 'rb')
ecal = icalendar.Calendar.from_ical(e.read())
for component in ecal.walk():
   if component.name == "VEVENT":
       print(component.get("name"))
       print(component.get("description"))
       print(component.get("organizer"))
       print(component.get("location"))
       print(component.decoded("dtstart"))
       print(component.decoded("dtend"))
e.close()

والنتيجة:

Awesome Meeting
Define the roadmap of our awesome project
MAILTO:jdoe@example.com
New York, USA
2022-01-25 08:00:00+00:00
2022-01-25 10:00:00+00:00

إلا هنا نحن نعرف كيفية إنشاء ملف iCal وقراءته. ارجع إلى وثائق ICALENDAR لمعرفة المزيد حول الحزمة.

اما الأن دعونا نتعلم كيفية معالجة التقويم في بايثون.

تحليل تقويم Google من عنوان URL

يمكننا أيضًا تحليل عنوان URL لتقويم Google. في هذا المثال، نستخدم حزمة ics.py، والتي يمكنك تثبيتها باستخدام الأمر التالي:

pip install ics

دعونا نستخدم تقويم Google العام حول مراحل القمر، ونحلله كملف iCal، ونستخرج الأحداث.

from ics import Calendar
import requests
 
# Parse the URL
url = "https://calendar.google.com/calendar/ical/ht3jlfaac5lfd6263ulfh4tql8%40group.calendar.google.com/public/basic.ics"
cal = Calendar(requests.get(url).text)
 
# Print all the events
print(cal.events)

وهنا جزء من الإخراج:

{<all-day event="" 'last="" quarter="" 9:37am'="" begin:2021-01-06="" end:2021-01-07="">,
 <all-day event="" 'new="" moon="" 5:00am'="" begin:2021-01-13="" end:2021-01-14="">,
 <all-day event="" 'first="" quarter="" 9:02pm'="" begin:2021-01-20="" end:2021-01-21="">,
 <all-day event="" 'full="" moon="" 7:16pm'="" begin:2021-01-28="" end:2021-01-29="">,
 <all-day event="" 'last="" quarter="" 5:37pm'="" begin:2021-02-04="" end:2021-02-05="">,
 <all-day event="" 'new="" moon="" 7:06pm'="" begin:2021-02-11="" end:2021-02-12="">,
 <all-day event="" 'first="" quarter="" 6:47pm'="" begin:2021-02-19="" end:2021-02-20="">,
 <all-day event="" 'full="" moon="" 8:17am'="" begin:2021-02-27="" end:2021-02-28="">,
 <all-day event="" 'last="" quarter="" 1:30am'="" begin:2021-03-06="" end:2021-03-07="">,
 <all-day event="" 'new="" moon="" 10:21am'="" begin:2021-03-13="" end:2021-03-14="">,
 <all-day event="" 'first="" quarter="" 2:40pm'="" begin:2021-03-21="" end:2021-03-22="">,
 <all-day event="" 'full="" moon="" 6:48pm'="" begin:2021-03-28="" end:2021-03-29="">,
 <all-day event="" 'last="" quarter="" 10:02am'="" begin:2021-04-04="" end:2021-04-05="">,
 <all-day event="" 'new="" moon="" 2:31am'="" begin:2021-04-12="" end:2021-04-13="">,
 <all-day event="" 'first="" quarter="" 6:59am'="" begin:2021-04-20="" end:2021-04-21="">,...}
</all-day></all-day></all-day></all-day></all-day></all-day></all-day></all-day></all-day></all-day></all-day></all-day></all-day></all-day></all-day>

هل تريد طباعته بشكل جميل؟ ألقِ نظرة على وحدتين شائعتين لجداول الطباعة الجميلة هنا.

دعونا نرتب الأحداث بترتيب تنازلي باستخدامsorted(). نستخدمsorted() بدلاً من fsort() لأن متغير الأحداث عبارة عن مجموعة، بينما يعملsort() مع القوائم.

events = cal.events
sorted_events = sorted(events, reverse = True)
sorted_events

هنا جزء من الإخراج:

[<all-day event="" 'full="" moon="" 12:33am'="" begin:2023-12-27="" end:2023-12-28="">,
 <all-day event="" 'first="" quarter="" 6:39pm'="" begin:2023-12-19="" end:2023-12-20="">,
 <all-day event="" 'new="" moon="" 11:32pm'="" begin:2023-12-12="" end:2023-12-13="">,
 <all-day event="" 'last="" quarter="" 5:49am'="" begin:2023-12-05="" end:2023-12-06="">,
 <all-day event="" 'full="" moon="" 9:16am'="" begin:2023-11-27="" end:2023-11-28="">,
 <all-day event="" 'first="" quarter="" 10:50am'="" begin:2023-11-20="" end:2023-11-21="">,
 <all-day event="" 'new="" moon="" 9:27am'="" begin:2023-11-13="" end:2023-11-14="">,
 <all-day event="" 'last="" quarter="" 8:37am'="" begin:2023-11-05="" end:2023-11-06="">,
 <all-day event="" 'full="" moon="" 8:24pm'="" begin:2023-10-28="" end:2023-10-29="">,
 <all-day event="" 'first="" quarter="" 3:29am'="" begin:2023-10-22="" end:2023-10-23="">,
 <all-day event="" 'new="" moon="" 5:55pm'="" begin:2023-10-14="" end:2023-10-15="">,
 <all-day event="" 'last="" quarter="" 1:48pm'="" begin:2023-10-06="" end:2023-10-07="">,
 <all-day event="" 'full="" moon="" 9:57am'="" begin:2023-09-29="" end:2023-09-30="">,
 <all-day event="" 'first="" quarter="" 7:32pm'="" begin:2023-09-22="" end:2023-09-23="">,
 <all-day event="" 'new="" moon="" 1:40am'="" begin:2023-09-15="" end:2023-09-16="">,
 <all-day event="" 'last="" quarter="" 10:21pm'="" begin:2023-09-06="" end:2023-09-07="">,
 <all-day event="" 'full="" moon="" 1:35am'="" begin:2023-08-31="" end:2023-09-01="">,...]
</all-day></all-day></all-day></all-day></all-day></all-day></all-day></all-day></all-day></all-day></all-day></all-day></all-day></all-day></all-day></all-day></all-day>

يمكن لوحدة ics أيضًا إنشاء ملفات iCalendar. لنفترض أنك تريد إضافة بعض الأحداث إلى تقويم عملك لحجز بعض الوقت كل يوم لمهامك. تريد ساعتين كل يوم، وسيكون من الجيد الحصول على ساعة أخرى. يمكنك القيام بذلك باستخدام الكود التالي:

import arrow
from ics import Calendar, Event
 
calendar = Calendar()
 
tz = 'Europe/Paris'
first_day = arrow.get("2022-02-14").replace(tzinfo=tz)
last_day = arrow.get("2022-02-18").replace(tzinfo=tz)
 
for day in arrow.Arrow.range('day', first_day, last_day):
    event = Event()
    event.name = "Working on the task"
    event.begin = day.replace(hour=8).to('utc').datetime
    event.end = day.replace(hour=10).to('utc').datetime
    event.transparent = False
    calendar.events.add(event)
 
    event = Event()
    event.name = "Continue on the task?"
    event.begin = day.replace(hour=10).to('utc').datetime
    event.end = day.replace(hour=11).to('utc').datetime
    event.transparent = True
    calendar.events.add(event)
 
print(calendar) # you can simply save this to a file

بسيطة جدا، أليس كذلك؟ لا داعي للقلق بشأن معرفات الأحداث أو سمات ملف iCalendar الأخرى المطلوبة. تحدد القيمة transparent مدى حضورك. صحيح يعني “لديك الوقت” وخطأ يعني “مبهم” (أي “مشغول”). قد لا يكون الأمر واضحًا، ولكن فكر في الأمر بهذه الطريقة: فهو يحتاج إما إلى إظهار الوقت أو حظره بناءً على مدى توفرك عند البحث عن أوقات متوفر/مشغول في التقويم الخاص بك.

انتبه أيضًا إلى المناطق الزمنية. تعمل وحدة ics مع قيم UTC.

الآن، كل ما عليك فعله هو الانتقال إلى إعدادات تقويم Google واستيراد ملف ics. قد ترغب في اختباره في تقويم اختبار منفصل قبل إضافته إلى تقويمك الرئيسي حيث لا توجد طريقة سهلة لحذف الأحداث بشكل مجمّع.

إذا كنت تريد معرفة المزيد حول معالجة البيانات والبرمجة باستخدام Python، فأنا أشجعك على الانضمام إلى مسار برمجة PYTHON الخاص بنا.

العمل مع iCalendar في بايثون والمزيد!

لقد قمنا بمراجعة كيفية العمل مع ملفات iCalendar في Python في هذه المقالة. لقد اكتشفنا كيفية إنشاء حدث وتخزينه كملف iCal وقراءته. لقد تعلمنا أيضًا كيفية معالجة التقويم من عنوان URL واستخراج الأحداث من تقويم Google العام.


اكتشاف المزيد من بايثون العربي

اشترك للحصول على أحدث التدوينات المرسلة إلى بريدك الإلكتروني.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *

Scroll to Top

اكتشاف المزيد من بايثون العربي

اشترك الآن للاستمرار في القراءة والحصول على حق الوصول إلى الأرشيف الكامل.

Continue reading