90 lines
2.7 KiB
Python
90 lines
2.7 KiB
Python
import json
|
|
import re
|
|
import requests
|
|
|
|
from django.conf import settings
|
|
from django.core.cache import cache
|
|
|
|
CACHE_DURATION = 3600
|
|
|
|
|
|
def decorate_commit_line(line):
|
|
escaped_line = line.replace('<', '<').replace('>', '>')
|
|
if line.startswith('<'):
|
|
return '<span class="in">%s</span>' % escaped_line
|
|
elif line.startswith('>'):
|
|
return '<span class="out">%s</span>' % escaped_line
|
|
return '<span class="other">%s</span>' % escaped_line
|
|
|
|
|
|
class Issue(object):
|
|
def __init__(self, issue_id):
|
|
self.id = issue_id
|
|
self.commits = []
|
|
|
|
def update_content(self):
|
|
response = requests.get(
|
|
'%s/issues/%s.json' % (settings.REDMINE_URL, self.id),
|
|
headers={'X-Redmine-API-Key': settings.REDMINE_API_KEY})
|
|
content = response.json()
|
|
cache.set('issue-%s' % self.id, content, CACHE_DURATION)
|
|
|
|
def get_attribute(self, attr):
|
|
content = cache.get('issue-%s' % self.id)
|
|
if content:
|
|
return content.get('issue').get(attr)
|
|
try:
|
|
self.update_content()
|
|
except requests.RequestException:
|
|
return '---'
|
|
return self.get_attribute(attr)
|
|
|
|
@property
|
|
def subject(self):
|
|
return self.get_attribute('subject')
|
|
|
|
@property
|
|
def closed_on(self):
|
|
if self.get_attribute('closed_on'):
|
|
return self.get_attribute('closed_on')
|
|
# fallback on updated_on, as "resolved (to deploy)" is not considered
|
|
# "closed"
|
|
return self.get_attribute('updated_on')
|
|
|
|
@property
|
|
def url(self):
|
|
return '%s/issues/%s' % (settings.REDMINE_URL, self.id)
|
|
|
|
@property
|
|
def priority_class(self):
|
|
return 'priority-%s' % self.get_attribute('priority')['name'].lower()
|
|
|
|
def add_commit(self, commit):
|
|
self.commits.append(commit)
|
|
|
|
|
|
class CommitAndIssues(object):
|
|
|
|
def __init__(self, oneline):
|
|
self.issues = []
|
|
self.commit = oneline.strip()
|
|
self.commit_html = decorate_commit_line(self.commit)
|
|
|
|
@classmethod
|
|
def get_for_commits(cls, module, v1, v2):
|
|
difflog = module.get_diff_log(v1, v2, format='full', grep=r'\#[0-9]\+')
|
|
commits = re.findall(r'^commit.*?\n\n.*?\n\n', difflog, re.DOTALL | re.MULTILINE)
|
|
oneline_commits = module.get_diff_log(v1, v2, grep=r'\#[0-9]\+').splitlines()
|
|
|
|
objects = []
|
|
for commit, oneline in zip(commits, oneline_commits):
|
|
obj = cls(oneline.strip())
|
|
for issue_id in re.findall(r'#(\d+)', commit):
|
|
obj.add_issue(issue_id)
|
|
objects.append(obj)
|
|
|
|
return objects
|
|
|
|
def add_issue(self, issue_id):
|
|
self.issues.append(Issue(issue_id))
|