Skip to content

Commit

Permalink
Refactored: issue base class
Browse files Browse the repository at this point in the history
  • Loading branch information
reinhardt committed Jun 8, 2020
1 parent 453a50e commit 12b6f15
Show file tree
Hide file tree
Showing 11 changed files with 125 additions and 86 deletions.
6 changes: 3 additions & 3 deletions plugin/octodon.vim
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ if _initialize_octodon_env():
from datetime import datetime
from octodon.clockwork import ClockWorkTimeLog
from octodon.cli import get_config
from octodon.tracking import ticket_pattern_jira
from octodon.jira import Jira
from octodon.utils import format_spent_time
from octodon.utils import get_time_sum

Expand All @@ -105,7 +105,7 @@ def OctodonClock():
if not re.match("^[0-9]{4}.*", line):
now = datetime.now().strftime("%H%M")
line = f"{now} {line}"
ticket_match = ticket_pattern_jira.search(line)
ticket_match = Jira.ticket_pattern.search(line)
if ticket_match:
config = get_config()
if config.has_section("jira"):
Expand All @@ -123,7 +123,7 @@ def OctodonClock():
)
issue_id = ticket_match[1]
issue = jira.get_issue(issue_id)
summary = issue.fields.summary
summary = issue.get_title()
issue_text = f"{issue_id}: {summary}"
if issue_text not in line:
line = line.replace(issue_id, issue_text)
Expand Down
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
jira
pyactiveresource
pystache
python-harvest
jira
python-harvest-redux
11 changes: 9 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,18 @@ def read(*rnames):
author_email="manuel.reinhardt@neon-cathedral.net",
url="https://pypi.python.org/pypi/octodon",
license="BSD",
packages=find_packages(".", exclude=["ez_setup"]),
packages=find_packages("src", exclude=["ez_setup"]),
package_dir={"": "src"},
namespace_packages=["octodon"],
include_package_data=True,
zip_safe=False,
install_requires=["jira", "pyactiveresource", "python-harvest-redux", "setuptools"],
install_requires=[
"jira",
"pyactiveresource",
"pystache",
"python-harvest-redux",
"setuptools",
],
extras_require={"test": ["mock"]},
entry_points="""
[console_scripts]
Expand Down
2 changes: 1 addition & 1 deletion src/octodon/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
# -*- coding: utf-8 -*-
__import__("pkg_resources").declare_namespace(__name__)
4 changes: 2 additions & 2 deletions src/octodon/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ def do_edit(self, *args):
def do_redmine(self, *args):
""" Write current bookings to redmine. """
try:
self.redmine.book_redmine(self.bookings)
self.redmine.book_time(self.bookings)
except Exception as e:
print(
"Error while booking - comments too long? Error was: "
Expand All @@ -373,7 +373,7 @@ def do_redmine(self, *args):
def do_jira(self, *args):
""" Write current bookings to jira. """
try:
self.jira.book_jira(self.bookings)
self.jira.book_time(self.bookings)
except Exception as e:
print(
"Error while booking - " "%s: %s" % (e.__class__.__name__, e),
Expand Down
4 changes: 2 additions & 2 deletions src/octodon/clockwork.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from datetime import datetime
from datetime import timedelta
from glob import glob
from octodon.tracking import ticket_pattern_jira
from octodon.jira import Jira


class ClockWorkTimeLog(object):
Expand Down Expand Up @@ -121,7 +121,7 @@ def get_facts(self, timesheet):
time_match.group(1).replace(":", ""), "%H%M"
)
next_task["description"] = time_match.group(2).strip()
issue_match = ticket_pattern_jira.search(next_task["description"])
issue_match = Jira.ticket_pattern.search(next_task["description"])
next_task["issue_id"] = None
if issue_match:
next_task["issue_id"] = issue_match.group(1)
Expand Down
9 changes: 9 additions & 0 deletions src/octodon/issue.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class Issue(object):
def get_tracker(self):
raise NotImplemented

def get_title(self):
raise NotImplemented

def get_project(self):
raise NotImplemented
33 changes: 29 additions & 4 deletions src/octodon/jira.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,51 @@
from datetime import datetime
from jira import JIRA
from jira import JIRAError
from octodon.issue import Issue

# from octodon.exceptions import ConnectionError
from octodon.exceptions import NotFound
from octodon.tracking import ticket_pattern_jira
import re
import sys


class JiraIssue(Issue):
def __init__(self, issue):
self.issue = issue

def get_tracker(self):
return self.issue.fields.issuetype.name

def get_title(self):
return self.issue.fields.summary

def get_project(self):
return self.issue.fields.project.key

def get_contracts(self):
contracts_field = self.issue.fields.customfield_10902
return (
[contracts_field.child.value] if hasattr(contracts_field, "child") else []
)


class Jira(object):
ticket_pattern = re.compile("#?([A-Z]+-[0-9]+)")

def __init__(self, url, user, password):
self.jira = JIRA(url, auth=(user, password))

def get_issue(self, issue_id):
if not self.ticket_pattern.match(issue_id):
return None
try:
return self.jira.issue(issue_id)
return JiraIssue(self.jira.issue(issue_id))
except JIRAError as je:
raise NotFound(status_code=je.status_code, text=je.text)

def book_jira(self, bookings):
def book_time(self, bookings):
for entry in bookings:
if not ticket_pattern_jira.match(entry["issue_id"]):
if not self.ticket_pattern.match(entry["issue_id"]):
continue
rm_entry = entry.copy()

Expand Down
28 changes: 26 additions & 2 deletions src/octodon/redmine.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,37 @@
import re
import sys
from octodon.exceptions import NotFound
from octodon.issue import Issue
from octodon.utils import get_default_activity
from pyactiveresource.activeresource import ActiveResource
from pyactiveresource import connection

ticket_pattern_redmine = re.compile("#?([0-9]+)")


class RedmineIssue(Issue):
def __init__(self, issue, Projects=None):
self.issue = issue
self.Projects = Projects

def get_tracker(self):
return self.issue["tracker"]["name"]

def get_title(self):
return self.issue["subject"]

def get_project(self):
project_id = self.issue["project"]["id"]
return self.Projects.get(project_id, {}).get("identifier")

def get_contracts(self):
return (
f.get("value", [])
for f in self.issue["custom_fields"]
if f["name"].startswith("Contracts")
)


class Redmine(object):
def __init__(self, url, user, password):
class RedmineResource(ActiveResource):
Expand Down Expand Up @@ -40,11 +64,11 @@ class Projects(RedmineResource):

def get_issue(self, issue_id):
try:
return self.Issue.get(int(issue_id))
return RedmineIssue(self.Issue.get(int(issue_id)), Projects=self.Projects)
except (connection.ResourceNotFound, connection.Error):
raise NotFound()

def book_redmine(self, bookings):
def book_time(self, bookings):
default_activity = get_default_activity(self.activities)
for entry in bookings:
if not ticket_pattern_redmine.match(entry["issue_id"]):
Expand Down
18 changes: 15 additions & 3 deletions src/octodon/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
import unittest
from datetime import date
from datetime import datetime
from mock import patch
from octodon.clockwork import ClockWorkTimeLog
from octodon.exceptions import NotFound
from octodon.jira import Jira
from octodon.tracking import Tracking
from octodon.redmine import Redmine
from octodon.redmine import RedmineIssue
from octodon.utils import clean_up_bookings
from octodon.utils import format_spent_time
from octodon.utils import read_from_file
Expand All @@ -14,6 +16,7 @@
from pyactiveresource.connection import ResourceNotFound
from tempfile import mkdtemp
from tempfile import mkstemp
from unittest.mock import patch

CACHEFILE = os.path.join(
os.path.dirname(os.path.abspath(__file__)), "octodon-projects.test.pickle"
Expand Down Expand Up @@ -64,12 +67,15 @@ def add(self, entry):
self.entries.append(entry)


class MockRedmine(object):
class MockRedmine(Redmine):
Projects = {
"22": {"id": "22", "name": "Cynaptic", "identifier": "cynaptic_3000"},
"23": {"id": "23", "name": "RRZZAA", "identifier": "rrzzaa"},
}

def __init__(self, *args):
pass

def get_issue(self, issue):
issues = {
"12345": {
Expand All @@ -93,7 +99,12 @@ def get_issue(self, issue):
}
if issue not in issues:
raise NotFound()
return issues[issue]
return RedmineIssue(issues[issue], Projects=self.Projects)


class MockJira(Jira):
def __init__(self, *args):
pass


class TestOctodon(unittest.TestCase):
Expand Down Expand Up @@ -142,6 +153,7 @@ def test_get_harvest_target(self):
task_mapping = {u"meeting": u"Meeting"}
tracking = Tracking(
redmine=MockRedmine(),
jira=MockJira(),
harvest=harvest,
project_mapping=project_mapping,
task_mapping=task_mapping,
Expand Down
Loading

0 comments on commit 12b6f15

Please sign in to comment.