すえひろがりっっっっ! このページをアンテナに追加 RSSフィード

2014-12-07

Spotlight から素早く Things にタスクを追加する Flashlight プラグインを作った

Spotlightプラグインシステム Flashlight を使って、Things にタスクを追加する Spotlight プラグインを作りました。

https://github.com/suer/flashlight-things-plugin

環境

セットアップ

1. Flashlightインストール

2. プラグインインストールする

    $ git clone https://github.com/suer/flashlight-things-plugin.git ~/Library/FlashlightPlugins/things.bundle

3. Flashlight を有効にする

f:id:suer:20141206225639p:image:w500

タスクを追加してみる

Spotlight を起動し、th もしくは things の後ろに追加したいタスクを記入する。

f:id:suer:20141206225637p:image:w500

クイック入力のビューが表示されるので、適宜補完して保存する。

f:id:suer:20141206225638p:image

まとめ

Flashlight を使えば、Spotlight に簡単に機能を追加できて便利。

2010-04-10

Cronのスケジュール記法を解決する

Rails + BackgrounDRb 環境で、柔軟なスケジューリングをしたくて、Cron の記法を簡単に解決できないかなぁ、とBackgrounDRbのソースを読んでいたら、CronTrigger という便利なクラスがありました。

これを使えば Rails アプリから柔軟にスケジュールを制御できていい感じ。

# cron_test.rb
require 'vendor/plugins/backgroundrb/server/lib/cron_trigger'

cron = BackgrounDRb::CronTrigger.new("*/10 * 8-20 * * * *")
p cron.sec    # 秒
p cron.min   # 分
p cron.hour # 時

$ ruby cron_test.rb
[0, 10, 20, 30, 40, 50]
0..59
[8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

それぞれ秒、分、時間が配列で返るようです。

BackgrounDRb は cron と違って秒と年が追加されているので注意。

これを使って、

class CreateSchedules < ActiveRecord::Migration
  def self.up
    create_table :schedules do |t|
      t.column :cron, :string          # スケジュール
      t.column :task_id, :integer   # タスクを表すテーブルへの外部キーのイメージ
      t.timestamps
    end
  end

  def self.down
    drop_table :schedules
  end
end

のようにテーブルを作成して、カラムcronにスケジュールを入れるようにします。

class Schedule < ActiveRecord::Base
  def self.find_triggered(time = Time.now)
    find(:all).select do |sched|
      cron = BackgrounDRb::CronTrigger.new(sched.cron)
      cron.sec.include?(time.sec) and cron.min.include?(time.min) and cron.hour.include?(time.hour)
    end
  end  
end

のようにしておけば、Schedule.find_triggered で実行すべきタスクを取得できるようになります。

(注) 秒、分、時間以外は無視しています。

とても便利なのでCronTrigger.rb だけ切り出したい。

2009-11-15

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

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

の続き。

プログラムは github から。

http://github.com/suer/redmine_ms_projects

今回の修正でなんとか使えるんじゃないかな。

前回からの残課題

のうち以下を潰しました。

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

スナップショット

MSPファイルの選択画面

対応しているのは XML 形式のみです。

MS Project で XML 形式で保存したものを選択してください。

f:id:suer:20091116000040p:image

インポートするタスクの選択画面

トラッカーと担当を選択することができます。

既に同じ名前のサブジェクトがある場合、そのチケットを更新します。

無い場合は新規にチケットを発行します。

f:id:suer:20091116000039p:image


更新、追加されたチケットの一覧表示画面

f:id:suer:20091116000615p:image

これだけです。

残課題

  • MS Project の方で「リソース」を割り当てているはずなので担当は自動的に決められるのですが、MSP ではタスクに対して複数リソースを割り当てられるのに対して、Redmine のチケットは一人にしか割り当てられません。これをどうするか、、、
  • 見た目をなんとかする。
  • XML でどんくさいことしてるのでなおす
  • チケット間の関連付けを MSP から持ってくる




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

2009-09-25

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

2007-04-10

{OpenGrok

クロスリファレンサです.

Tomcat で動きます.

Mac OS X 10.4.9 で実験してみました.

コンパイル

Ant の JFlex タスクが必要です.

JFlex

ここから落としてきて展開.

lib/JFlex.jar を Ant 実行時のクラスパスが通るところに置きます.

あとは,

 
 $ ant webapp 

で source.war というファイルができるのでこれを配備するとこれで一応動きます.

タグの作成

 $ java -jar opengrok.jar -s SRC_DIR DATA_DIR 

で, SRC_DIR 以下のソースを解析して DATA_DIR にタグを作ります.

ただしこのとき,Exuberant Ctags が実行できない,と言われます.

Mac の /usr/bin/ctags はそれではないっぽいので,新にインストールします.

Exuberant Ctags

ここからダウンロードしてきてインストール

通常通り, configure; make; make install で行けます.

特に設定しなければ,/usr/local/bin/ctags にインストールされます.

ctags をインストール後,先程のコマンドに -c オプションで ctags のパスを指定すると

 $ java -jar opengrok.jar -s SRC_DIR DATA_DIR -c /usr/local/bin/ctags 

タグが作成されます.

Web アプリ側の設定

web.xml の DATA_ROOT と SRC_ROOT の値をディレクトリを絶対パスで書きます.

以上で動きます.

動作

20070410-opengrok_enter.png

ブラウザでアクセスするとこんな感じ.

20070410-opengrok_expect.png

検索で一つも引っ掛からない場合,似た感じの単語を教えてくれる.

20070410-opengrok_dir.png

File Path: で検索するとディレクトリ探索もできる.