Redmine

Redmineのチケット呟きTwitterBOT

投稿日:

プロジェクト管理ソフトウェアのひとつにRedmineというものがあります。
Ruby on Railsで構築するWebベースのソフトウェアで、ソフトウェア工房で立ち上がっている色んなプロジェクトを管理していけたらいいなーなんて考えています。

今回はそのRedmineに登録されたチケット(タスク)を、ランダムで定期的に呟くTwitterBOTを作ってみましたので、記録しておきます。

動作環境は、

  • CentOS6.5でサーバ構築済み
  • 学内Proxyを通している
  • Redmine構築済み(プロジェクトは立ってて、チケットも入ってる)

で、Pythonに関して使ったものは、

本体 Python2.7.5
パッケージ管理 pip
Pythonのバージョン管理 virtualenv(virtualenvwrapper)
DBパッケージ MySQL-python(1.2.5)
Twitterパッケージ twitter(1.10.2)

で、作業内容は、

  • Pythonの設定をする
  • RedmineのDB構造を調べる
  • Twitterのアカウントを作成し、トークンキーを取得する
  • プログラムを書く
  • cronを設定する

です。

Pythonの設定をする


Pythonは弄ったことがなく、当然設定も何もしていなかったので、1から準備する必要があります。

まず、CentOS6.5に入っているデフォルトのPythonも、yumで取得できるPythonも、ちょっと古いVer2.6なので、新しいPythonを手動で導入する必要があります。
Pythonは現在3.3が最新のメジャーバージョンなのですが、2.xと3.xで構文がだいぶ変わっており、ライブラリ互換のために2.7.xでバグフィックスリリースのみ行われています。
今回使用するtwitterのライブラリも3.xには対応していないため、2.7.5を導入します。

しかし、今後の利用も考え、irtualenv(virtualenvwrapper)を使って仮想環境を切り替え、複数バージョンを利用できるようにしました。
参考: http://qiita.com/fukkyy/items/d0f5b8b4819f055c6dee

PHPにpearがあるように、Pythonにもパッケージ(ライブラリ)管理システムとして、pipがあります。
使い方はpearとかyumとかと同じで、 pip install でインストール、 pip list インストール済パッケージリストです。

他にもeasy_installとか、distributeとか、setuptoolsとか色々あるようですが、よくわからなかったので、pipとvirtualenvを使ってます(Pythonのインストールは手動)。

virtualenvでpython2.7の環境を選択したら、pipで必要なパッケージを導入していきます。
MySQLのパッケージはMySQL-pythonでいいのですが、TwitterのパッケージはProxy周りで色々と問題があり、tweepy、python-twitterは使えませんでした。
試行錯誤した挙句、そのまんまの名前 twitter というパッケージがProxy環境下でも使えたので、これを採用しました。
(たぶんごにょごにょすれば、他のパッケージでもProxy環境下で使えます。たぶん。)
参考:
https://pypi.python.org/pypi/MySQL-python/1.2.5
https://pypi.python.org/pypi/twitter

RedmineのDB構造を調べる


RedmineのデータベースはMySQLで管理されており、db_redmineというデータベース名です。

mysql>use db_redmine
Database changed
mysql>show tables;
+-------------------------------------+
| Tables_in_db_redmine                |
+-------------------------------------+
| attachments                         |
| auth_sources                        |
| boards                              |
| changes                             |
| changeset_parents                   |
| changesets                          |
| changesets_issues                   |
| comments                            |
| custom_fields                       |
| custom_fields_projects              |
| custom_fields_trackers              |
| custom_values                       |
| documents                           |
| enabled_modules                     |
| enumerations                        |
| groups_users                        |
| issue_categories                    |
| issue_relations                     |
| issue_statuses                      |
| issues                              |
| journal_details                     |
| journals                            |
| member_roles                        |
| members                             |
| messages                            |
| news                                |
| open_id_authentication_associations |
| open_id_authentication_nonces       |
| projects                            |
| projects_trackers                   |
| queries                             |
| repositories                        |
| roles                               |
| schema_migrations                   |
| settings                            |
| time_entries                        |
| tokens                              |
| trackers                            |
| user_preferences                    |
| users                               |
| versions                            |
| watchers                            |
| wiki_content_versions               |
| wiki_contents                       |
| wiki_pages                          |
| wiki_redirects                      |
| wikis                               |
| workflows                           |
+-------------------------------------+

RoRで作成されたテーブルなので、全部末尾にsがついていますね。
かなり分かりやすい構造と名前になっています。

今回使うのは、チケット一覧が格納されているissuesと、その状態を表すissue_statuses、プロジェクト一覧のprojectsです。
他にもissuesは外部キーをたくさん持っているので、descで調べると面白いです。

Twitterアカウントを作成し、トークンキーを取得する


Bot用にTwitterの新規アカウントを作成して、アプリケーションを登録し、OAuth認証に必要なトークンキーを取得します。
参考: http://d.hatena.ne.jp/killinsun/20130606/1370542828

プログラムを書く


準備は整ったので、PythonでMySQLからチケットを取り出しTwitterで呟くプログラムを書いていきます。
といっても、ライブラリを使うだけなので、数行で書けます。

# -*- coding: utf-8 -*-
import os
import random
from twitter import *
import MySQLdb

# 設定
CONSUMER_KEY        = '****'
CONSUMER_SECRET     = '****'
ACCESS_TOKEN        = '****'
ACCESS_TOKEN_SECRET = '****'
DB_DB = 'db_redmine'
DB_USER = 'root'
DB_PW = ''****''
DB_CHARSET = 'utf8'

db = MySQLdb.connect(db=DB_DB, user=DB_USER, passwd=DB_PW, charset=DB_CHARSET)
cursor = db.cursor(MySQLdb.cursors.DictCursor)

# RMSプロジェクトから未完了のチケットのみを取得する
cursor.execute(
        'select iss.id as id, st.name as state, iss.subject as name '
        'from issues as iss '
        'join issue_statuses as st on st.id = iss.status_id '
        'join projects as p on p.id = iss.project_id '
        'where st.name <> "完了" and p.name = "RMS"')

# ランダムに一つ選ぶ
ticket = random.choice(cursor.fetchall())

# コメント内容を整形
tweet = u'[{}]{}: {}'.format(ticket['state'], ticket['id'], ticket['name'])

# 呟く!
api = Twitter(auth=OAuth(ACCESS_TOKEN, ACCESS_TOKEN_SECRET, CONSUMER_KEY, CONSUMER_SECRET))
api.statuses.update(status = tweet)

簡単ですね。
※コメント内容が140文字以上になった場合の処理はしてません

cronを設定する


後はcronで実行するシェルスクリプトを書き、実行するだけなのですが、ここで2つポイントがあるので注意です。

#!/bin/bash
source ~/.virtualenvs/py27/bin/activate
export https_proxy=****
python ~/bot/redmine_issues.py

まず、cronで実行するシェルスクリプト内ではvirtualenvwrapperのwork onは使えません
そのため、virtualenvを直接叩く必要があります(2行目)。

次に、Proxyの設定です(3行目)。
直接シェルスクリプトを叩く場合は問題ないのですが、cronはシステムのProxy設定を読んでくれないため、通りません。
しかも、下記の3つの設定方法は無視されます。

#export HTTP_PROXY=****
#export http_proxy=****
#export HTTPS_PROXY=****

私の大学のProxy環境が特殊なのかわかりませんが、そういうものみたいです。

ここまでできたら、あとはcrontab -eで設定を追加すれば終わりです。

0 8,16 * * * /root/cron/redmine_issues

毎日8:00、16:00に先ほどのシェルスクリプトを叩いてくれます。

完成


 

これで起床後や夕方のプロジェクト活動前にちょっとした刺激を貰えますね。

アイコンが素っ気ないので変えたいのですが、どなたか作っていただけないでしょうか(ソフトウェア工房ではデザイナーを募集しています!!)。

  • この記事を書いた人
  • 最新記事
アバター

snakazawa

好きなこと・分野: プロジェクト活動,ソフトウェア工学,アルゴリズム
OBです。

-Redmine
-, , ,

Copyright© ソフトウェア工房 , 2019 All Rights Reserved Powered by AFFINGER5.