1
|
|
|
# json parser implementation |
2
|
|
|
from juggler import * |
|
|
|
|
3
|
|
|
import json, re, math |
|
|
|
|
4
|
|
|
import dateutil.parser |
|
|
|
|
5
|
|
|
|
6
|
|
|
class DictJugglerTaskDepends(JugglerTaskDepends): |
7
|
|
|
def load_from_issue(self, issue): |
8
|
|
|
""" |
9
|
|
|
Args: |
10
|
|
|
issue["depends"] - a list of identifiers that this task depends on |
11
|
|
|
""" |
12
|
|
|
if "depends" in issue: |
|
|
|
|
13
|
|
|
# TODO HERE: remove ID normalization! |
14
|
|
|
if isinstance(issue["depends"], str) or isinstance(issue['depends'], unicode): |
|
|
|
|
15
|
|
|
self.set_value([int(x) for x in re.findall(r"[\w']+", issue["depends"])]) |
16
|
|
|
# TODO check for list, else add idfr |
17
|
|
|
else: self.set_value([int(x) for x in issue["depends"]]) |
18
|
|
|
|
19
|
|
|
class DictJugglerTaskPriority(JugglerTaskPriority): |
20
|
|
|
def load_from_issue(self, issue): |
21
|
|
|
if "priority" in issue: self.set_value(int(issue["priority"])) |
|
|
|
|
22
|
|
|
|
|
|
|
|
23
|
|
|
class DictJugglerTaskStart(JugglerTaskStart): |
24
|
|
|
def load_from_issue(self, issue): |
25
|
|
|
if "start" in issue: |
|
|
|
|
26
|
|
|
if isinstance(issue["start"], str): |
27
|
|
|
self.set_value(dateutil.parser.parse(issue["start"])) |
28
|
|
|
else: |
29
|
|
|
self.set_value(issue["start"]) |
30
|
|
|
|
|
|
|
|
31
|
|
|
class DictJugglerTaskEffort(JugglerTaskEffort): |
32
|
|
|
UNIT = "h" |
33
|
|
|
def load_from_issue(self, issue): |
34
|
|
|
if "effort" in issue: self.set_value(math.ceil(issue["effort"])) |
|
|
|
|
35
|
|
|
|
36
|
|
|
class DictJugglerTaskAllocate(JugglerTaskAllocate): |
37
|
|
|
def load_from_issue(self, issue): |
|
|
|
|
38
|
|
|
if "allocate" in issue: self.set_value(issue["allocate"]) |
|
|
|
|
39
|
|
|
else: self.set_value("me") # stub! |
40
|
|
|
|
41
|
|
|
class DictJugglerTask(JugglerTask): |
42
|
|
|
def load_default_properties(self, issue): |
|
|
|
|
43
|
|
|
self.set_property(DictJugglerTaskDepends(issue)) |
44
|
|
|
self.set_property(DictJugglerTaskEffort(issue)) |
45
|
|
|
self.set_property(DictJugglerTaskAllocate(issue)) |
46
|
|
|
self.set_property(DictJugglerTaskStart(issue)) |
47
|
|
|
self.set_property(DictJugglerTaskPriority(issue)) |
48
|
|
|
def load_from_issue(self, issue): |
49
|
|
|
self.set_id(issue["id"]) |
50
|
|
|
if "summary" in issue: self.summary = issue["summary"] |
|
|
|
|
51
|
|
|
|
52
|
|
|
class DictJuggler(GenericJuggler): |
|
|
|
|
53
|
|
|
""" a simple dictionary based format parser """ |
54
|
|
|
def __init__(self, issues): |
|
|
|
|
55
|
|
|
self.issues = issues |
56
|
|
|
def load_issues(self): |
57
|
|
|
return self.issues |
58
|
|
|
def create_task_instance(self, issue): |
59
|
|
|
return DictJugglerTask(issue) |
60
|
|
|
|
61
|
|
|
class JsonJuggler(DictJuggler): |
|
|
|
|
62
|
|
|
def __init__(self, json_issues): |
|
|
|
|
63
|
|
|
self.issues = json.loads(json_issues) |
64
|
|
|
def toJSON(self): |
65
|
|
|
# TODO HERE: decode tasks back to JSON |
66
|
|
|
for t in self.walk(JugglerTask): |
67
|
|
|
for i in self.issues: |
68
|
|
|
if t.get_id() == i["id"]: |
69
|
|
|
i["booking"] = t.walk(JugglerBooking)[0].decode()[0].isoformat() |
70
|
|
|
return json.dumps(self.issues, sort_keys=True, indent=4, separators=(',', ': ')) |
71
|
|
|
|
|
|
|
|
72
|
|
|
|