Ejemplo n.º 1
0
def prepareVobj(view, uuid, recordSet, vobjs):
    """
    Determine if a recordset is for a vtodo, or a vevent, then create it.
    
    Modifications may not have event records OR task records, so for
    modifications, check what was done for the master.  This relies on 
    recordsets for masters being processed before modifications.
    
    """
    master_uuid, recurrenceID = translator.splitUUID(view, uuid)
    if recurrenceID is None:
        note, event = hasNoteOrEvent(recordSet)
    else:
        if vobjs.get(master_uuid).name.lower() == 'vevent':
            task, event = False, True
        else:
            task, event = True, False

    if event:
        vevent = vobject.newFromBehavior('vevent')
        vevent.isNative = True
        vobjs[uuid] = vevent
    else:  # @@@ assert note?
        vtodo = vobject.newFromBehavior('vtodo')
        vtodo.isNative = True
        vobjs[uuid] = vtodo
Ejemplo n.º 2
0
def prepareVobj(view, uuid, recordSet, vobjs):
    """
    Determine if a recordset is for a vtodo, or a vevent, then create it.
    
    Modifications may not have event records OR task records, so for
    modifications, check what was done for the master.  This relies on 
    recordsets for masters being processed before modifications.
    
    """
    master_uuid, recurrenceID = translator.splitUUID(view, uuid)
    if recurrenceID is None:
        note, event = hasNoteOrEvent(recordSet)
    else:
        if vobjs.get(master_uuid).name.lower() == 'vevent':
            task, event = False, True
        else:
            task, event = True, False
            
    if event:
        vevent = vobject.newFromBehavior('vevent')
        vevent.isNative = True
        vobjs[uuid] = vevent
    else: # @@@ assert note?
        vtodo = vobject.newFromBehavior('vtodo')
        vtodo.isNative = True
        vobjs[uuid] = vtodo
Ejemplo n.º 3
0
    def __init__(self, invitation, resp, email):
        # create
        ans = vobject.newFromBehavior('vcalendar')
        ans.add('method')
        ans.method.value = "REPLY"
        ans.add('vevent')

        for i in ["uid", "summary", "dtstart", "dtend", "organizer"]:
            if i in invitation.vevent.contents:
                ans.vevent.add( invitation.vevent.contents[i][0] )

        # new timestamp
        ans.vevent.add('dtstamp')
        ans.vevent.dtstamp.value = datetime.utcnow().replace(tzinfo = invitation.vevent.dtstamp.value.tzinfo)

        ans.vevent.add('attendee')
        ans.vevent.attendee_list.pop()

        if 'attendee' in invitation.vevent.contents:
            atts = invitation.vevent.contents['attendee']
            for a in atts:
                if self._get_email(a) == email:
                    ans.vevent.attendee_list.append(self._set_resp(a,resp))

        self.ans = ans
Ejemplo n.º 4
0
    def __init__(self, app, time_limit=None):
        job_base.TimeLimitedJob.__init__(self, app, time_limit)
        self.app = app

        self.calendar_change_count = 0
        self.count = 0
        self.vobject_calendar = vobject.newFromBehavior('vcalendar')

        self.app.calendar = None
        self.app.calendar_lock = threading.Lock()
Ejemplo n.º 5
0
def generate_response_for(invite):
    #cal = vobject.iCalendar()
    rsp = vobject.newFromBehavior('vcalendar')
    rsp.add('method')
    rsp.method.value = "REPLY"
    rsp.add('vevent')

    for key in ['uid', 'summary', 'dtstart', 'dtend', 'organizer']:
        if invite.vevent.contents.has_key(key):
            rsp.vevent.add(invite.vevent.contents[key][0])

    rsp.vevent.add('dtstamp')
    rsp.vevent.dtstamp.value = datetime.utcnow().replace(
        tzinfo = invite.vevent.dtstamp.value.tzinfo)

    return rsp
Ejemplo n.º 6
0
def get_answer(invitation):
    # create
    ans = vobject.newFromBehavior('vcalendar')
    ans.add('method')
    ans.method.value = "REPLY"
    ans.add('vevent')

    # just copy from invitation
    for i in ["uid", "summary", "dtstart", "dtend", "organizer"]:
        if invitation.vevent.contents.has_key(i):
            ans.vevent.add( invitation.vevent.contents[i][0] )

    # new timestamp
    ans.vevent.add('dtstamp')
    ans.vevent.dtstamp.value = datetime.utcnow().replace(
            tzinfo = invitation.vevent.dtstamp.value.tzinfo)
    return ans
Ejemplo n.º 7
0
def get_answer(invitation):
    # create
    ans = vobject.newFromBehavior('vcalendar')
    ans.add('method')
    ans.method.value = "REPLY"
    ans.add('vevent')

    # just copy from invitation
    for i in ["uid", "summary", "dtstart", "dtend", "organizer"]:
        if invitation.vevent.contents.has_key(i):
            ans.vevent.add(invitation.vevent.contents[i][0])

    # new timestamp
    ans.vevent.add('dtstamp')
    ans.vevent.dtstamp.value = datetime.utcnow().replace(
        tzinfo=invitation.vevent.dtstamp.value.tzinfo)
    return ans
Ejemplo n.º 8
0
def get_answer(invitation):
    # create
    ans = vobject.newFromBehavior('vcalendar')
    ans.add('method')
    ans.method.value = "REPLY"
    ans.add('vevent')

    # just copy from invitation
    #for i in ["uid", "summary", "dtstart", "dtend", "organizer"]:
    # There's a problem serializing TZ info in Python, temp fix
    for i in ["uid", "summary", "organizer"]:
        if i in invitation.vevent.contents:
            ans.vevent.add( invitation.vevent.contents[i][0] )

    # new timestamp
    ans.vevent.add('dtstamp')
    ans.vevent.dtstamp.value = datetime.utcnow().replace(
            tzinfo = invitation.vevent.dtstamp.value.tzinfo)
    return ans
Ejemplo n.º 9
0
def upload_calendar(data):
    #Check if called from client side (not necessary)
    if (isinstance(data, str)):
        data = json.loads(data)

    #Connect to CalDav Account
    account = frappe.get_doc("CalDav Account", data["caldavaccount"])
    """
    account = data["caldavaccount"]
    """
    client = caldav.DAVClient(url=account.url,
                              username=account.username,
                              password=account.password)
    principal = client.principal()
    calendars = principal.calendars()
    cal = None

    #Look for the right calendar
    for calendar in calendars:
        if (str(calendar) == data["calendarurl"]):
            cal = calendar

    #Go through events
    erp_events = frappe.db.sql("""
        SELECT
            *
        FROM `tabEvent`
        WHERE icalendar = '{icalendar}' AND custom_pattern is NULL;
    """.format(icalendar=data["icalendar"]),
                               as_dict=1)

    weekdays = [
        "monday", "tuesday", "wednesday", "thursday", "friday", "saturday",
        "sunday"
    ]
    rrweekdays = [RR.MO, RR.TU, RR.WE, RR.TH, RR.FR, RR.SA, RR.SU]

    upstats = {
        "10a": 0,
        "10b": 0,
        "10c": 0,
        "11b": 0,
        "not_uploadable": 0,
        "cancelled_or_closed_of_no_uploadable": 0,
        "exceptions": 0,
    }

    rstats = {
        "mapped": 0,
        "not_mapped": 0,
    }
    #Error Stack
    error_stack = []

    for idx, ee in enumerate(erp_events):
        uploadable = True
        try:
            print(ee)
            #Case 10a: Status Open, everything nominal
            if (ee["status"] == "Open"):
                new_calendar = vobject.newFromBehavior('vcalendar')
                e = new_calendar.add('vevent')
                e.add('summary').value = ee["subject"]
                dtstart = ee["starts_on"]
                e.add('dtstart').value = dtstart
                e.add('description').value = ee["description"]
                if (ee["event_type"] in ["Public", "Private", "Confidential"]):
                    e.add('class').value = ee["event_type"]
                #Case 10b: Status Open, but Event Type is Cancelled
                elif (ee["event_type"] == "Cancelled"):
                    uploadable = False
                    upstats["10b"] += 1
                #Case 10c: Status Open, but Event Type not in [Public, Private, Confidential,Cancelled]
                else:
                    uploadable = False
                    upstats["10c"] += 1
                    raise Exception(
                        'Exception:', 'Event with Name ' + ee["name"] +
                        ' has the invalid Event Type ' + ee["event_type"])
                dtend = ee["ends_on"]
                if (dtend == None):
                    dtend = dtstart + datetime.timedelta(minutes=15)
                    frappe.db.set_value('Event',
                                        ee["name"],
                                        'ends_on',
                                        dtend,
                                        update_modified=False)
                if (ee["all_day"] == 0):
                    e.add('dtend').value = dtend
                else:
                    e.dtstart.value = dtstart.date()
                    dtend = (dtend.date() + datetime.timedelta(days=1))
                    e.add('dtend').value = dtend

                if (ee["last_modified"] == None):
                    frappe.db.set_value('Event',
                                        ee["name"],
                                        'last_modified',
                                        ee["modified"].replace(microsecond=0),
                                        update_modified=False)
                    e.add('last-modified').value = ee["modified"].replace(
                        microsecond=0)
                else:
                    e.add('last-modified').value = ee["last_modified"]

                if (ee["created_on"] == None):
                    frappe.db.set_value('Event',
                                        ee["name"],
                                        'created_on',
                                        ee["creation"].replace(microsecond=0),
                                        update_modified=False)
                    e.add('created').value = ee["creation"].replace(
                        microsecond=0)
                else:
                    e.add('created').value = ee["created_on"]

                #Create rrule
                rrule = None
                until = ee["repeat_till"]
                byweekday = []
                if (ee["repeat_this_event"] == 1
                        and ee["repeat_till"] != None):
                    until = datetime.datetime(until.year, until.month,
                                              until.day, dtstart.hour,
                                              dtstart.minute, dtstart.second)
                if (ee["repeat_on"] == "Daily"):
                    rrule = RR.rrule(freq=RR.DAILY, until=until)
                elif (ee["repeat_on"] == "Weekly"):
                    for idx, weekday in enumerate(weekdays):
                        if (ee[weekday] == 1):
                            byweekday.append(rrweekdays[idx])
                    rrule = RR.rrule(freq=RR.WEEKLY,
                                     until=until,
                                     byweekday=byweekday)
                elif (ee["repeat_on"] == "Monthly"):
                    rrule = RR.rrule(freq=RR.MONTHLY, until=until)
                elif (ee["repeat_on"] == "Yearly"):
                    rrule = RR.rrule(freq=RR.YEARLY, until=until)

                if (rrule != None):
                    e.add('rrule').value = rrule
                    rstats["mapped"] += 1
                else:
                    rstats["not_mapped"] += 1

                #Remove None Children
                none_attributes = []
                for child in e.getChildren():
                    if (child.value == None):
                        none_attributes.append(child.name.lower())
                for attr in none_attributes:
                    e.__delattr__(attr)

                ics = new_calendar.serialize()
                print(ics)
                frappe.db.set_value('Event',
                                    ee["name"],
                                    'uid',
                                    e.uid.value,
                                    update_modified=False)

                #Upload
                if (uploadable):
                    cal.save_event(ics)
                    upstats["10a"] += 1
                else:
                    upstats["not_uploadable"] += 1
            #Case 11a: Status != Open
            else:
                uploadable = False
                upstats["11b"] += 1
        except Exception as ex:
            #traceback.print_exc()
            tb = traceback.format_exc()
            upstats["exceptions"] += 1
            error_stack.append({
                "message":
                "Could not upload event. Exception: \n" + tb,
                "event":
                json.dumps(ee)
            })

        #Update UI
        percent_progress = idx / len(erp_events) * 100
        frappe.publish_progress(percent=percent_progress, title="Uploading")

    #Return JSON and Log
    message = {}
    upstats["cancelled_or_closed_of_no_uploadable"] = upstats[
        "not_uploadable"] - upstats["10b"] - upstats["11b"]
    message["upstats"] = upstats
    message["rstats"] = rstats
    message["error_stack"] = error_stack
    """
    """

    d = frappe.get_doc("iCalendar", data["icalendar"])
    d.last_sync_log = json.dumps(message)
    d.save()
    d.add_comment('Comment',
                  text="Stats:\n" + str(upstats) + "\nRRule Stats:\n" +
                  str(rstats))
    """
    """

    return json.dumps(message)
Ejemplo n.º 10
0
def email_appointment(sender, to, message, cust_id, cust_name, cust_phone, 
      cmp_name, begin, duration, member_name):
   ''' Create and send email with iCalendar event attached
   '''

   # Create email 
   msg = Message()
   msg['Subject'] = u'RDV Call center Multimédia %s' % cust_name
   msg['To'] = to
   msg['From'] = sender
   msg['Content-class'] = 'urn:content-classes:calendarmessage'
   msg['Content-type'] = 'text/calendar; method=REQUEST; charset=UTF-8'
   msg['Content-transfer-encoding'] = '8BIT'

   # vCal (vobject automatically adds missing fields, eg. UUID)
   vcal = vobject.newFromBehavior('vcalendar')
   vcal.add('method').value = u'REQUEST'
   vcal.add('vevent')
   vcal.add('prodid').value = '-//SysNux.pf/NONSGML AstPortal V1.0//EN'
   vcal.add('version').value = '2.0'
   vcal.vevent.add('description').value = u'''Rendez-vous fixé par le Call Center Multimédia pour la campagne "%s"

Client n°%s / %s
N° de téléphone : %s
Message :
-----
%s
-----

Observations particulières :
NB : Cet événement est envoyé à titre d'information et ne nécessite pas de retour.

Merci et bonne réception
%s
''' % (cmp_name, cust_id, cust_name, cust_phone, message, member_name)
   vcal.vevent.add('dtstart').value = begin
   vcal.vevent.add('dtend').value = begin + timedelta(0, duration*60)
   vcal.vevent.add('class').value = u'PUBLIC'
   vcal.vevent.add('dtstamp').value = datetime.now()
   vcal.vevent.add('created').value = datetime.now()
   vcal.vevent.add('last-modified').value = datetime.now()
   vcal.vevent.add('organizer').value = u'mailto:%s' % sender
   vcal.vevent.add('attendee').value = u'mailto:%s' % to
   vcal.vevent.add('transp').value = 'OPAQUE'
   vcal.vevent.add('summary').value = u'RDV %s' % cust_name
   vcal.add('vtimezone')
   vcal.vtimezone.add('tzid').value = 'Pacific/Tahiti'
   vcal.vtimezone.add('x-lic-location').value = 'Pacific/Tahiti'
   vcal.vtimezone.add('standard')
   vcal.vtimezone.standard.add('TZOFFSETFROM').value = '-1000'
   vcal.vtimezone.standard.add('TZOFFSETTO').value = '-1000'
   vcal.vtimezone.standard.add('TZNAME').value = 'TAHT'
   vcal.vtimezone.standard.add('DTSTART').value = datetime(1970,1,1)
#   valarm = vobject.newFromBehavior('VALARM')
#   valarm.add('trigger').value = timedelta(-1)
#   valarm.add('action').value = 'email'
#   valarm.add('attendee').value = to
#   valarm.add('summary').value = 'Rappel RDV %s' % cust_name
#   valarm.add('description').value = 'RDV dans 24 heures avec client %s' % cust_id
#   vcal.vevent.add(valarm)
   log.debug(vcal.prettyPrint())
   msg.set_payload(vcal.serialize())

   # Send email
   log.debug(msg.as_string())
   s = smtplib.SMTP()
   try:
      s.connect('localhost')
      s.sendmail(sender, to, msg.as_string())
      s.close()
   except:
      flash(u'Une erreur est survenue, l\'email n\'a pu être envoyé', 'error')
            write_cur.execute('INSERT INTO calendars (principaluri, displayname, uri, ctag, description, calendarorder, calendarcolor, timezone, components) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)', var)
            calendarid = write_cur.lastrowid
        else:
            calendarid = row[0]

        # Clear calendar first
        write_cur.execute('DELETE FROM calendarobjects WHERE calendarid = %s', [calendarid])
            
        read_cur.execute('SELECT c.carddata, c.uri FROM cards as c JOIN addressbooks as a ON c.addressbookid = a.id WHERE a.principaluri = %s', [uri])
        for row in read_cur.fetchall():
            card = vobject.readOne(row[0])
            carduri = row[1]

            if hasattr(card, 'bday'):
                bday = datetime.strptime(card.bday.value, '%Y-%m-%d').date()
                ca = vobject.newFromBehavior('vcalendar')

                # Create event
                ev = ca.add('vevent')
                ev.add('summary').value = card.fn.value
                ev.add('dtstart').value = bday
                ev.add('dtend').value = bday+timedelta(days=1)
                ev.add('class').value = "public"
                ev.add('created').value = now
                ev.add('dtstamp').value = now
                ev.add('last-modified').value = now 
                ev.add('rrule').value = "FREQ=YEARLY;BYMONTHDAY="+str(bday.day)+";BYMONTH="+str(bday.month);
                ev.add('transp').value = "TRANSPARENT"
                ev.add('categories').value = ["Birthday"]
                ev.add('x-microsoft-cdo-alldayevent').value = "TRUE"
Ejemplo n.º 12
0
import vobject

cal = vobject.newFromBehavior('vcalendar')
cal.behavior
print(cal)