SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

タスクが10倍気持ちよくなる 開発環境のリノベーション講座

イライラを解消! 乱立するRedmineの情報をまとめて確認できる環境を構築する

タスクが10倍気持ちよくなる 開発環境のリノベーション講座 第1回


プロジェクトの親子関係を保持するための実装

 ここからは、サンプルとして筆者が作成した、Redmineの情報を集約し表示するツールのコードを見ながら、プロジェクトの親子関係を保持する方法を紹介します。

 なお、この記事ページに表示するのは、説明に必要なサンプルコードの一部です。サンプルコード全体は、GitHubから入手できます。

ProjectNodeクラス

 まず、プロジェクト自身の情報とサブプロジェクトとの関係を保持する必要があります。

 プロジェクトの情報を保持するクラス ProjectNode の定義は次のようになります。

class ProjectNode(object):

    def __init__(self, project):
        self.project = project
        self.children = []
        self.has_parent = hasattr(project, u'parent')
    
    def add_child(self, child):
        self.children.append(child)

    def trace(self, family=None):
        family = [] if family is None else family
        family.append(self.project.name)
        
        self.execute(family)
    
        if len(self.children) > 0:
            for child in self.children:
                child.trace(family)
        family.pop()
    
    def execute(self, family=None):
        print("%s has %d children" % ('/'.join(family), len(self.children)))

 __init__ メソッドでは、projectインスタンスと、サブプロジェクト (子) を保持するための配列をそれぞれ初期化しています。また、自分に親がいるかどうかをチェックし、フラグhas_parentに保持します。

 trace メソッドは、親プロジェクトから自プロジェクトに至るプロジェクト名のリストを格納した family 配列に再帰的にアクセスしています。

 execute メソッドは、親を含めたプロジェクト名とサブプロジェクト数を表示するアクションを実施します。

プロジェクトツリーの構築

 Redmine上では、プロジェクトの親子関係を後から変更することもできるため、親子の順序は保証されません。そこで、いったん全プロジェクトを読み出した後に、親子関係を整理することにしました。次のコードでは、プロジェクトIDをキーにしてプロジェクト情報の実体を保持する ProjectNode オブジェクトを紐付けるマップ project_map を構築しています。

redmine = Redmine('http://redmine-server/', key='API_KEY')
projects = redmine.project.all()

project_map = {}
for project in projects:
    project_map[project.id] = ProjectNode(project)
プロジェクトのマップ例
プロジェクトのマップ例

 

 これで、すべてのプロジェクト情報をプログラム上に持つことができるので、次のようにして、このマップを元に親子関係を整理し、登録していきます。

project_root = []
for node in project_map.values():
    if node.has_parent:
        parent_id = node.project.parent.id
        project_map[parent_id].add_child(node)
    else:
        project_root.append(node)

 以上で project_root リストに、一番上位の階層のプロジェクトが登録された状態になりました。

プロジェクトツリーの探索

 プロジェクトツリーをたどる(探索する)コードは次のとおりです。

for node in project_root:
    node.trace()

 なお、Remine上のプロジェクト構造は次の図のようになっています。

実際のプロジェクト構造
実際のプロジェクト構造

 

 そのためコードの出力は、次のようにとなります。

ビジネス has 2 children
ビジネス/執筆 has 1 children
ビジネス/執筆/CodeZine 執筆 has 0 children
ビジネス/開発案件 has 0 children
ホーム has 0 children
サークル活動 has 0 children

 説明は割愛しますが、チケットについても同様の方法で親子関係を表せます。

出力フォーマッタ

 さて、Redmine 上のデータを取得して、親子関係を整理し、簡単な出力ができるところまでたどり着きました。次は、取得したプロジェクトやチケットの情報を表示する処理です。

 Webブラウザで見られるよう、データをHTMLとして整形できると良さそうです。Pythonには様々なテンプレートエンジンがありますが、GitHubで配布しているサンプルコートでは、Jinja2を選択しました。興味のある方はダウンロードしてソースコードをご覧ください。

まとめ

 ここまで、実装例も混ぜながら、RedmineのREST APIの使い方、取得したデータ構造、親子関係の扱い方を紹介してきました。

 紹介したのは基本的な部分(REST APIによる情報の取得)だけでしたが、これをベースにアイデア次第でいろいろ機能を追加・拡張できると思います。例えば、次のようなものを検知して出力に反映することができます。

  • 期日が近づいている、もしくは過ぎてしまったチケット
  • 担当者が指定されていないチケット
  • 更新が滞っているチケット

 また、今回は、プロジェクト単位でチケットを整理しましたが、担当者ごとのチケットを出力することも可能です。皆さんもいろいろ考えて実装してみてください。

 次回もテーマはREST APIで情報を登録する技術です。例として、運用管理ツール「Zabbix」からのアラートをもとにRedmineのチケットを起票する方法を紹介する予定です。お楽しみに。

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
タスクが10倍気持ちよくなる 開発環境のリノベーション講座連載記事一覧
この記事の著者

中島 隆明(株式会社ワークスアプリケーションズ)(ナカジマ タカアキ)

株式会社ワークスアプリケーションズ所属。R&D部門であるATE Div.に在籍し、パッケージソフトウェアを支える、インフラやOS、ミドルウェアといったシステムエンジニアリング領域を主に担当。CompTIA Cloud Essentials認定取得。趣味はジャズをはじめとした音楽全般。 ・Web s...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/8331 2014/12/16 11:15

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー