Skip to content
Browse files

Merge branch 'master' of https://git.fachschaften.org/redmine_ical

  • Loading branch information...
2 parents 92aa211 + 41b7547 commit 1abf3c62e3eb87364ef298846fa1aaaf5c1202bc @cole committed Jan 18, 2011
View
17 README.rdoc
@@ -1,17 +0,0 @@
-= redmine_icalendar_export (redmics)
-
-ICalendar (ICS) view of issue- and version-deadlines.
-
-== Licence
-
-GPL v2
-
-== Requirements
-
-This plug-in requires icalendar >= 1.1.5 (http://icalendar.rubyforge.org/).
-
-Further, a the hook view_calendars_show_bottom needs to be present in app/views/calendars/show.html.erb. The hook is not yet in Redmine core, a patch can be found in extra/. If you want this hook in Redmine Core to avoid patching your Redmine, please vote for it here: http://www.redmine.org/issues/6586
-
-== Implementation details
-
-Issues are exported as VEVENT-items with their due-date as the event date. The same applies to versions. Unassigned issues have the status TENTATIVE.
View
29 README.textile
@@ -0,0 +1,29 @@
+h1. Redmine Ical
+
+ICalendar (ICS) view of issue and version due dates.
+
+h2. Requirements
+
+* icalendar >= 1.1.5 (http://icalendar.rubyforge.org/).
+
+h2. Installation
+
+Generic Redmine plugin installation instructions can be found in the "Redmine wiki":http://www.redmine.org/wiki/redmine/Plugins#Installing-a-plugin.
+
+Note that this plugin doesn't require a database migration but 2 patches included in the @extra@ folder. The gist of it is: go to your redmine directory, run the following commands and restart redmine:
+
+<pre>git clone https://git.fachschaften.org/redmine_ical
+patch -p 1 < vendor/plugins/redmine_ical/extra/ics_format_accepts_key_auth.patch
+patch -p 1 < vendor/plugins/redmine_ical/extra/view_calendars_show_bottom_hook.patch</pre>
+
+h2. Features
+
+Issue and version due dates are exported as calendar events.
+
+The plugin is "custom query"-aware, thus you can add @&query_id=1@ to the link generated by redmine to see only issues as per the custom query with ID 1. Sadly the Redmine User Interface is lacking in that regard and I haven't found a nice way to auto-generate those URLs.
+
+You can also navigate to a global calendar to view all your issues and versions accross the whole redmine by going to http://your.redmine/issues/calendar, the link to the ical view is available there too.
+
+h2. License
+
+GPL v2.0 (the full text of the license is included with the plugin)
View
117 app/controllers/i_calendar_controller.rb
@@ -1,117 +0,0 @@
-# redmics - redmine icalendar export plugin
-# Copyright (c) 2010 Frank Schwarz, frank.schwarz@buschmais.com
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
-require 'icalendar'
-
-class ICalendarController < ApplicationController
- before_filter :find_optional_project
- accept_key_auth :index
-
- def index
- # project
- project_condition = @project ? ["#{Project.table_name}.id IN (?)", ([@project.id] + @project.descendants.collect(&:id))] : nil
-
- # issue status
- case params[:status]
- when 'all'
- status_condition = []
- when 'open'
- status_condition = ["#{IssueStatus.table_name}.is_closed = ?", false]
- else
- status_condition = nil
- end
-
- # assignment
- case params[:assigned_to]
- when 'me'
- assigned_to_condition = ["assigned_to_id = #{User.current.id}"]
- when '+'
- assigned_to_condition = ["assigned_to_id is not null"]
- when '*'
- assigned_to_condition = []
- else
- end
-
- events = []
- # queries
- unless status_condition.nil? || assigned_to_condition.nil?
- c = ARCondition.new(project_condition)
- c << status_condition unless status_condition.empty?
- c << assigned_to_condition unless assigned_to_condition.empty?
- events += Issue.find(
- :all,
- :include => [:tracker, :assigned_to, :priority, :project, :status, :fixed_version, :author],
- :conditions => c.conditions
- )
- end
- events += Version.find(
- :all,
- :include => [:project],
- :conditions => project_condition
- )
-
- @cal_string = create_calendar(events).to_ical
- send_data @cal_string, :type => Mime::ICS, :filename => 'issues.ics'
- end
-
-private
-
- def find_optional_project
- @project = Project.find_by_identifier(params[:project_id])
- end
-
- def create_calendar(events)
- cal = Icalendar::Calendar.new
- events.each { |i|
- if (i.due_date == nil) && (i.is_a? Issue) && (i.fixed_version != nil)
- i.due_date = i.fixed_version.due_date
- end
- if i.due_date == nil
- next
- end
- event = Icalendar::Event.new
- event.dtstart i.due_date, {'VALUE' => 'DATE'}
- event.dtend i.due_date + 1, {'VALUE' => 'DATE'}
- project_prefix = @project.nil? ? "#{i.project.name}: " : "" # add project name if this is a global feed
- if i.is_a? Issue
- event.summary "#{project_prefix}#{i.subject} (#{i.status.name})"
- event.url url_for(:controller => 'issues', :action => 'show', :id => i.id, :project_id => i.project.identifier)
- unless i.fixed_version.nil?
- event.categories [i.fixed_version.name]
- end
- contacts = [i.author, i.assigned_to] + i.watcher_users
- contacts.compact.uniq.each do |contact|
- event.add_contact contact.name, {"ALTREP" => contact.mail}
- end
- event.organizer "mailto:#{i.author.mail}", {"CN" => i.author.name}
- event.status i.assigned_to == nil ? "TENTATIVE" : "CONFIRMED"
- event.created i.created_on.to_date, {'VALUE' => 'DATE'}
- elsif i.is_a? Version
- event.summary "#{project_prefix}%s '#{i.name}'" % l(:label_calendar_deadline)
- event.url url_for(:controller => 'versions', :action => 'show', :id => i.id)
- else
- end
- unless i.description.nil?
- event.description = i.description
- end
- cal.add_event(event)
- }
- return cal
- end
-
-end
-
View
5 app/views/calendars/_additional_ical_links.html.erb
@@ -0,0 +1,5 @@
+<% if User.current.allowed_to?(:view_calendar, @project, :global => true)%>
+ <% other_formats_links do |f| %>
+ <%= f.link_to 'ICS', :url => params.merge({:key => User.current.rss_key, :format => 'ics'}) %>
+ <% end %>
+<% end %>
View
5 app/views/hooks/redmine_icalendar_export/_view_calendars_show_bottom.html.erb
@@ -1,5 +0,0 @@
-<% if User.current.allowed_to?(:view_calendar, @project, :global => true)%>
- <% other_formats_links do |f| %>
- <%= f.link_to 'ICS', :url => { :status => 'all', :assigned_to => '*', :controller => 'i_calendar', :action => 'index', :project_id => @project, :key => User.current.rss_key, :format => 'atom' } %>
- <% end %>
-<% end %>
View
9 config/locales/de.yml
@@ -1,9 +0,0 @@
-# German strings go here
-de:
- label_icalendar_header: ICalendar
- label_issues_mine: Meine Tickets
- label_issues_assigned: Zugewiesene Tickets
- label_issues_all: Alle Tickets
- label_issues_open_only: nur offene
- label_calendar_deadline: Ende
-
View
8 config/locales/en.yml
@@ -1,8 +0,0 @@
-# English strings go here
-en:
- label_icalendar_header: ICalendar
- label_issues_mine: My issues
- label_issues_assigned: Assigned issues
- label_issues_all: All issues
- label_issues_open_only: open only
- label_calendar_deadline: deadline
View
8 config/locales/es.yml
@@ -1,8 +0,0 @@
-# Spanish strings go here
-es:
- label_icalendar_header: ICalendar
- label_issues_mine: Mis peticiones
- label_issues_assigned: Peticiones asignadas
- label_issues_all: Todas peticiones
- label_issues_open_only: sólo abiertas
- label_calendar_deadline: fin
View
13 extra/ics_format_accepts_key_auth.patch
@@ -0,0 +1,13 @@
+diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
+index 803eb5f..b69e458 100644
+--- a/app/controllers/application_controller.rb
++++ b/app/controllers/application_controller.rb
+@@ -68,7 +68,7 @@ class ApplicationController < ActionController::Base
+ user = User.try_to_autologin(cookies[:autologin])
+ session[:user_id] = user.id if user
+ user
+- elsif params[:format] == 'atom' && params[:key] && accept_key_auth_actions.include?(params[:action])
++ elsif %w(atom ics).include?(params[:format]) && params[:key] && accept_key_auth_actions.include?(params[:action])
+ # RSS key authentication does not start a session
+ User.find_by_rss_key(params[:key])
+ elsif Setting.rest_api_enabled? && api_request?
View
22 init.rb
@@ -1,6 +1,7 @@
-# redmics - redmine icalendar export plugin
+# redmine_ical
# Copyright (c) 2010 Frank Schwarz, frank.schwarz@buschmais.com,
# Jan Schulz-Hofen (Planio), jan@plan.io
+# Felix Schäfer, felix@fachschaften.org
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
@@ -17,16 +18,21 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
require 'redmine'
+require 'dispatcher'
-require 'redmine_icalendar_export/hooks'
+Dispatcher.to_prepare do
+ require 'redmine_ical/patch_redmine_classes'
+end
+
+require_dependency 'redmine_ical/view_hooks'
-Redmine::Plugin.register :redmine_icalendar_export do
- name 'redmine icalendar export plugin (aka redmics)'
- author 'Frank Schwarz, Jan Schulz-Hofen (Planio)'
+Redmine::Plugin.register :redmine_ical do
+ name 'Redmine Ical Plugin'
+ author 'Felix Schäfer (based on work from Frank Schwarz and Jan Schulz-Hofen (Planio))'
description 'ICalendar view of issue- and version-deadlines'
- version '1.1'
- url 'http://code.google.com/p/redmics/'
- author_url 'http://www.buschmais.de/'
+ version 'thegcat-trunk'
+ url 'https://orga.fachschaften.org/projects/redmine_ical'
+ author_url 'http://orga.fachschaften.org/users/3'
end
View
147 lib/redmine_ical/patch_redmine_classes.rb
@@ -0,0 +1,147 @@
+# redmine_ical
+# Copyright (c) 2010 Frank Schwarz, frank.schwarz@buschmais.com,
+# Jan Schulz-Hofen (Planio), jan@plan.io
+# Felix Schäfer, felix@fachschaften.org
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+require_dependency 'calendars_controller'
+require_dependency 'issue'
+require_dependency 'version'
+
+require 'icalendar'
+
+module Plugin
+ module Ical
+ module CalendarsController
+ module ClassMethods
+
+ end
+
+ module InstanceMethods
+ def show_with_ical
+ respond_to do |format|
+ format.html { show_without_ical }
+ format.ics { render :text => ical, :layout => false }
+ end
+ end
+
+ def ical
+ # retrieve events 3 months old or newer
+ retrieve_query
+ @query.group_by = nil
+ @events = []
+ three_months_ago = 3.months.ago
+ if @query.valid?
+ @events += @query.issues(:include => [:tracker, :assigned_to, :priority],
+ :conditions => ["((start_date >= ?) OR (due_date >= ?))", three_months_ago, three_months_ago])
+ @events += @query.versions(:conditions => ["effective_date >= ?", three_months_ago])
+ end
+ cal = Icalendar::Calendar.new
+ cal.product_id = "+//IDN fachschaften.org//redmine_ical//EN"
+ html_title(@query.new_record? ? l(:label_calendar) : @query.name) # tricks redmine into outputting a pretty title on next call of html_title
+ cal.custom_property("X-WR-CALNAME;VALUE=TEXT", html_title)
+ @events.each do |event|
+ e = event.to_ical_hash
+ return unless e
+ e[:url] = url_for(:controller => e[:type].to_s.pluralize, :action => 'show', :id => e[:id], :only_path => false)#, :host => request.host, :port => request.port, :protocol => request.protocol)
+ cal.event do
+ summary e[:summary]
+ description e[:description]
+ created e[:created].to_datetime
+ last_modified e[:updated].to_datetime
+ dtstart e[:date], {"VALUE" => ["DATE"]}
+ dtend e[:date]+1, {"VALUE" => ["DATE"]}
+ uid "redmine:#{e[:type].to_s}-#{e[:id]}@#{defined?(request) ? request.host : ::Socket.gethostname}"
+ url e[:url]
+ end
+ end
+ cal.to_ical
+ end
+ end
+
+ def self.included(receiver)
+ receiver.extend ClassMethods
+ receiver.send :include, InstanceMethods
+ receiver.class_eval do
+ unloadable
+ include ApplicationHelper
+ alias_method_chain :show, :ical
+ accept_key_auth :show
+ end
+ end
+ end
+
+ module Issue
+ module ClassMethods
+ end
+
+ module InstanceMethods
+ def to_ical_hash
+ date = due_date
+ date ||= fixed_version.due_date if fixed_version
+ return unless date
+ {:summary => "#{project.name} - #{tracker.name} ##{id}: #{subject}",
+ :description => description,
+ :created => created_on,
+ :updated => updated_on,
+ :date => date,
+ :type => :issue,
+ :id => id
+ }
+ end
+ end
+
+ def self.included(receiver)
+ receiver.extend ClassMethods
+ receiver.send :include, InstanceMethods
+ receiver.class_eval do
+ unloadable
+ end
+ end
+ end
+
+ module Version
+ module ClassMethods
+ end
+
+ module InstanceMethods
+ def to_ical_hash
+ return unless due_date
+ {:summary => "#{project.name} - #{name}",
+ :description => description,
+ :created => created_on,
+ :updated => updated_on,
+ :date => due_date,
+ :type => :version,
+ :id => id
+ }
+ end
+ end
+
+ def self.included(receiver)
+ receiver.extend ClassMethods
+ receiver.send :include, InstanceMethods
+ receiver.class_eval do
+ unloadable
+ end
+ end
+ end
+ end
+end
+
+CalendarsController.send(:include, ::Plugin::Ical::CalendarsController)
+Issue.send(:include, ::Plugin::Ical::Issue)
+Version.send(:include, ::Plugin::Ical::Version)
View
12 lib/redmine_icalendar_export/hooks.rb → lib/redmine_ical/view_hooks.rb
@@ -1,6 +1,7 @@
-# redmics - redmine icalendar export plugin
+# redmine_ical
# Copyright (c) 2010 Frank Schwarz, frank.schwarz@buschmais.com,
# Jan Schulz-Hofen (Planio), jan@plan.io
+# Felix Schäfer, felix@fachschaften.org
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
@@ -15,8 +16,11 @@
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-module RedmineIcalendarExport
- class ViewHooks < Redmine::Hook::ViewListener
- render_on :view_calendars_show_bottom, :partial => 'hooks/redmine_icalendar_export/view_calendars_show_bottom'
+
+module Plugin
+ module Ical
+ class ViewHooks < Redmine::Hook::ViewListener
+ render_on :view_calendars_show_bottom, :partial => 'calendars/additional_ical_links'
+ end
end
end

0 comments on commit 1abf3c6

Please sign in to comment.
Something went wrong with that request. Please try again.