93 lines
3.4 KiB
Python
93 lines
3.4 KiB
Python
import warnings
|
|
from typing import Dict, List
|
|
|
|
from ics.grammar.parse import ContentLine
|
|
from ics.parsers.attendee_parser import AttendeeParser, PersonParser
|
|
from ics.serializers.attendee_serializer import AttendeeSerializer, PersonSerializer
|
|
from ics.utils import escape_string, unescape_string
|
|
|
|
|
|
class Person(object):
|
|
class Meta:
|
|
name = "ABSTRACT-PERSON"
|
|
parser = PersonParser
|
|
serializer = PersonSerializer
|
|
|
|
def __init__(self, email: str, common_name: str = None, dir: str = None, sent_by: str = None) -> None:
|
|
self.email = email
|
|
self.common_name = common_name or email
|
|
self.dir = dir
|
|
self.sent_by = sent_by
|
|
self.extra: Dict[str, List[str]] = {}
|
|
|
|
@classmethod
|
|
def parse(cls, line: ContentLine) -> "Person":
|
|
email = unescape_string(line.value)
|
|
if email.lower().startswith("mailto:"):
|
|
email = email[len("mailto:"):]
|
|
val = cls(email)
|
|
val.populate(line)
|
|
return val
|
|
|
|
def populate(self, line: ContentLine) -> None:
|
|
if line.name != self.Meta.name:
|
|
raise ValueError("line isn't an {}".format(self.Meta.name))
|
|
|
|
params = dict(line.params)
|
|
for param_name, (parser, options) in self.Meta.parser.get_parsers().items():
|
|
values = params.pop(param_name, [])
|
|
if not values and options.required:
|
|
if options.default:
|
|
values = options.default
|
|
default_str = "\\n".join(map(str, options.default))
|
|
message = ("The %s property was not found and is required by the RFC." +
|
|
" A default value of \"%s\" has been used instead") % (param_name, default_str)
|
|
warnings.warn(message)
|
|
else:
|
|
raise ValueError('A {} must have at least one {}'.format(line.name, param_name))
|
|
|
|
if not options.multiple and len(values) > 1:
|
|
raise ValueError('A {} must have at most one {}'.format(line.name, param_name))
|
|
|
|
if options.multiple:
|
|
parser(self, values) # Send a list or empty list
|
|
else:
|
|
if len(values) == 1:
|
|
parser(self, values[0]) # Send the element
|
|
else:
|
|
parser(self, None) # Send None
|
|
|
|
self.extra = params # Store unused lines
|
|
|
|
def serialize(self) -> ContentLine:
|
|
line = ContentLine(self.Meta.name, params=self.extra, value=escape_string('mailto:%s' % self.email))
|
|
for output in self.Meta.serializer.get_serializers():
|
|
output(self, line)
|
|
return line
|
|
|
|
def __str__(self) -> str:
|
|
"""Returns the attendee in an ContentLine format."""
|
|
return str(self.serialize())
|
|
|
|
|
|
class Organizer(Person):
|
|
class Meta:
|
|
name = 'ORGANIZER'
|
|
parser = PersonParser
|
|
serializer = PersonSerializer
|
|
|
|
|
|
class Attendee(Person):
|
|
def __init__(self, email: str, common_name: str = None, dir: str = None, sent_by: str = None,
|
|
rsvp: bool = None, role: str = None, partstat: str = None, cutype: str = None) -> None:
|
|
super().__init__(email, common_name, dir, sent_by)
|
|
self.rsvp = rsvp
|
|
self.role = role
|
|
self.partstat = partstat
|
|
self.cutype = cutype
|
|
|
|
class Meta:
|
|
name = 'ATTENDEE'
|
|
parser = AttendeeParser
|
|
serializer = AttendeeSerializer
|