Пример #1
0
    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()
Пример #2
0
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)
Пример #3
0
    def getQualifiedParameterName(self, argname):

        "Return the 'argname' qualified using the calendar name."

        return EventAggregatorSupport.getQualifiedParameterName(self.calendar_name, argname)
Пример #4
0
 def getFullMonthLabel(self, year_month):
     page = self.page
     request = page.request
     return EventAggregatorSupport.getFullMonthLabel(request, year_month)