Bearbeiten Sie Redmine mit Python Redmine

Python Redmine

Python Redmine ist eine Python-Bibliothek, die mit Redmine kommuniziert.

Es hat die folgenden Funktionen.

・ 100% Unterstützung für Redmine API-Funktionen (Sie können sogar ein Projekt erstellen) · Python 2.7, 3.4-3.7

Die Details werden unten beschrieben. https://python-redmine.com/

Wie installiert man

Es kann mit pip oder easy_install installiert werden.

$ pip install python-redmine

Oder

$ easy_install python-redmine

Aktivieren Sie als Einstellung auf der Redmine-Seite "Webdienst über REST-API aktivieren" auf der Registerkarte "API" im Bildschirm "Administration" -> "Einstellungen".

image.png

Wenn Sie die API hier aktivieren, können Sie den API-Schlüssel auf dem Bildschirm mit den persönlichen Einstellungen überprüfen. image.png

Stichprobe

Ein Beispiel wird unten beschrieben. Dieses Beispiel wird mit Python 3.7 + Python Redmine 2.2.1 + Redmine 4.0.3.Stable unter Windows bestätigt.

Authentifizierungsmethode

Sie können eine Verbindung zu redmine herstellen, indem Sie einen Benutzernamen und ein Kennwort angeben.

from redminelib import Redmine
redmine = Redmine('http://localhost/redmine', username='admin', password='admin')

Alternativ können Sie eine Verbindung mit dem API-Schlüssel wie folgt herstellen.

from redminelib import Redmine
redmine = Redmine('http://localhost/redmine', key='e4a413a3b7a3c238102b7393c035bbc5f5eb6409')

Ticketbetrieb

Siehe unten für den Ticketbetrieb https://python-redmine.com/resources/issue.html

Ticket erstellen

Sie können ein Ticket erstellen, indem Sie mit redmine.issue.new () ein Ticketobjekt erstellen, dort Eigenschaften festlegen und speichern.

import datetime
from redminelib import Redmine
redmine = Redmine('http://192.168.0.200/', key='60076966cebf71506ae3f2391da649235a2b1d46')
issue = redmine.issue.new()
issue.project_id = 'Test1'
issue.subject = 'Gegenstand'
issue.tracker_id = 1     #Tracker
issue.description = 'Zeigen Sie den Inhalt des Tickets.\n Zeilenumbrüche sind ebenfalls möglich.'
issue.status_id = 1      #Status
issue.priority_id = 1    #Priorität
issue.assigned_to_id = 1 #Verantwortliche ID
issue.watcher_user_ids = [1] #ID des zu beobachtenden Benutzers
issue.parent_issue_id = 12     #Übergeordnete Ticket-ID
issue.start_date = datetime.date(2014, 1, 1) #Anfangsdatum
issue.due_date = datetime.date(2014, 2, 1)   #Frist
issue.estimated_hours = 4   #Erwartete Arbeitskräfte
issue.done_ratio = 40
issue.custom_fields = [{'id': 1, 'value': 'foo'}]
issue.uploads = [{'path': 'C:\\dev\\python3\\redmine\\test.txt'}]
issue.custom_fields = [{'id': 1, 'value': 'foo'}]
issue.save()

Holen Sie sich ein einzelnes Ticket

Geben Sie die Ticket-ID mit redmine.issue.get () an. Wenn es nicht existiert redmine.exceptions.ResourceNotFoundError Eine Ausnahme tritt auf.

import datetime
from redminelib import Redmine
from redminelib.exceptions import ResourceNotFoundError

redmine = Redmine('http://192.168.0.200/', key='60076966cebf71506ae3f2391da649235a2b1d46')
try:
    issue = redmine.issue.get(60)
    print (dir(issue))
    print ('id:%d' % issue.id)
    print ('project:%s' % issue.project.name)
    print ('project_id:%d' % issue.project.id)
    print ('subject:%s' % issue.subject)
    print ('tracker:%s' % issue.tracker.name)
    print ('tracker_id:%d' % issue.tracker.id)
    print ('description:%s' % issue.description)
    print ('status:%s' % issue.status.name)
    print ('status:%d' % issue.status.id)
    print ('author:%s' % issue.author.name)
    print ('author_id:%d' % issue.author.id)
    if hasattr(issue, 'assigned'):
        print ('assigned:%s' % issue.assigned_to.name)
        print ('assigned_id:%d' % issue.assigned_to.id)
    print ('watcher--------')
    for u in issue.watchers:
        print (' %d:%s' % (u.id, u.name))
    print ('Erstellungsdatum:%s' % issue.created_on)
    print ('Aktualisierungsdatum:%s' % issue.updated_on)
    if hasattr(issue, 'start_date'):
        print ('start_date:%s' % issue.start_date)
    if hasattr(issue, 'due_date'):
        print ('issue_date:%s' % issue.due_date)
    if hasattr(issue, 'issue.estimated_hours'):
        print ('estimated_hours:%d' % issue.estimated_hours)
    print ('Arbeitszeit:%d' % issue.spent_hours)
    print ('Aufzeichnung der Arbeitszeit----------')
    for t in issue.time_entries:
        print('  ID:%d' % t.id)
        print('Aktivitäten:%s' % t.activity)
        print('Kommentar:%s' % str(t.comments))
        print('Erstellungsdatum:%s' % t.created_on)
        print('Zeit:%s' %t.hours)
        print('Ticketnummer:%s' % t.issue)
        print('Projekt-ID:%s' % t.project)
        print('Datum:%s' % t.spent_on)
        print('Aktualisierungsdatum:%s' % t.updated_on)
        print('  user:%d %s' % (t.user.id,t.user.name)) 
    print ('done_ratio:%d' % issue.done_ratio) 
    print ('priority:%s' % issue.priority.name)
    print ('priority_id:%d' % issue.priority.id)
    print ('custom_fields----')
    for c in issue.custom_fields:
        print ('  %d:%s = %s' % (c.id, c.name, c.value))
    print ('attachements---')
    for f in issue.attachments:
        print ('  id:%d' % (f.id))
        print ('  author:%s' % (f.author)) 
        print ('  content_url:%s' % (f.content_url))
        print ('  created_on:%s' % (f.created_on))
        print ('  description:%s' % (f.description))
        print ('  filename:%s' % (f.filename))
        print ('  filesize:%d' % (f.filesize))
        print ('  ---------------')
    print ('changeset---')
    for c in issue.changesets:
        #Commit-Protokoll als Wörterbuchtyp gespeichert
        print ('  %s' % c)
    if hasattr(issue, 'parent'):
        print ('parent:%s' % issue.parent)
    print ('children----------')
    for c in issue.children:
        print ('  %s:%s' % (c.id, c.subject))
    print ('relation----------')
    for r in issue.relations:
        print ('  %d:%d->%d(%s)' % (r.id, r.issue_id, r.issue_to_id, r.relation_type)) 
except (ResourceNotFoundError):
    print ('Not found')

Elemente, für die keine Eingabe erfolgt, haben selbst keine Eigenschaften. Daher müssen Sie die Existenz mit hasattr überprüfen.

Die Benutzerinformationen der Beobachter, der verantwortlichen Person und des Erstellers enthalten nur die minimal erforderlichen Informationen. Wenn Sie den Anmeldenamen usw. erhalten möchten, rufen Sie die Benutzerdetails wie folgt aus der Benutzer-ID ab.

user = redmine.user.get(u.id)

Holen Sie sich alle Tickets

Es kann mit redmine.issue.all () erhalten werden. Folgende Parameter können weggelassen werden.

sort (string): Sortierreihenfolge Limit (Ganzzahl): Obergrenze der Anzahl der Akquisitionen Offset (Ganzzahl): Startposition der Erfassung

import datetime
from redminelib import Redmine

redmine = Redmine('http://192.168.0.200/', key='60076966cebf71506ae3f2391da649235a2b1d46')
issues = redmine.issue.all(sort='category:desc')
for issue in issues:
  print ('%d:%s' % (issue.id, issue.subject))

Erhalt eines Tickets für bestimmte Bedingungen

Tickets mit bestimmten Bedingungen können mit redmine.issue.filter extrahiert werden. Im Folgenden extrahiert die verantwortliche Person ihr Ticket.

import datetime
from redminelib import Redmine

redmine = Redmine('http://192.168.0.200/', key='60076966cebf71506ae3f2391da649235a2b1d46')
issues = redmine.issue.filter(assigned_to_id='me')
for issue in issues:
  print ('%d:%s' % (issue.id, issue.subject))

Sie können auch nach registrierter Abfrage suchen, indem Sie query_id verwenden.

Operator für Abfrage

Schließlich lesen Sie nur die REST-API, damit Sie sie mit von Redmine unterstützten Operatoren verwenden können. http://www.redmine.org/projects/redmine/wiki/Rest_Issues

In dem obigen Dokument werden Beispiele wie "! \ " ">" "<" "" "~" Vorgestellt.

Um beispielsweise eine Aufgabe zu erhalten, die niemandem zugewiesen ist, lautet die Implementierung wie folgt.

import datetime
from redminelib import Redmine

redmine = Redmine('http://192.168.0.200/', key='60076966cebf71506ae3f2391da649235a2b1d46')
issues = redmine.issue.filter(assigned_to_id='!*')
for issue in issues:
  print ('%d:%s' % (issue.id, issue.subject))

Wenn Sie die Aufgabe einer anderen verantwortlichen Person als Ihnen selbst übernehmen möchten, ist dies wie folgt.

import datetime
from redminelib import Redmine

redmine = Redmine('http://192.168.0.200/', key='60076966cebf71506ae3f2391da649235a2b1d46')
issues = redmine.issue.filter(assigned_to_id='!me')
for issue in issues:
  print ('%d:%s' % (issue.id, issue.subject))

Wir können sehen, dass verschiedene Konditionierungen durch die Verwendung von Operatoren wie Verweigerung und Bereichsspezifikation möglich sind. Das Problem ist jedoch, dass die REST-API-Dokumentation uns nicht sagt, welche Art von Operator es gibt.

Daher muss auf den tatsächlichen Code verwiesen werden.

redmine/app/models/query.rb https://github.com/redmine/redmine/blob/9746ab7e5be2db5e2d233ee37365cf21ba4b893a/app/models/query.rb#L254

Wenn Sie sich diese Implementierung ansehen, können Sie sehen, welche Art von Operatoren definiert sind. Es können jedoch nicht alle Elemente von allen Bedienern verwendet werden. Im Betreff können beispielsweise "\ *: all", "! \ *: None" und "~: include" verwendet werden, "^: beginnt mit" jedoch nicht. Ob dies verwendet werden kann oder nicht, entspricht den Bedingungen, die auf dem Filtereinstellungsbildschirm unten ausgeführt werden können. image.png

Ticketerneuerung

Mit redmine.issue.get erhaltene Tickets können geändert und gespeichert werden. Das folgende Beispiel ist ein Beispiel für die Änderung des Ticketstatus.

# -*- coding: utf-8 -*-
import datetime
from redmine import Redmine

redmine = Redmine('http://localhost/redmine', key='e4a413a3b7a3c238102b7393c035bbc5f5eb6409')
issue = redmine.issue.get(51)
issue.status_id = 2
issue.save()

Manipulation der Arbeitszeit

Siehe unten für Arbeitszeitvorgänge https://python-redmine.com/resources/time_entry.html

Holen Sie sich Arbeitszeit

Das Folgende ist ein Beispiel für die Aufzählung der Arbeitszeiten.

import datetime
from redminelib import Redmine

redmine = Redmine('http://192.168.0.200/', key='60076966cebf71506ae3f2391da649235a2b1d46')
time_entries = redmine.time_entry.all()
for t in time_entries:
    print('  ID:%d' % t.id)
    print('Aktivitäten:%s' % t.activity)
    print('Kommentar:%s' % str(t.comments))
    print('Erstellungsdatum:%s' % t.created_on)
    print('Zeit:%s' %t.hours)
    print('Ticketnummer:%s' % t.issue)
    print('Projekt-ID:%s' % t.project)
    print('Datum:%s' % t.spent_on)
    print('Aktualisierungsdatum:%s' % t.updated_on)
    print('  user:%d %s' % (t.user.id,t.user.name))
    print('Arbeitsklassifizierung%d %s' % (t.activity.id, t.activity.name))

Aufzeichnung der Arbeitszeit

Ein Beispiel für die Aufzeichnung der Arbeitszeit ist unten gezeigt.

import datetime
from redminelib import Redmine

redmine = Redmine('http://192.168.0.200/', key='60076966cebf71506ae3f2391da649235a2b1d46')
time_entry = redmine.time_entry.new()
time_entry.issue_id = 60
time_entry.spent_on = datetime.date(2014, 1, 14)
time_entry.hours = 3
time_entry.activity_id = 4
time_entry.comments = 'hello'
time_entry.activity_id = 8
time_entry.save()

Zusammenfassung

Dieses Mal haben wir nur einen Teil der bereitgestellten API überprüft. Es wurde jedoch bestätigt, dass die Vorgänge, die auf dem Webbildschirm ausgeführt werden können, abgedeckt sind.

Wenn Sie Python Redmine verwenden, können Sie davon ausgehen, dass Sie Redmine mit Python frei betreiben können. Es ist zu erwarten, dass Folgendes realisiert werden kann.

das ist alles

Recommended Posts

Bearbeiten Sie Redmine mit Python Redmine
Starten Sie Python
Scraping mit Python
Versuchen Sie, Excel mit Python (Xlwings) zu betreiben.
Bedienen Sie Filemaker von Python aus
Fibonacci-Sequenz mit Python
Kinesis mit Python betreiben
Datenbereinigung mit Python
Bedienen Sie Neutronen von Python!
Verwenden von Python # externen Paketen
WiringPi-SPI-Kommunikation mit Python
Betreiben Sie Blender mit Python
Altersberechnung mit Python
Betreiben Sie LXC von Python aus
Suchen Sie Twitter mit Python
Namensidentifikation mit Python
Hinweise zur Verwendung von Python-Unterprozessen
Versuchen Sie es mit Tweepy [Python2.7]
Betreiben Sie Excel mit Python (1)
Betreiben Sie Excel mit Python (2)
Registrieren Sie Tickets mit der Redmine-API mithilfe von Python-Anforderungen
Python-Memo mit perl-ternärem Operator
Scraping mit Python 3.5 async / await
Betreiben Sie Excel mit Python Open Pyxl
Speichern Sie Bilder mit Python3-Anforderungen
Betreiben Sie TwitterBot mit Lambda, Python
[S3] CRUD mit S3 unter Verwendung von Python [Python]
[Python] Versuchen Sie, Tkinters Leinwand zu verwenden
Verwenden von Quaternion mit Python ~ numpy-quaternion ~
Versuchen Sie es mit Kubernetes Client -Python-
Python-Notizen zur Verwendung von Perl-Spezialvariablen
[Python] Verwenden von OpenCV mit Python (Basic)
Scraping mit Python 3.5 Async-Syntax
Überwachung von Website-Änderungen mit Python
[Hinweis] Betreiben Sie MongoDB mit Python
Mit Python auf Twitter posten
Starten Sie mit Python zu Selen
Suchalgorithmus mit word2vec [Python]
Ändern Sie die Python-Version mit pyenv
Python: Grundlagen der Verwendung von Scikit-Learn ①
# 1 [python3] Einfache Berechnung mit Variablen
Erstellen Sie JIRA-Tickets mit Python
Instrumentensteuerung mit Python [pyvisa]
Bearbeiten Sie Tabellenkalkulationen lokal mit Python
Python-Memo mit Perl --join
Web Scraping mit Selenium (Python)
[Python] Validierung von JSON mit Voluptuous
[Python] [SQLite3] Betreiben Sie SQLite mit Python (Basic)
Online-Übertragung mit Python
Datenanalyse mit Python-Pandas
Übersetzt mit Googletrans in Python
Verwenden des Python-Modus in der Verarbeitung
Verwenden von OpenCV mit Python @Mac
[Python] Schießspiel mit Pyxel
Registrieren Sie das Redmine-Problem von Python
Senden Sie mit Python mit Google Mail
Versuchen Sie, eine Excel-Datei mit Python (Pandas / XlsxWriter) zu betreiben
Versuchen Sie, eine Excel-Datei mit Python (Pandas / XlsxWriter) zu betreiben