Project

General

Profile

Feature #1077 » redmine-0.9-stable-roadmap-icalendar-ics-export.patch

iCal integration (webcal subscription, ics export) - y v, 2010-05-30 18:23

View differences:

app/controllers/projects_controller.rb (working copy)
15 15
# along with this program; if not, write to the Free Software
16 16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17 17

  
18
require 'vpim/icalendar'
19

  
18 20
class ProjectsController < ApplicationController
19 21
  menu_item :overview
20 22
  menu_item :activity, :only => :activity
......
27 29
  before_filter :authorize, :except => [ :index, :list, :add, :copy, :archive, :unarchive, :destroy, :activity ]
28 30
  before_filter :authorize_global, :only => :add
29 31
  before_filter :require_admin, :only => [ :copy, :archive, :unarchive, :destroy ]
30
  accept_key_auth :activity
32
  accept_key_auth :activity, :roadmap
31 33
  
32 34
  after_filter :only => [:add, :edit, :archive, :unarchive, :destroy] do |controller|
33 35
    if controller.request.post?
......
318 320
    
319 321
    @versions = @project.shared_versions.sort
320 322
    @versions.reject! {|version| version.closed? || version.completed? } unless params[:completed]
321
    
322 323
    @issues_by_version = {}
323 324
    unless @selected_tracker_ids.empty?
324 325
      @versions.each do |version|
......
328 329
                                                   :order => "#{Project.table_name}.lft, #{Tracker.table_name}.position, #{Issue.table_name}.id")
329 330
        @issues_by_version[version] = issues
330 331
      end
332
    end    
333
    @versions.reject! {|version| !project_ids.include?(version.project_id) && @issues_by_version[version].empty?}        
334
    respond_to do |format|        
335
      format.html
336
      format.ics do      
337
        calendar = Vpim::Icalendar.create2('Redmine')      
338
        @versions.each do |version|      
339
          calendar.add_event do |event|
340
            if version.effective_date
341
              event.dtstart       version.effective_date
342
              event.dtend         version.effective_date
343
              event.summary       "#{version.project.name} #{version.name}"
344
              event.description   version.description
345
              event.url           url_for(:controller => 'versions', :action => 'show', :id => version)
346
            end
347
          end
348
                            
349
          @issues_by_version[version].each do |issue|                      
350
            options = []
351
            options.push Vpim::DirectoryInfo::Field.create('SUMMARY', issue.subject)
352
            options.push Vpim::DirectoryInfo::Field.create('DTSTART;VALUE=DATE', issue.start_date) if issue.start_date
353
            options.push Vpim::DirectoryInfo::Field.create('DUE;VALUE=DATE', issue.due_date) if issue.due_date
354
            options.push Vpim::DirectoryInfo::Field.create('DESCRIPTION', issue.description) if issue.description
355
            options.push Vpim::DirectoryInfo::Field.create('URL', url_for(:controller => 'issues', :action => 'show', :id => issue))
356
           
357
            # See http://tools.ietf.org/html/rfc2445#section-4.8.1.9
358
            if issue.priority              
359
              priority = case issue.priority.position
360
                when Range.new(0, IssuePriority.active.default.position, true) then '9'
361
                when IssuePriority.active.default.position then '5'
362
                else '1'
363
              end                   
364
              options.push Vpim::DirectoryInfo::Field.create('PRIORITY', priority)        
365
            end
366
            
367
            # See http://tools.ietf.org/html/rfc2445#section-4.8.1.11
368
            if issue.closed? 
369
              options.push Vpim::DirectoryInfo::Field.create('STATUS', 'COMPLETED')  
370
              options.push Vpim::DirectoryInfo::Field.create('COMPLETED', issue.updated_on)           
371
            end                        
372
            calendar.push Vpim::Icalendar::Vtodo.create(options)                                                          
373
          end
374
        end
375
        render :text => calendar.encode  
376
      end    
331 377
    end
332
    @versions.reject! {|version| !project_ids.include?(version.project_id) && @issues_by_version[version].empty?}
378

  
333 379
  end
334 380
  
335 381
  def activity
app/views/projects/roadmap.rhtml (working copy)
41 41

  
42 42
<h3><%= l(:label_version_plural) %></h3>
43 43
<% @versions.each do |version| %>
44
<%= link_to format_version_name(version), "##{version.name}" %><br />
44
  <%= link_to format_version_name(version), "##{version.name}" %><br />
45 45
<% end %>
46

  
47
<h3>Export</h3>
48
<%= link_to 'iCalendar', :controller => 'projects', :action => 'roadmap', :format => 'ics', :key => User.current.rss_key, :only_path => false, :protocol => 'webcal' %><br />
49
<%= link_to 'iCalendar (ICS Export)', :controller => 'projects', :action => 'roadmap', :format => 'ics', :key => User.current.rss_key %>
50

  
46 51
<% end %>
47 52

  
48 53
<% html_title(l(:label_roadmap)) %>
config/routes.rb (working copy)
178 178
      project_views.connect 'projects.:format', :action => 'index'
179 179
      project_views.connect 'projects/new', :action => 'add'
180 180
      project_views.connect 'projects/:id', :action => 'show'
181
      project_views.connect 'projects/:id/:action', :action => /roadmap|destroy|settings/
181
      project_views.connect 'projects/:id/:action', :action => /destroy|settings/
182
      project_views.connect 'projects/:id/roadmap.:format', :action => 'roadmap'
182 183
      project_views.connect 'projects/:id/files', :action => 'list_files'
183 184
      project_views.connect 'projects/:id/files/new', :action => 'add_file'
184 185
      project_views.connect 'projects/:id/versions/new', :action => 'add_version'
(6-6/12)