|
| 1 | +from atlassian import Jira |
| 2 | +import pprint |
| 3 | +import argparse |
| 4 | +import logging |
| 5 | + |
| 6 | +logging.basicConfig(level=logging.ERROR) |
| 7 | + |
| 8 | +""" |
| 9 | + This is example for to generate the weekly report in one button |
| 10 | + You can adjust the days based on the field self.days. |
| 11 | + user.txt better to prepare one by line: |
| 12 | + user3 |
| 13 | + user2 |
| 14 | + user1 |
| 15 | + as result you can give a csv file |
| 16 | +""" |
| 17 | + |
| 18 | + |
| 19 | +class ReportGenerator: |
| 20 | + def __init__(self, jira): |
| 21 | + print("Init configs") |
| 22 | + self.jira = jira |
| 23 | + self.cases = [] |
| 24 | + self.users = [] |
| 25 | + self.days = 7 |
| 26 | + |
| 27 | + def __fetch_user_activity(self, user): |
| 28 | + flag = True |
| 29 | + limit = 10 |
| 30 | + step = 0 |
| 31 | + jql = f"((assignee was in ({user})) OR assignee in ({user})) AND updated > -{self.days}d " |
| 32 | + print(f"Start fetching info jql = {jql}") |
| 33 | + while flag: |
| 34 | + values = [] |
| 35 | + try: |
| 36 | + response = self.jira.jql(jql, fields=['created', 'summary', 'status'], expand="changelog", |
| 37 | + limit=limit, |
| 38 | + start=step * limit) |
| 39 | + values = response.get('issues') or [] |
| 40 | + except ValueError: |
| 41 | + values = [] |
| 42 | + if values: |
| 43 | + step += 1 |
| 44 | + for value in values: |
| 45 | + value['actor'] = self.jira.user(user).get("displayName") |
| 46 | + self.cases.append(value) |
| 47 | + else: |
| 48 | + flag = False |
| 49 | + |
| 50 | + def __get_changes_of_cases(self, histories): |
| 51 | + from datetime import datetime, timezone |
| 52 | + today = datetime.now(timezone.utc) |
| 53 | + output = "" |
| 54 | + for history in histories: |
| 55 | + change_date = datetime.strptime(history.get("created"), '%Y-%m-%dT%H:%M:%S.%f%z') |
| 56 | + difference = today - change_date |
| 57 | + if difference.days > self.days: |
| 58 | + continue |
| 59 | + output = [history.get('author').get('name'), f"{change_date:%Y-%m-%d}"] # person who did the change |
| 60 | + changes = ["Listing all items that changed:"] |
| 61 | + for item in history.get("items"): |
| 62 | + changes.append(f"{item['field']} - {item['fromString']}- {item['toString']}") |
| 63 | + output.append("\t".join(changes)) |
| 64 | + return " - ".join(output) |
| 65 | + |
| 66 | + def fetching(self): |
| 67 | + for user in self.users: |
| 68 | + self.__fetch_user_activity(user=user) |
| 69 | + pass |
| 70 | + |
| 71 | + def console_output(self, delimiter="|", console=True): |
| 72 | + """ |
| 73 | + Print values to check |
| 74 | + :return: |
| 75 | + """ |
| 76 | + number = 1 |
| 77 | + data = [] |
| 78 | + for case in self.cases: |
| 79 | + print(f"Processing case #{number}") |
| 80 | + output = [case.get("actor"), case.get("key"), case.get("fields").get("summary"), |
| 81 | + case.get("fields").get("status").get("name")] |
| 82 | + histories = (case.get("changelog") or {}).get("histories") or [] |
| 83 | + output.append('"' + self.__get_changes_of_cases(histories) + '"') |
| 84 | + line = delimiter.join(output) |
| 85 | + if console: |
| 86 | + print(line) |
| 87 | + data.append(line) |
| 88 | + number += 1 |
| 89 | + return "\n".join(data) |
| 90 | + |
| 91 | + def export(self, filename, delimiter=";"): |
| 92 | + """ |
| 93 | + Prepare a csv file |
| 94 | + :return: |
| 95 | + """ |
| 96 | + |
| 97 | + write_file = open(filename, "w") |
| 98 | + write_file.write(self.console_output(delimiter=delimiter, console=False)) |
| 99 | + write_file.close() |
| 100 | + |
| 101 | + def load_users(self, filename): |
| 102 | + users = [] |
| 103 | + with open(filename, "r") as f: |
| 104 | + for line in f: |
| 105 | + users.append(line.strip()) |
| 106 | + self.users = users |
| 107 | + pass |
| 108 | + |
| 109 | + |
| 110 | +def main(): |
| 111 | + parser = argparse.ArgumentParser(description="Just wrapper to make arguments") |
| 112 | + parser.add_argument("--url", type=str, action="store") |
| 113 | + parser.add_argument("--user", type=str, action="store") |
| 114 | + parser.add_argument("--password", type=str, action="store") |
| 115 | + parser.add_argument('--user_file', type=str, action="store", description="user.txt with username in each line") |
| 116 | + args = parser.parse_args() |
| 117 | + # validate jql method |
| 118 | + jira = Jira(url=args.url, username=args.user, password=args.password) |
| 119 | + report = ReportGenerator(jira=jira) |
| 120 | + report.load_users(args.user_file) |
| 121 | + report.fetching() |
| 122 | + # report.print() |
| 123 | + report.export("export.csv") |
| 124 | + |
| 125 | + |
| 126 | +if __name__ == "__main__": |
| 127 | + main() |
0 commit comments