Пример #1
0
    def serialize(self, component: Component, output: Container,
                  context: ContextDict):
        value = self.get_value(component)
        if not TYPE_CHECKING:
            assert isinstance(value, dateutil.rrule.rruleset)
        for rrule in itertools.chain(value._rrule, value._exrule):
            if rrule._dtstart is None: continue
            # check that the rrule uses the same DTSTART as a possible Timespan(Converter)
            dtstart = context["DTSTART"]
            if dtstart:
                if dtstart != rrule._dtstart:
                    raise ValueError("differing DTSTART values")
            else:
                context["DTSTART"] = rrule._dtstart
                dt_value = DatetimeConverter.serialize(rrule._dtstart,
                                                       context=context)
                output.append(ContentLine(name="DTSTART", value=dt_value))

        for rrule in value._rrule:
            output.append(rrule_to_ContentLine(rrule))
        for exrule in value._exrule:
            cl = rrule_to_ContentLine(exrule)
            cl.name = "EXRULE"
            output.append(cl)
        for rdate in unique_justseen(sorted(value._rdate)):
            output.append(
                ContentLine(name="RDATE",
                            value=DatetimeConverter.serialize(rdate)))
        for exdate in unique_justseen(sorted(value._exdate)):
            output.append(
                ContentLine(name="EXDATE",
                            value=DatetimeConverter.serialize(exdate)))
Пример #2
0
    def serialize(self, component: Component, output: Container,
                  context: ContextDict):
        value: Timespan = self.get_value(component)
        dt_conv: ValueConverter
        if value.is_all_day():
            value_type = {"VALUE": ["DATE"]}
            dt_conv = DateConverter
        else:
            value_type = {}  # implicit default is {"VALUE": ["DATE-TIME"]}
            dt_conv = DatetimeConverter

        if value.get_begin():
            # prevent rrule serializer from adding its own DTSTART value
            assert "DTSTART" not in context
            context["DTSTART"] = value.get_begin()

            params = copy_extra_params(
                cast(ExtraParams, self.get_extra_params(component, "begin")))
            params.update(value_type)
            dt_value = dt_conv.serialize(value.get_begin(), params, context)
            output.append(
                ContentLine(name="DTSTART", params=params, value=dt_value))

        if value.get_end_representation() == "end":
            end_name = {"end": "DTEND", "due": "DUE"}[value._end_name()]
            params = copy_extra_params(
                cast(ExtraParams, self.get_extra_params(component, end_name)))
            params.update(value_type)
            dt_value = dt_conv.serialize(value.get_effective_end(), params,
                                         context)
            output.append(
                ContentLine(name=end_name, params=params, value=dt_value))

        elif value.get_end_representation() == "duration":
            params = copy_extra_params(
                cast(ExtraParams, self.get_extra_params(component,
                                                        "duration")))
            duration = value.get_effective_duration()
            assert duration is not None
            dur_value = DurationConverter.serialize(duration, params, context)
            output.append(
                ContentLine(name="DURATION", params=params, value=dur_value))
Пример #3
0
def test_any_text_value_recode(value):
    esc = TextConv.serialize(value)
    assert TextConv.parse(esc) == value
    cl = ContentLine("TEST", value=esc)
    assert parse_contentline(cl.serialize()) == cl
    assert list(string_to_containers(cl.serialize())) == [cl]
    vals = [esc, esc, "test", esc]
    cl2 = ContentLine("TEST", value=TextConv.join_value_list(vals))
    assert list(TextConv.split_value_list(cl2.value)) == vals
    assert parse_contentline(cl.serialize()) == cl
    assert list(string_to_containers(cl.serialize())) == [cl]
Пример #4
0
 def serialize(self, component: "Component", output: Container,
               context: ContextDict):
     if self.is_multi_value:
         self.__serialize_multi(component, output, context)
     else:
         value = self.get_value(component)
         if value:
             params = copy_extra_params(
                 cast(ExtraParams, self.get_extra_params(component)))
             converter = self.__find_value_converter(params, value)
             serialized = converter.serialize(value, params, context)
             output.append(
                 ContentLine(name=self.ics_name,
                             params=params,
                             value=serialized))
Пример #5
0
    def serialize(self, component: "Component", output: Container,
                  context: ContextDict):
        value: Timespan = self.get_value(component)
        if value.is_all_day():
            value_type = {"VALUE": ["DATE"]}
            dt_conv = DateConverter.INST
        else:
            value_type = {}  # implicit default is {"VALUE": ["DATE-TIME"]}
            dt_conv = DatetimeConverter.INST

        if value.get_begin():
            params = copy_extra_params(
                cast(ExtraParams, self.get_extra_params(component, "begin")))
            params.update(value_type)
            dt_value = dt_conv.serialize(value.get_begin(), params, context)
            output.append(
                ContentLine(name="DTSTART", params=params, value=dt_value))

        if value.get_end_representation() == "end":
            end_name = {"end": "DTEND", "due": "DUE"}[value._end_name()]
            params = copy_extra_params(
                cast(ExtraParams, self.get_extra_params(component, end_name)))
            params.update(value_type)
            dt_value = dt_conv.serialize(value.get_effective_end(), params,
                                         context)
            output.append(
                ContentLine(name=end_name, params=params, value=dt_value))

        elif value.get_end_representation() == "duration":
            params = copy_extra_params(
                cast(ExtraParams, self.get_extra_params(component,
                                                        "duration")))
            dur_value = DurationConverter.INST.serialize(
                value.get_effective_duration(), params, context)
            output.append(
                ContentLine(name="DURATION", params=params, value=dur_value))
Пример #6
0
    def __serialize_multi(self, component: Component, output: Container,
                          context: ContextDict):
        extra_params = cast(List[ExtraParams],
                            self.get_extra_params(component))
        values = self.get_value_list(component)
        if not extra_params:
            extra_params = repeat(None)
        elif len(extra_params) != len(values):
            raise ValueError(
                "length of extra params doesn't match length of parameters"
                " for attribute %s of %r" % (self.attribute.name, component))

        merge_next = False
        current_params = None
        current_values = []

        for value, params in zip(values, extra_params):
            merge_next = False
            params = copy_extra_params(params)
            if params.pop("__merge_next", None) == ["TRUE"]:
                merge_next = True
            converter = self.__find_value_converter(params, value)
            serialized = converter.serialize(
                value, params, context)  # might modify params and context

            if current_params is not None:
                if current_params != params:
                    raise ValueError()
            else:
                current_params = params

            current_values.append(serialized)

            if not merge_next:
                cl = ContentLine(
                    name=self.ics_name,
                    params=params,
                    value=converter.join_value_list(current_values))
                output.append(cl)
                current_params = None
                current_values = []

        if merge_next:
            raise ValueError(
                "last value in value list may not have merge_next set")
Пример #7
0
def test_issue_182_seconds_ignored():
    todo = Todo.from_container(
        lines_to_container([
            "BEGIN:VTODO", "DTSTART;TZID=Europe/Berlin:20180219T120005",
            "COMPLETED;TZID=Europe/Brussels:20180418T150001", "END:VTODO"
        ]))
    assert todo.begin == datetime(2018,
                                  2,
                                  19,
                                  12,
                                  0,
                                  5,
                                  tzinfo=gettz("Europe/Berlin"))
    assert todo.completed == datetime(2018,
                                      4,
                                      18,
                                      15,
                                      0,
                                      1,
                                      tzinfo=gettz("Europe/Brussels"))

    with pytest.raises(ValueError):
        Todo.from_container(
            lines_to_container([
                "BEGIN:VTODO",
                "DTSTART;TZID=Europe/Berlin:2018-02-19 12:00:05", "END:VTODO"
            ]))

    container = lines_to_container([
        "BEGIN:VTODO",
        "COMPLETED:;TZID=Europe/Brussels:20180418T150001",
        #         ^ this : breaks parsing
        "END:VTODO"
    ])
    assert container[0] == ContentLine(
        "COMPLETED", value=";TZID=Europe/Brussels:20180418T150001")
    pytest.raises(ValueError, Todo.from_container, container)
Пример #8
0
from ics.valuetype.text import TextConverter
# Text may be comma-separated multi-value but is never quoted, with the characters [\\;,\n] escaped
from tests.contentline import VALUE

TextConv: TextConverter = TextConverter.INST


def parse_contentline(line: str) -> ContentLine:
    cl, = Parser.lines_to_contentlines(Parser.string_to_lines(line))
    return cl


@pytest.mark.parametrize("inp_esc, out_uesc", [
    ("SUMMARY:Project XYZ Final Review\\nConference Room - 3B\\nCome Prepared.",
     ContentLine(
         "SUMMARY",
         value="Project XYZ Final Review\nConference Room - 3B\nCome Prepared."
     )),
    ("DESCRIPTION;ALTREP=\"cid:[email protected]\":The Fall'98 Wild Wizards Conference - - Las Vegas\\, NV\\, USA",
     ContentLine(
         "DESCRIPTION", {"ALTREP": ["cid:[email protected]"]},
         value="The Fall'98 Wild Wizards Conference - - Las Vegas, NV, USA")),
    ("TEST:abc\\r\\n\\,\\;:\"\t=xyz",
     ContentLine("TEST", value="abc\r\n,;:\"\t=xyz")),
])
def test_example_text_recode(inp_esc, out_uesc):
    par_esc = parse_contentline(inp_esc)
    par_uesc = attr.evolve(par_esc, value=TextConv.parse(par_esc.value))
    out_esc = attr.evolve(out_uesc, value=TextConv.serialize(out_uesc.value))
    assert par_uesc == out_uesc
    ser_esc = out_esc.serialize()
    assert inp_esc == ser_esc
Пример #9
0
 def serialize(self, component: Component, output: Container,
               context: ContextDict):
     output.append(
         ContentLine(name="ACTION",
                     params=component.extra_params.get("ACTION", {}),
                     value=component.action))