class TaskJuggler::ICalReport

This Report derivative generates iCalendar files.

Public Class Methods

new(report) click to toggle source

Create a new ICalReport with report as description.

Calls superclass method
# File lib/taskjuggler/reports/ICalReport.rb, line 23
def initialize(report)
  super
end

Public Instance Methods

generateIntermediateFormat() click to toggle source

Generate an intermediate version of the report data.

Calls superclass method
# File lib/taskjuggler/reports/ICalReport.rb, line 28
def generateIntermediateFormat
  super
  # Prepare the task list.
  @taskList = PropertyList.new(@project.tasks)
  @taskList.setSorting(a('sortTasks'))
  @taskList = filterTaskList(@taskList, nil, a('hideTask'), a('rollupTask'),
                             a('openNodes'))
  @taskList.sort!

  # Prepare the resource list. This is not yet used.
  @resourceList = PropertyList.new(@project.resources)
  @resourceList.setSorting(a('sortResources'))
  @resourceList = filterResourceList(@resourceList, nil, a('hideResource'),
                                     a('rollupResource'), a('openNodes'))
  @resourceList.sort!

  @query = @report.project.reportContexts.last.query.dup

  @ical = ICalendar.new("#{AppConfig.packageName}-#{@project['projectid']}")
  # Use the project start date of the current date (whichever is earlier)
  # for the calendar creation date.
  @ical.creationDate = [ @report.project['start'], TjTime.new ].min
  # Use the project 'now' date a last modification date.
  @ical.lastModified = @report.project['now']

  # We only care about the first requested scenario.
  scenarioIdx = a('scenarios').first
  uidMap = {}
  @taskList.each do |task|
    todo = ICalendar::Todo.new(
      @ical, "#{task['projectid', scenarioIdx]}-#{task.fullId}",
      task.name, task['start', scenarioIdx], task['end', scenarioIdx])
    # Save the ical UID of this TODO.
    uidMap[task] = todo.uid
    @query.property = task
    @query.attributeId = 'complete'
    @query.scenarioIdx = scenarioIdx
    @query.process
    todo.percentComplete = @query.to_num.to_i
    # We must convert the TJ priority range (1 - 1000) to iCalendar range
    # (0 - 9).
    todo.priority = (task['priority', scenarioIdx] - 1) / 100
    # If there is a parent task and it's known already, we set the
    # relation in the TODO component.
    if task.parent && uidMap[task.parent]
      todo.relatedTo = uidMap[task.parent]
    end
    # If we have a task note, use this for the DESCRIPTION property.
    if (note = task.get('note'))
      note = note.to_s
      todo.description = note
    end
    # Check if we have a responsible resource with an email address. Since
    # ICalendar only knows one organizer we ignore all but the first.
    organizer = nil
    if !(responsible = task['responsible', scenarioIdx]).empty? &&
       @resourceList.include?(organizer = responsible[0]) &&
       organizer.get('email')
      todo.setOrganizer(organizer.name, organizer.get('email'))
    end
    # Set the assigned resources as attendees.
    attendees = []
    task['assignedresources', scenarioIdx].each do |resource|
      next unless @resourceList.include?(resource) &&
                  resource.get('email')
      attendees << resource
      todo.addAttendee(resource.name, resource.get('email'))
    end

    # Generate an additional VEVENT entry for all leaf tasks that aren't
    # milestones.
    if task.leaf? && !task['milestone', scenarioIdx] && @report.get('novevents') == [false]
      event = ICalendar::Event.new(
        @ical, "#{task['projectid', scenarioIdx]}-#{task.fullId}",
        task.name, task['start', scenarioIdx], task['end', scenarioIdx])
      event.description = note if note
      if organizer
        event.setOrganizer(organizer.name, organizer.get('email'))
      end

      attendees.each do |attendee|
        event.addAttendee(attendee.name, attendee.get('email'))
      end
    end

    # Generate VJOURNAL entries for all the journal entries of this task.
    @report.project['journal'].
      entriesByTask(task, a('start'), a('end'),
                    a('hideJournalEntry')).each do |entry|
      journal = ICalendar::Journal.new(
        @ical, "#{task['projectid', scenarioIdx]}-#{task.fullId}",
        entry.headline, entry.date)
      journal.relatedTo = uidMap[task]
      journal.description = entry.summary.to_s + entry.details.to_s
      # Set the author of the journal entry as organizer.
      if (author = entry.author) && @resourceList.include?(author) &&
         author.get('email')
        journal.setOrganizer(author.name, author.get('email'))
      end
    end
  end
end
to_iCal() click to toggle source

Convert the intermediate format into a DOS formated String.

# File lib/taskjuggler/reports/ICalReport.rb, line 132
def to_iCal
  @ical.to_s
end