1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

redmineで定例会議チケットを発行してもらうスクリプト

Last updated at Posted at 2023-04-12

ChatGPTさんに作ってもらいました

2023/04/13
冗長になったので、リライトしています。

Python-Redmine利用版

質問

あなたはPythonエンジニアです。
redmineに週次の定例会議のチケットを発行したいです。
以下の条件を満たすPythonプログラムを作ってください。
cronに関する回答は不要です。

・プログラムはcronで毎日実行される
・以下のcsvファイルをインプットとする。
 開催曜日,チケット発行曜日,雛形チケット
・雛形チケットをコピーして、タイトルにある(yyyy/mm/dd)の記載を開催日(チケット発行日以降、直近となる開催曜日)に書き換え
・雛形チケットに子チケットがある場合は子チケットもすべて同様に処理
・python-redmineモジュールを使う。バージョンは2.4.0とする。
・作成したチケットの開始日はチケット発行日、期日は開催曜日に設定する

回答

redmine.issue.copyを使わず、新しいチケットを作成し、属性をコピーするプログラムを以下に示します。

import csv
import datetime
from redminelib import Redmine

# Redmine接続設定
redmine_url = 'https://your_redmine_url'
api_key = 'your_api_key'
redmine = Redmine(redmine_url, key=api_key)

# 曜日を数値に変換する辞書
day_name_to_number = {
    '': 0,
    '': 1,
    '': 2,
    '': 3,
    '': 4,
    '': 5,
    '': 6,
}

def create_new_ticket(template_ticket, due_date):
    new_ticket = redmine.issue.new()
    new_ticket.project_id = template_ticket.project.id
    new_ticket.tracker_id = template_ticket.tracker.id
    new_ticket.subject = template_ticket.subject.replace('(yyyy/mm/dd)', due_date.strftime('%Y/%m/%d'))
    new_ticket.description = template_ticket.description
    new_ticket.status_id = template_ticket.status.id
    new_ticket.priority_id = template_ticket.priority.id
    new_ticket.assigned_to_id = template_ticket.assigned_to.id if hasattr(template_ticket, 'assigned_to') else None
    new_ticket.start_date = datetime.date.today()
    new_ticket.due_date = due_date
    new_ticket.save()

    return new_ticket

def process_template_ticket(template_ticket, due_date):
    new_ticket = create_new_ticket(template_ticket, due_date)

    for child in template_ticket.children:
        child_template_ticket = redmine.issue.get(child.id)
        process_template_ticket(child_template_ticket, due_date)

with open('input.csv', newline='', encoding='utf-8') as csvfile:
    reader = csv.reader(csvfile)
    next(reader, None)  # ヘッダ行をスキップ

    for row in reader:
        meeting_day, issue_day, template_ticket_id = row
        meeting_day_number = day_name_to_number[meeting_day]
        issue_day_number = day_name_to_number[issue_day]

        today = datetime.date.today()
        today_day_number = today.weekday()

        if today_day_number == issue_day_number:
            days_until_meeting = (meeting_day_number - today_day_number) % 7
            meeting_date = today + datetime.timedelta(days=days_until_meeting)

            template_ticket = redmine.issue.get(template_ticket_id)
            process_template_ticket(template_ticket, meeting_date)

Python-Redmine APIを使えない場合(requests利用)

質問

python-redmine を使わないバージョンを作ってください

回答

import csv
import datetime
import requests

# Redmine接続設定
redmine_url = 'https://your_redmine_url'
api_key = 'your_api_key'

# 曜日を数値に変換する辞書
day_name_to_number = {
    '': 0,
    '': 1,
    '': 2,
    '': 3,
    '': 4,
    '': 5,
    '': 6,
}

headers = {'Content-Type': 'application/json', 'X-Redmine-API-Key': api_key}

def create_new_ticket(template_ticket, due_date):
    new_ticket = {
        'issue': {
            'project_id': template_ticket['project']['id'],
            'tracker_id': template_ticket['tracker']['id'],
            'subject': template_ticket['subject'].replace('(yyyy/mm/dd)', due_date.strftime('%Y/%m/%d')),
            'description': template_ticket['description'],
            'status_id': template_ticket['status']['id'],
            'priority_id': template_ticket['priority']['id'],
            'assigned_to_id': template_ticket['assigned_to']['id'] if 'assigned_to' in template_ticket else None,
            'start_date': datetime.date.today().isoformat(),
            'due_date': due_date.isoformat(),
        }
    }

    response = requests.post(f'{redmine_url}/issues.json', json=new_ticket, headers=headers)
    return response.json()['issue']

def process_template_ticket(template_ticket, due_date):
    new_ticket = create_new_ticket(template_ticket, due_date)

    if 'children' in template_ticket:
        for child in template_ticket['children']:
            child_template_ticket = requests.get(f'{redmine_url}/issues/{child["id"]}.json', headers=headers).json()['issue']
            process_template_ticket(child_template_ticket, due_date)

with open('input.csv', newline='', encoding='utf-8') as csvfile:
    reader = csv.reader(csvfile)
    next(reader, None)  # ヘッダ行をスキップ

    for row in reader:
        meeting_day, issue_day, template_ticket_id = row
        meeting_day_number = day_name_to_number[meeting_day]
        issue_day_number = day_name_to_number[issue_day]

        today = datetime.date.today()
        today_day_number = today.weekday()

        if today_day_number == issue_day_number:
            days_until_meeting = (meeting_day_number - today_day_number) % 7
            meeting_date = today + datetime.timedelta(days=days_until_meeting)

            template_ticket = requests.get(f'{redmine_url}/issues/{template_ticket_id}.json?include=children', headers=headers).json()['issue']
            process_template_ticket(template_ticket, meeting_date)

1
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?