BacklogAPI有効活用 -週次レポート-

目的

プロジェクトの課題が今週にどの程度更新され、そのうちどの程度が完了したか調べたい
プロジェクトを複数横断して、その週に更新されたチケットを集める

やってみた事

設定ファイルに記述されたプロジェクトで
その週に更新された課題を代表者のメールアドレスに送信する

送信されるレポートメールサンプル

代表者メールアドレスにその週に更新があったプロジェクト
とその課題がメール送信されます

▼ [PRJ_NAME] チケット 4件 更新 内完了 2件
[PRJ_NAME-10] 課題の概要
[PRJ_NAME-15] 課題の概要
[PRJ_NAME-22] 課題の概要
[PRJ_NAME-31] 課題の概要

 

▼ [PRJ_NAME] チケット 3件 更新 内完了 0件
[PRJ_NAME-3] 課題の概要
[PRJ_NAME-11] 課題の概要
[PRJ_NAME-20] 課題の概要

設定ファイル"config.ini"の記述例

Windowsのiniファイルの構文に従って設定ファイルを記述します

プログラム本体

 

動作確認環境

  • Python2.6.6
  • backloglib(python)

https://code.google.com/p/backloglib/

設定ファイル

プログラムと同じディレクトリに配置の上
ファイル名をconfig.iniとしてください

ソースコード

# -*- coding: utf-8 -*-

#####
## FileName:report_mail_weekly.py
## Author:Ryo Tanaka
## Version:0.1.1
## Date:2014/12/25
## Usage:./report_mail_weekly.py
## Summary:更新が今週のBACKLOGのプロジェクトサマリをメール送信します
#####

__author__ = 'tanaka'
import math
import datetime
import backloglib
import smtplib
import ConfigParser
from email.MIMEText import MIMEText
from email.Header import Header
from email.Utils import formatdate

############
# 設定項目 #
############
config_file = "config.ini"

spacename = "スペースネームを記載 xxxx.backlog.jp の部分です"
username = "API用ユーザネームを記載 APIリクエストに使うユーザ名"
password = "API用ユーザパスワードを記載 APIリクエストに使うユーザのパスワード"

smtpsvr = "メール送信サーバアドレス"
port = 25

from_addr = 'メール送信元アドレスを記載'

#
# get_week_start その週の初めを取得します
# @param today datetime.datetime.todayオブジェクト
# @return week_start 週の初めの西暦(YYYYMMDD)
#
def get_week_start(today):
    week_start = today + datetime.timedelta(days=-week_start_offset)
    week_start = week_start.strftime('%Y%m%d')
    return week_start

#
# get_week_end その週の終わりを取得します
# @param today datetime.datetime.todayオブジェクト
# @return week_end 週の終わりの西暦(YYYYMMDD)
#
def get_week_end(today):
    week_end = today + datetime.timedelta(days=week_end_offset)
    week_end = week_end.strftime('%Y%m%d')
    return week_end

#
# create_message MIMETextを作成
# @param from_addr 送信元アドレス
# @param to_addr 送信先アドレス
# @param subject 件名
# @param body メール本文
# @param encoding 文字エンコーディング
# @return msg MIMEText
#
def create_message(from_addr, to_addr, subject, body, encoding):
    msg = MIMEText(body, 'plain', encoding)
    msg['Subject'] = Header(subject, encoding)
    msg['From'] = from_addr
    msg['To'] = to_addr
    msg['Date'] = formatdate(localtime=True)
    msg['X-Priority'] = '1'
    return msg

#
# send_mail メール送信
# @param from_addr 送信元アドレス
# @param to_addr 送信先アドレス
# @param msg 送信するMIMEText
#
def send_mail(from_addr, to_addr, msg):
    smtp = smtplib.SMTP(smtpsvr, port)
    smtp.sendmail(from_addr, [to_addr], msg.as_string())
    smtp.close()

#
# make_report 報告レポート作成
# @param project プロジェクト名
# @param summary 課題の概要
# @param issue 課題キー
# @param total 課題数
# @param finish_total 完了した課題数
# @return rep 構築されたレポート
#
def make_report(project, issue, summary, total, finish_total):
    rep = u"▼ [" + project + u"]" + "\n" \
        + u"チケット " + str(total) + u"件 更新 内完了 " + str(finish_total) + u"件" + "\n" \
        + u"[" + issue + u"] " + summary + "\n"

    return rep

#
# append_report 報告レポート追記
# @param report 追記元レポート
# @param issue 追記課題キー
# @param summary 追記課題概要
#
def append_report(report, issue, summary):
    rep = report + u"[" + issue + u"] " + summary + "\n"
    return rep

# #### #
# MAIN #
# #### #
if __name__ == "__main__" :

    config = ConfigParser.SafeConfigParser()
    config.read("./config.ini")

    projects = config.get("ProjectName", "project")
    projects = projects.splitlines()

    chief_addr = config.get("ChiefAddress", "address")

    today = datetime.datetime.today()
    week_start_offset = int(str(today.weekday()))
    week_end_offset = 7 - week_start_offset
    week_start = get_week_start(today)
    week_end = get_week_end(today)

    compiled_report = ""

    backlog = backloglib.Backlog(spacename, username, password)

    for prj_index in range(len(projects)):

        project = backlog.get_project(projects[prj_index])
        report_subject = "【BACKLOG】" + project.key + "プロジェクト週次レポート"

        issues = backlog.find_issue({
                                        'projectId':project.id,
                                        'sort':"DUE_DATE",
                                        'updated_on_min':week_start,
                                        'updated_on_max':week_end,
                                        'order':1
                                   })

        issues_finished = backlog.find_issue({
                                                 'projectId':project.id,
                                                 'statusId': 4,
                                                 'sort':"CREATED",
                                                 'updated_on_min':week_start,
                                                 'updated_on_max':week_end,
                                                 'order':1
                                            })

        total = len(issues)
        total_finished = len(issues_finished)

        if len(issues) < 1:
            continue

        report = [0 for cnt in range(len(projects))]

        for issue_index in range(len(issues)):

            issue = backlog.get_issue(issues[issue_index].id)

            if issue_index == 0:
                rep_section = make_report(project.key, issues[issue_index].key, issues[issue_index].summary, total, total_finished)
                report[prj_index] = rep_section
            else:
                report[prj_index] = append_report(report[prj_index], issues[issue_index].key, issues[issue_index].summary)

        report[prj_index] = report[prj_index].encode('utf-8')
        compiled_report += report[prj_index] + "\n"

    report = "".join(map(str, report)) # 配列を結合

whole_msg = create_message(from_addr, chief_addr, report_subject, str(compiled_report), 'utf-8')
send_mail(from_addr, chief_addr, whole_msg)
exit(0)

config.iniサンプル

# 情報を取得するBACKLOGプロジェクトの名称(複数指定可)
[ProjectName]
project:TEST1
        TEST2

# 代表者メールアドレス
[ChiefAddress]
address = test@test.com

お詫び

2015/01/29 に上記ソースコードのメール送信部分にてエラーが起きてしまう部分を修正しました。

投稿者プロフィール

スカイブロガー

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


Time limit is exhausted. Please reload CAPTCHA.