python-redmineでRedmineの作業記録を一括入力する
python-redmineでRedmineの作業記録を一括入力する

python-redmineでRedmineの作業記録を一括入力する

redmineベースのプロジェクト管理を行っているチームでは、redmineの作業記録を毎日入力する必要があります。

 

基本的には、毎日異なった記録を入力する日課になるはずですが、立場によっては毎日同じ稼働を記録することとなります。

 

そこで、python3のライブラリ「python-redmine」を使用した「作業時間の記録」の投入方法を記録してみます。

 

python-redmineでredmineを操作

今回使用するライブラリ「python-redmine」は、名前のとおりredmineを操作するためのライブラリとなります。

 

redmineのapiキーを利用することでredmineへデータを投入することができます。

 

例として、チームに所属している扱いであるが作業はしておらず、管理者から稼働報告が求められている立場の場合、「python-redmine」を活用することができます。

 

このような場合、毎日固定でデータ投入する時間がもったいないのでpython-redmineでAPIを使用したデータ投入を行ってみました。

 

コーディングに入る前の準備-土日祝日判定など

稼働時間の自動入力で考えなければならないのは、土日祝日判定です。

 

土日であれば、週単位で簡単に導き出すことができますが、この手のものは祝日判定が厄介です。

 

確実な土日祝日判定を行うために内閣府が公開している「国民の祝日」のcsvをダウンロードすることで対応することにしました。

 

csvファイルを踏まえて今回必要となる材料は、以下のとおりとなります。

 

 

python側のソースコード全体はこちらとなります。

 

japan_holiday.py

 

import csv
from datetime import datetime
 
 
class JapanHoliday:
    """
    「国民の祝日」のCSVを使用して日付('2017/01/01' %Y/%m/%d形式)が土、日、休日か判定するクラス
    """
 
    def __init__(self, path='syukujitsu.csv', encoding='cp932'):
        self._holidays = self._read_holiday(path, encoding)
 
    def _read_holiday(self, path, encoding):
        """
        CSVファイルを読み込み、self.holidaysに以下の形式のdictをListに格納
        """
        holidays = {}
        with open(path, encoding=encoding, newline='') as f:
            reader = csv.reader(f)
            next(reader)  # CSVのヘッダーを飛ばす
            for row in reader:
                day, name = row[0], row[1]
                holidays[day] = {'day': day, 'name': name}
        return holidays
 
    def is_holiday(self, day_str):
        """
        土、日、祝日か判定する
        """
        try:
            day = datetime.strptime(day_str, '%Y/%m/%d')
            if day.weekday() >= 5:
                return True
        except ValueError:
            print('日付は2018/03/01 %Y/%m/%dの形式で入力してください')
            raise ValueError
        if day_str in self._holidays:
            return True
        return False
 
    def get_holiday_dict(self):
        """
        祝日を一覧化したdictを返す
        """
        return self._holidays

working_time_operation_for_redmine.py

# -*- coding: utf-8 -*-
import datetime
from redminelib import Redmine
import calendar
from japan_holiday import JapanHoliday

now = datetime.datetime.now()
holiday = JapanHoliday()

redmine = Redmine('http://[ipアドレス]/redmine', key='[redmine api]')

now = datetime.datetime.now()
_, lastday = calendar.monthrange(now.year,now.month)

for i in range(1,lastday+1):
    days =  holiday.is_holiday(str(now.year) + '/' + str(now.month) + '/' + str(i))
    if days :  
        time_entry = redmine.time_entry.new()
        time_entry.project_id = 1
        time_entry.spent_on = datetime.date(now.year, now.month, i)
        time_entry.hours = 8.0
        time_entry.activity_id = 1
        time_entry.comments = '休日'
        time_entry.custom_fields = [{'id': 1, 'value': '[カスタム値]'}]
        time_entry.save()
        print(str(time_entry.spent_on) + '完了')
    else:
        time_entry = redmine.time_entry.new()
        time_entry.project_id = 1
        time_entry.spent_on = datetime.date(now.year, now.month, i)
        time_entry.hours = 8.0
        time_entry.activity_id = 1
        time_entry.comments = '〇〇案件対応'
        time_entry.custom_fields = [{'id': 1, 'value': '[カスタム値]'}]
        time_entry.save()
        print(str(time_entry.spent_on)+ '完了')

 

出力結果

2019-02-12完了
2019-02-13完了
2019-02-14完了
2019-02-15完了
2019-02-16完了
2019-02-17完了
2019-02-18完了
2019-02-19完了
2019-02-20完了
2019-02-21完了
2019-02-22完了
2019-02-23完了
2019-02-24完了
2019-02-25完了
2019-02-26完了
2019-02-27完了
2019-02-28完了

 

解説

「japan_holiday.py」をインポートし、「holiday.is_holiday」関数へ「yyyy/mm/dd」形式で日付を渡すことで、土日祝日なのかを判定することができます。

 

判定結果を元に祝日の場合の作業記録と平日の作業記録の書き方を分けます。

 

肝心な、redmineへ連携するための項目はこちらとなります。

 

redmine = Redmine('http://[ipアドレス]/redmine', key='[redmine api]')
time_entry = redmine.time_entry.new()
time_entry.project_id = 1
time_entry.spent_on = datetime.date(now.year, now.month, i)
time_entry.hours = 8.0
time_entry.activity_id = 1
time_entry.comments = '休日'
time_entry.custom_fields = [{'id': 1, 'value': '[カスタム値]'}]
time_entry.save()

 

Redmineには、redmineのURLとredmineにて発行したAPIを記述します。

 

今回は作業記録なので、「redmine.time_entry.new()」を使用することで、作業記録の型を作ることができます。

 

その後は、プロジェクトIDである「project_id」や作業時間である「hours = 8.0」などを代入します。

 

ポイントとしては、カスタムフィールドの入れ方は、プロパティと値をセットにして投入する必要があるため、事前にカスタムフィールドのIDとカスタム値を把握する必要があります。

 

値の代入を完了したら、「save()」によりredmineへ登録することができます。

 

なお、本コードでは実行日から実行月末日までループし、作業予定日の入力を行います。

 

例として、2月の場合「2月28日」までのループを「calendar.monthrange(now.year,now.month)」により実現することができます。

 

ここまで出来上がったら、cronなどで月の1日にpythonの実行を設定しておけば、完全自動化で作業記録を導入することが可能となります。

  • .