def CreateReminder(cal, days, text, fromaddress): """Creates a calendar entry in days days with title text. Args: cal: A Calendar. days: How many days in the future to create the reminder. text: The calendar summary Returns: A calendar entry. """ event = Event() event.add('summary', text) eventdate = datetime.datetime.now() + datetime.timedelta(days=int(days)) event.add('dtstart',eventdate) event.add('dtend', eventdate) event.add('dtstamp', eventdate) event['uid'] = str(uuid.uuid1()) + '@kumari.net' event.add('priority', 5) organizer = vCalAddress('MAILTO:%s' % fromaddress) organizer.params['cn'] = vText('%s' % fromaddress) organizer.params['role'] = vText('CHAIR') event['organizer'] = organizer event['location'] = vText('Online') cal.add_component(event) return cal
def get_ical(self): cal = Calendar() adate = self.start_date for shift in self.shifts: event = Event() if shift not in self.definitions: print('WARNING: Unknown shift: {}'.format(shift), file=sys.stderr) times = None else: if self.definitions[shift]: times = [self.definitions[shift]['start'], self.definitions[shift]['end']] else: times = None if times is not None: starttime = time(int(times[0][:2]), int(times[0][2:4]), tzinfo=self.timezone) event.add('dtstart', datetime.combine(adate, starttime)) if int(times[0]) > int(times[1]): enddate = adate + timedelta(1) else: enddate = adate endtime = time(int(times[1][:2]), int(times[1][2:4]), tzinfo=self.timezone) event.add('dtend', datetime.combine(enddate, endtime)) if 'title' in self.definitions[shift]: event['summary'] = self.definitions[shift]['title'] cal.add_component(event) adate += timedelta(1) return cal.to_ical()
def get(self, request, **kwargs): client = CachedWaniKani(kwargs['api_key']) queue = client.upcoming() cal = Calendar() cal.add('prodid', '-//Wanikani Reviews//github.com/kfdm/django-wanikani//') cal.add('version', '2.0') newqueue = collections.defaultdict(list) for ts in list(queue.keys()): newts = ts.date() newqueue[newts] += queue.pop(ts) queue = newqueue for ts in sorted(queue): if not len(queue[ts]): continue event = Event() event.add('summary', '復習 {0}'.format(len(queue[ts]))) event.add('dtstart', ts) cal.add_component(event) return HttpResponse( content=cal.to_ical(), content_type='text/calendar; charset=utf-8' )
def make_anc_ical(request, anc=None): # Collect future meetings and sort after collating meetings across ANCs. now = datetime.datetime.now() meetings = [] for mtganc, mtgs in meeting_data.items(): if anc != None and mtganc.lower() != anc: continue for mtgdate, mtginfo in sorted(mtgs['meetings'].items()): mtgdate = dateutil.parser.parse(mtgdate) if mtgdate < now: continue meetings.append( (mtgdate, mtganc, mtginfo) ) meetings.sort() # Make ical. from icalendar import Calendar, Event cal = Calendar() for mtgdate, mtganc, mtginfo in meetings: if mtginfo.get("status") == "invalid": continue event = Event() event.add('dtstart', mtgdate) event['summary'] = "ANC %s Meeting" % mtganc event['description'] = "See ANCFinder.org for details: http://ancfinder.org/%s" % mtganc event['location'] = '; '.join(mtginfo[k] for k in ('building', 'address', 'root') if mtginfo.get(k)) event['link'] = mtginfo.get("link") cal.add_component(event) return HttpResponse(cal.to_ical(), "text/calendar" if "mime" not in request.GET else "text/plain")
def generate(lessons): """ Generates ical calendar (as a byte string) from an iterable of lessons (QuerySet, list...) """ # Adjust the timezone, so the time is correctly displayed in GCalendar tz = pytz.timezone('Europe/Madrid') cal = Calendar() cal.add('prodid', '-//Calendari HorarisPompeu.com//mxm.dk//') cal.add('version', '2.0') # Give the calendar a name. I use this to remind the users where the # calendar comes from, in case they need a new one. cal.add('x-wr-calname', 'horarispompeu.com {}'.format( settings.TERM_STRING)) cal.add('x-wr-timezone', 'Europe/Madrid') for entry in lessons: event = Event() summary = "\n".join([entry.subject.name, entry.entry]) event.add('summary', summary) event.add('location', entry.location) event.add('dtstart', tz.localize(entry.date_start)) event.add('dtend', tz.localize(entry.date_end)) event.add('dtstamp', datetime.now(tz)) cal.add_component(event) return cal.to_ical()
def export_to_ics(schedule,start_of_week,end_of_week): cal=Calendar() cal.add('version','2.0') cal.add('prodid','-//python2.7//EN') today=datetime.today() for shift in schedule: if (shift!=None): shift_start=shift['shift_start'] shift_end=shift['shift_end'] shift_event=Event() uid=str(shift_start)+'-'+str(shift_end)+'@gmail.com' shift_event.add('uid',uid) shift_event.add('dtstamp',today) shift_event.add('dtstart',shift_start) shift_event.add('dtend',shift_end) shift_event.add('summary','Kickin Chicken') cal.add_component(shift_event) start_of_week=start_of_week.replace('/','') end_of_week=end_of_week.replace('/','') file_path='/file_path/' fname=file_path+start_of_week+'_'+end_of_week+'.ics' f=open(fname,'w') f.write(cal.to_ical()) f.close()
def gen_ical(courses): cal = Calendar() cal["version"] = "2.0" cal[ "prodid" ] = "-//Zhejiang University//LIU Dongyuan//ZH" # *mandatory elements* where the prodid can be changed, see RFC 5445 for course in courses: for lesson in course["lessons"]: weeks = lesson["weeks"] for recur in weeks: event = Event() event.add("summary", unify_brackets(course["name"])) offset_days = lesson["day"] - 1 + 7 * (int(recur) - 1) offset = timedelta(days=offset_days) classdate = week_start + offset start = lesson_time[lesson["start"]]["start"] end = lesson_time[lesson["end"]]["end"] event.add("dtstart", datetime.combine(classdate, start)) event.add("dtend", datetime.combine(classdate, end)) event.add("location", lesson["location"]) event.add("description", u"教师:" + course["teacher"]) event["uid"] = str(uuid1()) + "@ZJU" cal.add_component(event) return cal.to_ical()
def export(request, agenda_id): event = get_object_or_404(CustomAgendaItems, id = agenda_id) cal = Calendar() site = Site.objects.get_current() cal.add('prodid', '-//%s Events Calendar//%s//' % (site.name, site.domain)) cal.add('version', '2.0') site_token = site.domain.split('.') site_token.reverse() site_token = '.'.join(site_token) ical_event = Event() ical_event.add('location', event.location) ical_event.add('summary', event.title) # ical_event.add('description', event.session_description) start = datetime.combine(event.start_date, event.start_time) ical_event.add('dtstart', start) end = datetime.combine(event.start_date, event.end_time) ical_event.add('dtend', end and end or start) ical_event.add('dtstamp', end and end or start) ical_event['uid'] = '%d.event.events.%s' % (event.id, site_token) cal.add_component(ical_event) response = HttpResponse(cal.to_ical(), content_type="text/calendar") response['Content-Disposition'] = 'attachment; filename=%s.ics' % event.slug return response
def ical(): # init calendar cal = Calendar() cal.add('prodid', '-//Radio freies Krautchan//EN') cal.add('version', '2.0') cal.add('method', 'PUBLISH' ) # add some useful iCal extensions cal.add('x-wr-calname', 'RfK') cal.add('x-wr-caldesc', 'Radio freies Krautchan') cal.add('x-wr-timezone', 'UTC') # adding planned shows result = get_shows() if result: for show in result: djs = get_djs(show) summary = "%s with %s" % (show.name, ', '.join(djs)) event = Event() event.add('uid', str(show.show)) event.add('summary', summary) event.add('description', show.description) event.add('dtstart', show.begin) event.add('dtend', show.end) cal.add_component(event) return Response(cal.to_ical(), mimetype='text/calendar')
def export_ics(self): events = Event.get_recent_past_and_future() url_base = 'http://' + self.request.headers.get('host', 'events.hackerdojo.com') cal = Calendar() for event in events: iev = CalendarEvent() iev.add('summary', event.name if event.status == 'approved' else event.name + ' (%s)' % event.status.upper()) # make verbose description with empty fields where information is missing ev_desc = '__Status: %s\n__Member: %s\n__Type: %s\n__Estimated size: %s\n__Info URL: %s\n__Fee: %s\n__Contact: %s, %s\n__Rooms: %s\n\n__Details: %s\n\n__Notes: %s' % ( event.status, event.owner(), event.type, event.estimated_size, event.url, event.fee, event.contact_name, event.contact_phone, event.roomlist(), event.details, event.notes) # then delete the empty fields with a regex ev_desc = re.sub(re.compile(r'^__.*?:[ ,]*$\n*',re.M),'',ev_desc) ev_desc = re.sub(re.compile(r'^__',re.M),'',ev_desc) ev_url = url_base + event_path(event) iev.add('description', ev_desc + '\n--\n' + ev_url) iev.add('url', ev_url) if event.start_time: iev.add('dtstart', event.start_time.replace(tzinfo=pytz.timezone('US/Pacific'))) if event.end_time: iev.add('dtend', event.end_time.replace(tzinfo=pytz.timezone('US/Pacific'))) cal.add_component(iev) return 'text/calendar', cal.as_string()
def test_parsers(self): obj = AcademicEvents() cal = Calendar() event = Event() event.add('dtstart', date(2014, 12, 5)) event.add('dtend', date(2014, 12, 6)) event['summary'] = "Test Event" start, end = obj.parse_dates(event) self.assertEquals(start, "2014-12-05") self.assertEquals(end, "2014-12-05") year, quarter = obj.parse_year_quarter(event) self.assertEquals(year, None) self.assertEquals(quarter, None) event['description'] = ' Year: 2018 ' year, quarter = obj.parse_year_quarter(event) self.assertEquals(year, '2018') self.assertEquals(quarter, None) event['description'] = ' Year: 2018\nQuarter: Winter\nMore Content' year, quarter = obj.parse_year_quarter(event) self.assertEquals(year, '2018') self.assertEquals(quarter, 'Winter')
def build_calendar(issues, ics_path): cal = Calendar() for i in issues: event = Event() if "Full" in str(i.status): summary = "[COMPLET] " + i.subject else: summary = i.subject event.add('summary', summary) event.add('description', i.description) event['uid'] = i.id for c in i.custom_fields: if c.id == 20: # 20 is 'debut' start_time = str(c.value).replace(':', '')+"00" if c.id == 21: # 21 is 'fin' end_time = str(c.value).replace(':', '')+"00" event['dtstart'] = i.due_date.replace('/','')+"T"+start_time event['dtend'] = i.due_date.replace('/','')+"T"+end_time event['dtstamp'] = vDatetime(now).to_ical() organizer = vCalAddress('MAILTO:[email protected]') organizer.params['cn'] = vText('Les fruits défendus') event['organizer'] = organizer event['location'] = vText('Montréal, QC') cal.add_component(event) f = open(ics_path, 'wb') f.write(cal.to_ical()) f.close()
def process_xls(filename): wb = xlrd.open_workbook(filename) sheet = wb.sheet_by_index(0) calendar = Calendar() calendar.add('x-wr-calname','Schedule for U8 Summer Hockey 2015') for irow in range(sheet.nrows): row = sheet.row(irow) basedate = xlrd.xldate_as_tuple(row[1].value, wb.datemode) (hh, mmxx) = row[3].value.split(':') hh = int(hh) mm = int(mmxx[:2]) xx = mmxx[2:] if xx == 'PM': hh += 12 basedt = list(basedate[:3]) + [hh, mm] tstamp = datetime(*basedt) uid = tstamp.strftime('%Y%m%d%H%M')+'@pugswald.com' event = Event() event.add('uid', uid) event.add('dtstart', tstamp) event.add('summary', 'AYHL U8 Hockey %s'%row[2].value) event.add('dtend', tstamp + timedelta(minutes=60)) event.add('location', row[5].value) alarm = Alarm() alarm.add('action', 'DISPLAY') alarm.add('description', 'Reminder') alarm.add('trigger', timedelta(minutes=-45)) event.add_component(alarm) calendar.add_component(event) print calendar.to_ical()
def __new_event(self, new_ev): """Start and end strings are in the format "MM/DD/YYYY HH:MM:SS" """ s, e, summary, location = new_ev event = Event() event.add('summary', summary) event.add('location', location) event.add('dtstart', datetime(int(s[6:10]), \ int(s[0:2]), \ int(s[3:5]), \ int(s[11:13]), \ int(s[14:16]), \ int(s[17:19]), \ 0, \ self.__tz())) event.add('dtend', datetime(int(e[6:10]), \ int(e[0:2]), \ int(e[3:5]), \ int(e[11:13]), \ int(e[14:16]), \ int(e[17:19]), \ 0, \ self.__tz())) event.add('dtstamp', datetime.now(self.__tz())) # Workaround for a bug in UIDGenerator # Wasn't fixed when this was released event['uid'] = self.__getUID() self.__backend.new(self.__cal, self.__uri, event) self.__reload_events()
def convert_to_calendar(data): dict_calendar = { "format": CALENDAR, } pattern_frequence = '' if data['frequence'] == EVERYMONTH: pattern_frequence = MONTHLY elif data['frequence'] == EVERYWEEK: pattern_frequence = WEEKLY elif data['frequence'] == EVERYDAY: pattern_frequence = DAILY calendar_event = Event() rule_pattern = { 'freq': pattern_frequence, 'byhour': data["time"].hour, 'byminute': data["time"].minute, } if pattern_frequence == MONTHLY: rule_pattern['bymonthday'] = data["date"] elif pattern_frequence == WEEKLY: rule_pattern['byday'] = CALENDAR_DAY_DICT[data["day"]] calendar_event.add('rrule', rule_pattern) dict_calendar['pattern'] = calendar_event.to_ical() return dict_calendar
def generate_ical(object): cal = Calendar() cal['PRODID'] = 'Kawaz' cal['VERSION'] = '2.0' site = Site.objects.get(pk=settings.SITE_ID) event = CalEvent() event['summary'] = object.title event['description'] = object.body event['class'] = 'PUBLIC' if object.pub_state == 'public' else 'PRIVATE' if object.category: event['categories'] = object.category.label event['dtstamp'] = vDatetime(object.created_at) if object.place: event['location'] = object.place event['dtstart'] = vDatetime(object.period_start).to_ical() if object.period_end: event['dtend'] = vDatetime(object.period_end).to_ical() def create_vaddress(user): va = vCalAddress('MAILTO:{}'.format(user.email)) va.params['cn'] = vText(user.nickname) va.params['ROLE'] = vText(user.role) return va organizer = create_vaddress(object.organizer) event['organizer'] = organizer event['URL'] = 'http://{}{}'.format(site.domain, object.get_absolute_url()) for attendee in object.attendees.all(): event.add('attendee', create_vaddress(attendee), encode=0) cal.add_component(event) return cal
def sk_forum_planning_calendar(request): from datetime import datetime, date from icalendar import Calendar, Event, UTC, LocalTimezone # timezone cal = Calendar() cal.add('prodid', '-//SK Forum Calendar//killingar.net//') cal.add('version', '2.0') import MySQLdb connection = MySQLdb.connect(user='******', passwd='2oVGx8VwuqUfY', db='forum') cursor = connection.cursor() from django.utils.encoding import smart_unicode cursor.execute(u'SELECT id FROM users where name = "%s"' % (smart_unicode(request.REQUEST['username']))) userID = cursor.fetchall()[0] cursor.execute("select id, name, time, description from events, eventdata where events.id = eventdata.event and events.visible = 1 and eventdata.user = %s and eventdata.data in (1, 0)" % userID) rows = cursor.fetchall() for row in rows: id, name, time, description = row event = Event() event.add('summary', smart_unicode(name.decode('latin-1'))) #event.add('dtstart', 'DATE:'+time.strftime("%Y%m%d")) #event.add('dtend', 'DATE:'+time.strftime("%Y%m%d")) event.add('dtstart', date(time.year, time.month, time.day)) event.add('dtend', date(time.year, time.month, time.day)) if description: event.add('description', smart_unicode(description.decode('latin-1'))) #event.add('X-FUNAMBOL-ALLDAY', '') event['uid'] = 'planning/%[email protected]' % id event.add('priority', 5) # normal priority cal.add_component(event) connection.close() return HttpResponse(cal.as_string(), content_type='text/calendar')
def AddAppointments( self, Appointments ): """ adding appointments to ICS file (It is actually events) event = Event() event.add('summary', 'Python meeting about calendaring') event.add('dtstart', datetime(2005,4,4,8,0,0,tzinfo=UTC)) >>> event.add('dtend', datetime(2005,4,4,10,0,0,tzinfo=UTC)) event.add('dtstart', datetime(2005,4,4,8,0,0,tzinfo=UTC)) event.add('dtend', datetime(2005,4,4,10,0,0,tzinfo=UTC)) event.add('dtstamp', datetime(2005,4,4,0,10,0,tzinfo=UTC)) from icalendar import vCalAddress, vText organizer = vCalAddress('MAILTO:[email protected]') organizer.params['cn'] = vText('Max Rasmussen') organizer.params['role'] = vText('CHAIR') event['organizer'] = organizer event['location'] = vText('Odense, Denmark') event['uid'] = '20050115T101010/[email protected]' event.add('priority', 5) """ for App in Appointments: event = Event() if App.has_key( 'Class' ): event.add('summary', App['Subject']+" - "+App['Class']) else: event.add('summary', App['Subject']) event.add('dtstart', App['Hours'][0]) event.add('dtend', App['Hours'][1]) if App.has_key( 'Location' ): event.add( 'location', App['Location'] ) self.cal.add_component(event)
def process_xls(filename): wb = xlrd.open_workbook(filename) sheet = wb.sheet_by_index(0) calendar = Calendar() calendar.add('x-wr-calname','Schedule for U8 Adv Winter Hockey 2015') for irow in range(sheet.nrows): row = sheet.row(irow) evt_desc = None if row[0].value == "U8 Advanced": evt_desc = row[0].value if row[1].value == "Group 1" or row[1].value == "Group 2": evt_desc = row[1].value if evt_desc is None: continue basedate = xlrd.xldate_as_tuple(row[3].value, wb.datemode) basedt = list(basedate[:3]) + get_hhmm(row[4].value) tstamp = datetime(*basedt) basedt_end = list(basedate[:3]) + get_hhmm(row[5].value) tstamp_end = datetime(*basedt_end) uid = tstamp.strftime('%Y%m%d%H%M')+'@pugswald.com' event = Event() event.add('uid', uid) event.add('dtstart', tstamp) event.add('summary', 'AYHL Hockey - %s'%evt_desc) event.add('dtend', tstamp_end) event.add('location', row[6].value) alarm = Alarm() alarm.add('action', 'DISPLAY') alarm.add('description', 'Reminder') alarm.add('trigger', timedelta(minutes=-45)) event.add_component(alarm) calendar.add_component(event) print calendar.to_ical()
def add_event(calendar, event_data): event = Event() for icalendar_key, model_attribute in icalendar_to_model_keys.items(): if model_attribute in event_data: if event_data[model_attribute] is not None: event.add(icalendar_key, event_data[model_attribute]) calendar.add_component(event)
def add_event(x): event = Event() event.add('uid', x["uid"]) event.add('summary', x["name"]) event.add('dtstart', datetime.strptime(x["date"], "%d %B %Y %HH%M")) event.add('location', x["place"]) event.add('description', x["price"]) cal.add_component(event)
def icsfilemaker(data): cal=Calendar() cal.add('version','2.0') cal.add('prodid','-//cal test//studybuddy.com//') daterule=dt.datetime.now()#this is needed just to initialize the vevent pattern=re.compile(r'(\S+)([AP]M)')#pattern to find the first time in the textblock from the user(the times are gotten in the following format ('11:30','AM')) pattern1=re.compile(r'(\d+)')#pattern to get the first two digits in a timeslot(i.e. the 11 from 11:30 ) daysrc=['MO','TU','WE','TH','FR','SA','SU']#lists of days for BYDAY pattern2=re.compile(r'(\S+)\s+(\S+)\s+([AP]M)')#pattern to get the time in the following format 11 00 AM for i in xrange(1,len(data)):#iterating over the data list for j in xrange(1,len(data[0])): if data[i][j]!='' and not(data[i][j].isspace()) and data[i][j]!='place':#only interact with textblocks i.e.non-empty elements of the list if re.findall(pattern,data[i][j]):#if search is successful assign the timeslot timeslot=re.findall(pattern,data[i][j])#gets the time from the textblock elif re.findall(pattern2,data[i][j]):#if search is successful assign the timeslot and reformat each element of the timeslot list to (11:30,AM) just as above timeslot=re.findall(pattern2,data[i][j]) count=0 for a in timeslot: timeslot[count]=('%d:%s'%(int(a[0]),a[1]),a[2]) count=count+1 if len(timeslot)==2:#if it has the start and end times proceed forward minutes=int(re.findall(pattern1,timeslot[0][0])[1])#get the min 30 from 11:30 nlsplit=data[i][j].split('\n')#split the text at \n since x\nx\nx\nx for each textblock dur=dt.datetime.strptime('%s%s'%(timeslot[1][0],timeslot[1][1]), "%I:%M%p")-dt.datetime.strptime('%s%s'%(timeslot[0][0],timeslot[0][1]), "%I:%M%p")#get the duration of each event in 24 hours time hour=dt.datetime.strptime('%s%s'%(timeslot[0][0],timeslot[0][1]), "%I:%M%p").hour# get the hour of the start time in 24 hours eg 11 from 11:30 event=Event()#creating an event instance alarm=Alarm()#creating an alarm instance event.add('dtstart',daterule)#adding the start date event.add('exdate',daterule)#excluding the start date event.add('rrule',{'FREQ':'WEEKLY','BYDAY':daysrc[j-1],'BYHOUR':hour,'BYMINUTE':minutes,'BYSECOND':0,'UNTIL':datetime(2015,12,30,23,59,59)})#generate weekly events for each text block until 30 of December event.add('summary','%s\r\n%s'%(nlsplit[0],nlsplit[1]))#adds a title for each text block alarm['trigger']='-PT30M'#triggers 30 mins before 3 times at 10 min intervals and displays the message in the description alarm['repeat']=3 alarm['duration']='PT10M' alarm['action']='DISPLAY' alarm['Description']='Time for %s %s'%(nlsplit[0],nlsplit[1])#Time for SWFR 3MX3 Lecture event.add_component(alarm)#adds the alarm to the event if 'AM' not in nlsplit[len(nlsplit)-1] and 'PM' not in nlsplit[len(nlsplit)-1] and ':' not in nlsplit[len(nlsplit)-1]:#adds the location which should be the last sentence, if it is not the last sentence it is not added event.add('location',nlsplit[len(nlsplit)-1]) event['duration']='PT%dH%dM'%(int(dur.total_seconds()//3600),int((dur.total_seconds()//60)%60))#calculates the duration from the dur variable which is a timedelta object, using total seconds between the start and end times for a textblock and simple math the hours and minuts are derived cal.add_component(event) file=open(os.path.expanduser("~/Desktop/cal.ics"),'w+')#creates the ics file file.write(cal.to_ical()) file.close()
def ical_feed(request, variant, secret_id): if variant not in ('due', 'waiting'): return HttpResponseNotFound() try: store = models.TaskStore.objects.get(secret_id=secret_id) except: return HttpResponseNotFound() if not store.ical_enabled: return HttpResponseNotFound() if variant == 'due': calendar_title = "Tasks Due" task_filter = { 'due.any': None, 'status': 'pending', } field = 'due' elif variant == 'waiting': calendar_title = "Tasks Waiting" task_filter = { 'status': 'waiting', } field = 'wait' tasks = store.client.filter_tasks(task_filter) calendar = Calendar() calendar.add('version', '2.0') calendar.add('prodid', '-//inthe.am//ical.%s//' % variant) calendar.add('X-WR-CALNAME', calendar_title) for task in tasks: if field not in task: continue event = Event() event.add('uid', task['uuid']) event.add('dtstart', task[field].date()) event.add( 'dtend', task[field].date() + datetime.timedelta(days=1) ) event.add( 'dtstamp', task.get( 'modified', task['entry'] ) ) event.add('summary', task['description']) calendar.add_component(event) return HttpResponse( calendar.to_ical(), content_type='text/calendar', )
def vevent(request, talk_id): t = get_object_or_404(Talk, pk=talk_id) event = Event() event.add('description', t.title) ical = event.to_ical response = HttpResponse(ical, mimetype='text/calendar') response['Filename'] = 'filename.ics' # IE needs this response['Content-Disposition'] = 'attachment; filename=talk-%s.ics'%t.start.strftime('%Y%m') return response
def toEvent(self): e = Event() e.add("summary", self.title + " " + self.kind) e.add("dtstamp", datetime.now()) e.add("dtstart", self.getDatetime()) e.add("duration", timedelta(hours=1)) if self.room is not None: e.add("location", self.room) return e
def render_ical(rows, schema): calendar = Calendar() for row in rows: event = Event() for key, value in row.items(): if value: event.add(key, value) calendar.add_component(event) return calendar.to_ical()
def export_schedule(crns): weekday_offset = {} for i, day in enumerate(DAYS): weekday_offset[day] = i calendar = Calendar() calendar.add('prodid', '-//YACS Course Schedule//EN') calendar.add('version', '2.0') sections = Section.objects.filter(crn__in=crns).prefetch_related('periods', 'section_times', 'section_times__period', 'course', 'semester') semester_start = datetime.datetime(sections[0].semester.year, sections[0].semester.month, 1, 0, tzinfo=pytz.timezone("America/New_York")).astimezone(pytz.utc) found = False current = datetime.datetime.utcnow() semester_end = semester_start + datetime.timedelta(150) events = list(rpi_calendars.filter_related_events(rpi_calendars.download_events(rpi_calendars.get_url_by_range(str(semester_start.date()).replace('-', ''), str(current.date()).replace('-', ''))))) events.extend(list(rpi_calendars.filter_related_events(rpi_calendars.download_events(rpi_calendars.get_url())))) days_off = [] break_start = None break_end = None for e in events: if re.search(str(sections[0].semester.name.split(' ')[0]) + ' ' + str(sections[0].semester.year), e.name) != None: semester_start = e.start found = True if re.search(".*(no classes).*", e.name.lower()) != None and found: days_off.append([e.start.date()]) if re.search(".*(spring break)|(thanksgiving).*", e.name.lower()) != None and found: break_start = e.start if re.search(".*(classes resume).*", e.name.lower()) != None and break_start != None: break_end = e.start if re.search("(.*)study-review days", str(e.name).lower()) != None and found: semester_end = e.start break length = break_end - break_start for i in range(length.days): days_off.append([(break_start + datetime.timedelta(i)).date()]) for s in sections: for p in s.periods.all(): event = Event() offset = weekday_offset[p.days_of_week[0]] - semester_start.weekday() if offset < 0: offset = 7 + offset begin = semester_start + datetime.timedelta(offset) event.add('summary', '%s - %s (%s)' % (s.course.code, s.course.name, s.crn)) event.add('dtstart', datetime.datetime(begin.year, begin.month, begin.day, p.start.hour, p.start.minute, tzinfo=pytz.timezone("America/New_York")).astimezone(pytz.utc)) event.add('dtend', datetime.datetime(begin.year, begin.month, begin.day, p.end.hour, p.end.minute, tzinfo=pytz.timezone("America/New_York")).astimezone(pytz.utc)) days = [] for d in p.days_of_week: days.append(d[:2]) event.add('rrule', dict( freq='weekly', interval=1, byday=days, until=datetime.datetime(semester_end.year, semester_end.month, semester_end.day, p.end.hour, p.end.minute, tzinfo=pytz.timezone("America/New_York")).astimezone(pytz.utc))) event.add('exdate', days_off) calendar.add_component(event) output = calendar.to_ical().replace("EXDATE", "EXDATE;VALUE=DATE") print output return output
def parse_ical_from_url(url, user): """Parses user's ical file from given URL Creates CalendarEntry-instances for each relevant VEVENT and attaches them to the given user """ response = None try: response = urllib2.urlopen(url) except urllib2.URLError: # Try to replace webcal protocol with http response = urllib2.urlopen(url.replace("webcal", "http", 1)) calendar = Calendar.from_ical(response.read()) eventlist = [component for component in calendar.walk('vevent')] now = datetime.now(pytz.utc) # Generate more events from recurrences recurrences = [] for event in eventlist: rrules = None if 'rrule' in event: rrules = event['rrule'] if rrules: duration = event[DTEND].dt - event[DTSTART].dt start = event[DTSTART].dt for recurrence_datetime in (rrulestr( rrules.to_ical(), dtstart=start).between( now, now + timedelta(days=7))): recurrence = Event() recurrence[SUMMARY] = event[SUMMARY] recurrence[LOCATION] = event[LOCATION] recurrence[STATUS] = 'CONFIRMED' recurrence.add('dtstart', recurrence_datetime) recurrence.add('dtend', recurrence_datetime + duration) recurrences.append(recurrence) eventlist += recurrences # Relevant events start from today to 7 days ahead relevanteventlist = [event for event in eventlist if (type(event[DTSTART].dt) is datetime and event[DTSTART].dt > now and event[DTSTART].dt < now + timedelta(days=7) and event[STATUS] == 'CONFIRMED' and not # Facebook participation filtering ('PARTSTAT' in event and event['PARTSTAT'] not in ['ACCEPTED', 'MAYBE']))] # Persist events to database for event in relevanteventlist: entry = create_calendarentry_from_ical_event(event) entry.user = user entry.save()
def make_ical(self): for row in self.csv_data: event = Event() event.add('summary', row[self.NAME]) event.add('dtstart', row[self.START_DATE]) event.add('dtend', row[self.END_DATE]) event.add('description', row[self.DESCRIPTION]) event.add('location', row[self.LOCATION]) self.cal.add_component(event) return self.cal
def get(self, format): events = Event.all().filter('status IN', ['approved', 'canceled']).order('start_time') url_base = 'http://' + self.request.headers.get('host', 'events.hackerdojo.com') if format == 'json': self.response.headers['content-type'] = 'application/json' events = map(lambda x: x.to_dict(summarize=True), Event.get_approved_list()) self.response.out.write(simplejson.dumps(events)) elif format == 'ics': cal = Calendar() for event in events: iev = CalendarEvent() iev.add('summary', event.name if event.status == 'approved' else event.name + ' (%s)' % event.status.upper()) # make verbose description with empty fields where information is missing ev_desc = '__Status: %s\n__Member: %s\n__Type: %s\n__Estimated size: %s\n__Info URL: %s\n__Fee: %s\n__Contact: %s, %s\n__Rooms: %s\n\n__Details: %s\n\n__Notes: %s' % ( event.status, event.owner(), event.type, event.estimated_size, event.url, event.fee, event.contact_name, event.contact_phone, event.roomlist(), event.details, event.notes) # then delete the empty fields with a regex ev_desc = re.sub(re.compile(r'^__.*?:[ ,]*$\n*',re.M),'',ev_desc) ev_desc = re.sub(re.compile(r'^__',re.M),'',ev_desc) ev_url = url_base + event_path(event) iev.add('description', ev_desc + '\n--\n' + ev_url) iev.add('url', ev_url) if event.start_time: iev.add('dtstart', event.start_time.replace(tzinfo=pytz.timezone('US/Pacific'))) if event.end_time: iev.add('dtend', event.end_time.replace(tzinfo=pytz.timezone('US/Pacific'))) cal.add_component(iev) self.response.headers['content-type'] = 'text/calendar' self.response.out.write(cal.as_string()) elif format =='rss': url_base = 'http://' + self.request.headers.get('host', 'events.hackerdojo.com') rss = PyRSS2Gen.RSS2( title = "Hacker Dojo Events Feed", link = url_base, description = "Upcoming events at the Hacker Dojo in Mountain View, CA", lastBuildDate = datetime.now(), items = [PyRSS2Gen.RSSItem( title = event.name, link = url_base + event_path(event), description = event.details, guid = url_base + event_path(event), pubDate = event.updated, ) for event in events] ) self.response.headers['content-type'] = 'application/xml' self.response.out.write(rss.to_xml())
def get_cal_event(info: CourseInfo, start_date: Union[tuple, list], *, start_week=0, end_week=1) -> Event: """返回一个 cal event :param info: 课程信息 :param start_date: 正式开学的第一天,格式为 (年,月,日) :param start_week: 开始星期的序号,0 开始 :param end_week: 结束星期的序号,0 开始 :return: Calender Event """ # 初始化 event event = Event() # 开始日期 start_time = datetime(year=start_date[0], month=start_date[1], day=start_date[2], hour=info.time[0], minute=info.time[1]) + timedelta( weeks=info.week_range[start_week] - 1, days=info.week - 1) # 一天中的开始时间 event.add('dtstart', start_time) # 一天中的结束时间 event.add('dtend', start_time + timedelta(minutes=DURATION)) # 提前通知的时间 event.add('trigger', start_time - timedelta(minutes=ADVANCE_NOTICE)) # 重复的日期,以及在哪一周结束 event.add( 'rrule', { 'freq': 'weekly', 'interval': '1', 'byday': info.week_text, 'until': start_time + timedelta(weeks=(info.week_range[end_week] - info.week_range[start_week])) }) # 课程名 event.add('summary', info.name) # 上课地址 event.add('location', info.classroom) # 其余课程信息 event.add('description', f'课程号:{info.id}\n教师:{info.teacher}\n周次:{info.week_range_text}') return event
) result = pattern.findall(html.text) for exp in result: expName = exp[1] expStart = exp[4] expEnd = exp[6] expDate = exp[8] expClassroom = exp[9] expList.append([expName, expStart, expEnd, expDate, expClassroom]) return expList source = input("请确保当前处于校园网或翼讯网络环境下,回车继续...") expList = get_experiments() cal = Calendar() for exp in expList: e = Event() e.add("description", exp[0] + ' @ ' + exp[4]) e.add('summary', exp[0] + ' @ ' + exp[4]) start = datetime.strptime(exp[3] + ' ' + exp[1], '%m/%d/%Y %H:%M') e.add('dtstart', start) end = datetime.strptime(exp[3] + ' ' + exp[2], '%m/%d/%Y %H:%M') e.add('dtend', end) e.add('location', exp[4]) cal.add_component(e) f = open(credentials.IDS_USERNAME + '_physicsExperiment.ics', 'wb') f.write(cal.to_ical()) f.close() print("物理实验日历文件已保存到 " + credentials.IDS_USERNAME + '_physicsExperiment.ics')
def __create_event(self, e, date, title_prop, dateprop, properties_by_slug, categories_property, timezones): self.__create_timezone(date, timezones) name = e.get_property(title_prop["id"]) clean_props = {"NAME": name} event = Event() tzid = f";tzid={date.timezone}" if date.timezone != None else "" event.add("uid", e.id) event.add("dtstamp", self.__ical_datetime(e.created), encode=0) event.add(f"dtstart{tzid}", self.__ical_datetime(date.start), encode=0) if date.end is not None: event.add(f"dtend{tzid}", self.__ical_datetime(date.end), encode=0) desc = "🔗 " + e.get_browseable_url() + "\n\n" desc += "__________\n\n" for k, v in e.get_all_properties().items(): if k != dateprop["slug"] and k != categories_property: name = properties_by_slug[k]["name"] desc += f"{name}: {v}\n" clean_props[name] = v title = f"[{clean_props[categories_property]}] {clean_props['NAME']}" event.add("summary", title) event.add("description", desc) return event
def send_to_zimbra(act, created_in_redtail): # Create .ics file and place them into calendar c = Calendar() e = Event() if created_in_redtail: act['uid'] = '{}_{}'.format(act['uid'], re.search(r'\d+', act['dtstart']).group()) e.add('uid', act['uid']) e.add('uid', act['uid']) e.add('summary', act['summary']) e.add('dtstart', redtail.parse_date(act['dtstart'], act['allday'], user_timezone)) e.add('dtend', redtail.parse_date(act['dtend'], act['allday'], user_timezone)) e.add('DESCRIPTION', act['desc']) e.add('X-MICROSOFT-CDO-ALLDAYEVENT', act['allday']) c.add_component(e) with open('{}/to_zimbra_{}.ics'.format(directory, act['uid']), 'w+') as f: f.write(c.to_ical()) # Sends ICS file to Zimbra to import the appointment with open('{}/to_zimbra_{}.ics'.format(directory, act['uid']), 'rb') as f: r = requests.post( zimbra_url + '/calendar?fmt=ics', auth=(zimbra_username, zimbra_password), files={'{}/to_zimbra_{}.ics'.format(directory, act['uid']): f}) if r.status_code == requests.codes.ok: print 'Sent "{}" to Zimbra'.format(act['summary']) return act['uid']
for title in movies: details = movies[title] screening = details.get('Screening Date') if not screening: continue times = dt_re.findall(screening) for d, m, y, H, M in times: event = Event() description = '' for k, v in details.items(): if not isinstance(v, unicode): v = unicode(v, encoding='utf-8') v = ' '.join(v.splitlines()) description += ' %s: %s' % (k, v) event.add('summary', title.replace(',', '\,').replace(';', '\;')) event.add('description', description.replace(',', '\,').replace(';', '\;')) event.add( 'dtstart', datetime(int('20' + y), int(m), int(d), int(H), int(M), 0, tzinfo=tz)) event.add( 'dtend', datetime(int('20' + y), int(m),
def generate_ics_for_event(uid, title, course_name, now, start, organizer_name, organizer_email): """ Generates an ics-formatted bytestring for the given assignment information. To pretty-print the bytestring, do: `ics.decode('utf8').replace('\r\n', '\n')` """ # icalendar library: https://icalendar.readthedocs.io/en/latest/ # ics format spec: https://tools.ietf.org/html/rfc2445 # ics conventions spec: https://tools.ietf.org/html/rfc5546 organizer = vCalAddress('mailto:' + organizer_email) organizer.params['cn'] = vText(organizer_name) event = Event() event.add('uid', uid) event.add('dtstamp', now) event.add('organizer', organizer, encode=0) event.add('summary', title) event.add('description', HTML(_('{assignment} is due for {course}.')).format(assignment=title, course=course_name)) event.add('dtstart', start) event.add('duration', timedelta(0)) event.add('transp', 'TRANSPARENT') # available, rather than busy cal = Calendar() cal.add('prodid', '-//Open edX//calendar_sync//EN') cal.add('version', '2.0') cal.add('method', 'REQUEST') cal.add_component(event) return cal.to_ical()
tzc = icalendar.Timezone() tzc.add('tzid', 'America/Denver') tzc.add_component(tzd) tzc.add_component(tzs) cal.add_component(tzc) return cal cal = InitCalWithPrelims() seq = 0 event = Event() params = {"TZID":"America/Denver"} event.add('dtstart', datetime.datetime(2018, 8, 21, 10, 0, 0), params) event.add('dtend', datetime.datetime(2018, 8, 21, 11, 0, 0), params) event.add('sequence', seq) event.add('summary', 'Test publish update 1') event.add('uid', '2cba2310-8246-4408-985c-5b2bb067d248') cal.add_component(event) event = Event() params = {"TZID":"America/Denver"} event.add('dtstart', datetime.datetime(2018, 8, 22, 10, 0, 0), params) event.add('dtend', datetime.datetime(2018, 8, 22, 11, 0, 0), params) event.add('sequence', seq) event.add('summary', 'Test publish update 2') event.add('uid', '0dab10b8-e138-4ea4-aba3-e4816f912b35') cal.add_component(event)
def getEvent(self): event = Event() alarm = Alarm() alarm.add('UID', uuid.uuid4()) alarm.add('TRIGGER', timedelta(minutes=-15)) alarm.add('ACTION', 'AUDIO') event.add('summary', self.c_name) event.add('dtstart', self.getStartTime(self.time_zone)) event.add('dtend', self.getEndTime(self.time_zone)) event.add('dtstamp', datetime.now(tz=utc)) event.add('location', self.classroom + ' ' + self.c_teacher) event['uid'] = str(uuid.uuid4()) event.add( 'rrule', { 'freq': 'weekly', 'interval': str(self.step), 'count': str(self.end_week - self.start_week + 1) }) event.add('description', self.getDescription()) event.add_component(alarm) return event
mail_date, mail_subject)) continue # End of if (name is None) or ... cal = Calendar() dates = [] for shift_obj in shifts_list: role = shift_obj.role start_date_time_obj = shift_obj.start_date_time_obj end_date_time_obj = shift_obj.end_date_time_obj dates.append(shift_obj.day) event = Event() event.add('summary', role) event.add('dtstart', start_date_time_obj) event.add('dtend', end_date_time_obj) #event.add('description', "Sample Description") event.add('location', "North Shore Dog, Danvers MA 01923") cal.add_component(event) # End of for shift_result in results_shift # End of for shift_obj in shifts_list f = open(FILENAME, 'wb') f.write(cal.to_ical()) f.close()
import feedparser DATE_FORMAT = "%a, %d %b %Y %H:%M:%S GMT" feed = feedparser.parse("http://www.co.frederick.va.us/fredcocal.xml") cal = Calendar() cal.add('VERSION', '2.0') cal.add('PRODID', 'feed2ical 0.1') cal.add('X-WR-CALNAME;VALUE=TEXT', feed.channel.title) cal.add('X-WR-CALDESC;VALUE=TEXT', feed.channel.description) for item in feed['items']: event_date = datetime.strptime(item.caldate, DATE_FORMAT).replace(tzinfo=LocalTimezone()) published_date = datetime.strptime( item.updated, DATE_FORMAT).replace(tzinfo=LocalTimezone()) event = Event() event.add('UID', item.guid) event.add('SUMMARY', item.title) event.add('DESCRIPTION', item.description) event.add('URL;VALUE=URI', item.link) event.add('DTSTART', event_date.date()) event.add('DTEND', event_date.date()) event.add('DTSTAMP', published_date) cal.add_component(event) sys.stdout.write(cal.as_string())
CALENDAR_URL = "https://www.seiyu.co.jp/service/5off/" if __name__ == '__main__': html = urllib.request.urlopen(CALENDAR_URL).read().decode("utf-8") bs = BeautifulSoup(html, "lxml") c = Calendar() c.add("version", "2.0") year = datetime.today().year base_month = datetime.today().month items = bs.find_all("ul", class_="off_calendar_list") for item in items: month = int( item.find("span", class_="off_calendar_month").text.strip("/")) if month < base_month: base_month = month year = year + 1 for i in item.find_all("span", class_="off_calendar_day"): day = int(i.text) e = Event() e.add("summary", "西友 5% OFF 開催日") e.add("dtstart", vDate(datetime(year, month, day))) c.add_component(e) print(c.to_ical().decode("utf-8").strip())
def schedule_ical(): schedule = _get_scheduled_proposals(request.args) title = 'EMF {}'.format(event_start().year) cal = Calendar() cal.add('summary', title) cal.add('X-WR-CALNAME', title) cal.add('X-WR-CALDESC', title) cal.add('version', '2.0') for event in schedule: cal_event = Event() cal_event.add('uid', event['id']) cal_event.add('summary', event['title']) cal_event.add('description', event['description']) cal_event.add('location', event['venue']) cal_event.add('dtstart', event['start_date']) cal_event.add('dtend', event['end_date']) cal.add_component(cal_event) return Response(cal.to_ical(), mimetype='text/calendar')
def updateHourly(self): try: data = json.loads(requests.get("http://api.wunderground.com/api/" + WUNDERGROUND_API + "/hourly10day/q/pws:IBERLIN1705.json").content) except: print("Error in hourly update") return False for e in data['hourly_forecast']: hour = int(e['FCTTIME']['hour']) day = int(e['FCTTIME']['mday']) month = int(e['FCTTIME']['mon']) year = int(e['FCTTIME']['year']) rain = float(e['qpf']['metric']) snow = float(e['snow']['metric']) temp = float(e['temp']['metric']) wind = float(e['wspd']['metric']) dewpoint = float(e['dewpoint']['metric']) uvi = float(e['uvi']) humidity = float(e['humidity']) if rain > 0.0: #ical event = Event() event.add('summary', "Rain: %.0f mm" % (rain)) event.add('dtstart', datetime(year, month, day, hour, 0, 0, 0, timezone('Europe/Berlin'))) event.add('dtend', datetime(year, month, day, hour, 59, 0, 0, timezone("Europe/Berlin"))) event.add('description', DESC) self._newcal.add_component(event) #google ge = EVENT ge['summary'] = "Rain: %.0f mm" % (rain) ge['start']['dateTime'] = '%02d-%02d-%02dT%02d:00:00' % (year, month, day, hour) ge['end' ]['dateTime'] = '%02d-%02d-%02dT%02d:59:00' % (year, month, day, hour) self.addCalendarEnties(ge) if snow > 0.0: #ical event = Event() event.add('summary', "Snow: %.0f cm" % (snow)) event.add('dtstart', datetime(year, month, day, hour, 0, 0, 0, timezone('Europe/Berlin'))) event.add('dtend', datetime(year, month, day, hour, 59, 0, 0, timezone("Europe/Berlin"))) event.add('description', DESC) self._newcal.add_component(event) #google ge = EVENT ge['summary'] = "Snow: %.0f cm" % (snow) ge['start']['dateTime'] = '%02d-%02d-%02dT%02d:00:00' % (year, month, day, hour) ge['end' ]['dateTime'] = '%02d-%02d-%02dT%02d:59:00' % (year, month, day, hour) self.addCalendarEnties(ge) if uvi > 4.0: #ical event = Event() event.add('summary', "UV-Index: %.0f" % (uvi)) event.add('dtstart', datetime(year, month, day, hour, 0, 0, 0, timezone('Europe/Berlin'))) event.add('dtend', datetime(year, month, day, hour, 59, 0, 0, timezone("Europe/Berlin"))) event.add('description', DESC) self._newcal.add_component(event) #google ge = EVENT ge['summary'] = "UV-Index: %.0f" % (uvi) ge['start']['dateTime'] = '%02d-%02d-%02dT%02d:00:00' % (year, month, day, hour) ge['end' ]['dateTime'] = '%02d-%02d-%02dT%02d:59:00' % (year, month, day, hour) self.addCalendarEnties(ge) if temp > 30.0 or temp < -10.0: #ical event = Event() event.add('summary', "Temp: %.0f C" % (temp)) event.add('dtstart', datetime(year, month, day, hour, 0, 0, 0, timezone('Europe/Berlin'))) event.add('dtend', datetime(year, month, day, hour, 59, 0, 0, timezone("Europe/Berlin"))) event.add('description', DESC) self._newcal.add_component(event) #google ge = EVENT ge['summary'] = "Temp: %.0f C" % (temp) ge['start']['dateTime'] = '%02d-%02d-%02dT%02d:00:00' % (year, month, day, hour) ge['end' ]['dateTime'] = '%02d-%02d-%02dT%02d:59:00' % (year, month, day, hour) self.addCalendarEnties(ge) if (temp - dewpoint) < 3: #ical event = Event() event.add('summary', "Muggy: %.0f %%" % (humidity)) event.add('dtstart', datetime(year, month, day, hour, 0, 0, 0, timezone('Europe/Berlin'))) event.add('dtend', datetime(year, month, day, hour, 59, 0, 0, timezone("Europe/Berlin"))) event.add('description', DESC) self._newcal.add_component(event) #google ge = EVENT ge['summary'] = "Muggy: %.0f %%" % (humidity) ge['start']['dateTime'] = '%02d-%02d-%02dT%02d:00:00' % (year, month, day, hour) ge['end' ]['dateTime'] = '%02d-%02d-%02dT%02d:59:00' % (year, month, day, hour) self.addCalendarEnties(ge) if wind > 23.0: #ical event = Event() event.add('summary', "Wind: %.1f km/h" % (wind)) event.add('dtstart', datetime(year, month, day, hour, 0, 0, 0,timezone('Europe/Berlin'))) event.add('dtend', datetime(year, month, day, hour, 59, 0, 0,timezone("Europe/Berlin"))) event.add('description', DESC) self._newcal.add_component(event) #google ge = EVENT ge['summary'] = "Wind: %.1f km/h" % (wind) ge['start']['dateTime'] = '%02d-%02d-%02dT%02d:00:00' % (year, month, day, hour) ge['end' ]['dateTime'] = '%02d-%02d-%02dT%02d:59:00' % (year, month, day, hour) self.addCalendarEnties(ge) return True
def calendar_ical(request, token, userid): """ Return an iCalendar for this user, authenticated by the token in the URL """ local_tz = pytz.timezone(settings.TIME_ZONE) utc = pytz.utc user = get_object_or_404(Person, userid=userid) # make sure the token in the URL (32 hex characters) matches the token stored in the DB config = _get_calendar_config(user) if 'token' not in config or config['token'] != token: # no token set or wrong token provided return NotFoundResponse(request) #else: # authenticated now = datetime.datetime.now() start = local_tz.localize(now - datetime.timedelta(days=180)) end = local_tz.localize(now + datetime.timedelta(days=365)) cal = Calendar() cal.add('version', '2.0') cal.add('prodid', '-//SFU CourSys//courses.cs.sfu.ca//') cal.add('X-PUBLISHED-TTL', 'PT1D') for data in _calendar_event_data(user, start, end, local_tz, dt_string=False): e = Event() e['uid'] = str(data['id']) e.add('summary', data['title']) e.add('dtstart', _ical_datetime(utc, data['start'])) e.add('dtend', _ical_datetime(utc, data['end'])) if data['category'] in ('DUE', 'HOLIDAY'): # these shouldn't be "busy" on calendars e.add('transp', 'TRANSPARENT') else: e.add('transp', 'OPAQUE') # spec says no TZID on UTC times if 'TZID' in e['dtstart'].params: del e['dtstart'].params['TZID'] if 'TZID' in e['dtend'].params: del e['dtend'].params['TZID'] e.add('categories', data['category']) if 'url' in data: e.add('url', data['url']) if 'location' in data: e.add('location', data['location']) cal.add_component(e) resp = HttpResponse(cal.to_ical(), content_type="text/calendar") return resp
def calendar_add(caldav_conn, args): cal = Calendar() cal.add( 'prodid', '-//{author_short}//{product}//{language}'.format( author_short=__author_short__, product=__product__, language=args.language)) cal.add('version', '2.0') event = Event() ## TODO: timezone ## read timestamps from arguments event_spec = args.event_time.split('+') if len(event_spec) > 3: raise ValueError( 'Invalid event time "%s" - can max contain 2 plus-signs' % args.event_time) elif len(event_spec) == 3: event_time = '%s+%s' % tuple(event_spec[0:2]) event_duration = event_spec[2] elif len(event_spec) == 2 and not event_spec[1][-1:] in time_units: event_time = '%s+%s' % tuple(event_spec[0:2]) event_duration = '1h' elif len(event_spec) == 2: event_time = '%s' % event_spec[0] event_duration = event_spec[1] else: event_time = event_spec[0] event_duration = '1h' ## TODO: error handling event_duration_secs = int( event_duration[:-1]) * time_units[event_duration[-1:]] dtstart = dateutil.parser.parse(event_spec[0]) if args.whole_day: if event_spec[1][-1:] != 'd': raise ValueError( 'Duration of whole-day event must be multiple of 1d') duration = int(event_spec[1][:-1]) dtstart = dateutil.parser.parse(event_spec[0]) dtend = dtstart + timedelta(days=duration) event.add('dtstart', _date(dtstart.date())) event.add('dtend', _date(dtend.date())) else: event.add('dtstart', dtstart) ## TODO: handle duration and end-time as options. default 3600s by now. event.add('dtend', dtstart + timedelta(0, event_duration_secs)) event.add('dtstamp', _now()) uid = uuid.uuid1() event.add('uid', str(uid)) for attr in vcal_txt_one + vcal_txt_many: if attr == 'summary': continue val = getattr(args, 'set_' + attr) if val: event.add(attr, val) event.add('summary', ' '.join(args.summary)) cal.add_component(event) _calendar_addics(caldav_conn, cal.to_ical(), uid, args) print("Added event with uid=%s" % uid)
def add_event(self, uid, start, end, summary, **kwargs): """Ad an event to the calendar""" if isinstance(start, str): start = getDatetimeFromString(start) if isinstance(end, str): end = getDatetimeFromString(end) ev = Event() ev.add('uid', uid) ev.add('dtstart', start) ev.add('dtend', end) ev.add('summary', summary) datestamp = kwargs.pop('dtstamp', datetime.utcnow()) ev.add('DTSTAMP', datestamp) for key, value in kwargs.items(): if value: ev.add(key, value) self.add_component(ev)
e.add('last-modified', now) e.add('sequence', 0) for row in reader: if first: first = False continue event, _, _, _, _, _, _, _, _, date, weekno, weeks, lr, ltr, dev, ff, _, _ = row dt = datetime.strptime(date, '%Y-%m-%d').replace(tzinfo=timezone.utc) + timedelta(hours=12) if 'FF' in event: e = Event() e.add('summary', 'QGIS Feature Freeze {}'.format(dev)) e.add('dtstart', dt) e.add('dtend', dt) adduid(e, 'ff-{}@qgis.org'.format(dev)) cal.add_component(e) if 'SF' in event: e = Event() e.add('summary', 'QGIS Soft Freeze', dev) e.add('dtstart', dt) e.add('dtend', dt) adduid(e, 'sf-{}@qgis.org'.format(dev)) cal.add_component(e) if ltr: label = 'Extra point release' if event == 'EPR' else 'Point release'
endTime = tempStartDate + ' ' + endTime endTime = datetime.strptime(endTime, '%Y-%m-%d %H:%M:%S') startTime = tempStartDate + ' ' + startTime startTime = datetime.strptime(startTime, '%Y-%m-%d %H:%M:%S') endDate = classesInfo[classId]['end_date'] + ' 00:00:00' endDate = datetime.strptime(endDate, '%Y-%m-%d %H:%M:%S') days = (endDate - startTime).days print 'startDate:', startTime print 'startDateEndTime', endTime print 'endDate:', endDate print 'days:', days weeks = days / 7 + 1 event = Event() if (classesInfo[classId]['topic'] != None): event.add( 'summary', classesInfo[classId]['topic'] + classesInfo[classId]['title']) else: event.add('summary', classesInfo[classId]['title']) event.add('dtstart', startTime) event.add('dtend', endTime) event.add('rrule', { 'freq': 'weekly', 'count': weeks }) event.add('location', classesInfo[classId]['room']) cal.add_component(event) print cal f = open('../../../courses.ics', 'wb') f.write(cal.to_ical())
def mkevent(data, cal, dt, duration, alarm=False, isDebug=False): if not data[0]: assert not (data[1] or data[2] or data[3] or data[4]) return weeks, week_day, all_week, classes = get_schedule(data, isDebug) event_class = Event() event_class.add('SUMMARY', data[0]) if data[3] is not None: dsp = data[3] if data[4] is not None: dsp = "教师:" + data[4] + "\n教学班号:" + data[1] else: dsp = "教学班号:" + data[1] event_class.add('DESCRIPTION', dsp) for start_class, end_class in classes: for start_week, end_week in weeks: event = event_class.copy() if all_week is False: count = int(end_week) - int(start_week) + 1 event.add("RRULE", {"freq": "weekly", "count": count}) class_start_date = dt + \ datetime.timedelta(weeks=int(start_week) - 1, days=week_dic[week_day] - 1) class_start_time = datetime.timedelta( hours=time_dict[int(start_class)][0][0], minutes=time_dict[int(start_class)][0][1]) class_end_time = datetime.timedelta( hours=time_dict[int(end_class)][1][0], minutes=time_dict[int(end_class)][1][1]) dtstart = class_start_date + class_start_time dtend = class_start_date + class_end_time namespace = uuid.UUID( bytes=int(dtstart.timestamp()).to_bytes(length=8, byteorder='big') + int(dtend.timestamp()).to_bytes(length=8, byteorder='big')) else: dtstart = ( dt + datetime.timedelta(weeks=int(start_week) - 1)).date() dtend = (dt + datetime.timedelta(weeks=int(end_week))).date() namespace = uuid.UUID( bytes=int(dtstart.toordinal()).to_bytes(length=8, byteorder='big') + int(dtend.toordinal()).to_bytes(length=8, byteorder='big')) add_datetime(event, 'DTEND', dtend) add_datetime(event, 'DTSTART', dtstart) event.add('UID', uuid.uuid3(namespace, data[0] + "-" + data[1])) event.add('DTSTAMP', datetime.datetime.now()) ''' TRIGGER:-PT24H REPEAT:1 DURATION:PT15M ACTION:DISPLAY ''' if alarm: event.add('TRIGGER', datetime.timedelta(minutes=0 - duration)) event.add('REPEAT', "1") event.add('ACTION', "DISPLAY") cal.add_component(event)
def get_ics_file(self, events_exported, partner): """ Returns iCalendar file for the event invitation. @param event: event object (browse record) @return: .ics file content """ ics = Event() event = self[0] #~ raise Warning(self.env.cr.dbname) #~ The method below needs som proper rewriting to avoid overusing libraries. def ics_datetime(idate, allday=False): if idate: if allday: return str(vDatetime(datetime.fromtimestamp(mktime(strptime(idate, DEFAULT_SERVER_DATETIME_FORMAT)))).to_ical())[:8] else: return vDatetime(datetime.fromtimestamp(mktime(strptime(idate, DEFAULT_SERVER_DATETIME_FORMAT)))).to_ical() + 'Z' return False #~ try: #~ # FIXME: why isn't this in CalDAV? #~ import vobject #~ except ImportError: #~ return res #~ cal = vobject.iCalendar() #~ event = cal.add('vevent') if not event.start or not event.stop: raise osv.except_osv(_('Warning!'), _("First you have to specify the date of the invitation.")) ics['summary'] = event.name if event.description: ics['description'] = event.description if event.location: ics['location'] = event.location if event.rrule: ics['rrule'] = event.rrule #~ ics.add('rrule', str(event.rrule), encode=0) #~ raise Warning(ics['rrule']) if event.alarm_ids: for alarm in event.alarm_ids: if alarm.type == 'notification': valarm = Alarm() valarm.add('ACTION', 'DISPLAY') if alarm.interval == 'days': delta = timedelta(days=alarm.duration) elif alarm.interval == 'hours': delta = timedelta(hours=alarm.duration) elif alarm.interval == 'minutes': delta = timedelta(minutes=alarm.duration) trigger = valarm.add('TRIGGER', -delta) #fields.Datetime.from_string(event.start) - valarm.add('DESCRIPTION', event.name) ics.add_component(valarm) if event.attendee_ids: for attendee in event.attendee_ids: attendee_add = ics.get('attendee') attendee_add = attendee.cn and ('CN=' + attendee.cn) or '' if attendee.cn and attendee.email: attendee_add += ':' attendee_add += attendee.email and ('MAILTO:' + attendee.email) or '' ics.add('attendee', attendee_add, encode=0) if events_exported: event_not_found = True for event_comparison in events_exported: #~ raise Warning('event_comparison = %s ics = %s' % (event_comparison, ics)) if str(ics) == event_comparison: event_not_found = False break if event_not_found: events_exported.append(str(ics)) ics['uid'] = '%s@%s-%s' % (event.id, self.env.cr.dbname, partner.id) ics['created'] = ics_datetime(strftime(DEFAULT_SERVER_DATETIME_FORMAT)) tmpStart = ics_datetime(event.start, event.allday) tmpEnd = ics_datetime(event.stop, event.allday) if event.allday: ics['dtstart;value=date'] = tmpStart else: ics['dtstart'] = tmpStart if tmpStart != tmpEnd or not event.allday: if event.allday: ics['dtend;value=date'] = str(vDatetime(datetime.fromtimestamp(mktime(strptime(event.stop, DEFAULT_SERVER_DATETIME_FORMAT))) + timedelta(hours=24)).to_ical())[:8] else: ics['dtend'] = tmpEnd return [ics, events_exported] else: events_exported.append(str(ics)) ics['uid'] = '%s@%s-%s' % (event.id, self.env.cr.dbname, partner.id) ics['created'] = ics_datetime(strftime(DEFAULT_SERVER_DATETIME_FORMAT)) tmpStart = ics_datetime(event.start, event.allday) tmpEnd = ics_datetime(event.stop, event.allday) if event.allday: ics['dtstart;value=date'] = tmpStart else: ics['dtstart'] = tmpStart if tmpStart != tmpEnd or not event.allday: if event.allday: ics['dtend;value=date'] = str(vDatetime(datetime.fromtimestamp(mktime(strptime(event.stop, DEFAULT_SERVER_DATETIME_FORMAT))) + timedelta(hours=24)).to_ical())[:8] else: ics['dtend'] = tmpEnd return [ics, events_exported]
data = scraperwiki.sqlite.select("* from HamDemScraper.swdata") cal = Calendar() cal.add('version', '2.0') cal.add('prodid', '-//Google Inc//Google Calendar 70.9054//EN') cal.add('calscale', 'GREGORIAN') cal.add('method', 'PUBLISH') cal.add('X-WR-CALNAME', 'Hamilton County Democratic Party Events') cal.add('X-WR-TIMEZONE', 'America/Detroit') cal.add('X-ORIGINAL-URL', 'http://scraperwikiviews.com/run/torontoca_events_calendar_ical/') for row_num, ev in enumerate(data): event = Event() event.add('summary', ev['name'].replace(",","\,")) event.add('description', ev['description'].replace(",","\,").replace(";","\;")) startdt = enddt = datetime.datetime.strptime(ev['date'], "%Y-%m-%d") event.add('dtstart;VALUE=DATE', vDate(startdt).ical()) event.add('DURATION', "PT1H0M0S") event.add('dtstamp;VALUE=DATE-TIME', vDatetime(startdt).ical()) event.add('uid', str(row_num)+"@toronto-events") event.add('class', 'PUBLIC') cal.add_component(event) scraperwiki.utils.httpresponseheader("Content-Type", "text/calendar") scraperwiki.utils.httpresponseheader("Content-Disposition", "inline; filename=ham_dems.ics")
def get_ics_of_events(request): cal = Calendar() cal.add('prodid', 'Hacker Agenda') cal.add('version', '2.0') for event in filter_events(request=request, queryset=Event.objects.all()): ics_event = ICSEvent() ics_event.add('summary', '%s [%s]' % (event.title, event.source)) if event.start.hour == 0 and event.start.minute == 0: ics_event.add('dtstart', event.start.date()) else: ics_event.add('dtstart', event.start) if event.end: ics_event.add('dtend', event.end) else: ics_event.add('dtend', event.start + timedelta(hours=3)) ics_event.add('dtstamp', event.start) ics_event['uid'] = event.url cal.add_component(ics_event) return HttpResponse(cal.to_ical(), mimetype="text/calendar")
def calendar(self, request, season, club=None, division=None, team=None, **kwargs): if season.disable_calendar: # The GONE response informs client that they should remove this resource # from their cache. When a calendar has been added to user's mobile device # they may never look at it again, but we continue to process the requests # which can have poor performance. Try to influence a cleanup of clients. return HttpResponseGone() if team is not None: matches = team.matches elif division is not None: matches = division.matches elif club is not None: matches = club.matches.filter(stage__division__season=season) else: matches = season.matches # Do not include matches which have not had the time scheduled matches = matches.exclude(datetime__isnull=True) # Perform select_related to reduce extra queries matches = matches.select_related( "stage__division__season__competition") # Reduce the size of the data set to return from the database matches = matches.defer( "date", "time", "home_team__copy", "home_team__names_locked", "home_team__order", "home_team__short_title", "home_team__timeslots_after", "home_team__timeslots_before", "home_team_score", "away_team__copy", "away_team__names_locked", "away_team__order", "away_team__short_title", "away_team__timeslots_after", "away_team__timeslots_before", "away_team_score", "bye_processed", "evaluated", "external_identifier", "forfeit_winner", "include_in_ladder", "is_bye", "is_forfeit", "is_washout", "rank_importance", "videos", "stage__division__season__competition__copy", "stage__division__season__competition__enabled", "stage__division__season__competition__order", "stage__division__season__competition__rank_importance", "stage__division__season__competition__short_title", "stage__division__season__competition__short_title", "stage__division__season__competition__slug_locked", "stage__division__season__competition__slug_locked", "stage__division__season__competition__title", "stage__division__season__complete", "stage__division__season__copy", "stage__division__season__disable_calendar", "stage__division__season__enabled", "stage__division__season__hashtag", "stage__division__season__mode", "stage__division__season__mvp_results_public", "stage__division__season__order", "stage__division__season__rank_importance", "stage__division__season__short_title", "stage__division__season__slug_locked", "stage__division__season__start_date", "stage__division__season__statistics", "stage__division__season__timezone", "stage__division__bonus_points_formula", "stage__division__copy", "stage__division__draft", "stage__division__forfeit_against_score", "stage__division__forfeit_for_score", "stage__division__games_per_day", "stage__division__include_forfeits_in_played", "stage__division__order", "stage__division__points_formula", "stage__division__rank_division", "stage__division__rank_importance", "stage__division__short_title", "stage__division__slug_locked", "stage__division__sportingpulse_url", "stage__carry_ladder", "stage__copy", "stage__follows", "stage__keep_ladder", "stage__keep_mvp", "stage__order", "stage__rank_importance", "stage__scale_group_points", "stage__short_title", "stage__slug_locked", ) # Remove any matches that are part of a draft division unless being viewed # by a superuser. if not request.user.is_superuser: matches = matches.exclude(stage__division__draft=True) # For development server turn back plain text to make debugging easier if settings.DEBUG: content_type = "text/plain" else: content_type = "text/calendar" response = HttpResponse(content_type=content_type) cal = Calendar() cal.add("prodid", "-//Tournament Control//%s//" % request.get_host()) cal.add("version", "2.0") for match in matches.order_by("datetime", "play_at"): event = Event() event["uid"] = match.uuid.hex event.add("summary", match.title) event.add("location", f"{match.stage.division.title} ({match.stage.title})") event.add("dtstart", match.datetime) # FIXME match duration should not be hardcoded event.add("dtend", match.datetime + timedelta(minutes=45)) # FIXME should be the last modified time of the match event.add("dtstamp", timezone.now()) try: # Determine the resource uri to the detailed match view uri = reverse( "competition:match", kwargs={ "match": match.pk, "division": match.stage.division.slug, "season": match.stage.division.season.slug, "competition": match.stage.division.season.competition.slug, }, ) except NoReverseMatch: LOG.exception("Unable to resolve url for %r", match) else: # Combine the resource uri with our current request context event.add("description", request.build_absolute_uri(uri)) cal.add_component(event) response.write(cal.to_ical()) return response
def favourites_ical(): code = request.args.get('token', None) user = None if code: user = User.get_by_checkin_code(app.config.get('FEED_SECRET_KEY'), str(code)) if not current_user.is_anonymous: user = current_user if not user: abort(404) schedule = _get_scheduled_proposals(request.args, override_user=user) title = 'EMF {} Favourites for {}'.format(event_start().year, user.name) cal = Calendar() cal.add('summary', title) cal.add('X-WR-CALNAME', title) cal.add('X-WR-CALDESC', title) cal.add('version', '2.0') for event in schedule: if not event['is_fave']: continue cal_event = Event() cal_event.add('uid', event['id']) cal_event.add('summary', event['title']) cal_event.add('description', event['description']) cal_event.add('location', event['venue']) cal_event.add('dtstart', event['start_date']) cal_event.add('dtend', event['end_date']) cal.add_component(cal_event) return Response(cal.to_ical(), mimetype='text/calendar')
def make_calfeed(the_title, the_events, the_language, the_uid): """ construct an ical-compliant stream from a list of events """ def _make_summary(event): """ makes the summary: the title, plus band name and status """ return f'{event.band.name}:{event.title} ({GigStatusChoices(event.status).label})' def _make_description(event): """ description is the details, plus the setlist """ deets = event.details if event.details else '' setlist = event.setlist if event.setlist else '' space = '\n\n' if deets and setlist else '' return f'{deets}{space}{setlist}' # set up language cal = Calendar() with translation.override(the_language): cal.add('prodid', '-//Gig-o-Matic//gig-o-matic.com//') cal.add('version', '2.0') cal.add('X-WR-CALNAME', the_title) cal.add('X-WR-CALDESC', '{0} {1}'.format(_('Gig-o-Matic calendar for'), the_title)) for e in the_events: with timezone.override(e.band.timezone): event = Event() event.add('dtstamp', timezone.now()) event.add('uid', e.cal_feed_id) event.add('summary', _make_summary(e)) event.add('dtstart', e.date) event.add( 'dtend', e.enddate if e.enddate else e.date + timedelta(hours=1)) event.add('description', _make_description(e)) event.add('location', e.address) event.add('url', 'http://{0}/gig/{1}'.format(URL_BASE, e.id)) # todo don't hardwire the URL # todo go2 also has sequence:0, status:confirmed, and transp:opaque attributes - need those? cal.add_component(event) return cal.to_ical()
def main(): city_name = sys.argv[1] latitude = sexastr2deci(sys.argv[2]) longitude = sexastr2deci(sys.argv[3]) tz = sys.argv[4] start_year = int(sys.argv[5]) year = start_year jd = swisseph.julday(year, 1, 1, 0) jd_start = jd if len(sys.argv) == 7: script = sys.argv[6] else: script = 'deva' #Default script is devanagari swisseph.set_sid_mode(swisseph.SIDM_LAHIRI) #Force Lahiri Ayanamsha sun_month_day = jd - get_last_dhanur_transit(jd, latitude, longitude) month_start_after_set = 0 template_file = open('cal_template_compre.tex') template_lines = template_file.readlines() for i in range(0, len(template_lines) - 3): print template_lines[i][:-1] samvatsara_id = (year - 1568) % 60 + 1 #distance from prabhava samvatsara_names = '%s–%s' % (year_names[script][samvatsara_id], year_names[script][(samvatsara_id % 60) + 1]) new_yr = mesha_sankranti[script] + '~(' + year_names[script][ (samvatsara_id % 60) + 1] + '-' + samvatsara[script] + ')' print '\\mbox{}' print '{\\font\\x="Candara" at 60 pt\\x %d\\\\[0.5cm]}' % year print '\\mbox{\\font\\x="Sanskrit 2003:script=deva" at 48 pt\\x %s}\\\\[0.5cm]' % samvatsara_names print '{\\font\\x="Candara" at 48 pt\\x \\uppercase{%s}\\\\[0.5cm]}' % city_name print '\hrule' #INITIALISE VARIABLES jd_sunrise = [None] * 368 jd_sunset = [None] * 368 jd_moonrise = [None] * 368 longitude_moon = [None] * 368 longitude_sun = [None] * 368 longitude_sun_set = [None] * 368 sun_month_id = [None] * 368 sun_month = [None] * 368 sun_month_rise = [None] * 368 moon_month = [None] * 368 month_data = [None] * 368 tithi_data_string = [None] * 368 tithi_sunrise = [None] * 368 nakshatram_data_string = [None] * 368 nakshatram_sunrise = [None] * 368 karanam_data_string = [None] * 368 karanam_sunrise = [None] * 368 yogam_data_string = [None] * 368 yogam_sunrise = [None] * 368 weekday = [None] * 368 sunrise = [None] * 368 sunset = [None] * 368 madhya = [None] * 368 rahu = [None] * 368 yama = [None] * 368 festival_day_list = {} festivals = [''] * 368 weekday_start = swisseph.day_of_week(jd) + 1 #swisseph has Mon = 0, non-intuitively! ################################################## #Compute all parameters -- latitude/longitude etc# ################################################## for d in range(-1, 367): jd = jd_start - 1 + d [y, m, dt, t] = swisseph.revjul(jd) weekday = (weekday_start - 1 + d) % 7 local_time = pytz.timezone(tz).localize(datetime(y, m, dt, 6, 0, 0)) #checking @ 6am local - can we do any better? tz_off = datetime.utcoffset(local_time).seconds / 3600.0 #compute offset from UTC jd_sunrise[d + 1] = swisseph.rise_trans( jd_start=jd + 1, body=swisseph.SUN, lon=longitude, lat=latitude, rsmi=swisseph.CALC_RISE | swisseph.BIT_DISC_CENTER)[1][0] jd_sunset[d + 1] = swisseph.rise_trans( jd_start=jd + 1, body=swisseph.SUN, lon=longitude, lat=latitude, rsmi=swisseph.CALC_SET | swisseph.BIT_DISC_CENTER)[1][0] jd_moonrise[d + 1] = swisseph.rise_trans( jd_start=jd + 1, body=swisseph.MOON, lon=longitude, lat=latitude, rsmi=swisseph.CALC_RISE | swisseph.BIT_DISC_CENTER)[1][0] longitude_sun[d + 1] = swisseph.calc_ut( jd_sunrise[d + 1], swisseph.SUN)[0] - swisseph.get_ayanamsa( jd_sunrise[d + 1]) longitude_moon[d + 1] = swisseph.calc_ut( jd_sunrise[d + 1], swisseph.MOON)[0] - swisseph.get_ayanamsa( jd_sunrise[d + 1]) longitude_sun_set[d + 1] = swisseph.calc_ut( jd_sunset[d + 1], swisseph.SUN)[0] - swisseph.get_ayanamsa( jd_sunset[d + 1]) sun_month_id[d + 1] = int(1 + math.floor(( (longitude_sun_set[d + 1]) % 360) / 30.0)) sun_month[d + 1] = int(1 + math.floor(( (longitude_sun_set[d + 1]) % 360) / 30.0)) sun_month_rise[d + 1] = int(1 + math.floor(( (longitude_sun[d + 1]) % 360) / 30.0)) if (d <= 0): continue t_sunrise = (jd_sunrise[d] - jd) * 24.0 + tz_off t_sunset = (jd_sunset[d] - jd) * 24.0 + tz_off #Solar month calculations if month_start_after_set == 1: sun_month_day = 0 month_start_after_set = 0 if sun_month[d] != sun_month[d + 1]: sun_month_day = sun_month_day + 1 if sun_month[d] != sun_month_rise[d + 1]: month_start_after_set = 1 [_m, sun_month_end_time] = get_angam_data_string( masa_names[script], 30, jd_sunrise[d], jd_sunrise[d + 1], t_sunrise, longitude_moon[d], longitude_sun[d], longitude_moon[d + 1], longitude_sun[d + 1], [0, 1], script) elif sun_month_rise[d] != sun_month[d]: #mAsa pirappu! #sun moves into next rAsi before sunset -- check rules! sun_month_day = 1 [_m, sun_month_end_time] = get_angam_data_string( masa_names[script], 30, jd_sunrise[d], jd_sunrise[d + 1], t_sunrise, longitude_moon[d], longitude_sun[d], longitude_moon[d + 1], longitude_sun[d + 1], [0, 1], script) else: sun_month_day = sun_month_day + 1 sun_month_end_time = '' month_data[d] = '\\sunmonth{%s}{%d}{%s}' % (masa_names[script][ sun_month[d]], sun_month_day, sun_month_end_time) #KARADAYAN NOMBU -- easy to check here if sun_month_end_time != '': #month ends today if (sun_month[d] == 12 and sun_month_day == 1) or (sun_month[d] == 11 and sun_month_day != 1): festival_day_list[karadayan_nombu[script]] = [d] #KOODARA VALLI -- easy to check here if sun_month[d] == 9 and sun_month_day == 27: festival_day_list[koodaravalli[script]] = [d] #Sunrise/sunset and related stuff (like rahu, yama) [rhs, rms, rss] = deci2sexa( t_sunrise) #rise hour sun, rise minute sun, rise sec sun [shs, sms, sss] = deci2sexa(t_sunset) length_of_day = t_sunset - t_sunrise yamagandam_start = t_sunrise + (1 / 8.0) * ( yamagandam_octets[weekday] - 1) * length_of_day yamagandam_end = yamagandam_start + (1 / 8.0) * length_of_day rahukalam_start = t_sunrise + (1 / 8.0) * (rahukalam_octets[weekday] - 1) * length_of_day rahukalam_end = rahukalam_start + (1 / 8.0) * length_of_day madhyahnikam_start = t_sunrise + (1 / 5.0) * length_of_day sunrise[d] = '%02d:%02d' % (rhs, rms) sunset[d] = '%02d:%02d' % (shs, sms) madhya[d] = print_time(madhyahnikam_start) rahu[d] = '%s--%s' % (print_time(rahukalam_start), print_time(rahukalam_end)) yama[d] = '%s--%s' % (print_time(yamagandam_start), print_time(yamagandam_end)) [tithi_sunrise[d], tithi_data_string[d]] = get_angam_data_string( tithi_names[script], 12, jd_sunrise[d], jd_sunrise[d + 1], t_sunrise, longitude_moon[d], longitude_sun[d], longitude_moon[d + 1], longitude_sun[d + 1], [1, -1], script) [nakshatram_sunrise[d], nakshatram_data_string[d]] = get_angam_data_string( nakshatra_names[script], (360.0 / 27.0), jd_sunrise[d], jd_sunrise[d + 1], t_sunrise, longitude_moon[d], longitude_sun[d], longitude_moon[d + 1], longitude_sun[d + 1], [1, 0], script) [karanam_sunrise[d], karanam_data_string[d]] = get_angam_data_string( karanam_names[script], 6, jd_sunrise[d], jd_sunrise[d + 1], t_sunrise, longitude_moon[d], longitude_sun[d], longitude_moon[d + 1], longitude_sun[d + 1], [1, -1], script) [yogam_sunrise[d], yogam_data_string[d]] = get_angam_data_string( yogam_names[script], (360.0 / 27.0), jd_sunrise[d], jd_sunrise[d + 1], t_sunrise, longitude_moon[d], longitude_sun[d], longitude_moon[d + 1], longitude_sun[d + 1], [1, 1], script) #ASSIGN MOON MONTHS last_month_change = 1 last_moon_month = None for d in range(1, 367): #Assign moon_month for each day if (tithi_sunrise[d] == 1): for i in range(last_month_change, d): #print '%%#Setting moon_month to sun_month_id, for i=%d:%d to %d' %(last_month_change,d-1,sun_month_id[d]) if (sun_month_id[d] == last_moon_month): moon_month[i] = sun_month_id[d] % 12 + 0.5 else: moon_month[i] = sun_month_id[d] last_month_change = d last_moon_month = sun_month_id[d] elif (tithi_sunrise[d] == 2 and tithi_sunrise[d - 1] == 30): #prathama tithi was never seen @ sunrise for i in range(last_month_change, d): #print '%%@Setting moon_month to sun_month_id, for i=%d:%d to %d (last month = %d)' %(last_month_change,d-1,sun_month_id[d],last_moon_month) if (sun_month_id[d - 1] == last_moon_month): moon_month[i] = sun_month_id[d - 1] % 12 + 0.5 else: moon_month[i] = sun_month_id[d - 1] last_month_change = d last_moon_month = sun_month_id[d - 1] for i in range(last_month_change, 367): moon_month[i] = sun_month_id[last_month_change - 1] + 1 #for d in range(1,367): #jd = jd_start-1+d #[y,m,dt,t] = swisseph.revjul(jd) #print '%%#%02d-%02d-%4d: %3d:%s (sunrise tithi=%d) {%s}' % (dt,m,y,d,moon_month[d],tithi_sunrise[d],tithi_data_string[d]) log_file = open('cal_log_%4d.txt' % year, 'w') for d in range(1, 367): jd = jd_start - 1 + d [y, m, dt, t] = swisseph.revjul(jd) log_data = '%02d-%02d-%4d\t[%3d]\tsun_rashi=%8.3f\ttithi=%8.3f\tsun_month=%2d\tmoon_month=%4.1f\n' % ( dt, m, y, d, (longitude_sun_set[d] % 360) / 30.0, get_angam_float(jd_sunrise[d], 12.0, [1, -1]), sun_month[d], moon_month[d]) log_file.write(log_data) #PRINT CALENDAR for d in range(1, 367): jd = jd_start - 1 + d [y, m, dt, t] = swisseph.revjul(jd) weekday = (weekday_start - 1 + d) % 7 ################## #Festival details# ################## ###--- MONTHLY VRATAMS ---### #EKADASHI Vratam if tithi_sunrise[d] == 11 or tithi_sunrise[ d] == 12: #One of two consecutive tithis must appear @ sunrise! #check for shukla ekadashi if (tithi_sunrise[d] == 11 and tithi_sunrise[d + 1] == 11): festivals[d + 1] = sarva[script] + '~' + get_ekadashi_name( paksha='shukla', month=moon_month[d], script=script) #moon_month[d] or [d+1]? if moon_month[d + 1] == 4: festivals[d + 1] += '\\\\' + chaturmasya_start[script] if moon_month[d + 1] == 8: festivals[d + 1] += '\\\\' + chaturmasya_end[script] elif (tithi_sunrise[d] == 11 and tithi_sunrise[d + 1] != 11): #Check dashami end time to decide for whether this is sarva/smartha tithi_arunodayam = get_tithi( jd_sunrise[d] - (1 / 15.0) * (jd_sunrise[d] - jd_sunrise[d - 1]) ) #Two muhurtams is 1/15 of day-length if tithi_arunodayam == 10: festivals[d] = smartha[script] + '~' + get_ekadashi_name( paksha='shukla', month=moon_month[d], script=script) festivals[d + 1] = vaishnava[script] + '~' + get_ekadashi_name( paksha='shukla', month=moon_month[d], script=script) if moon_month[d] == 4: festivals[d] += '\\\\' + chaturmasya_start[script] if moon_month[d] == 8: festivals[d] += '\\\\' + chaturmasya_end[script] else: festivals[d] = sarva[script] + '~' + get_ekadashi_name( paksha='shukla', month=moon_month[d], script=script) if moon_month[d] == 4: festivals[d] += '\\\\' + chaturmasya_start[script] if moon_month[d] == 8: festivals[d] += '\\\\' + chaturmasya_end[script] elif (tithi_sunrise[d - 1] != 11 and tithi_sunrise[d] == 12): festivals[d] = sarva[script] + '~' + get_ekadashi_name( paksha='shukla', month=moon_month[d], script=script) if moon_month[d] == 4: festivals[d] += '\\\\' + chaturmasya_start[script] if moon_month[d] == 8: festivals[d] += '\\\\' + chaturmasya_end[script] if tithi_sunrise[d] == 26 or tithi_sunrise[ d] == 27: #One of two consecutive tithis must appear @ sunrise! #check for krishna ekadashi if (tithi_sunrise[d] == 26 and tithi_sunrise[d + 1] == 26): festivals[d + 1] = sarva[script] + '~' + get_ekadashi_name( paksha='krishna', month=moon_month[d], script=script) #moon_month[d] or [d+1]? elif (tithi_sunrise[d] == 26 and tithi_sunrise[d + 1] != 26): #Check dashami end time to decide for whether this is sarva/smartha tithi_arunodayam = get_tithi( jd_sunrise[d] - (1 / 15.0) * (jd_sunrise[d] - jd_sunrise[d - 1]) ) #Two muhurtams is 1/15 of day-length if tithi_arunodayam == 25: festivals[d] = smartha[script] + '~' + get_ekadashi_name( paksha='krishna', month=moon_month[d], script=script) festivals[d + 1] = vaishnava[script] + '~' + get_ekadashi_name( paksha='krishna', month=moon_month[d], script=script) else: festivals[d] = sarva[script] + '~' + get_ekadashi_name( paksha='krishna', month=moon_month[d], script=script) elif (tithi_sunrise[d - 1] != 26 and tithi_sunrise[d] == 27): festivals[d] = sarva[script] + '~' + get_ekadashi_name( paksha='krishna', month=moon_month[d], script=script) #PRADOSHA Vratam if tithi_sunrise[d] == 12 or tithi_sunrise[d] == 13: ldiff_set = (swisseph.calc_ut(jd_sunset[d], swisseph.MOON)[0] - swisseph.calc_ut(jd_sunset[d], swisseph.SUN)[0]) % 360 ldiff_set_tmrw = ( swisseph.calc_ut(jd_sunset[d + 1], swisseph.MOON)[0] - swisseph.calc_ut(jd_sunset[d + 1], swisseph.SUN)[0]) % 360 tithi_sunset = int(1 + math.floor(ldiff_set / 12.0)) tithi_sunset_tmrw = int(1 + math.floor(ldiff_set_tmrw / 12.0)) if tithi_sunset <= 13 and tithi_sunset_tmrw != 13: festivals[d] = pradosham[script] elif tithi_sunset_tmrw == 13: festivals[d + 1] = pradosham[script] if tithi_sunrise[d] == 27 or tithi_sunrise[d] == 28: ldiff_set = (swisseph.calc_ut(jd_sunset[d], swisseph.MOON)[0] - swisseph.calc_ut(jd_sunset[d], swisseph.SUN)[0]) % 360 ldiff_set_tmrw = ( swisseph.calc_ut(jd_sunset[d + 1], swisseph.MOON)[0] - swisseph.calc_ut(jd_sunset[d + 1], swisseph.SUN)[0]) % 360 tithi_sunset = int(1 + math.floor(ldiff_set / 12.0)) tithi_sunset_tmrw = int(1 + math.floor(ldiff_set_tmrw / 12.0)) if tithi_sunset <= 28 and tithi_sunset_tmrw != 28: festivals[d] = pradosham[script] elif tithi_sunset_tmrw == 28: festivals[d + 1] = pradosham[script] #SANKATAHARA chaturthi if tithi_sunrise[d] == 18 or tithi_sunrise[d] == 19: ldiff_moonrise_yest = ( swisseph.calc_ut(jd_moonrise[d - 1], swisseph.MOON)[0] - swisseph.calc_ut(jd_moonrise[d - 1], swisseph.SUN)[0]) % 360 ldiff_moonrise = ( swisseph.calc_ut(jd_moonrise[d], swisseph.MOON)[0] - swisseph.calc_ut(jd_moonrise[d], swisseph.SUN)[0]) % 360 ldiff_moonrise_tmrw = ( swisseph.calc_ut(jd_moonrise[d + 1], swisseph.MOON)[0] - swisseph.calc_ut(jd_moonrise[d + 1], swisseph.SUN)[0]) % 360 tithi_moonrise_yest = int(1 + math.floor(ldiff_moonrise_yest / 12.0)) tithi_moonrise = int(1 + math.floor(ldiff_moonrise / 12.0)) tithi_moonrise_tmrw = int(1 + math.floor(ldiff_moonrise_tmrw / 12.0)) if tithi_moonrise == 19: if tithi_moonrise_yest != 19: #otherwise yesterday would have already been assigned festivals[d] = chaturthi[script] if moon_month[d] == 5: #shravana krishna chaturthi festivals[d] = maha[script] + festivals[d] elif tithi_moonrise_tmrw == 19: festivals[d + 1] = chaturthi[script] if moon_month[ d] == 5: #moon_month[d] and[d+1] are same, so checking [d] is enough festivals[d + 1] = maha[script] + festivals[d + 1] #SHASHTHI Vratam if tithi_sunrise[d] == 5 or tithi_sunrise[d] == 6: if tithi_sunrise[d] == 6 or (tithi_sunrise[d] == 5 and tithi_sunrise[d + 1] == 7): if tithi_sunrise[ d - 1] != 6: #otherwise yesterday would have already been assigned festivals[d] = shashthi[script] if moon_month[d] == 8: #kArtika krishna shashthi festivals[d] = skanda[script] + festivals[d] elif tithi_sunrise[d + 1] == 6: festivals[d + 1] = shashthi[script] if moon_month[ d] == 8: #moon_month[d] and[d+1] are same, so checking [d] is enough festivals[d + 1] = skanda[script] + festivals[d + 1] ###--- OTHER (MAJOR) FESTIVALS ---### #type of month | month number | type of angam (tithi|nakshatram) | angam number | min_t cut off for considering prev day (without sunrise_angam) as festival date purvaviddha_rules = { akshaya_tritiya[script]: ['moon_month', 2, 'tithi', 3, 0], chitra_purnima[script]: ['sun_month', 1, 'tithi', 15, 0], durgashtami[script]: ['moon_month', 7, 'tithi', 8, 0], mahanavami[script]: ['moon_month', 7, 'tithi', 9, 0], vijayadashami[script]: ['moon_month', 7, 'tithi', 10, 0], dipavali[script]: ['moon_month', 7, 'tithi', 29, 0], shankara_jayanti[script]: ['moon_month', 2, 'tithi', 5, 0], yajur_upakarma[script]: ['moon_month', 5, 'tithi', 15, 0], rg_upakarma[script]: ['moon_month', 5, 'nakshatram', 22, 0], sama_upakarma[script]: ['sun_month', 5, 'nakshatram', 13, 0], rishi_panchami[script]: ['moon_month', 6, 'tithi', 5, 0], ananta_chaturdashi[script]: ['moon_month', 6, 'tithi', 14, 0], mahalaya_paksham[script]: ['moon_month', 6, 'tithi', 16, 0], hanumat_jayanti[script]: ['sun_month', 9, 'tithi', 30, 0], ardra_darshanam[script]: ['sun_month', 9, 'nakshatram', 6, 0], ratha_saptami[script]: ['sun_month', 10, 'tithi', 7, 0], goda_jayanti[script]: ['sun_month', 4, 'nakshatram', 11, 0], adi_krittika[script]: ['sun_month', 4, 'nakshatram', 3, 0], phalguni_uttaram[script]: ['sun_month', 12, 'nakshatram', 12, 4], mahalaya_amavasya[script]: ['moon_month', 6, 'tithi', 30, 0], uma_maheshvara_vratam[script]: ['moon_month', 6, 'tithi', 15, 0] } for x in iter(purvaviddha_rules.keys()): rule = purvaviddha_rules[x] if rule[0] == 'moon_month': if moon_month[d] == rule[1]: if rule[2] == 'tithi': fday = get_festival_day_purvaviddha( rule[3], tithi_sunrise, d, jd_sunrise[d], jd_sunrise[d + 1], get_tithi, rule[4]) elif rule[2] == 'nakshatram': fday = get_festival_day_purvaviddha( rule[3], nakshatram_sunrise, d, jd_sunrise[d], jd_sunrise[d + 1], get_nakshatram, rule[4]) if fday is not None: if festival_day_list.has_key(x): if festival_day_list[x][0] != fday: #Second occurrence of a festival within a Gregorian calendar year festival_day_list[x] = [ festival_day_list[x][0], fday ] else: festival_day_list[x] = [fday] elif rule[0] == 'sun_month': if sun_month[d] == rule[1]: if rule[2] == 'tithi': fday = get_festival_day_purvaviddha( rule[3], tithi_sunrise, d, jd_sunrise[d], jd_sunrise[d + 1], get_tithi, rule[4]) elif rule[2] == 'nakshatram': fday = get_festival_day_purvaviddha( rule[3], nakshatram_sunrise, d, jd_sunrise[d], jd_sunrise[d + 1], get_nakshatram, rule[4]) if fday is not None: if festival_day_list.has_key(x): if festival_day_list[x][0] != fday: #Second occurrence of a festival within a Gregorian calendar year festival_day_list[x] = [ festival_day_list[x][0], fday ] else: festival_day_list[x] = [fday] else: print 'Error; unknown string in rule: %s' % (rule[0]) return #NAVARATRI START if moon_month[d] == 7 and moon_month[d - 1] == 6: festival_day_list[navaratri_start[script]] = [d] #PONGAL/AYANAM if sun_month[d] == 10 and sun_month[d - 1] == 9: festival_day_list[uttarayanam[script]] = [d] if sun_month[d] == 4 and sun_month[d - 1] == 3: festival_day_list[dakshinayanam[script]] = [d] if sun_month[d] == 1 and sun_month[d - 1] == 12: festival_day_list[new_yr] = [d] if moon_month[d] == 1 and moon_month[d - 1] != 1: festival_day_list[yugadi[script]] = [d] #SHRIRAMANAVAMI if moon_month[d] == 1: if tithi_sunrise[d] == 8 or tithi_sunrise[d] == 9: t_11 = get_tithi(jd_sunrise[d] + (jd_sunset[d] - jd_sunrise[d]) * (2.0 / 5.0)) #madhyahna1 start t_12 = get_tithi(jd_sunrise[d] + (jd_sunset[d] - jd_sunrise[d]) * (3.0 / 5.0)) #madhyahna1 end t_21 = get_tithi(jd_sunrise[d + 1] + (jd_sunset[d + 1] - jd_sunrise[d + 1]) * (2.0 / 5.0)) #madhyahna2 start t_22 = get_tithi(jd_sunrise[d + 1] + (jd_sunset[d + 1] - jd_sunrise[d + 1]) * (3.0 / 5.0)) #madhyahna2 end if t_11 == 9 or t_12 == 9: if t_21 == 9 or t_22 == 9: festival_day_list[ramanavami[script]] = [d + 1] else: festival_day_list[ramanavami[script]] = [d] #JANMASHTAMI if moon_month[d] == 5: if tithi_sunrise[d] == 22 or tithi_sunrise[d] == 23: t_11 = get_tithi(jd_sunset[d] + (jd_sunrise[d + 1] - jd_sunset[d]) * (7.0 / 15.0)) #nishita1 start t_12 = get_tithi(jd_sunset[d] + (jd_sunrise[d + 1] - jd_sunset[d]) * (8.0 / 15.0)) #nishita1 end #t_11 = get_tithi(jd_sunset[d]+(jd_sunrise[d+1]-jd_sunset[d])*(2.0/5.0))#madhyaratri1 start #t_12 = get_tithi(jd_sunset[d]+(jd_sunrise[d+1]-jd_sunset[d])*(3.0/5.0))#madhyaratri1 end t_21 = get_tithi(jd_sunset[d + 1] + (jd_sunrise[d + 2] - jd_sunset[d + 1]) * (7.0 / 15.0)) #nishita2 start t_22 = get_tithi(jd_sunset[d + 1] + (jd_sunrise[d + 2] - jd_sunset[d + 1]) * (8.0 / 15.0)) #nishita2 end #t_21 = get_tithi(jd_sunset[d+1]+(jd_sunrise[d+2]-jd_sunset[d+1])*(2.0/5.0))#madhyaratri2 start #t_22 = get_tithi(jd_sunset[d+1]+(jd_sunrise[d+2]-jd_sunset[d+1])*(3.0/5.0))#madhyaratri2 end if t_11 == 23 or t_12 == 23: if t_21 == 23 or t_22 == 23: festival_day_list[janmashtami[script]] = [d + 1] else: festival_day_list[janmashtami[script]] = [d] #SHIVARATRI if moon_month[d] == 11: if tithi_sunrise[d] == 28 or tithi_sunrise[d] == 29: t_11 = get_tithi(jd_sunset[d] + (jd_sunrise[d + 1] - jd_sunset[d]) * (7.0 / 15.0)) #nishita1 start t_12 = get_tithi(jd_sunset[d] + (jd_sunrise[d + 1] - jd_sunset[d]) * (8.0 / 15.0)) #nishita1 end t_21 = get_tithi(jd_sunset[d + 1] + (jd_sunrise[d + 2] - jd_sunset[d + 1]) * (7.0 / 15.0)) #nishita2 start t_22 = get_tithi(jd_sunset[d + 1] + (jd_sunrise[d + 2] - jd_sunset[d + 1]) * (8.0 / 15.0)) #nishita2 end if t_11 == 29 or t_12 == 29: if t_21 == 29 or t_22 == 29: festival_day_list[shivaratri[script]] = [d + 1] else: festival_day_list[shivaratri[script]] = [d] #VINAYAKA CHATURTHI if moon_month[d] == 6: if tithi_sunrise[d] == 3 or tithi_sunrise[d] == 4: t_11 = get_tithi(jd_sunrise[d] + (jd_sunset[d] - jd_sunrise[d]) * (2.0 / 5.0)) #madhyahna1 start t_12 = get_tithi(jd_sunrise[d] + (jd_sunset[d] - jd_sunrise[d]) * (3.0 / 5.0)) #madhyahna1 end t_21 = get_tithi(jd_sunrise[d + 1] + (jd_sunset[d + 1] - jd_sunrise[d + 1]) * (2.0 / 5.0)) #madhyahna2 start t_22 = get_tithi(jd_sunrise[d + 1] + (jd_sunset[d + 1] - jd_sunrise[d + 1]) * (3.0 / 5.0)) #madhyahna2 end if t_11 == 4 or t_12 == 4: if t_21 == 4 or t_22 == 4: festival_day_list[vchaturthi[script]] = [d + 1] else: festival_day_list[vchaturthi[script]] = [d] #Add saved festivals festival_day_list[gayatri_japam[script]] = [ festival_day_list[yajur_upakarma[script]][0] + 1 ] festival_day_list[varalakshmi_vratam[script]] = [ festival_day_list[yajur_upakarma[script]][0] - ((weekday_start - 1 + festival_day_list[yajur_upakarma[script]][0] - 5) % 7) ] for x in iter(festival_day_list.keys()): for j in range(0, len(festival_day_list[x])): if festivals[festival_day_list[x][j]] != '': festivals[festival_day_list[x][j]] += '\\\\' festivals[festival_day_list[x][j]] += x ###--- ECLIPSES ---### ###--- LUNAR ECLIPSES ---### swisseph.set_topo(lon=longitude, lat=latitude, alt=0.0) #Set location jd = jd_start while 1: next_ecl_lun = swisseph.lun_eclipse_when(jd) jd = next_ecl_lun[1][0] + (tz_off / 24.0) jd_ecl_lun_start = next_ecl_lun[1][2] + (tz_off / 24.0) jd_ecl_lun_end = next_ecl_lun[1][3] + (tz_off / 24.0) ecl_y = swisseph.revjul( jd - 1 )[0] # -1 is to not miss an eclipse that occurs after sunset on 31-Dec! if ecl_y != start_year: break else: ecl_lun_start = swisseph.revjul(jd_ecl_lun_start)[3] ecl_lun_end = swisseph.revjul(jd_ecl_lun_end)[3] if (jd_ecl_lun_start - (tz_off / 24.0)) == 0.0 or (jd_ecl_lun_end - (tz_off / 24.0)) == 0.0: jd = jd + 20 #Move towards the next eclipse... at least the next full moon (>=25 days away) continue fday = int(math.floor(jd_ecl_lun_start) - math.floor(jd_start) + 1) #print '%%',jd,fday,jd_sunrise[fday],jd_sunrise[fday-1] if (jd < (jd_sunrise[fday] + tz_off / 24.0)): fday -= 1 if ecl_lun_start < swisseph.revjul(jd_sunrise[fday + 1] + tz_off / 24.0)[3]: ecl_lun_start += 24 #print '%%',jd,fday,jd_sunrise[fday],jd_sunrise[fday-1],ecl_lun_start, ecl_lun_end jd_moonrise_ecl_day = swisseph.rise_trans( jd_start=jd_sunrise[fday], body=swisseph.MOON, lon=longitude, lat=latitude, rsmi=swisseph.CALC_RISE | swisseph.BIT_DISC_CENTER)[1][0] + (tz_off / 24.0) jd_moonset_ecl_day = swisseph.rise_trans( jd_start=jd_moonrise_ecl_day, body=swisseph.MOON, lon=longitude, lat=latitude, rsmi=swisseph.CALC_SET | swisseph.BIT_DISC_CENTER)[1][0] + (tz_off / 24.0) #if jd_ecl_lun_start<(jd_sunrise[fday]+(tz_off/24.0)): if ecl_lun_end < ecl_lun_start: ecl_lun_end += 24 #print '%%', (jd_ecl_lun_start), (jd_ecl_lun_end), (jd_moonrise_ecl_day), (jd_moonset_ecl_day) #print '%%', swisseph.revjul(jd_ecl_lun_start), swisseph.revjul(jd_ecl_lun_end), swisseph.revjul(jd_moonrise_ecl_day), swisseph.revjul(jd_moonset_ecl_day) if jd_ecl_lun_end < jd_moonrise_ecl_day or jd_ecl_lun_start > jd_moonset_ecl_day: jd = jd + 20 #Move towards the next eclipse... at least the next full moon (>=25 days away) continue lun_ecl_str = chandra_grahanam[script] + '~\\textsf{' + print_time2( ecl_lun_start) + '}{\\RIGHTarrow}\\textsf{' + print_time2( ecl_lun_end) + '}' if festivals[fday] != '': festivals[fday] += '\\\\' festivals[fday] += lun_ecl_str jd = jd + 20 ###--- SOLAR ECLIPSES ---### swisseph.set_topo(lon=longitude, lat=latitude, alt=0.0) #Set location jd = jd_start while 1: next_ecl_sol = swisseph.sol_eclipse_when_loc(julday=jd, lon=longitude, lat=latitude) jd = next_ecl_sol[1][0] + (tz_off / 24.0) jd_ecl_sol_start = next_ecl_sol[1][1] + (tz_off / 24.0) jd_ecl_sol_end = next_ecl_sol[1][4] + (tz_off / 24.0) ecl_y = swisseph.revjul( jd - 1 )[0] # -1 is to not miss an eclipse that occurs after sunset on 31-Dec! if ecl_y != start_year: break else: #print '%%', fday, (jd_ecl_sol_start), (jd_ecl_sol_end), (jd_sunrise[fday]) #print '%%', swisseph.revjul(jd_ecl_sol_start), swisseph.revjul(jd_ecl_sol_end), swisseph.revjul(jd_sunrise[fday]) fday = int(math.floor(jd) - math.floor(jd_start) + 1) if (jd < (jd_sunrise[fday] + tz_off / 24.0)): fday -= 1 #print '%%', fday, (jd_ecl_sol_start), (jd_ecl_sol_end), (jd_sunrise[fday]) #print '%%', swisseph.revjul(jd_ecl_sol_start), swisseph.revjul(jd_ecl_sol_end), swisseph.revjul(jd_sunrise[fday]) ecl_sol_start = swisseph.revjul(jd_ecl_sol_start)[3] ecl_sol_end = swisseph.revjul(jd_ecl_sol_end)[3] if (jd_ecl_sol_start - (tz_off / 24.0)) == 0.0 or ( jd_ecl_sol_end - (tz_off / 24.0) ) == 0.0: # or jd_ecl_end<jd_sunrise[fday] or jd_ecl_start>jd_sunset[fday]: jd = jd + 20 #Move towards the next eclipse... at least the next new moon (>=25 days away) continue if ecl_sol_end < ecl_sol_start: ecl_sol_end += 24 sol_ecl_str = surya_grahanam[script] + '~\\textsf{' + print_time2( ecl_sol_start) + '}{\\RIGHTarrow}\\textsf{' + print_time2( ecl_sol_end) + '}' if festivals[fday] != '': festivals[fday] += '\\\\' festivals[fday] += sol_ecl_str jd = jd + 20 ###--- FESTIVAL ADDITIONS COMPLETE ---### ###--- PRINT LIST OF FESTIVALS (Page 2) ---### if script == 'en': cal = Calendar() print '\\newpage' print '\\centerline {\\LARGE {{%s}}}\\mbox{}\\\\[2cm]' % list_of_festivals[ script] print '\\begin{center}' print '\\begin{minipage}[t]{0.3\\linewidth}' print '\\begin{center}' print '\\begin{tabular}{>{\\sffamily}r>{\\sffamily}r>{\\sffamily}cp{6cm}}' mlast = 1 for d in range(1, 367): jd = jd_start - 1 + d [y, m, dt, t] = swisseph.revjul(jd) weekday = (weekday_start - 1 + d) % 7 if festivals[d] != '': if m != mlast: mlast = m #print '\\hline\\\\' print '\\\\' if m == 5 or m == 9: print '\\end{tabular}' print '\\end{center}' print '\\end{minipage}\hspace{1cm}%' print '\\begin{minipage}[t]{0.3\\linewidth}' print '\\begin{center}' print '\\begin{tabular}{>{\\sffamily}r>{\\sffamily}l>{\\sffamily}cp{6cm}}' print '%s & %s & %s & {\\raggedright %s} \\\\' % ( MON[m], dt, WDAY[weekday], festivals[d]) if script == 'en': event = Event() event.add('summary', festivals[d]) event.add('dtstart', datetime(y, m, dt)) event.add('dtend', datetime(y, m, dt)) cal.add_component(event) if m == 12 and dt == 31: break print '\\end{tabular}' print '\\end{center}' print '\\end{minipage}' print '\\end{center}' print '\\clearpage' if script == 'en': cal_fname = '%s-%4d.ics' % (city_name, start_year) cal_file = open(cal_fname, 'w') cal_file.write(cal.as_string()) cal_file.close() #Layout calendar in LATeX format #We use a separate loop here, because of festivals like varalakshmi #vratam, for which we backtrack to the previous friday from yajur #upakarma and change the list of festivals! for d in range(1, 367): jd = jd_start - 1 + d [y, m, dt, t] = swisseph.revjul(jd) weekday = (weekday_start - 1 + d) % 7 if dt == 1: if m > 1: if weekday != 0: #Space till Sunday for i in range(weekday, 6): print "{} &" print "\\\\ \hline" print '\end{tabular}' print '\n\n' #Begin tabular print '\\begin{tabular}{|c|c|c|c|c|c|c|}' print '\multicolumn{7}{c}{\Large \\bfseries \sffamily %s %s}\\\\[3mm]' % ( month[m], y) print '\hline' print '\\textbf{\\textsf{SUN}} & \\textbf{\\textsf{MON}} & \\textbf{\\textsf{TUE}} & \\textbf{\\textsf{WED}} & \\textbf{\\textsf{THU}} & \\textbf{\\textsf{FRI}} & \\textbf{\\textsf{SAT}} \\\\ \hline' #print '\\textbf{भानु} & \\textbf{इन्दु} & \\textbf{भौम} & \\textbf{बुध} & \\textbf{गुरु} & \\textbf{भृगु} & \\textbf{स्थिर} \\\\ \hline' #Blanks for previous weekdays for i in range(0, weekday): print "{} &" print '\caldata{\\textcolor{%s}{%s}}{%s{%s}}{\\sundata{%s}{%s}{%s}}{\\tnyk{%s}{%s}{%s}{%s}}{\\rahuyama{%s}{%s}}{%s} ' % ( daycol[weekday], dt, month_data[d], get_chandra_masa(moon_month[d], chandra_masa_names, script), sunrise[d], sunset[d], madhya[d], tithi_data_string[d], nakshatram_data_string[d], yogam_data_string[d], karanam_data_string[d], rahu[d], yama[d], festivals[d]) if weekday == 6: print "\\\\ \hline" else: print "&" if m == 12 and dt == 31: break # For debugging specific dates #if m==4 and dt==10: # break for i in range(weekday + 1, 6): print "{} &" if weekday != 6: print "\\\\ \hline" print '\end{tabular}' print '\n\n' print template_lines[-2][:-1] print template_lines[-1][:-1]
def to_ical(table, first_monday): message = "OK" error = "" code = 0 data = {} rule = re.compile(r"[^a-zA-Z0-9\-,]") cal = Calendar() cal['version'] = '2.0' cal['prodid'] = '-//NUC//Syllabus//CN' # *mandatory elements* where the prodid can be changed, see RFC 5445 mondaySplit = first_monday.split('-') start_monday = date(int(mondaySplit[0]), int(mondaySplit[1]), int(mondaySplit[2])) # 开学第一周星期一的时间 dict_day = { 1: relativedelta(hours=8, minutes=0), 3: relativedelta(hours=10, minutes=10), 5: relativedelta(hours=14, minutes=30), 7: relativedelta(hours=16, minutes=40), 9: relativedelta(hours=19, minutes=30) } dict_day2 = { 1: relativedelta(hours=8, minutes=0), 3: relativedelta(hours=10, minutes=10), 5: relativedelta(hours=14, minutes=0), 7: relativedelta(hours=16, minutes=10), 9: relativedelta(hours=19, minutes=0) } for i in table: if "Course_Week" not in i: continue for j in rule.sub('', i["Course_Week"]).split(','): if j.find('-') != -1: d = j.split('-') for dday in range(int(d[0]), int(d[1]) + 1): event = Event() dtstart_date = start_monday + relativedelta( weeks=(dday - 1)) + relativedelta( days=int(int(i["Course_Time"])) - 1) dtstart_datetime = datetime.combine( dtstart_date, datetime.min.time()) if dtstart_date.month >= 5 and dtstart_date.month < 10: dtstart = dtstart_datetime + dict_day[int( i["Course_Start"])] else: dtstart = dtstart_datetime + dict_day2[int( i["Course_Start"])] dtend = dtstart + relativedelta(hours=1, minutes=40) event.add('X-WR-TIMEZONE', 'Asia/Shanghai') event.add('uid', str(uuid1()) + '@Dreace') event.add('summary', i["Course_Name"]) event.add('dtstamp', datetime.now()) event.add( 'dtstart', dtstart.replace(tzinfo=cst_tz).astimezone(cst_tz)) event.add('dtend', dtend.replace(tzinfo=cst_tz).astimezone(cst_tz)) event.add('rrule', { 'freq': 'weekly', 'interval': 1, 'count': 1 }) event.add('location', i["Course_Building"] + i["Course_Classroom"]) cal.add_component(event) else: if j == '': continue event = Event() dtstart_date = start_monday + relativedelta( weeks=(int(j) - 1)) + relativedelta( days=int(int(i["Course_Time"])) - 1) dtstart_datetime = datetime.combine(dtstart_date, datetime.min.time()) if dtstart_date.month >= 5 and dtstart_date.month < 10: dtstart = dtstart_datetime + dict_day[int( i["Course_Start"])] else: dtstart = dtstart_datetime + dict_day2[int( i["Course_Start"])] dtend = dtstart + relativedelta(hours=1, minutes=40) event.add('X-WR-TIMEZONE', 'Asia/Shanghai') event.add('uid', str(uuid1()) + '@Dreace') event.add('summary', i["Course_Name"]) event.add('dtstamp', datetime.now()) event.add('dtstart', dtstart.replace(tzinfo=cst_tz).astimezone(cst_tz)) event.add('dtend', dtend.replace(tzinfo=cst_tz).astimezone(cst_tz)) event.add('rrule', { 'freq': 'weekly', 'interval': 1, 'count': 1 }) event.add('location', i["Course_Building"] + i["Course_Classroom"]) cal.add_component(event) filename = hashlib.md5( json.dumps(table).encode('utf8')).hexdigest().upper() + ".ics" write_ics_file(filename, cal) data["url"] = "https://blog-cdn.dreace.top/files/" + filename return {"message": message, "error": error, "code": code, "data": data}
def json2ics(input_file, output_folder): LOG = logging.getLogger(__name__) LOG.info('Convert from JSON file %s to %s folder.', input_file, output_folder) try: calendars = {} with open(input_file, "rb") as src: input = json.load(src) for (date_zh, value) in input.items(): # LOG.debug('date_zh: %s', date_zh) m = re.search(u'[0]*([0-9]+)年[0]*([0-9]+)月[0]*([0-9]+)日', date_zh) year = int(m.group(1)) + 1911 month = int(m.group(2)) day = int(m.group(3)) date = datetime.date(year, month, day) # LOG.debug('date: %s', date) for (schedule_of_what, schedules) in value.items(): # LOG.debug('schedule_of_what: %s', schedule_of_what) m = re.search(u'^((.*)活動行程|(.*)行程)$', schedule_of_what) whom_zh = m.group(2) if not whom_zh: whom_zh = m.group(3) # LOG.debug('whom_zh: %s', whom_zh) whom = { u'總統': 'president', u'副總統': 'vice-president', u'總統府': 'president-office', }[whom_zh] # LOG.debug('whom: %s', whom) for schedule in schedules: # LOG.debug('schedule: %s', schedule) m = re.search( u'^((\d+)[::](\d+)(~(\d+)[::](\d+))?[^\s]*\s+)?(.*)$', schedule) # LOG.debug('s: %s', m.group(1)) # LOG.debug('s: %s', m.group(2)) # LOG.debug('s: %s', m.group(3)) # LOG.debug('s: %s', m.group(4)) # LOG.debug('s: %s', m.group(5)) # LOG.debug('s: %s', m.group(6)) # LOG.debug('s: %s', m.group(7)) if m.group(1): hhstart = int(m.group(2)) mmstart = int(m.group(3)) ttstart = datetime.time(hhstart, mmstart) else: ttstart = datetime.time(0, 0) # LOG.debug('ttstart: %s', ttstart) if m.group(4): hhend = int(m.group(5)) mmend = int(m.group(6)) ttend = datetime.time(hhend, mmend) else: ttend = datetime.time(23, 23) # LOG.debug('ttend: %s', ttend) summary = m.group(7) # if string.find(summary, u'潘乃傑') >= 0: # pprint(summary) # LOG.debug(summary) dtstart = datetime.datetime.combine(date, ttstart) dtend = datetime.datetime.combine(date, ttend) # LOG.debug('summary: %s', summary) # LOG.debug('dtstart: %s', dtstart) # LOG.debug('dtend: %s', dtend) event = Event() event.add('summary', summary) event['uid'] = '%s/%s@%s.g0v.tw' % ( dtstart.isoformat(), dtend.isoformat(), whom) event.add('dtstamp', dtstart) event.add('dtstart', dtstart) event.add('dtend', dtend) # LOG.debug(event) if whom not in calendars: calendars[whom] = [] calendars[whom].append(event) for whom in calendars.keys(): path = os.path.join(output_folder, '%s.ics' % whom) with open(path, "wb") as dst: ical = Calendar() ical.add('prodid', '-//President Schedule//g0v.tw//') ical.add('version', '2.0') for event in calendars[whom]: ical.add_component(event) dst.write(ical.to_ical()) except IOError as e: LOG.exception(e, 'Encounter IOError')
def fetch_plan(plan_id): wd = request.args.get('wd', default=None, type=int) url = 'https://trv.no/plan/{0}/'.format(plan_id) page = requests.get(url).text soup = BeautifulSoup(page, 'html.parser') title = soup.find('title').string if title.startswith('Side ikke funnet') or len(page) == 0: return 'you sure this is an correct plan id?' table = soup.find("table", {"class": "bins"}) c = Calendar() c.add('X-WR-RELCALID', 'TRV Tømmeplan') c.add('X-WR-CALNAME', 'TRV Tømmeplan') c.add('X-WR-TIMEZONE', 'Europe/Oslo') c.add('X-FROM-URL', '{0}'.format(request.base_url)) c.add('X-AUTHOR', 'https://github.com/jkaberg/trv-ical-server') for table_row in table.select('tbody tr'): class_data = table_row["class"] year = class_data[0].replace('year-', '') week_type = None if len(class_data) > 1: week_type = class_data[1] cells = table_row.findAll('td') if len(cells) > 0: dates = cells[2].text.split(' - ') week = cells[0].text.strip() trv_type = cells[1].text.strip() start = dates[0].split('.') end = dates[1].split('.') start_year = int(year) start_month = int(start[1]) start_day = int(start[0]) end_year = int(year) end_month = int(end[1]) end_day = int(end[0]) # 0=Monday, 4=Friday start_time = None end_time = None if wd in range(0, 4): start_time = datetime(start_year, start_month, start_day, 0, 0) + timedelta(days=wd) end_time = datetime(start_year, start_month, start_day, 0, 0) + timedelta(days=wd + 1) # we need to check if start month is end of year and end month is start of year # if this is the case we need to add a year to end_year # this happends when end month is on a new year if start_month == 12 and end_month == 1: end_year += 1 e = Event() e.add('description', trv_type) e.add('uid', str(uuid.uuid4())) e.add('summary', trv_type) if start_time and end_time: e.add('dtstart', start_time.date()) e.add('dtend', end_time.date()) else: e.add('dtstart', datetime(start_year, start_month, start_day).date()) e.add( 'dtend', datetime(end_year, end_month, end_day).date() - timedelta(days=1)) e.add('dtstamp', datetime.now()) if week_type == 'tommefri-uke': desc = 'Avfall tømmes ikke kommende uke.' else: desc = 'Kommende uke tømmes {0}.'.format(trv_type.lower()) a = Alarm() a.add('action', 'display') a.add( 'trigger', datetime(start_year, start_month, start_day) - timedelta(hours=4)) a.add('description', desc) e.add_component(a) c.add_component(e) return Response(c.to_ical(), mimetype='text/calendar')
def _make_ics(event, etime): cal = Calendar() cal.add('prodid', 'N1-send-availability-package') cal.add('version', '1.0') evt = Event() evt.add('summary', event.title) evt.add('location', event.location) evt.add('description', event.description) evt.add('dtstart', etime.start) evt.add('dtend', etime.end) evt.add('dtstamp', datetime.now()) evt['uid'] = '{timestamp}/{email}'.format(timestamp=time.mktime( datetime.now().timetuple()), email=event.organizer.email) evt.add('priority', 5) organizer = vCalAddress('MAILTO:{}'.format(event.organizer.email)) organizer.params['cn'] = vText(event.organizer.name) organizer.params['role'] = vText('CHAIR') evt['organizer'] = organizer for attendee in event.attendees: atnd = vCalAddress('MAILTO:{}'.format(attendee.email)) atnd.params['cn'] = vText(attendee.name) atnd.params['ROLE'] = vText('REQ-PARTICIPANT') evt.add('attendee', atnd, encode=0) cal.add_component(evt) return cal.to_ical()