def write_items(self, calendar): """ Write all events to the calendar """ for item in self.items: event = Event() if vText( 'MEETING') in item['categories'] else Todo() for ifield, efield in ITEM_EVENT_FIELD_MAP: val = item.get(ifield) if isinstance(val, list): for list_item in val: event.add(efield, list_item) elif val is not None: event.add(efield, val) calendar.add_component(event)
def make_service_call(host, port, username, pwd, dbname, option): def uid_generat(data):# UID generat sha_obj = hashlib.sha1(data) return sha_obj.hexdigest() if host == '1' and port == '1': sock_common = xmlrpclib.ServerProxy('http://127.0.0.1:8069/xmlrpc/common') uid = sock_common.login(dbname, username, pwd) sock = xmlrpclib.ServerProxy('http://127.0.0.1:8069/xmlrpc/object') else: sock_common = xmlrpclib.ServerProxy('http://'+host+':'+port+'/xmlrpc/common') uid = sock_common.login(dbname, username, pwd) sock = xmlrpclib.ServerProxy('http://'+host+':'+port+'/xmlrpc/object') if option == "task": task_ids = sock.execute(dbname, uid, pwd, 'crm.task', 'search',\ [('task_type', '=', 't'), ('user_id', '=', uid), ('state', '!=', 'cancel')]) task_data = sock.execute(dbname, uid, pwd, 'crm.task', 'read', task_ids,\ ['name','description','start_datetime','stop_datetime',\ 'priority','state','location','write_date']) def ics_datetime(idate): if idate: #returns the datetime as UTC, because it is stored as it in the database idate = idate.split('.', 1)[0] return DT.datetime.strptime(idate,\ '%Y-%m-%d %H:%M:%S').replace(tzinfo=pytz.timezone('UTC')) return False cal = Calendar() cal.add('PRODID', 'Zimbra-Calendar-Provider') cal.add('VERSION', '2.0') cal.add('METHOD', 'PUBLISH') for data in task_data: todo = Todo() todo.add('summary', data['name']) todo.add('description', data['description']) if data['start_datetime']: todo.add('DTSTART', ics_datetime(data['start_datetime'])) else: todo.add('DTSTART', ics_datetime(data['stop_datetime'])) if data['stop_datetime']: todo.add('DUE', ics_datetime(data['stop_datetime'])) else: todo.add('DUE', ics_datetime(data['start_datetime'])) if data['write_date']: todo.add('DTSTAMP', DT.datetime.strptime(data['write_date'],\ '%Y-%m-%d %H:%M:%S')) todo.add('LAST-MODIFIED', \ DT.datetime.strptime(data['write_date'], '%Y-%m-%d %H:%M:%S')) todo['uid'] = uid_generat('crmTask'+str(data['id'])) if data['priority'] == 'low': todo.add('priority', 9) elif data['priority'] == 'medium': todo.add('priority', 5) elif data['priority'] == 'high': todo.add('priority', 1) else: todo.add('priority', 5) if data['state'] == 'done': todo.add('status', 'COMPLETED') todo.add('PERCENT-COMPLETE', 100) elif data['state'] == 'cancel': todo.add('status', 'DEFERRED') elif data['state'] == 'open': todo.add('status', 'IN-PROCESS') else: todo.add('status', 'NEEDS-ACTION') todo.add('PERCENT-COMPLETE', 0) cal.add_component(todo) return cal.to_ical() else: event_ids = sock.execute(dbname, uid, pwd, 'calendar.event', 'search',\ [('user_id','=',uid)]) event_data = sock.execute(dbname, uid, pwd, 'calendar.event', 'read',\ event_ids,['show_as','allday','name','description',\ 'start_datetime','stop_datetime','location','write_date','start_date','stop_date']) # 'start','stop','location','write_date']) def ics_datetime(idate): if idate: #returns the datetime as UTC, because it is stored as it in the database return DT.datetime.strptime(idate,\ '%Y-%m-%d %H:%M:%S').replace(tzinfo=pytz.timezone('UTC')) return False cal = Calendar() cal.add('PRODID', 'Zimbra-Calendar-Provider') cal.add('VERSION', '2.0') cal.add('METHOD', 'PUBLISH') for data in event_data: event = Event() if data['allday']: event.add('CREATED', date.today()) event.add('DTSTART', DT.datetime.combine(DT.datetime.strptime(data['start_date'], '%Y-%m-%d'), DT.time.min)) event.add('DTEND', DT.datetime.combine(DT.datetime.strptime(data['stop_date'], '%Y-%m-%d'), DT.time.max)) event.add('X-MICROSOFT-CDO-ALLDAYEVENT', 'TRUE') else: event.add('CREATED', date.today()) event.add('DTSTART', ics_datetime(data['start_datetime'])) event.add('DTEND', ics_datetime(data['stop_datetime'])) event.add('X-MICROSOFT-CDO-ALLDAYEVENT', 'FALSE') if data['write_date']: event.add('DTSTAMP', DT.datetime.strptime(data['write_date'],\ '%Y-%m-%d %H:%M:%S')) event.add('LAST-MODIFIED', \ DT.datetime.strptime(data['write_date'], '%Y-%m-%d %H:%M:%S')) if data['show_as']: event.add('X-MICROSOFT-CDO-INTENDEDSTATUS', data['show_as']) event.add('UID', uid_generat('crmCalendar'+str(data['id']))) event.add('SUMMARY', data['name']) if data['description']: event.add('DESCRIPTION', data['description']) if data['location']: event.add('LOCATION', data['location']) cal.add_component(event) return cal.to_ical()
def task_create(task=None, title='Task title', due=None, alarm=None, note='', sequence=0, uid=None, priority=None, next_action=None): from uuid import uuid4 from icalendar import Calendar, Todo, Alarm if task is not None: title = task.name due = task.due alarm = task.alarm note = task.note sequence = task.sequence priority = task.priority next_action = task.next_action if (due is not None and alarm is None): # Should not arrive here, this should have already have been handled alarm = due if is_same_time(due, universe.defaulttime.due): # Warning for day events 1800 - 1000 = 8 hours alarm = due + universe.defaulttime.alldaydiff else: # Default warning of an hour alarm = due + universe.defaulttime.diff if (alarm is not None and due is None): due = alarm # alarm now defunct - just use due cal = Calendar() cal.add('prodid', '-//enoky//v0.1//EN') cal.add('version', '2.0') todo = Todo() todo.add('summary', title) if priority is not None: todo.add('priority', priority) if due is not None: todo.add('due', due) todo.add('dtstart', due) todo.add('status', 'NEEDS-ACTION') todo.add('dtstamp', universe.now) todo.add('created', universe.now) if uid is None: uid = uuid4() todo['uid'] = uid todo.add('sequence', sequence) notenext = note if (next_action is not None) and (len(next_action) > 0): if len(notenext) > 0: notenext = notenext + '\n' notenext = notenext + universe.next_char + ' ' + next_action.lstrip() if len(notenext) > 0: todo.add('description', notenext) if alarm is not None: valarm = Alarm() valarm['uid'] = uuid4() valarm.add('trigger', alarm) # Possibly not needed. How add due date?! valarm.add('description', 'Event reminder') valarm.add('action', 'DISPLAY') todo.add_component(valarm) cal.add_component(todo) vcal = cal.to_ical() return vcal
def todo_add(caldav_conn, args): ## TODO: copied from calendar_add, should probably be consolidated if args.icalendar or args.nocaldav: niy(feature="add todo item by icalendar raw stdin data or create raw icalendar data to stdout") if args.todo_uid: uid = args.todo_uid else: uid = uuid.uuid1() cal = Calendar() cal.add('prodid', '-//{author_short}//{product}//{language}'.format(author_short=__author_short__, product=__product__, language=args.language)) cal.add('version', '2.0') todo = Todo() todo.add('dtstamp', _now()) for setarg in ('due', 'dtstart'): if getattr(args, 'set_'+setarg): if type(getattr(args, 'set_'+setarg)) == str: val = dateutil.parser.parse(getattr(args, 'set_'+setarg)) else: val = getattr(args, 'set_'+setarg) todo.add(setarg, val) todo.add('uid', str(uid)) todo.add('summary', ' '.join(args.summaryline)) todo.add('status', 'NEEDS-ACTION') if args.is_child: for t in todo_select(caldav_conn, args): todo.add('related-to', t.instance.vtodo.uid.value) rt = t.instance.vtodo.add('related-to') rt.params['RELTYPE']=['CHILD'] rt.value = str(uid) t.save() for attr in vtodo_txt_one: if attr == 'summary': continue val = getattr(args, 'set_'+attr) if val: todo.add(attr, val) ## TODO: this doesn't currently work quite the way we'd like it to ## work (it adds to lines to the ical, and vobject cares only ## about one of them), and if we do get it to work, we'd like to ## refactor and get the same logic in the edit-function for attr in vtodo_txt_many: val = getattr(args, 'set_'+attr) if val: vals = val.split(',') todo.add(attr, vals) if args.alarm is not None: alarm = create_alarm(' '.join(args.summaryline), parse_time_delta(args.alarm)) todo.add_component(alarm) cal.add_component(todo) _calendar_addics(caldav_conn, cal.to_ical(), uid, args) print("Added todo item with uid=%s" % uid)
def todo_add(caldav_conn, args): ## TODO: copied from calendar_add, should probably be consolidated if args.icalendar or args.nocaldav: niy(feature="add todo item by icalendar raw stdin data or create raw icalendar data to stdout") if args.todo_uid: uid = args.todo_uid else: uid = uuid.uuid1() cal = Calendar() cal.add( "prodid", "-//{author_short}//{product}//{language}".format( author_short=__author_short__, product=__product__, language=args.language ), ) cal.add("version", "2.0") todo = Todo() ## TODO: what does the cryptic comment here really mean, and why was the dtstamp commented out? dtstamp is required according to the RFC. ## TODO: (cryptic old comment:) not really correct, and it breaks i.e. with google calendar todo.add("dtstamp", datetime.now()) for arg in ("set_due", "set_dtstart"): if getattr(args, arg): if type(getattr(args, arg)) == str: val = dateutil.parser.parse(getattr(args, arg)) else: val = getattr(args, arg) todo.add(arg, val) todo.add("uid", str(uid)) todo.add("summary", " ".join(args.summaryline)) todo.add("status", "NEEDS-ACTION") if args.is_child: for t in todo_select(caldav_conn, args): todo.add("related-to", t.instance.vtodo.uid.value) rt = t.instance.vtodo.add("related-to") rt.params["RELTYPE"] = ["CHILD"] rt.value = str(uid) t.save() for attr in vtodo_txt_one + vtodo_txt_many: if attr == "summary": continue val = getattr(args, "set_" + attr) if val: todo.add(attr, val) cal.add_component(todo) _calendar_addics(caldav_conn, cal.to_ical(), uid, args) print("Added todo item with uid=%s" % uid)
def todo_add(caldav_conn, args): ## TODO: copied from calendar_add, should probably be consolidated if args.icalendar or args.nocaldav: niy(feature= "add todo item by icalendar raw stdin data or create raw icalendar data to stdout" ) if args.todo_uid: uid = args.todo_uid else: uid = uuid.uuid1() cal = Calendar() cal.add( 'prodid', '-//{author_short}//{product}//{language}'.format( author_short=__author_short__, product=__product__, language=args.language)) cal.add('version', '2.0') todo = Todo() todo.add('dtstamp', _now()) for setarg in ('due', 'dtstart'): if getattr(args, 'set_' + setarg): if type(getattr(args, 'set_' + setarg)) == str: val = dateutil.parser.parse(getattr(args, 'set_' + setarg)) else: val = getattr(args, 'set_' + setarg) todo.add(setarg, val) todo.add('uid', str(uid)) todo.add('summary', ' '.join(args.summaryline)) todo.add('status', 'NEEDS-ACTION') if args.is_child: for t in todo_select(caldav_conn, args): todo.add('related-to', t.instance.vtodo.uid.value) rt = t.instance.vtodo.add('related-to') rt.params['RELTYPE'] = ['CHILD'] rt.value = str(uid) t.save() for attr in vtodo_txt_one: if attr == 'summary': continue val = getattr(args, 'set_' + attr) if val: todo.add(attr, val) ## TODO: this doesn't currently work quite the way we'd like it to ## work (it adds to lines to the ical, and vobject cares only ## about one of them), and if we do get it to work, we'd like to ## refactor and get the same logic in the edit-function for attr in vtodo_txt_many: val = getattr(args, 'set_' + attr) if val: vals = val.split(',') todo.add(attr, vals) if args.alarm is not None: alarm = create_alarm(' '.join(args.summaryline), parse_time_delta(args.alarm)) todo.add_component(alarm) cal.add_component(todo) _calendar_addics(caldav_conn, cal.to_ical(), uid, args) print("Added todo item with uid=%s" % uid)
def todo_add(caldav_conn, args): ## TODO: copied from calendar_add, should probably be consolidated if args.icalendar or args.nocaldav: niy(feature= "add todo item by icalendar raw stdin data or create raw icalendar data to stdout" ) if args.todo_uid: uid = args.todo_uid else: uid = uuid.uuid1() cal = Calendar() cal.add( 'prodid', '-//{author_short}//{product}//{language}'.format( author_short=__author_short__, product=__product__, language=args.language)) cal.add('version', '2.0') todo = Todo() ## TODO: what does the cryptic comment here really mean, and why was the dtstamp commented out? dtstamp is required according to the RFC. ## TODO: (cryptic old comment:) not really correct, and it breaks i.e. with google calendar todo.add('dtstamp', datetime.now()) for arg in ('set_due', 'set_dtstart'): if getattr(args, arg): if type(getattr(args, arg)) == str: val = dateutil.parser.parse(getattr(args, arg)) else: val = getattr(args, arg) todo.add(arg, val) todo.add('uid', str(uid)) todo.add('summary', ' '.join(args.summaryline)) todo.add('status', 'NEEDS-ACTION') if args.is_child: for t in todo_select(caldav_conn, args): todo.add('related-to', t.instance.vtodo.uid.value) rt = t.instance.vtodo.add('related-to') rt.params['RELTYPE'] = ['CHILD'] rt.value = str(uid) t.save() for attr in vtodo_txt_one + vtodo_txt_many: if attr == 'summary': continue val = getattr(args, 'set_' + attr) if val: todo.add(attr, val) cal.add_component(todo) _calendar_addics(caldav_conn, cal.to_ical(), uid, args) print("Added todo item with uid=%s" % uid)
'E': 'EASTERLY', } ical_freq_hsh = { 'YEARLY': 'y', 'MONTHLY': 'm', 'WEEKLY': 'w', 'DAILY': 'd', 'HOURLY': 'h', 'MINUTELY': 'n', # 'EASTERLY': 'e' } item_types = { '*': Event(), '-': Todo(), '%': Journal() } # BEGIN:VCALENDAR # VERSION:2.0 # PRODID:-//etm_tk 3.2.38//dgraham.us// # BEGIN:VEVENT # SUMMARY:Charleston Volvo Open # DTSTART;VALUE=DATE:20190402 # UID:f42d3035fd634835a01f6193a925f32eetm # RRULE:FREQ=DAILY;COUNT=4 # END:VEVENT # END:VCALENDAR
def create_calendar_feed(user, secret): if True: #try: # check access enabled = frappe.db.get_value("Calendar Feed Settings", "Calendar Feed Settings", "enabled") if float(enabled) == 0: return erp_secret = frappe.db.get_value("Calendar Feed Settings", "Calendar Feed Settings", "secret") if not secret == erp_secret: return # initialise calendar cal = Calendar() # set properties cal.add('prodid', '-//finkzeit//libracore//') cal.add('version', '2.0') # get data for public events show_public_events = frappe.db.get_value("Calendar Feed Settings", "Calendar Feed Settings", "show_public_events") if float(show_public_events) == 1: sql_query = """SELECT `subject`, `starts_on`, `ends_on`, `modified`, `description` FROM `tabEvent` WHERE `event_type` = 'Public'""" events = frappe.db.sql(sql_query, as_dict=True) # add events for erp_event in events: event = Event() event.add('summary', erp_event['subject']) event.add('dtstart', erp_event['starts_on']) if erp_event['ends_on']: event.add('dtend', erp_event['ends_on']) event.add('dtstamp', erp_event['modified']) event.add('description', erp_event['description']) # add to calendar cal.add_component(event) # get data for personal events sql_query = """SELECT `subject`, `starts_on`, `ends_on`, `modified`, `description` FROM `tabEvent` WHERE `event_type` = 'Private' AND (`owner` = '{user}' OR `modified_by` = '{user}')""".format( user=user) events = frappe.db.sql(sql_query, as_dict=True) # add events for erp_event in events: event = Event() event.add('summary', erp_event['subject']) event.add('dtstart', erp_event['starts_on']) if erp_event['ends_on']: event.add('dtend', erp_event['ends_on']) event.add('dtstamp', erp_event['modified']) event.add('description', erp_event['description']) # add to calendar cal.add_component(event) # get data for personal todo's sql_query = """SELECT IFNULL(`reference_type`, '-') AS `reference_type`, IFNULL(`reference_name`, '-') AS `reference_name`, `description`, `modified`, `date` FROM `tabToDo` WHERE `status` = 'Open' AND (`owner` = '{user}' OR `modified_by` = '{user}')""".format( user=user) todos = frappe.db.sql(sql_query, as_dict=True) # add events for erp_todo in todos: todo = Todo() todo.add( 'summary', "{0} {1}".format(erp_todo['reference_type'], erp_todo['reference_name'])) todo.add('dtstamp', erp_todo['modified']) todo.add('description', erp_todo['description']) if erp_todo['date']: todo.add('due', erp_todo['date']) todo.add('status', 'Open') # add to calendar cal.add_component(todo) # return calendar object return cal
def make_todo(item: ToDoItem) -> Todo: todo = Todo() todo['uid'] = item.id todo['summary'] = item.title todo['status'] = "Completed" if item.completed else "In Progress" return todo
def TodoFromJSON(cal, data): tz = pytz.timezone("Europe/Budapest") if 'dynalist_info' in data: if data['note'] == '': description = data['dynalist_info'] else: description = data['note'] + '\n' + data['dynalist_info'] else: description = data['note'] duedate = data['date'].replace('-', '') time = data['time'].replace(':', '') if not duedate == '': Y = int(duedate[:4]) m = int(duedate[4:6]) D = int(duedate[6:8]) if not time == '': H = int(time[:2]) M = int(time[2:4]) if cal is None: cal = Calendar() cal.add('prodid', '-//Dynatask//') cal.add('version', '2.0') todo = Todo() if 'dynalist_id' in data: todo.add('uid', data['caldav_uid']) todo.add('X-DYNATASK-DYNALISTID', data['dynalist_id']) elif 'caldav_uid' in data: todo.add('uid', data['caldav_uid']) todo.add('summary', data['name']) now = datetime.now(pytz.utc) todo.add('dtstamp', now) todo.add('created', now) todo.add('last-modified', now) if not duedate == '': if not time == '': todo.add('due', datetime(Y, m, D, H, M, tzinfo=tz)) else: todo.add('due', datetime(Y, m, D).date()) todo.add('description', description) if 'checked' in data: if data['checked']: todo.add('status', 'COMPLETED') todo.add('completed', datetime.now(pytz.utc)) todo.add('percent-complete', '100') else: todo.add('status', 'NEEDS-ACTION') todo.add('percent-complete', '0') if 'caldav_parent' in data: todo.add('related-to', data['caldav_parent']) if 'alarm' in data and not data['alarm'] == '': alarm = Alarm() alarm.add('action', 'DISPLAY') alarm.add('trigger', timedelta(minutes=-int(data['alarm']))) todo.add_component(alarm) cal.add_component(todo) return (cal)
def createVTODOs(task, parent=None): todos = [] todo = Todo() try: todo.add('UID', str(task['id'])) except KeyError: todo.add('UID', str(uuid.uuid1())) try: todo.add('dtstamp', datetime.strptime(task['createdAt'], "%Y-%m-%dT%H:%M:%S.%f%z")) except ValueError: #Thank you for using different formats within the same field! try: todo.add('dtstamp', datetime.strptime(task['createdAt'], "%Y-%m-%dT%H:%M:%S%z")) except: logger.error('Could not parse creation date for Task {}'.format(task['id'])) quit() todo.add('summary', task.get('title', '')) if task.get('dueDate', None) is not None: todo.add('DUE', datetime.strptime(task['dueDate'], "%Y-%m-%dT%H:%M:%S")) if task['completed']: todo.add('status', 'COMPLETED') todo.add('PERCENT-COMPLETE', '100') todo.add('COMPLETED', datetime.strptime(task['completedAt'], "%Y-%m-%dT%H:%M:%S.%f%z")) todo.add('LAST-MODIFIED', datetime.strptime(task['completedAt'], "%Y-%m-%dT%H:%M:%S.%f%z")) todo.add('COMMENT', task.get('notes', '')) if task.get('reminders', False): reminders = [] for reminder in task['reminders']: try: reminders += [datetime.strptime(reminder['remindAt'], "%Y-%m-%dT%H:%M:%S.%f%z")] except ValueError: #Thank you for using different formats within the same file! try: reminders += [datetime.strptime(reminder['remindAt'], "%Y-%m-%dT%H:%M:%S%z")] except: logger.error('Could not parse reminder date for Task {}'.format(task['id'])) logger.debug('Task {} has {} reminders. Not supported'.format(task['id'], len(reminders))) if task.get('comment', False): todo.add('description', task['comment']) if task.get('files', False): logger.error('There are files linked!') if parent is not None: todo.add('RELATED-TO', parent) todos.extend([todo]) if task.get('subtasks', False): logger.debug('Task {} has {} subtasks'.format(task['id'], len(task['subtasks']))) for subtask in task['subtasks']: todos.extend(createVTODOs(subtask, parent=task['id'])) return todos
def todo_ical_export(request): ''' Type: iCalendar Mime: text/calendar Ext: ics #tpl = loader.get_template('task/todo.ics') #response.write(tpl.render(Context({'object_list': object_list})).encode('utf-8')) ''' user = User.objects.get(pk=request.user.id) # aka author response = HttpResponse(mimetype='text/calendar') response['Content-Disposition'] = '; filename=todo.ics' cal = Calendar() cal.add('version', '2.0') cal.add('prodid', '-//LanSite GroupWare//eap.su//') for object in vToDo.objects.filter(user=user): todo = Todo() # 1. Task #todo['created'] = object.created todo.add('created', object.created) todo.add('last-modified', object.updated) todo.add('summary', object.summary) if (object.getstatusname()): todo.add('status', object.getstatusname()) if (object.getrestrictionname()): todo.add('class', object.getrestrictionname()) if (object.getcategories()): todo.add('categories', object.getcategories()) # 2. vCal if object.attendee: email = object.attendee.email if email: todo.add('attendee', 'MAILTO:%s' % email) email = user.email if email: todo.add('organizer', 'MAILTO:%s' % email) if object.description: todo.add('description', object.description) if object.start_d: if object.start_t: todo.add('dtstart', datetime.combine(object.start_d, object.start_t)) else: todo.add('dtstart', object.start_d) if object.duration_d: if object.duration_t: todo.add('duration', timedelta( days=object.duration_d, hours=object.duration_t.hour, minutes=object.duration_t.minute, seconds=object.duration_t.second )) else: todo.add('duration', timedelta(days=object.duration_d)) if object.location: todo.add('location', object.location) if object.priority: todo.add('priority', object.priority) if object.URL: todo.add('URL', object.URL) # 3. vToDo if object.due_d: if object.due_t: todo.add('due', datetime.combine(object.due_d, object.due_t)) else: todo.add('due', object.due_d) if object.completed: todo.add('completed', object.completed) if object.percent: todo.add('percent-complete', object.percent) cal.add_component(todo) response.write(cal.as_string()) # .encode('utf-8') return response