def read_events(self, url): """ Read events from the given events RSS feed, specified by 'url', creating new Wiki pages where appropriate. """ request = self.request request.user.may = IAmRoot() category_pagenames = self.options.categories.split() # Locate the template for events. template_page = PageEditor(request, self.options.template) if not template_page.exists(): print "Template %r cannot be found. Not importing any events!" % self.options.template return # Process the feed. feed = urllib.urlopen(url) try: nodes = xml.dom.pulldom.parse(feed) event_details = {} in_item = 0 # Read the nodes from the feed. for node_type, value in nodes: if node_type == xml.dom.pulldom.START_ELEMENT: if value.nodeName == "item": in_item = 1 # Get the value of the important fields. elif in_item and value.nodeName in self.FIELDS: nodes.expandNode(value) event_details[value.nodeName] = self.text(value) # Where all fields have been read, make a new page. if reduce(lambda x, y: x and event_details.has_key(y), self.FIELDS, 1): # Define the page. title = event_details["title"] # Use any parent page information. full_title = EventAggregatorSupport.getFullPageName(self.options.parent, title) # Find the start and end dates. dates = EventAggregatorSupport.getDateStrings(title) # Require one or two dates. if dates and 1 <= len(dates) <= 2: # Deduce the end date. if len(dates) == 2: start_date, end_date = dates elif len(dates) == 1: start_date = end_date = dates[0] # Load the new page and replace the event details in the body. new_page = PageEditor(request, full_title, uid_override=self.options.author) # Delete the page if requested. if new_page.exists() and self.options.delete: try: new_page.deletePage() except new_page.AccessDenied: print "Page %r has not been deleted." % full_title # Complete the new page. elif not new_page.exists() or self.options.overwrite: event_details["summary"] = title event_details["start"] = start_date event_details["end"] = end_date try: EventAggregatorSupport.fillEventPageFromTemplate( template_page, new_page, event_details, category_pagenames) except new_page.Unchanged: print "Page %r is not changed." % full_title else: print "Not overwriting page %r." % full_title else: print "Could not deduce dates from %r." % title event_details = {} elif node_type == xml.dom.pulldom.END_ELEMENT: if value.nodeName == "item": in_item = 0 finally: feed.close()
def execute(macro, args): """ Execute the 'macro' with the given 'args': an optional list of selected category names (categories whose pages are to be shown), together with optional named arguments of the following forms: start=YYYY-MM shows event details starting from the specified month start=current-N shows event details relative to the current month end=YYYY-MM shows event details ending at the specified month end=current+N shows event details relative to the current month mode=calendar shows a calendar view of events mode=list shows a list of events by month mode=table shows a table of events names=daily shows the name of an event on every day of that event names=weekly shows the name of an event once per week calendar=NAME uses the given NAME to provide request parameters which can be used to control the calendar view template=PAGE uses the given PAGE as the default template for new events (or the default template from the configuration if not specified) parent=PAGE uses the given PAGE as the parent of any new event page """ request = macro.request fmt = macro.formatter page = fmt.page _ = request.getText # Interpret the arguments. try: parsed_args = args and wikiutil.parse_quoted_separated(args, name_value=False) or [] except AttributeError: parsed_args = args.split(",") parsed_args = [arg for arg in parsed_args if arg] # Get special arguments. category_names = [] raw_calendar_start = None raw_calendar_end = None calendar_start = None calendar_end = None mode = None name_usage = "weekly" calendar_name = None template_name = getattr(request.cfg, "event_aggregator_new_event_template", "EventTemplate") parent_name = None for arg in parsed_args: if arg.startswith("start="): raw_calendar_start = arg[6:] elif arg.startswith("end="): raw_calendar_end = arg[4:] elif arg.startswith("mode="): mode = arg[5:] elif arg.startswith("names="): name_usage = arg[6:] elif arg.startswith("calendar="): calendar_name = arg[9:] elif arg.startswith("template="): template_name = arg[9:] elif arg.startswith("parent="): parent_name = arg[7:] else: category_names.append(arg) original_calendar_start = calendar_start = EventAggregatorSupport.getParameterMonth(raw_calendar_start) original_calendar_end = calendar_end = EventAggregatorSupport.getParameterMonth(raw_calendar_end) # Find request parameters to override settings. calendar_start = EventAggregatorSupport.getFormMonth(request, calendar_name, "start") or calendar_start calendar_end = EventAggregatorSupport.getFormMonth(request, calendar_name, "end") or calendar_end mode = EventAggregatorSupport.getQualifiedParameter(request, calendar_name, "mode", mode or "calendar") # Get the events. events, shown_events, all_shown_events, earliest, latest = \ EventAggregatorSupport.getEvents(request, category_names, calendar_start, calendar_end) # Get a concrete period of time. first, last = EventAggregatorSupport.getConcretePeriod(calendar_start, calendar_end, earliest, latest) # Define a view of the calendar, retaining useful navigational information. view = View(page, calendar_name, raw_calendar_start, raw_calendar_end, original_calendar_start, original_calendar_end, calendar_start, calendar_end, first, last, category_names, template_name, parent_name, mode, name_usage) # Make a calendar. output = [] # Output download controls. output.append(fmt.div(on=1, css_class="event-controls")) output.append(view.writeDownloadControls()) output.append(fmt.div(on=0)) # Output a table. if mode == "table": # Start of table view output. output.append(fmt.table(on=1, attrs={"tableclass" : "event-table"})) output.append(fmt.table_row(on=1)) output.append(fmt.table_cell(on=1, attrs={"class" : "event-table-heading"})) output.append(fmt.text(_("Event dates"))) output.append(fmt.table_cell(on=0)) output.append(fmt.table_cell(on=1, attrs={"class" : "event-table-heading"})) output.append(fmt.text(_("Event location"))) output.append(fmt.table_cell(on=0)) output.append(fmt.table_cell(on=1, attrs={"class" : "event-table-heading"})) output.append(fmt.text(_("Event details"))) output.append(fmt.table_cell(on=0)) output.append(fmt.table_row(on=0)) # Get the events in order. ordered_events = EventAggregatorSupport.getOrderedEvents(all_shown_events) # Show the events in order. for event in ordered_events: event_page = event.getPage() event_summary = event.getSummary(parent_name) event_details = event.getDetails() # Prepare CSS classes with category-related styling. css_classes = ["event-table-details"] for topic in event_details.get("topics") or event_details.get("categories") or []: # Filter the category text to avoid illegal characters. css_classes.append("event-table-category-%s" % "".join(filter(lambda c: c.isalnum(), topic))) attrs = {"class" : " ".join(css_classes)} output.append(fmt.table_row(on=1)) # Start and end dates. output.append(fmt.table_cell(on=1, attrs=attrs)) output.append(fmt.span(on=1)) output.append(fmt.text(str(event_details["start"]))) output.append(fmt.span(on=0)) if event_details["start"] != event_details["end"]: output.append(fmt.text(" - ")) output.append(fmt.span(on=1)) output.append(fmt.text(str(event_details["end"]))) output.append(fmt.span(on=0)) output.append(fmt.table_cell(on=0)) # Location. output.append(fmt.table_cell(on=1, attrs=attrs)) if event_details.has_key("location"): output.append(fmt.text(event_details["location"])) output.append(fmt.table_cell(on=0)) # Link to the page using the summary. output.append(fmt.table_cell(on=1, attrs=attrs)) output.append(event_page.linkToPage(request, event_summary)) output.append(fmt.table_cell(on=0)) output.append(fmt.table_row(on=0)) # End of table view output. output.append(fmt.table(on=0)) # Output a list or calendar. elif mode in ("list", "calendar"): # Output top-level information. # Start of list view output. if mode == "list": output.append(fmt.bullet_list(on=1, attr={"class" : "event-listings"})) # Visit all months in the requested range, or across known events. for month in first.months_until(last): # Either output a calendar view... if mode == "calendar": # Output a month. output.append(fmt.table(on=1, attrs={"tableclass" : "event-month"})) output.append(fmt.table_row(on=1)) output.append(fmt.table_cell(on=1, attrs={"class" : "event-month-heading", "colspan" : "21"})) # Either write a month heading or produce links for navigable # calendars. output.append(view.writeMonthHeading(month)) output.append(fmt.table_cell(on=0)) output.append(fmt.table_row(on=0)) # Weekday headings. output.append(fmt.table_row(on=1)) for weekday in range(0, 7): output.append(fmt.table_cell(on=1, attrs={"class" : "event-weekday-heading", "colspan" : "3"})) output.append(fmt.text(_(EventAggregatorSupport.getDayLabel(weekday)))) output.append(fmt.table_cell(on=0)) output.append(fmt.table_row(on=0)) # Process the days of the month. start_weekday, number_of_days = month.month_properties() # The start weekday is the weekday of day number 1. # Find the first day of the week, counting from below zero, if # necessary, in order to land on the first day of the month as # day number 1. first_day = 1 - start_weekday while first_day <= number_of_days: # Find events in this week and determine how to mark them on the # calendar. week_start = month.as_date(max(first_day, 1)) week_end = month.as_date(min(first_day + 6, number_of_days)) full_coverage, week_slots = EventAggregatorSupport.getCoverage( week_start, week_end, shown_events.get(month, [])) # Output a week, starting with the day numbers. output.append(view.writeDayNumbers(first_day, number_of_days, month, full_coverage)) # Either generate empty days... if not week_slots: output.append(view.writeEmptyWeek(first_day, number_of_days)) # Or generate each set of scheduled events... else: output.append(view.writeWeekSlots(first_day, number_of_days, month, week_end, week_slots)) # Process the next week... first_day += 7 # End of month. output.append(fmt.table(on=0)) # Or output a summary view... elif mode == "list": # Output a list. output.append(fmt.listitem(on=1, attr={"class" : "event-listings-month"})) output.append(fmt.div(on=1, attr={"class" : "event-listings-month-heading"})) # Either write a month heading or produce links for navigable # calendars. output.append(view.writeMonthHeading(month)) output.append(fmt.div(on=0)) output.append(fmt.bullet_list(on=1, attr={"class" : "event-month-listings"})) # Get the events in order. ordered_events = EventAggregatorSupport.getOrderedEvents(shown_events.get(month, [])) # Show the events in order. for event in ordered_events: event_page = event.getPage() event_details = event.getDetails() event_summary = event.getSummary(parent_name) output.append(fmt.listitem(on=1, attr={"class" : "event-listing"})) # Link to the page using the summary. output.append(fmt.paragraph(on=1)) output.append(event_page.linkToPage(request, event_summary)) output.append(fmt.paragraph(on=0)) # Start and end dates. output.append(fmt.paragraph(on=1)) output.append(fmt.span(on=1)) output.append(fmt.text(str(event_details["start"]))) output.append(fmt.span(on=0)) output.append(fmt.text(" - ")) output.append(fmt.span(on=1)) output.append(fmt.text(str(event_details["end"]))) output.append(fmt.span(on=0)) output.append(fmt.paragraph(on=0)) # Location. if event_details.has_key("location"): output.append(fmt.paragraph(on=1)) output.append(fmt.text(event_details["location"])) output.append(fmt.paragraph(on=1)) # Topics. if event_details.has_key("topics") or event_details.has_key("categories"): output.append(fmt.bullet_list(on=1, attr={"class" : "event-topics"})) for topic in event_details.get("topics") or event_details.get("categories") or []: output.append(fmt.listitem(on=1)) output.append(fmt.text(topic)) output.append(fmt.listitem(on=0)) output.append(fmt.bullet_list(on=0)) output.append(fmt.listitem(on=0)) output.append(fmt.bullet_list(on=0)) # Output top-level information. # End of list view output. if mode == "list": output.append(fmt.bullet_list(on=0)) # Output view controls. output.append(fmt.div(on=1, css_class="event-controls")) output.append(view.writeViewControls()) output.append(fmt.div(on=0)) return ''.join(output)
def getQualifiedParameterName(self, argname): "Return the 'argname' qualified using the calendar name." return EventAggregatorSupport.getQualifiedParameterName(self.calendar_name, argname)
def getFullMonthLabel(self, year_month): page = self.page request = page.request return EventAggregatorSupport.getFullMonthLabel(request, year_month)