想要一份關于缺陷ticket的反饋次數和缺陷來往情況,做一個簡單的redmine缺陷分析報表
如何開始呢,思考歷程寫下來:
1.首先考慮是否可以從內部獲取數據,聽說redmine的數據庫是Mysql,但是我沒有賬號和權限
2.在一個查看是否提供接口,可以直接獲取,登陸啥的是個麻煩事兒,界面化太麻煩(能力有限,且耗時)
3.python的支持庫
4.爬蟲
優選1.3,其次是4,最差2了
下載python-redmine 在下載頁有少許的入門介紹,我也做少許的介紹吧

一 . 首先是定位項目篩選信息
如圖看到的箭頭指向,便是你的項目
定位項目之后,可以拿到項目下的所有的ticket,如圖中的第2點;其中某一條數據如3
再一個是filter函數,可以幫助我們去篩選我們想要的版本或者其他狀態的ticket
issues = list(redmine.issue.filter(project_id=46, tracker_id=1, status_id='*', fixed_version_id=387))
通過list將所有篩選的ticket組裝成列表,便是獲得了我們要分析的數據
打開你的debug,采用Evaluate查看信息

你可以挨個打開看看里面都記錄的是什么內容,從而提取你想要得到的信息
二. 數據處理
需求1:得到每個ticket的狀態變化
redmine中的狀態都是用123456去表示的狀態,所以我們需要一個轉換函數,對得到的狀態進行裝換
# 新建1 進行中2 已解決3 不處理 4 反饋 5 阻塞6 已關閉7 已指派8 不處理9 重新打開10 已驗證12
def change_value(num):
switch = {
'1': "新建", #已確定
'2': "進行中", #已確定
'3': "已解決", #已確定
'4': "反饋", # 已確定
'5': "已關閉", #已確定
'6': "已拒絕",
'7': "推遲", #已確定
'8': "已指派", #已確定
'9': "不處理", #已確定
'10': "重新打開", # 已確定
'11':"阻塞", #已確定
'12': "已驗證", #已確定
}
return switch.get(num,'未知信息')
當時,為了獲取這個信息,還專門去創建了一個所有狀態交互的ticket
需求2:將人員之間的交互流程以箭頭的方式進行體現,同時相鄰的人員同名算作一個
# details 從issue.journals獲取,name是issue.journals.resources[x].user.name
def get_history_message(details,name):
values = []
name_value = []
for value in details:
if value.get('name')== 'status_id':
old_value = value.get('old_value',None)
new_value = value.get('new_value',None)
if old_value and new_value:
if old_value.isdigit() == True and new_value.isdigit() == True:
values.append([change_value(old_value),change_value(new_value)])
name_value = [name,values]
return name_value
#傳入所有的交互人員list進行相鄰去重
def de_weightlist(list):
a = None
list2 = []
for i in list:
if i != a:
list2.append(i)
a = i
return list2
需求3:統計篩選過的人員的角色和反饋次數,并降序排
def statics(list):
name_feedback = []
name_list = []
for line in list:
a = line[0][0]
name_list.append(a)
feedback=len([j for line in list for i in line[0][1] for j in i if j=="反饋"])
result = Counter(name_list)
sort_list = sorted(result.items(), key=lambda x: x[1], reverse=True)
name_feedback = [sort_list,feedback]
return name_feedback
具體的實現由具體的需求決定,這里只是我的一個實例,希望對大家有所幫助
貼上完整的代碼:
from redminelib import Redmine
import csv
from collections import Counter
redmine = Redmine('http://.xx:888', username='username', password='******')
issues = list(redmine.issue.filter(project_id=123, tracker_id=1, status_id='*', fixed_version_id=123))
# 新建1 進行中2 已解決3 不處理 4 反饋 5 阻塞6 已關閉7 已指派8 不處理9 重新打開10 已驗證12
def change_value(num):
switch = {
'1': "新建", #已確定
'2': "進行中", #已確定
'3': "已解決", #已確定
'4': "反饋", # 已確定
'5': "已關閉", #已確定
'6': "已拒絕",
'7': "推遲", #已確定
'8': "已指派", #已確定
'9': "不處理", #已確定
'10': "重新打開", # 已確定
'11':"阻塞", #已確定
'12': "已驗證", #已確定
}
return switch.get(num,'未知信息')
def get_history_message(details,name):
values = []
name_value = []
for value in details:
if value.get('name')== 'status_id':
old_value = value.get('old_value',None)
new_value = value.get('new_value',None)
if old_value and new_value:
if old_value.isdigit() == True and new_value.isdigit() == True:
# massage = ""
# old_value1=change_value(old_value)
# new_value1=change_value(new_value)
#values.append(["將\""+change_value(old_value)+"\"改成\""+change_value(new_value)+"\""])
values.append([change_value(old_value),change_value(new_value)])
name_value = [name,values]
return name_value
def de_weightlist(list):
a = None
list2 = []
for i in list:
if i != a:
list2.append(i)
a = i
return list2
#統計list中user和狀態的次數
def statics(list):
name_feedback = []
name_list = []
for line in list:
a = line[0][0]
name_list.append(a)
feedback=len([j for line in list for i in line[0][1] for j in i if j=="反饋"])
result = Counter(name_list)
sort_list = sorted(result.items(), key=lambda x: x[1], reverse=True)
name_feedback = [sort_list,feedback]
return name_feedback
file_csv = 'E:/redmine.csv'
title = [ "ID", "主題","開始日期","功能模塊","創建者","ticket往返次數","每人經手次數","缺陷反饋次數","經手人(歷史記錄)"]
out = open(file_csv,'a',newline='')
csv_write = csv.writer(out,dialect='excel')
csv_write.writerow(title)
for issue in issues:
row_massage = [] #定義行列表
details = [] #定義歷史記錄保存列表
str_connect = "->" #連接符
issue_id = issue.id # ticket_ID
issue_author = issue.author # 作者
issue_subject = issue.subject # 主題
issue_history = list(issue.journals) # 歷史記錄列表
issue_startdate = getattr(issue, 'start_date', None) # 開始日期
for i,line in enumerate(issue_history):
detail = line.details
user= line.user.name
new_detail = get_history_message(detail, user)
if i+1 == 1:
details.append([new_detail, str_connect])
else:
if details[-1][0][0] == new_detail[0]:
details[-1][0].append(new_detail[-1])
else:
details.append([new_detail, str_connect])
muldle_msg = list(issue.custom_fields) # 功能模塊所在列表
nametime_feedbacklist = statics(details) #每個人在該缺陷中出現的次數和反饋次數
name_sort = nametime_feedbacklist[0] #名字排名
feedbanck_time = nametime_feedbacklist[-1] #反饋次數
muldle = muldle_msg[-1].value # 固定位置 功能模塊信息
row_massage=[issue_id,issue_subject,issue_startdate,muldle,issue_author,len(details),name_sort,feedbanck_time,details]
csv_write.writerow(row_massage) #寫入csv
print("write over")
最后得到的結果是這樣的:

拿到表格你可以做一些圖標之類的信息,反饋得更加明顯一些
努力去嘗試,相信你可以做得更好!