ics-py / ics-py

Pythonic and easy iCalendar library (rfc5545)

Home Page:http://icspy.readthedocs.org/en/stable/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Extending the Event class

s3bw opened this issue · comments

If I wish to have my own properties on the calendar event class, how can I subclass Event and extend it with custom properties?

With the current alpha, you should simply be able to subclass Event in an attrs-compliant manner and the properties should be picked up automatically.

@attr.s(eq=True, order=False)  # order methods are provided by Event
class MyEvent(`Event`):
    my_property: Optional[str] = attr.ib(default=None)

Basically, all ics Objects are created in this way. This also perfectly works for serialization, but unfortunately there is yet not nice way to tell the parser to inflate MyEvent objects instead of Events and thus your custom properties will still end up in the extras there. Making this easily doable with the indirection via the ComponentMeta object is on the roadmap, unfortunately I don't really have time to complete that project.

I managed to get the custom properties out of extras it was a faff, but it's a solution:

# Subclass the EventAttrs
@attr.s(eq=True, order=False)
class EventAttrs(ics.event.EventAttrs):
    custom_prop: Optional[str] = attr.ib(default=None)
    
class Event(ics.Event, EventAttrs):
    """A calendar event.
    """
    pass


@attr.s
class CalendarAttrs(ics.icalendar.CalendarAttrs):

    events: List[Event] = attr.ib(
        factory=list, converter=list, metadata={"ics_priority": -100},
    )


class Calendar(ics.Calendar, CalendarAttrs):
    pass


ics.initialize_converters()

ComponentMeta.BY_TYPE[Event] = ComponentMeta(Event)
ComponentMeta.BY_TYPE[Calendar] = ComponentMeta(Calendar)

I am now trying to figuring out how to add my own complex types instead of relying on str for my custom_prop

I guess you could even simplify this, as the ...Attrs classes are only internal workarounds to still allow custom init methods in older versions of attrs:

@attr.s
class MyObj(ics.Component):
	int_prop : int
	str_prop : str

@attr.s(eq=True, order=False)
class Event(ics.Event):
    custom_prop: Optional[MyObj] = attr.ib(default=None) # should also work as List[MyObj] for multiple

@attr.s
class Calendar(ics.Calendar):
    events: List[Event] = attr.ib(
        factory=list, converter=list, metadata={"ics_priority": -100},
    )

ics.initialize_converters()
ComponentMeta.BY_TYPE[ics.Event] = ComponentMeta(Event)
ComponentMeta.BY_TYPE[ics.Calendar] = ComponentMeta(Calendar)