add proxy for the first part and try to develop the second part

This commit is contained in:
Pierre Geeraert
2025-12-03 12:08:56 +00:00
parent 6c34d510e5
commit 460f18d85a
1095 changed files with 358799 additions and 5 deletions
@@ -0,0 +1,89 @@
import warnings
from collections import namedtuple
from typing import Any, Dict, Tuple, Iterable
from ics.grammar.parse import Container
from .utils import get_lines
from .serializers.serializer import Serializer
from .parsers.parser import Parser
Extractor = namedtuple(
'Extractor',
['function', 'type', 'required', 'multiple', 'default']
)
class Component(object):
class Meta:
name = "ABSTRACT"
parser = Parser
serializer = Serializer
_classmethod_args: Tuple
_classmethod_kwargs: Dict
@classmethod
def _from_container(cls, container: Container, *args: Any, **kwargs: Any):
k = cls()
k._classmethod_args = args
k._classmethod_kwargs = kwargs
k._populate(container)
return k
def _populate(self, container: Container) -> None:
if container.name != self.Meta.name:
raise ValueError("container isn't an {}".format(self.Meta.name))
for line_name, (parser, options) in self.Meta.parser.get_parsers().items():
lines = get_lines(container, line_name)
if not lines and options.required:
if options.default:
lines = 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") % (line_name, default_str)
warnings.warn(message)
else:
raise ValueError(
'A {} must have at least one {}'
.format(container.name, line_name))
if not options.multiple and len(lines) > 1:
raise ValueError(
'A {} must have at most one {}'
.format(container.name, line_name))
if options.multiple:
parser(self, lines) # Send a list or empty list
else:
if len(lines) == 1:
parser(self, lines[0]) # Send the element
else:
parser(self, None) # Send None
self.extra = container # Store unused lines
def serialize(self) -> str:
"""Returns the component in an iCalendar format."""
container = self.extra.clone()
for output in self.Meta.serializer.get_serializers():
output(self, container)
return str(container)
def serialize_iter(self) -> Iterable[str]:
"""Returns the component in an iCalendar format.
This returns an Iterable of multiple string chunks which should be concatenated to form the actual ics representation.
Note that individual items of the returned Iterable not necessarily correspond to individual lines,
linebreaks are contained at the right places within the items."""
return self.serialize().splitlines(keepends=True)
def __str__(self) -> str:
"""Starting from version 0.9, returns a short description of the Component."""
warnings.warn(
"Behaviour of str(Component) will change in version 0.9 to only return a short description, NOT the ics representation. "
"Use the explicit Component.serialize() to get the ics representation.", FutureWarning
)
return self.serialize()