Redmine MS Project インポートプラグイン開発記録 (1)

MS Project のファイル(XML形式)を Redmine のチケットとしてインポートするプラグインを(ちょっとだけ)作ったので、経過をまとめておきます。

ソースは github に置いてあります。
http://github.com/suer/redmine_ms_projects

動機

Redmine って非常にいい感じの issue 管理システムで、Trac と違って複数プロジェクトを管理できたりで普段から使っているのですが、こんないいシステムでも使っていると不満も出てくるものです。

普段、通常プロジェクトが開始するときには線表を引いています。
それで、実際に仕事にとりかかる時に Redmine にチケットを発行していくのですがこれがまためんどくさい。
せっかく線表を引いてるのにチケットを改めて発行するなんて、なんて二度手間。と、思ったので、じゃあ MS Project を Redmine に直接インポートすればいいんじゃね? と考えたのが始まりです。
ちなみに Excel で作成した線表なんて相手にしません。めんどくさそうだから。

あと、Redmine プラグインの作成方法はきっと需要があるはず。

開発経過

プラグインディレクトリの作成

プラグインディレクトリの作成から基本的な開発方法については id:mallowlabs:20081121:1227298411 を参照。

プラグインディレクトリは
RAILS_ROOT/vendor/plugins/redmine_ms_projects
としました。

このディレクトリをPLUGIN_ROOTとします。

MS Project ファイルの読み込み

.msp ファイル(バイナリ)を解析するのは面倒なので、MSPをXML形式で保存したものを相手にすることにします。

[PLUGINROOT/app/views/msprojects/index.html.erb]

<h2><%= l(:msproject) %></h2>

<% form_for :ms_project, :url => {:action => 'index', :project_id => @project }, :html => { :multipart => true } 
do |f| %>
  <%= file_field :file, :msproject %>
  <%= submit_tag l(:button_save) %>
<% end %>

<%= @added_tasks.size if @added_tasks %>

Rais の基本通りといった感じですが、注意点といえば、ファイルをアップロードする場合は :multipart => true を忘れないこと。
私はこれをよく忘れてハマります。


さて、MSP の XMLファイルを解析するために以下のようなヘルパを書いておきます。

[PLUGINROOT/app/helpers/msprojects_helper.rb]

require "rexml/document" 
module MsprojectsHelper

  def parse_ms_project xml
    tasks = []
    doc = REXML::Document.new xml 
    doc.elements.each('//Task') do |task_tag|
      task = Task.new
      name = task_tag.elements['Name']
      task.name = name.text if name
      date = Date.new
      start_date = task_tag.elements['Start']
      task.start_date = start_date.text.split('T')[0] if start_date
      finish_date = task_tag.elements['Finish']
      task.finish_date = finish_date.text.split('T')[0] if finish_date
      create_date = task_tag.elements['CreateDate']
      date_time = create_date.text.split('T')
      task.create_date = date_time[0] + ' ' + date_time[1] if start_date
      tasks << task
    end
    tasks
  end

end

汚いなorz

やってるのは Taskタグを探してきて各種データを格納してるだけです。

メインのコントローラ

[PLUGINROOT/app/controllers/msprojects_controller.rb]

class MsprojectsController < ApplicationController
  before_filter :find_project, :authorize, :only => :index

  helper :msprojects
  include MsprojectsHelper
  
  def index
    xml = ""
    tracker = Tracker.find 1
    @added_tasks = []
    if request.post?
      xml = params[:file][:msproject].read
      @tasks = parse_ms_project(xml)
      @tasks.each do |t|
        param = {
          :subject => t.name
        }
        issue = Issue.new param
        issue.project = @project
        issue.tracker = tracker
        issue.author = User.current
        issue.start_date = t.start_date
        issue.due_date = t.finish_date
        issue.updated_on = t.create_date
        @added_tasks << t if issue.save
      end
    end
  end

  private
  def find_project
    @project = Project.find(params[:project_id])
  end
end
  • fileアップロードフォームから受け取ったファイルを読み込む

   xml = params[:file][:msproject].read 

  • 先程作成したヘルパ parse_ms_project で MSP の XMLファイルを解析

  @tasks = parse_ms_project(xml) 

  • Issueオブジェクトを生成。各種データを入力


@tasks.each do |t|
param = {
:subject => t.name
}
issue = Issue.new param
issue.project = @project
issue.tracker = tracker
issue.author = User.current
issue.start_date = t.start_date
issue.due_date = t.finish_date
issue.updated_on = t.create_date
@added_tasks << t if issue.save
end
簡単ですね

注意点としては、Issue クラスは Project クラスとか Tracker クラスとかいろんなクラスに依存があるので、単純にハッシュを渡して new できません。
あと project と tracker 属性は必須なので必ず埋めてやる必要があります。
(tracker は決めうちで 1 にしてますorz)

まとめ

以上で大体できてるわけですがやっつけすぎて実用に耐えません。
既知の問題は以下の通りです。

  • MSProjectはリソース(人)を割り当てる機能があるが、それを反映していない。MS Project に書かれた人と Redmine 上のアカウントを紐付けるインタフェースが必要
  • トラッカーがバグで固定(!)。これも選択できるインタフェースが必要
  • MSProject はタスクの階層やタスク間の依存が表現できる。これは、チケット間の関連付け機能で実現するとおもしろそう!
  • 重複するタスクがあっても新規にチケットを作成してしまう

なんにせよ Redmine プラグイン、簡単でおもしろいと思います。
Redmine プラグイン開発は、model 間の関連が把握できれば、なんとかなることが多いです。それは、ソースを読むしか無いですが。

続く Redmine MS Project インポートプラグイン開発記録 (2) - すえひろがりっっっっ!




入門Redmine Linux/Windows対応
前田 剛
秀和システム
売り上げランキング: 112182