Пример #1
0
    def testSetCalendarProperties(self):
        c = self.principal.make_calendar(name="Yep", cal_id=self.testcal_id)
        assert_not_equal(c.url, None)

        props = c.get_properties([dav.DisplayName(), ])
        assert_equal("Yep", props[dav.DisplayName.tag])

        # Creating a new calendar with different ID but with existing name
        # - fails on zimbra only.
        # This is OK to fail.
        if 'zimbra' in str(c.url):
            assert_raises(Exception, self.principal.make_calendar,
                          "Yep", self.testcal_id2)
        else:
            # This may fail, and if it fails, add an exception to the test
            # (see the "if" above)
            cc = self.principal.make_calendar("Yep", self.testcal_id2)
            cc.delete()

        c.set_properties([dav.DisplayName("hooray"), ])
        props = c.get_properties([dav.DisplayName(), ])
        assert_equal(props[dav.DisplayName.tag], "hooray")

        # Creating a new calendar with different ID and old name, this should
        # work, shouldn't it?
        # ... ouch, now it fails with a 409 on zimbra (it didn't fail
        # earlier)
        if not 'zimbra' in str(c.url):
            cc = self.principal.make_calendar(
                name="Yep", cal_id=self.testcal_id2).save()
            assert_not_equal(cc.url, None)
            cc.delete()
Пример #2
0
    def testSetCalendarProperties(self):
        c = self.principal.make_calendar(name="Yep", cal_id=testcal_id)
        assert_not_equal(c.url, None)

        props = c.get_properties([
            dav.DisplayName(),
        ])
        assert_equal("Yep", props[dav.DisplayName.tag])

        ## Creating a new calendar with different ID but with existing name - fails on zimbra only.
        ## This is OK to fail.
        if 'zimbra' in str(c.url):
            assert_raises(Exception, self.principal.make_calendar, "Yep",
                          testcal_id2)

        c.set_properties([
            dav.DisplayName("hooray"),
        ])
        props = c.get_properties([
            dav.DisplayName(),
        ])
        assert_equal(props[dav.DisplayName.tag], "hooray")

        ## Creating a new calendar with different ID and old name - should never fail
        cc = self.principal.make_calendar(name="Yep",
                                          cal_id=testcal_id2).save()
        assert_not_equal(cc.url, None)
        cc.delete()
Пример #3
0
 def calendars(self):
     if not hasattr(self, '_calendars'):
         calendars = self.principal.calendars()
         self._calendars = {}
         for calendar in calendars:
             p = calendar.get_properties([
                 dav.DisplayName(),
             ])
             if p:
                 calname = p[dav.DisplayName().tag]
                 self._calendars[calname] = calendar
     return self._calendars
Пример #4
0
    def children(self, type=None):
        """
        List children, using a propfind (resourcetype) on the parent object,
        at depth = 1.
        """
        c = []

        depth = 1
        properties = {}

        props = [dav.ResourceType(), dav.DisplayName()]
        response = self._query_properties(props, depth)
        properties = self._handle_prop_response(
            response=response, props=props, type=type, what='tag')

        for path in list(properties.keys()):
            resource_type = properties[path][dav.ResourceType.tag]
            resource_name = properties[path][dav.DisplayName.tag]

            if resource_type == type or type is None:
                # TODO: investigate the RFCs thoroughly - why does a "get
                # members of this collection"-request also return the
                # collection URL itself?
                # And why is the strip_trailing_slash-method needed?
                # The collection URL should always end with a slash according
                # to RFC 2518, section 5.2.
                if (self.url.strip_trailing_slash() !=
                        self.url.join(path).strip_trailing_slash()):
                    c.append((self.url.join(path), resource_type,
                              resource_name))

        return c
Пример #5
0
def create_calendar(client, parent, name, id=None):
    """
    Create a new calendar with display name `name` in `parent`.
    """
    path = None
    if id is None:
        id = str(uuid.uuid1())

    name = dav.DisplayName(name)
    cal = cdav.CalendarCollection()
    coll = dav.Collection() + cal
    type = dav.ResourceType() + coll

    prop = dav.Prop() + [type, name]
    set = dav.Set() + prop

    mkcol = dav.Mkcol() + set

    q = etree.tostring(mkcol.xmlelement(),
                       encoding="utf-8",
                       xml_declaration=True)
    path = url.join(parent.url.path, id)

    r = client.mkcol(path, q)
    if r.status == 201:
        path = url.make(parent.url, path)
    else:
        raise error.MkcolError(r.raw)

    return (id, path)
Пример #6
0
 def update_calendar(self, calendar):
     """Update an existing calendar."""
     remote_cal = self.client.calendar(calendar.encoded_path)
     remote_cal.set_properties([
         dav.DisplayName(calendar.name),
         ical.CalendarColor(calendar.color)
     ])
Пример #7
0
    def handle_cal_list(self, message):
        self.please_wait()

        principal = self.caldav_.principal()
        calendars = principal.calendars()

        listcals = list()
        totalCalendars = len(calendars)

        # There is at least one calendar.
        if totalCalendars > 0:
            for calendar in calendars:
                tnameRaw = calendar.get_properties([
                    dav.DisplayName(),
                ])
                tname = tnameRaw[dav.DisplayName.tag]
                listcals.append(tname)

            cals = ", ".join(listcals)

            self.speak_dialog('cal.list.calendars',
                              data={
                                  "totalCalendars": totalCalendars,
                                  "calendars": cals
                              },
                              expect_response=False)

        # There is no calendar.
        else:
            self.speak_dialog('cal.list.calendars.none', expect_response=False)
Пример #8
0
    def Caldav(self):
        # Verbinding maken met CalDav agenda
        client = caldav.DAVClient(self.config["url"])
        principal = client.principal()
        calendars = principal.calendars()

        first_all = True
        # Lus door de beschikbare agenda's heen
        for calendar in calendars:
            # Zoek de naam hiervan op
            calendar_name = calendar.get_properties([
                dav.DisplayName(),
            ])["{DAV:}displayname"]

            # Alleen doorgaan indien de agenda in de 'calendars' config regel staat
            if calendar_name in self.config["calendars"]:
                first = True

                now = f.Now(self.config_full)

                # Evenementen voor vandaag zoeken, met een beetje buffer terug in de tijd.
                results = calendar.date_search(now - timedelta(hours=2),
                                               now + timedelta(days=1))
                for vevent in results:
                    event = Event(client=client, url=vevent.url)
                    event.load()

                    # Oke.. in de documentatie niks over hoe hier een nette string van te maken
                    # En in het object zelf zit ook niet echt een functie daarvoor, los van __str()__
                    start = event.instance.vevent.dtstart.__str__()
                    summary = event.instance.vevent.summary.__str__()
                    # Zo kan het ook.
                    summary = summary.replace("<SUMMARY{}", "")[:-1]
                    # Dit komt binnen: <DTSTART{'X-VOBJ-ORIGINAL-TZID': ['Europe/Amsterdam']}
                    # Dus split op } en dan de eerste verwijderen, en het > teken achteraan verwijderen
                    start = parse(''.join(start.split("}")[1:])[:-1])

                    # Eerste event in deze agenda? Toon de agenda naam
                    if first:
                        # Niet de eerste agenda? Extra witregel
                        if not first_all:
                            self.text += "<br/>"

                        self.text += "<h3>" + calendar_name + "</h3>"
                        first = False
                        first_all = False

                    # Event samenvatting (tijd + omschijving) toevoegen aan de text
                    dt = "%A %H:%M"
                    if (calendar_name.lower().find("birthday") >= 0
                            or calendar_name.lower().find("verjaardag") >= 0):
                        dt = "%A"

                    self.text += "{0} {1}<br/>".format(start.strftime(dt),
                                                       summary)

        if not first_all:
            self.hasText = True
Пример #9
0
    def get_named_calendar(self, name):

        if len(self.calendars) > 0:
            for calendar in self.calendars:
                properties = calendar.get_properties([dav.DisplayName()])
                display_name = properties["{DAV:}displayname"]
                if display_name == name:
                    return calendar
        return None
Пример #10
0
    def get_named_calendar(self, name):

        if len(self.calendars) > 0:
            for calendar in self.calendars:
                if calendar.get_properties([
                        dav.DisplayName(),
                ])['{DAV:}displayname'] == name:
                    return calendar
        return None
Пример #11
0
    def _create(self,
                name=None,
                id=None,
                supported_calendar_component_set=None):
        """
        Create a new calendar with display name `name` in `parent`.
        """
        if id is None:
            id = str(uuid.uuid1())
        self.id = id

        path = self.parent.url.join(id)
        self.url = path

        # TODO: mkcalendar seems to ignore the body on most servers?
        # at least the name doesn't get set this way.
        # zimbra gives 500 (!) if body is omitted ...

        prop = dav.Prop()
        if name:
            display_name = dav.DisplayName(name)
            prop += [
                display_name,
            ]
        if supported_calendar_component_set:
            sccs = cdav.SupportedCalendarComponentSet()
            for scc in supported_calendar_component_set:
                sccs += cdav.Comp(scc)
            prop += sccs
        set = dav.Set() + prop

        mkcol = cdav.Mkcalendar() + set

        r = self._query(root=mkcol,
                        query_method='mkcalendar',
                        url=path,
                        expected_return_value=201)

        # COMPATIBILITY ISSUE
        # name should already be set, but we've seen caldav servers failing
        # on setting the DisplayName on calendar creation
        # (DAViCal, Zimbra, ...).  Doing an attempt on explicitly setting the
        # display name using PROPPATCH.
        if name:
            try:
                self.set_properties([display_name])
            except:
                try:
                    current_display_name = self.get_properties([display_name])
                    if current_display_name != name:
                        logging.warning(
                            "caldav server not complient with RFC4791. unable to set display name on calendar.  Wanted name: \"%s\" - gotten name: \"%s\".  Ignoring."
                            % (name, current_display_name))
                except:
                    logging.warning(
                        "calendar server does not support display name on calendar?  Ignoring",
                        exc_info=True)
Пример #12
0
def newClient():
    client = caldav.DAVClient("https://sogo.inoio.de/SOGo/dav/public/loesungsraum/Calendar/personal/")
    principal = client.principal()
    calendars = principal.calendars()
    if len(calendars) > 0:
        calendar = calendars[0]
        print "Using calendar", calendar

        print "Renaming"
        calendar.set_properties([dav.DisplayName("Test calendar"),])
        print calendar.get_properties([dav.DisplayName(),])

        event = calendar.add_event(vcal)
        print "Event", event, "created"

        print "Looking for events in 2010-05"
        results = calendar.date_search(
            datetime(2010, 5, 1), datetime(2010, 6, 1))

        for event in results:
            print "Found", event
Пример #13
0
 def __init__(self, **kwargs):
     super(CalDav, self).__init__(**kwargs)
     self.window = kwargs.get("window", 60 * 60 * 24 * 7)
     self.client = caldav.DAVClient(kwargs["url"],
                                    username=kwargs["user"],
                                    password=kwargs["password"])
     self.principal = self.client.principal()
     self.all_calendars = dict([
         (calendar.get_properties([dav.DisplayName()])["{DAV:}displayname"],
          calendar) for calendar in self.principal.calendars()
     ])
     #print(self.all_calendars)
     self.calendars = [
         self.all_calendars[name] for name in kwargs["calendars"]
     ]
Пример #14
0
    def connect(self):

        client = caldav.DAVClient(self._calendar_url,
                                  username=self._user,
                                  password=self._password)
        principal = client.principal()
        calendars = principal.calendars()

        matched_calendar = None

        for calendar in calendars:
            calendar_displayname_property_dict = calendar.get_properties([
                dav.DisplayName(),
            ])
            value_list = list(calendar_displayname_property_dict.values())
            name = value_list[0]

            if self._calendar_name == name:
                matched_calendar = calendar
                break

        if matched_calendar:
            self._caldav_object = matched_calendar
Пример #15
0
# In[33]:

principal = client.principal()


# In[34]:

calendars = principal.calendars()


# In[35]:

if len(calendars) > 0:
    calendar = calendars[0]
    print ("Using calendar", calendar)

    print ("Renaming")
    calendar.set_properties([dav.DisplayName("Test calendar"),])
    print (calendar.get_properties([dav.DisplayName(),]))

    event = calendar.add_event(vcal)
    print ("Event", event, "created")

    print ("Ищу события в 2019 году")
    results = calendar.date_search(
        datetime(2019, 12, 1), datetime(2020,1, 1))

    for event in results:
        print ("Found", event)

Пример #16
0
    def testBackwardCompatibility(self):
        """
        Tobias Brox has done some API changes - but this thing should
        still be backward compatible.
        """
        if not 'backwards_compatibility_url' in self.server_params:
            return
        caldav = DAVClient(self.server_params['backwards_compatibility_url'])
        principal = Principal(
            caldav, self.server_params['backwards_compatibility_url'])
        c = Calendar(caldav, name="Yep", parent=principal,
                     id=testcal_id).save()
        assert_not_equal(c.url, None)

        c.set_properties([
            dav.DisplayName("hooray"),
        ])
        props = c.get_properties([
            dav.DisplayName(),
        ])
        assert_equal(props[dav.DisplayName.tag], "hooray")

        cc = Calendar(caldav, name="Yep", parent=principal).save()
        assert_not_equal(cc.url, None)
        cc.delete()

        e = Event(caldav, data=ev1, parent=c).save()
        assert_not_equal(e.url, None)

        ee = Event(caldav, url=url.make(e.url), parent=c)
        ee.load()
        assert_equal(e.instance.vevent.uid, ee.instance.vevent.uid)

        r = c.date_search(datetime(2006, 7, 13, 17, 00, 00),
                          datetime(2006, 7, 15, 17, 00, 00))
        assert_equal(e.instance.vevent.uid, r[0].instance.vevent.uid)
        assert_equal(len(r), 1)

        all = c.events()
        assert_equal(len(all), 1)

        e2 = Event(caldav, data=ev2, parent=c).save()
        assert_not_equal(e.url, None)

        tmp = c.event("*****@*****.**")
        assert_equal(e2.instance.vevent.uid, tmp.instance.vevent.uid)

        r = c.date_search(datetime(2007, 7, 13, 17, 00, 00),
                          datetime(2007, 7, 15, 17, 00, 00))
        assert_equal(len(r), 1)

        e.data = ev2
        e.save()

        r = c.date_search(datetime(2007, 7, 13, 17, 00, 00),
                          datetime(2007, 7, 15, 17, 00, 00))
        for e in r:
            print(e.data)
        assert_equal(len(r), 1)

        e.instance = e2.instance
        e.save()
        r = c.date_search(datetime(2007, 7, 13, 17, 00, 00),
                          datetime(2007, 7, 15, 17, 00, 00))
        for e in r:
            print(e.data)
        assert_equal(len(r), 1)
Пример #17
0
    def test_xml_parsing(self):
        """
        DAVResponse has quite some code to parse the XML received from the
        server.  This test contains real XML received from various
        caldav servers, and the expected result from the parse
        methods.
        """
        xml = """
<multistatus xmlns="DAV:">
  <response xmlns="DAV:">
    <href>/</href>
    <propstat>
      <prop>
        <current-user-principal xmlns="DAV:">
          <href xmlns="DAV:">/17149682/principal/</href>
        </current-user-principal>
      </prop>
      <status>HTTP/1.1 200 OK</status>
    </propstat>
  </response>
</multistatus>
"""
        expected_result = {
            '/': {
                '{DAV:}current-user-principal': '/17149682/principal/'
            }
        }

        assert_equal(
            MockedDAVResponse(xml).expand_simple_props(
                props=[dav.CurrentUserPrincipal()]), expected_result)

        xml = """
<multistatus xmlns="DAV:">
  <response xmlns="DAV:">
    <href>/17149682/principal/</href>
    <propstat>
      <prop>
        <calendar-home-set xmlns="urn:ietf:params:xml:ns:caldav">
          <href xmlns="DAV:">https://p62-caldav.icloud.com:443/17149682/calendars/</href>
        </calendar-home-set>
      </prop>
      <status>HTTP/1.1 200 OK</status>
    </propstat>
  </response>
</multistatus>"""
        expected_result = {
            '/17149682/principal/': {
                '{urn:ietf:params:xml:ns:caldav}calendar-home-set':
                'https://p62-caldav.icloud.com:443/17149682/calendars/'
            }
        }
        assert_equal(
            MockedDAVResponse(xml).expand_simple_props(
                props=[cdav.CalendarHomeSet()]), expected_result)

        xml = """
<multistatus xmlns="DAV:">
  <response xmlns="DAV:">
    <href>/</href>
    <propstat>
      <prop>
        <current-user-principal xmlns="DAV:">
          <href xmlns="DAV:">/17149682/principal/</href>
        </current-user-principal>
      </prop>
      <status>HTTP/1.1 200 OK</status>
    </propstat>
  </response>
</multistatus>"""
        expected_result = {
            '/': {
                '{DAV:}current-user-principal': '/17149682/principal/'
            }
        }
        assert_equal(
            MockedDAVResponse(xml).expand_simple_props(
                props=[dav.CurrentUserPrincipal()]), expected_result)

        xml = """
<multistatus xmlns="DAV:">
  <response>
    <href>/17149682/calendars/testcalendar-84439d0b-ce46-4416-b978-7b4009122c64/</href>
    <propstat>
      <prop>
                </prop>
      <status>HTTP/1.1 200 OK</status>
    </propstat>
    <propstat>
      <prop>
        <calendar-data xmlns="urn:ietf:params:xml:ns:caldav"/>
      </prop>
      <status>HTTP/1.1 404 Not Found</status>
    </propstat>
  </response>
  <response>
    <href>/17149682/calendars/testcalendar-84439d0b-ce46-4416-b978-7b4009122c64/20010712T182145Z-123401%40example.com.ics</href>
    <propstat>
      <prop>
        <calendar-data xmlns="urn:ietf:params:xml:ns:caldav">BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Example Corp.//CalDAV Client//EN
BEGIN:VEVENT
UID:[email protected]
DTSTAMP:20060712T182145Z
DTSTART:20060714T170000Z
DTEND:20060715T040000Z
SUMMARY:Bastille Day Party
END:VEVENT
END:VCALENDAR
</calendar-data>
      </prop>
      <status>HTTP/1.1 200 OK</status>
    </propstat>
  </response>
</multistatus>
"""
        expected_result = {
            '/17149682/calendars/testcalendar-84439d0b-ce46-4416-b978-7b4009122c64/':
            {
                '{urn:ietf:params:xml:ns:caldav}calendar-data': None
            },
            '/17149682/calendars/testcalendar-84439d0b-ce46-4416-b978-7b4009122c64/[email protected]':
            {
                '{urn:ietf:params:xml:ns:caldav}calendar-data':
                'BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:-//Example Corp.//CalDAV Client//EN\nBEGIN:VEVENT\nUID:[email protected]\nDTSTAMP:20060712T182145Z\nDTSTART:20060714T170000Z\nDTEND:20060715T040000Z\nSUMMARY:Bastille Day Party\nEND:VEVENT\nEND:VCALENDAR\n'
            }
        }
        assert_equal(
            MockedDAVResponse(xml).expand_simple_props(
                props=[cdav.CalendarData()]), expected_result)

        xml = """
<multistatus xmlns="DAV:">
  <response xmlns="DAV:">
    <href>/17149682/calendars/</href>
    <propstat>
      <prop>
        <resourcetype xmlns="DAV:">
          <collection/>
        </resourcetype>
        <displayname xmlns="DAV:">Ny Test</displayname>
      </prop>
      <status>HTTP/1.1 200 OK</status>
    </propstat>
  </response>
  <response xmlns="DAV:">
    <href>/17149682/calendars/06888b87-397f-11eb-943b-3af9d3928d42/</href>
    <propstat>
      <prop>
        <resourcetype xmlns="DAV:">
          <collection/>
          <calendar xmlns="urn:ietf:params:xml:ns:caldav"/>
        </resourcetype>
        <displayname xmlns="DAV:">calfoo3</displayname>
      </prop>
      <status>HTTP/1.1 200 OK</status>
    </propstat>
  </response>
  <response xmlns="DAV:">
    <href>/17149682/calendars/inbox/</href>
    <propstat>
      <prop>
        <resourcetype xmlns="DAV:">
          <collection/>
          <schedule-inbox xmlns="urn:ietf:params:xml:ns:caldav"/>
        </resourcetype>
      </prop>
      <status>HTTP/1.1 200 OK</status>
    </propstat>
    <propstat>
      <prop>
        <displayname xmlns="DAV:"/>
      </prop>
      <status>HTTP/1.1 404 Not Found</status>
    </propstat>
  </response>
  <response xmlns="DAV:">
    <href>/17149682/calendars/testcalendar-e2910e0a-feab-4b51-b3a8-55828acaa912/</href>
    <propstat>
      <prop>
        <resourcetype xmlns="DAV:">
          <collection/>
          <calendar xmlns="urn:ietf:params:xml:ns:caldav"/>
        </resourcetype>
        <displayname xmlns="DAV:">Yep</displayname>
      </prop>
      <status>HTTP/1.1 200 OK</status>
    </propstat>
  </response>
</multistatus>
"""
        expected_result = {
            '/17149682/calendars/': {
                '{DAV:}resourcetype': ['{DAV:}collection'],
                '{DAV:}displayname': 'Ny Test'
            },
            '/17149682/calendars/06888b87-397f-11eb-943b-3af9d3928d42/': {
                '{DAV:}resourcetype': [
                    '{DAV:}collection',
                    '{urn:ietf:params:xml:ns:caldav}calendar'
                ],
                '{DAV:}displayname':
                'calfoo3'
            },
            '/17149682/calendars/inbox/': {
                '{DAV:}resourcetype': [
                    '{DAV:}collection',
                    '{urn:ietf:params:xml:ns:caldav}schedule-inbox'
                ],
                '{DAV:}displayname':
                None
            },
            '/17149682/calendars/testcalendar-e2910e0a-feab-4b51-b3a8-55828acaa912/':
            {
                '{DAV:}resourcetype': [
                    '{DAV:}collection',
                    '{urn:ietf:params:xml:ns:caldav}calendar'
                ],
                '{DAV:}displayname':
                'Yep'
            }
        }
        assert_equal(
            MockedDAVResponse(xml).expand_simple_props(
                props=[dav.DisplayName()],
                multi_value_props=[dav.ResourceType()]), expected_result)

        xml = """
<multistatus xmlns="DAV:">
  <response xmlns="DAV:">
    <href>/17149682/calendars/testcalendar-f96b3bf0-09e1-4f3d-b891-3a25c99a2894/</href>
    <propstat>
      <prop>
        <getetag xmlns="DAV:">"kkkgopik"</getetag>
      </prop>
      <status>HTTP/1.1 200 OK</status>
    </propstat>
  </response>
  <response xmlns="DAV:">
    <href>/17149682/calendars/testcalendar-f96b3bf0-09e1-4f3d-b891-3a25c99a2894/1761bf8c-6363-11eb-8fe4-74e5f9bfd8c1.ics</href>
    <propstat>
      <prop>
        <getetag xmlns="DAV:">"kkkgorwx"</getetag>
      </prop>
      <status>HTTP/1.1 200 OK</status>
    </propstat>
  </response>
  <response xmlns="DAV:">
    <href>/17149682/calendars/testcalendar-f96b3bf0-09e1-4f3d-b891-3a25c99a2894/20010712T182145Z-123401%40example.com.ics</href>
    <propstat>
      <prop>
        <getetag xmlns="DAV:">"kkkgoqqu"</getetag>
      </prop>
      <status>HTTP/1.1 200 OK</status>
    </propstat>
  </response>
  <sync-token>HwoQEgwAAAh4yw8ntwAAAAAYAhgAIhUIopml463FieB4EKq9+NSn04DrkQEoAA==</sync-token>
</multistatus>
"""
        expected_results = {
            '/17149682/calendars/testcalendar-f96b3bf0-09e1-4f3d-b891-3a25c99a2894/':
            {
                '{DAV:}getetag': '"kkkgopik"',
                '{urn:ietf:params:xml:ns:caldav}calendar-data': None
            },
            '/17149682/calendars/testcalendar-f96b3bf0-09e1-4f3d-b891-3a25c99a2894/1761bf8c-6363-11eb-8fe4-74e5f9bfd8c1.ics':
            {
                '{DAV:}getetag': '"kkkgorwx"',
                '{urn:ietf:params:xml:ns:caldav}calendar-data': None
            },
            '/17149682/calendars/testcalendar-f96b3bf0-09e1-4f3d-b891-3a25c99a2894/[email protected]':
            {
                '{DAV:}getetag': '"kkkgoqqu"',
                '{urn:ietf:params:xml:ns:caldav}calendar-data': None
            }
        }
Пример #18
0
def receive(dbcal, calendar):

    rs_touched = set()
    ev_touched = set()
    rs_updated = rs_created = rs_deleted = 0
    count_update = 0
    count_new = 0
    count_deleted = 0
    #~ print "Using calendar", calendar

    props = calendar.get_properties([dav.DisplayName()])
    dbcal.name = props[dav.DisplayName().tag]
    dbcal.save()

    from_date = dbcal.start_date
    if not from_date:
        from_date = datetime.datetime.now() - datetime.timedelta(days=365)
    until_date = datetime.datetime.now() + datetime.timedelta(days=365)

    #~ from_date = aware(from_date)
    #~ until_date = aware(until_date)

    #~ print from_date.tzinfo, until_date.tzinfo
    #~ raise Exception("20110823")

    results = calendar.date_search(from_date, until_date)
    if results:
        for comp in results:
            #~ if len(list(comp.instance.getChildren())) != 1:
                #~ raise Exception("comp.instance.getChildren() is %s" % list(comp.instance.getChildren()))
            dblogger.info(
                "Got calendar component <<<\n%s\n>>>",
                prettyPrint(comp.instance))

            if comp.instance.vevent:
                event = comp.instance.vevent
                if isinstance(event, RecurringComponent):
                    """
                    in a google calendar, all events are parsed to a
                    RecurringComponent. if event.rruleset is None
                    we consider them non recurrent.
                    """

                    uid = event.uid.value
                    dtstart = event.dtstart.value

                    get_kw = {}
                    set_kw = {}
                    get_kw.update(uid=uid)
                    set_kw.update(summary=event.summary.value)
                    #~ dblogger.info("TRANSPARENCE IS %r", event.transp.value)
                    location_name = event.location.value
                    if location_name:
                        qs = Place.objects.filter(name__iexact=location_name)
                        if qs.count() == 0:
                            pl = Place(name=location_name)
                            pl.full_clean()
                            pl.save()
                            dblogger.info("Auto-created location %s", pl)
                        else:
                            pl = qs[0]
                            if qs.count() > 1:
                                dblogger.warning(
                                    "Found more than 1 Place for location %r", location_name)
                        set_kw.update(place=pl)
                    else:
                        set_kw.update(place=None)
                    if event.transp.value == 'TRANSPARENT':
                        set_kw.update(transparent=True)
                    else:
                        set_kw.update(transparent=False)
                    set_kw.update(description=event.description.value)
                    set_kw.update(calendar=dbcal)
                    #~ set_kw.update(location=event.location.value)
                    #~ kw.update(dtend=event.dtend.value)

                    dblogger.info("It's a RecurringComponent")
                    if event.rruleset:
                        try:
                            obj = RecurrenceSet.objects.get(uid=uid)
                            assert obj.calendar == dbcal
                            rs_updated += 1
                        except RecurrenceSet.DoesNotExist as e:
                        #~ except Exception, e:
                            obj = RecurrenceSet(uid=uid)
                            obj.calendar = dbcal
                            obj.user = dbcal.user
                            rs_created += 1
                        #~ raise Exception("20110823 must save rrule, rdate etc... %s" % type(event.rrule_list))
                        obj.rrules = '\n'.join(
                            [r.value for r in event.rrule_list])
                        #~ obj.exrules = '\n'.join([r.value for r in event.exrule_list])
                        #~ obj.rdates = '\n'.join([r.value for r in event.rdate_list])
                        #~ obj.exdates = '\n'.join([r.value for r in event.exdate_list])
                        obj.summary = event.summary.value
                        obj.description = event.description.value
                        setkw(obj, **dt2kw(dtstart, 'start'))
                        obj.full_clean()
                        obj.save()
                        dblogger.info("Saved %s", obj)
                        rs_touched.add(obj.pk)

                        set_kw.update(rset=obj)
                        if getattr(dtstart, 'tzinfo', False):
                            dtlist = event.rruleset.between(
                                aware(from_date), aware(until_date))
                        else:
                            dtlist = event.rruleset.between(
                                from_date, until_date)
                        dblogger.info("rrulset.between() --> %s", dtlist)
                    else:
                        dtlist = [dtstart]
                        dblogger.info("No rruleset")
                    duration = event.dtend.value - dtstart
                    for dtstart in dtlist:
                        dtend = dtstart + duration
                        get_kw = dt2kw(dtstart, 'start', **get_kw)
                        set_kw = dt2kw(dtend, 'end', **set_kw)
                        try:
                            obj = Event.objects.get(**get_kw)
                            count_update += 1
                        except Event.DoesNotExist as e:
                        #~ except Exception, e:
                            obj = Event(**get_kw)
                            obj.user = dbcal.user
                            count_new += 1
                        setkw(obj, **set_kw)
                        obj.full_clean()
                        obj.save()
                        dblogger.info("Saved %s", obj)
                        ev_touched.add(obj.pk)

                else:
                    raise Exception(
                        "comp.instance.vevent is a %s (expected VEvent)" % type(event))
            else:
                raise Exception(
                    "Got unhandled component %s"
                    % comp.instance.prettyPrint())
                #~ print "children:", [c for c in comp.instance.getChildren()]

            #~ raise StopIteration
    qs = dbcal.event_set.exclude(id__in=ev_touched)
    count_deleted = qs.count()
    qs.delete()  # note: doesn't call delete methods of individual objects
    qs = dbcal.recurrenceset_set.exclude(id__in=rs_touched)
    rs_deleted = qs.count()
    qs.delete()  # note: doesn't call delete methods of individual objects
    dblogger.info(
        "--> Created %d, updated %d, deleted %s Events",
        count_new, count_update, count_deleted)
    dblogger.info(
        "--> Created %d, updated %d, deleted %s RecurrenceSets",
        rs_created, rs_updated, rs_deleted)
Пример #19
0
    def _create(self, name, id=None):
        """
        Create a new calendar with display name `name` in `parent`.
        """
        if id is None:
            id = str(uuid.uuid1())
        self.id = id
            
        path = self.parent.url.join(id)
        self.url = path

        ## TODO: mkcalendar seems to ignore the body on most servers?  
        ## at least the name doesn't get set this way.
        ## zimbra gives 500 (!) if body is omitted ...

        if name:
            display_name = dav.DisplayName(name)
        cal = cdav.CalendarCollection()
        coll = dav.Collection() + cal
        type = dav.ResourceType() + coll

        prop = dav.Prop() + [type,]
        if name:
            prop += [display_name,]
        set = dav.Set() + prop

        mkcol = cdav.Mkcalendar() + set

        q = etree.tostring(mkcol.xmlelement(), encoding="utf-8",
                           xml_declaration=True)

        r = self.client.mkcalendar(path, q)

        if r.status != 201:
            raise error.MkcalendarError(r.raw)

        if name:
            try:
                self.set_properties([display_name])
            except:
                self.delete()
                raise

        ## Special hack for Zimbra!  The calendar we've made exists at
        ## the specified URL, and we can do operations like ls, even
        ## PUT an event to the calendar.  Zimbra will enforce that the
        ## event uuid matches the event url, and return either 201 or
        ## 302 - but alas, try to do a GET towards the event and we
        ## get 404!  But turn around and replace the calendar ID with
        ## the calendar name in the URL and hey ... it works!  

        ## TODO: write test cases for calendars with non-trivial
        ## names and calendars with names already matching existing
        ## calendar urls and ensure they pass.
        zimbra_url = self.parent.url.join(name)
        try:
            ret = self.client.request(zimbra_url)
            if ret.status == 404:
                raise error.NotFoundError
            ## insane server
            self.url = zimbra_url
        except error.NotFoundError:
            ## sane server
            pass
Пример #20
0
    def _create(self, name, id=None, supported_calendar_component_set=None):
        """
        Create a new calendar with display name `name` in `parent`.
        """
        if id is None:
            id = str(uuid.uuid1())
        self.id = id

        path = self.parent.url.join(id)
        self.url = path

        # TODO: mkcalendar seems to ignore the body on most servers?
        # at least the name doesn't get set this way.
        # zimbra gives 500 (!) if body is omitted ...

        # ehm ... this element seems non-existent in the RFC?
        # Breaks with baikal, too ...
        # cal = cdav.CalendarCollection()
        # coll = dav.Collection() # + cal # also breaks on baikal,
        #                                # and probably not needed?
        # type = dav.ResourceType() ## probably not needed?

        prop = dav.Prop()  # + [type,]
        if name:
            display_name = dav.DisplayName(name)
            prop += [display_name, ]
        if supported_calendar_component_set:
            sccs = cdav.SupportedCalendarComponentSet()
            for scc in supported_calendar_component_set:
                sccs += cdav.Comp(scc)
            prop += sccs
        set = dav.Set() + prop

        mkcol = cdav.Mkcalendar() + set

        r = self._query(root=mkcol, query_method='mkcalendar', url=path,
                        expected_return_value=201)

        # COMPATIBILITY ISSUE
        # name should already be set, but we've seen caldav servers failing
        # on setting the DisplayName on calendar creation
        # (DAViCal, Zimbra, ...).  Better to be explicit.
        if name:
            try:
                self.set_properties([display_name])
            except:
                self.delete()
                raise

        # Special hack for Zimbra!  The calendar we've made exists at
        # the specified URL, and we can do operations like ls, even
        # PUT an event to the calendar.  Zimbra will enforce that the
        # event uuid matches the event url, and return either 201 or
        # 302 - but alas, try to do a GET towards the event and we
        # get 404!  But turn around and replace the calendar ID with
        # the calendar name in the URL and hey ... it works!

        # TODO: write test cases for calendars with non-trivial
        # names and calendars with names already matching existing
        # calendar urls and ensure they pass.
        zimbra_url = self.parent.url.join(name)
        try:
            ret = self.client.request(zimbra_url)
            if ret.status == 404:
                raise error.NotFoundError
            # special hack for radicale.
            # It will happily accept any calendar-URL without returning 404.
            ret = self.client.request(self.parent.url.join(
                'ANYTHINGGOESHEREthisshouldforsurereturn404'))
            if ret.status == 404:
                # insane server
                self.url = zimbra_url
        except error.NotFoundError:
            # sane server
            pass
 def from_remote_calendar(cls, remote_calendar):
     props = remote_calendar.get_properties([dav.DisplayName(),])
     return (Calendar(props[dav.DisplayName.tag], remote_calendar.id))
Пример #22
0
def get_events_from_caldav( url, calendar_name ):
    client = caldav.DAVClient(url)
    principal = client.principal()
    calendars = principal.calendars()
    for calendar in calendars:
        if "{'{DAV:}displayname': '"+calendar_name+"'}" == str(calendar.get_properties([dav.DisplayName(),])): 
            print ("Using calendar: " + str(calendar))
            loaded_events = 0
            startdate = datetime.datetime.now() - dateutil.relativedelta.relativedelta(years = 1)
            enddate = startdate + dateutil.relativedelta.relativedelta(months=1)
            while startdate < datetime.datetime.now() + dateutil.relativedelta.relativedelta(years = 3):
                print("time: " + str(startdate) + " - " + str(enddate))
                for event in calendar.date_search(startdate,enddate):
                    eventlist.append(event.data)
                    loaded_events = loaded_events + 1
                startdate = enddate
                enddate = startdate + dateutil.relativedelta.relativedelta(months=1)
    return
Пример #23
0
def add_events_to_caldav( url, calendar_name ):
    client = caldav.DAVClient(url)
    principal = client.principal()
    calendars = principal.calendars()
    for calendar in calendars:
        if "{'{DAV:}displayname': '"+calendar_name+"'}" == str(calendar.get_properties([dav.DisplayName(),])): 
            print ("Using calendar: " + str(calendar))
            total_events = len(eventlist)
            saved_events = 0
            for event in eventlist:
                try:
                    calendar.add_event(event)
                    print("saved event " + str(saved_events) + " of " + str(total_events) + " events")
                    saved_events = saved_events + 1
                except:
                    print("An exception occurred")
                    print(event)
                    f = open("join_calendars.log", "a")
                    f.write("##############################################")
                    f.write(event)
                    f.close()
    return
Пример #24
0
    def _create(self, name, id=None, supported_calendar_component_set=None):
        """
        Create a new calendar with display name `name` in `parent`.
        """
        if id is None:
            id = str(uuid.uuid1())
        self.id = id

        path = self.parent.url.join(id)
        self.url = path

        ## TODO: mkcalendar seems to ignore the body on most servers?
        ## at least the name doesn't get set this way.
        ## zimbra gives 500 (!) if body is omitted ...

        cal = cdav.CalendarCollection()
        coll = dav.Collection() + cal
        type = dav.ResourceType() + coll

        prop = dav.Prop() + [
            type,
        ]
        if name:
            display_name = dav.DisplayName(name)
            prop += [
                display_name,
            ]
        if supported_calendar_component_set:
            sccs = cdav.SupportedCalendarComponentSet()
            for scc in supported_calendar_component_set:
                sccs += cdav.Comp(scc)
            prop += sccs
        set = dav.Set() + prop

        mkcol = cdav.Mkcalendar() + set

        r = self._query(root=mkcol,
                        query_method='mkcalendar',
                        url=path,
                        expected_return_value=201)

        if name:
            try:
                self.set_properties([display_name])
            except:
                self.delete()
                raise

        ## Special hack for Zimbra!  The calendar we've made exists at
        ## the specified URL, and we can do operations like ls, even
        ## PUT an event to the calendar.  Zimbra will enforce that the
        ## event uuid matches the event url, and return either 201 or
        ## 302 - but alas, try to do a GET towards the event and we
        ## get 404!  But turn around and replace the calendar ID with
        ## the calendar name in the URL and hey ... it works!

        ## TODO: write test cases for calendars with non-trivial
        ## names and calendars with names already matching existing
        ## calendar urls and ensure they pass.
        zimbra_url = self.parent.url.join(name)
        try:
            ret = self.client.request(zimbra_url)
            if ret.status == 404:
                raise error.NotFoundError
            ## insane server
            self.url = zimbra_url
        except error.NotFoundError:
            ## sane server
            pass
Пример #25
0
username = "******"
password = "******"
calendar_names = ["Müll", "Family", "Privat"]
final_url = "https://" + username + ":" + password + "@" + url

client = caldav.DAVClient(final_url)
principal = client.principal()
calendars = principal.calendars()

caldata_today = []
caldata_tomorrow = []

if len(calendars) > 0:
    for i in range(0, len(calendars) - 1):
        calendar_displayname = str(calendars[i].get_properties([
            dav.DisplayName(),
        ]))
        #print(calendar_displayname)
        for calendar_name in calendar_names:
            if calendar_displayname.find(calendar_name) > 0:
                calendar = calendars[i]
                html_today = '<table>'
                html_tomorrow = '<table>'
                searchdate = date.today()
                #print("Termine heute:",date(searchdate.year, searchdate.month, searchdate.day))
                results = calendar.date_search(
                    date(searchdate.year, searchdate.month, searchdate.day),
                    date(searchdate.year, searchdate.month,
                         searchdate.day + 1))
                for event in results:
                    ev = event
Пример #26
0
#         print("    Name: %-20s  URL: %s" % (c.name, c.url))
# else:
#     print("your principal has no calendars")


# regExp_dtstart = re.compile('(0-9){8}') 
# regExp_dtstart = re.compile('(20100729)')  
# DTSTART;TZID=Asia/Seoul:20100729T100000
# DTEND;TZID=Asia/Seoul:20100729T110000

KST = timezone('Asia/Seoul')
now = utc.localize(datetime.utcnow()).astimezone(KST).strftime('%Y%m%d')

if len(calendars) > 0:
    for calendar in calendars:
        properties = calendar.get_properties([dav.DisplayName(), ])
        display_name = properties['{DAV:}displayname']
        # 캘린더명 가져오기
        # print(properties)
        if display_name != '내 캘린더':continue
            # all_events = calendar.events()
        for event in calendar.events():
            data = get_vevent_data(event)
            dtstart = data.get('dtstart').dt.strftime('%Y%m%d')
            dtend = data.get('dtend').dt.strftime('%Y%m%d')
            # if type(dtstart.dt) == type(date.today()) :continue
            # print(type(dtstart.dt))
            # print(dtend.dt)
            print(display_name, dtstart, now, dtend)
            if not dtstart <= now <= dtend: continue
            print(display_name, data, '===============>', data.get('summary'))
Пример #27
0
    def testCalendar(self):
        c = Calendar(self.caldav,
                     name="Yep",
                     parent=self.principal,
                     id=testcal_id).save()
        assert_not_equal(c.url, None)
        # TODO: fail
        #props = c.get_properties([DAVDisplayName(),])
        #assert_equal("Yep", props[DAVDisplayName.tag])

        c.set_properties([
            dav.DisplayName("hooray"),
        ])
        props = c.get_properties([
            dav.DisplayName(),
        ])
        assert_equal(props[dav.DisplayName.tag], "hooray")
        print c

        cc = Calendar(self.caldav, name="Yep", parent=self.principal).save()
        assert_not_equal(cc.url, None)
        cc.delete()

        e = Event(self.caldav, data=ev1, parent=c).save()
        assert_not_equal(e.url, None)
        print e, e.data

        ee = Event(self.caldav, url=url.make(e.url), parent=c)
        ee.load()
        assert_equal(e.instance.vevent.uid, ee.instance.vevent.uid)

        r = c.date_search(datetime(2006, 7, 13, 17, 00, 00),
                          datetime(2006, 7, 15, 17, 00, 00))
        assert_equal(e.instance.vevent.uid, r[0].instance.vevent.uid)
        for e in r:
            print e.data
        assert_equal(len(r), 1)

        all = c.events()
        assert_equal(len(all), 1)

        e2 = Event(self.caldav, data=ev2, parent=c).save()
        assert_not_equal(e.url, None)

        tmp = c.event("*****@*****.**")
        assert_equal(e2.instance.vevent.uid, tmp.instance.vevent.uid)

        r = c.date_search(datetime(2006, 7, 13, 17, 00, 00),
                          datetime(2006, 7, 15, 17, 00, 00))
        for e in r:
            print e.data
        assert_equal(len(r), 1)

        e.data = ev2
        e.save()

        r = c.date_search(datetime(2006, 7, 13, 17, 00, 00),
                          datetime(2006, 7, 15, 17, 00, 00))
        for e in r:
            print e.data
        assert_equal(len(r), 1)
Пример #28
0
def main():
	parser = argparse.ArgumentParser()
	parser.add_argument('-i', metavar='FILE_NAME', help='Input JSON file with appointments', required=True)
	parser.add_argument('-o', metavar='FILE_NAME', help='Output ICS file')
	parser.add_argument('--caldav', metavar='CALDAV_URL', help='URL of the CALDAV server')
	parser.add_argument('-p', '--person_name', metavar='NAME', help='Name to append to calendar entries')
	args = parser.parse_args()

	if not args.o and not url:
		print ('Provide -o command line argument for file output or CALDAV_URL environment variable ' +
				'for CalDAV output')
		parser.print_help()
		sys.exit(1)

	appointments = None

	with open(args.i) as f:
		appointments = json.load(f)

	# Generate vcal events from appointments
	icalendars = []
	all_events = Calendar()

	for appointment in appointments:
		cal = Calendar()
		location = get_location(appointment['clinicName'])
		dt = dateutil.parser.parse(appointment['appointmentDate'])
		tz = pytz.timezone('Europe/Warsaw')
		local = dt.replace(tzinfo=tz)
		event = Event()
		#event['methdo']
		event['uid'] = '{0}@medicover.pl'.format(appointment['id'])
		event['dtstart'] = vDatetime(local)
		event['dtend'] = vDatetime(local + datetime.timedelta(minutes=appointment['duration']))
		event['dtstamp'] = vDatetime(now)
		event['summary'] = vText(appointment['specializationName'])
		summary = appointment['specializationName']
		if args.person_name:
			summary += u' – {0}'.format(args.person_name)
		event['summary'] = vText(summary)
		event['description'] = vText(u'{0}, {1}'.format(
			appointment['specializationName'], appointment['doctorName']))
		event['class'] = 'private'

		if location:
			event['location'] = vText(u'{0}, {1}, {2}'.format(appointment['clinicName'], location['address'], location['cityname']))
			geocode = location['geocode']
			if geocode:
				event['geo'] = '{0};{1}'.format(*geocode['geo'])
		else:
			event['location'] = appointment['clinicName']
			
		cal.add_component(event)
		icalendars.append(cal)
		all_events.add_component(event)

	# Write calendar to file.
	if args.o:
		print 'Writing ' + args.o
		output_file = open(args.o, 'w')
		output_file.write(all_events.to_ical())

	# Write calendar to CalDAV.
	if url:
		client = caldav.DAVClient(url)
		principal = client.principal()
		calendars = principal.calendars()

		for calendar in calendars:
			name = calendar.get_properties([dav.DisplayName(),])['{DAV:}displayname']
			if name == 'Medicover':
				for cal in icalendars:
					print cal.to_ical()
					event = calendar.add_event(cal.to_ical())
					print 'Event', event, 'created'
Пример #29
0
config = configparser.ConfigParser()
config.read(['config.dist.ini', 'config.ini'])
print("SevDesk API-Token: " + config.get("sevdesk", "apikey"))

print("Zeige alle Rechnungen an:")
params = {'token': config.get("sevdesk", "apikey"), 'limit': 1000, 'offset': 0}
response = requests.get('https://my.sevdesk.de/api/v1/Invoice', params=params)
if response.ok:
    jsonResponse = response.json()
    for invoice in jsonResponse['objects']:
        print(invoice)
calDavUrl = config.get('calendar', 'url')
print("Benuzte URL: %s" % calDavUrl)
client = caldav.DAVClient(calDavUrl, None, config.get('calendar', 'user'),
                          config.get('calendar', 'pass'))
principal = client.principal()
calendars = principal.calendars()
print(calendars)
for cal in calendars:
    calendar_name = cal.get_properties([dav.DisplayName()
                                        ])['{DAV:}displayname']
    section_name = 'calendar_' + calendar_name.replace(' ', '_')
    if section_name in config.sections():
        print("Price for %s: %.2f €" %
              (calendar_name, float(config.get(section_name, 'price'))))
        for event in cal.events():
            print("Ereignis: %s" % event)
    else:
        print("Calendar %s is not matched" % calendar_name)