python-redmineでRedmineの作業記録を一括入力する
redmineベースのプロジェクト管理を行っているチームでは、redmineの作業記録を毎日入力する必要があります。
基本的には、毎日異なった記録を入力する日課になるはずですが、立場によっては毎日同じ稼働を記録することとなります。
そこで、python3のライブラリ「python-redmine」を使用した「作業時間の記録」の投入方法を記録してみます。
python-redmineでredmineを操作
今回使用するライブラリ「python-redmine」は、名前のとおりredmineを操作するためのライブラリとなります。
redmineのapiキーを利用することでredmineへデータを投入することができます。
例として、チームに所属している扱いであるが作業はしておらず、管理者から稼働報告が求められている立場の場合、「python-redmine」を活用することができます。
このような場合、毎日固定でデータ投入する時間がもったいないのでpython-redmineでAPIを使用したデータ投入を行ってみました。
コーディングに入る前の準備-土日祝日判定など
稼働時間の自動入力で考えなければならないのは、土日祝日判定です。
土日であれば、週単位で簡単に導き出すことができますが、この手のものは祝日判定が厄介です。
確実な土日祝日判定を行うために内閣府が公開している「国民の祝日」のcsvをダウンロードすることで対応することにしました。
csvファイルを踏まえて今回必要となる材料は、以下のとおりとなります。
- syukujitsu.csv -> 国民の祝日について
- japan_holiday.py
- working_time_operation_for_redmine
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の実行を設定しておけば、完全自動化で作業記録を導入することが可能となります。