]> git.immae.eu Git - perso/Immae/Config/Nix.git/blobdiff - overlays/bugwarrior/mantisbt.patch
Squash changes containing private information
[perso/Immae/Config/Nix.git] / overlays / bugwarrior / mantisbt.patch
diff --git a/overlays/bugwarrior/mantisbt.patch b/overlays/bugwarrior/mantisbt.patch
deleted file mode 100644 (file)
index 85e5af1..0000000
+++ /dev/null
@@ -1,379 +0,0 @@
-diff --git a/bugwarrior/services/mantisbt.py b/bugwarrior/services/mantisbt.py
-new file mode 100644
-index 0000000..e54af0d
---- /dev/null
-+++ b/bugwarrior/services/mantisbt.py
-@@ -0,0 +1,361 @@
-+from builtins import filter
-+import re
-+import six
-+
-+import requests
-+from jinja2 import Template
-+
-+from bugwarrior.config import asbool, aslist, die
-+from bugwarrior.services import IssueService, Issue, ServiceClient
-+
-+import logging
-+log = logging.getLogger(__name__)
-+
-+
-+class MantisbtClient(ServiceClient):
-+    def __init__(self, host, token):
-+        self.host = host
-+        self.session = requests.Session()
-+        self.session.headers['Authorization'] = token
-+
-+    def _api_url(self, path, **context):
-+        """ Build the full url to the API endpoint """
-+        baseurl = "https://{}/api/rest".format(self.host)
-+        return baseurl + path.format(**context)
-+
-+    def get_user(self):
-+        return self.json_response(self.session.get(self._api_url("/users/me")))
-+
-+    def get_projects(self):
-+        return self._getter(self._api_url("/projects"), subkey="projects")
-+
-+    def get_issues(self):
-+        url = self._api_url("/issues?page_size=50")
-+        return self._getter(url, page_size=50, subkey="issues")
-+
-+    def get_assigned_issues(self):
-+        """ Returns all issues assigned to authenticated user.
-+        """
-+        url = self._api_url("/issues?page_size=50&filter_id=assigned")
-+        return self._getter(url, page_size=50, subkey="issues")
-+
-+    def get_monitored_issues(self):
-+        """ Returns all issues monitored by authenticated user.
-+        """
-+        url = self._api_url("/issues?page_size=50&filter_id=monitored")
-+        return self._getter(url, page_size=50, subkey="issues")
-+
-+    def get_reported_issues(self):
-+        """ Returns all issues reported by authenticated user.
-+        """
-+        url = self._api_url("/issues?page_size=50&filter_id=reported")
-+        return self._getter(url, page_size=50, subkey="issues")
-+
-+    def _getter(self, url, page_size=None, subkey=None):
-+        """ Pagination utility.  Obnoxious. """
-+
-+        results = []
-+        link = dict(next=url)
-+        page_number = 1
-+
-+        while 'next' in link:
-+            if page_size is not None:
-+                response = self.session.get(link['next'] + "&page=" + str(page_number))
-+            else:
-+                response = self.session.get(link['next'])
-+
-+            json_res = self.json_response(response)
-+
-+            if subkey is not None:
-+                json_res = json_res[subkey]
-+
-+            results += json_res
-+
-+            if page_size is not None and len(json_res) == page_size:
-+                page_number += 1
-+            else:
-+                break
-+
-+        return results
-+
-+class MantisbtIssue(Issue):
-+    TITLE = 'mantisbttitle'
-+    BODY = 'mantisbtbody'
-+    CREATED_AT = 'mantisbtcreatedon'
-+    UPDATED_AT = 'mantisbtupdatedat'
-+    CLOSED_AT = 'mantisbtclosedon'
-+    URL = 'mantisbturl'
-+    PROJECT = 'mantisbtproject'
-+    NUMBER = 'mantisbtnumber'
-+    USER = 'mantisbtuser'
-+    CATEGORY = 'mantisbtcategory'
-+    STATE = 'mantisbtstate'
-+
-+    UDAS = {
-+        TITLE: {
-+            'type': 'string',
-+            'label': 'Mantisbt Title',
-+        },
-+        BODY: {
-+            'type': 'string',
-+            'label': 'Mantisbt Body',
-+        },
-+        CREATED_AT: {
-+            'type': 'date',
-+            'label': 'Mantisbt Created',
-+        },
-+        UPDATED_AT: {
-+            'type': 'date',
-+            'label': 'Mantisbt Updated',
-+        },
-+        CLOSED_AT: {
-+            'type': 'date',
-+            'label': 'Mantisbt Closed',
-+        },
-+        PROJECT: {
-+            'type': 'string',
-+            'label': 'Mantisbt Project',
-+        },
-+        URL: {
-+            'type': 'string',
-+            'label': 'Mantisbt URL',
-+        },
-+        NUMBER: {
-+            'type': 'numeric',
-+            'label': 'Mantisbt Issue #',
-+        },
-+        USER: {
-+            'type': 'string',
-+            'label': 'Mantisbt User',
-+        },
-+        CATEGORY: {
-+            'type': 'string',
-+            'label': 'Mantisbt Category',
-+        },
-+        STATE: {
-+            'type': 'string',
-+            'label': 'Mantisbt State',
-+        }
-+    }
-+    UNIQUE_KEY = (URL, NUMBER, )
-+
-+    def _normalize_tag(self, label):
-+        return re.sub(r'[^a-zA-Z0-9]', '_', label)
-+
-+    def to_taskwarrior(self):
-+        body = self.record.get('description')
-+        if body:
-+            body = body.replace('\r\n', '\n')
-+
-+        created = self.parse_date(self.record.get('created_at'))
-+        updated = self.parse_date(self.record.get('updated_at'))
-+        closed_date = None
-+        if self.record["status"]["name"] in ["closed", "resolved"]:
-+            for history in self.record.get("history", []):
-+                if history.get("field", {}).get("name", "") == "status"\
-+                        and history.get("new_value", {}).get("name", "") in ["closed", "resolved"]:
-+                    closed_date = history["created_at"]
-+        closed = self.parse_date(closed_date)
-+
-+        return {
-+            'project': self.record['project']['name'],
-+            'priority': self.origin['default_priority'],
-+            'annotations': self.get_annotations(),
-+            'tags': self.get_tags(),
-+            'entry': created,
-+            'end': closed,
-+
-+            self.TITLE: self.record.get('summary'),
-+            self.BODY: body,
-+            self.CREATED_AT: created,
-+            self.UPDATED_AT: updated,
-+            self.CLOSED_AT: closed,
-+            self.URL: self.get_url(),
-+            self.PROJECT: self.record['project'].get('name'),
-+            self.NUMBER: self.record['id'],
-+            self.USER: self.record['reporter'].get('name'),
-+            self.CATEGORY: self.record['category'].get('name'),
-+            self.STATE: self.record['status'].get('label'),
-+        }
-+
-+    def get_url(self):
-+        return "https://{}view.php?id={}".format(self.extra['host'], self.record["id"])
-+
-+    def get_annotations(self):
-+        annotations = []
-+
-+        context = self.record.copy()
-+        annotation_template = Template(self.origin['annotation_template'])
-+
-+        for annotation_dict in self.record.get('notes', []):
-+            context.update({
-+                'text': annotation_dict['text'],
-+                'date': annotation_dict['created_at'],
-+                'author': annotation_dict['reporter'].get('name', 'unknown'),
-+                'view': annotation_dict['view_state']['label'],
-+                })
-+            annotations.append(
-+                    annotation_template.render(context)
-+                    )
-+        return annotations
-+
-+    def get_tags(self):
-+        tags = []
-+
-+        context = self.record.copy()
-+        tag_template = Template(self.origin['tag_template'])
-+
-+        for tag_dict in self.record.get('tags', []):
-+            context.update({
-+                'tag': self._normalize_tag(tag_dict['name'])
-+            })
-+            tags.append(
-+                tag_template.render(context)
-+            )
-+
-+        return tags
-+
-+    def get_default_description(self):
-+        return self.build_default_description(
-+            title=self.record['summary'],
-+            url=self.get_processed_url(self.get_url()),
-+            number=self.record['id'],
-+        )
-+
-+
-+class MantisbtService(IssueService):
-+    ISSUE_CLASS = MantisbtIssue
-+    CONFIG_PREFIX = 'mantisbt'
-+
-+    def __init__(self, *args, **kw):
-+        super(MantisbtService, self).__init__(*args, **kw)
-+
-+        self.host = self.config.get('host', 'www.mantisbt.org/bugs/')
-+
-+        token = self.get_password('token')
-+
-+        self.client = MantisbtClient(self.host, token)
-+        self.user = None
-+
-+        self.exclude_projects = self.config.get('exclude_projects', [], aslist)
-+        self.include_projects = self.config.get('include_projects', [], aslist)
-+
-+        self.involved_issues = self.config.get(
-+            'involved_issues', default=True, to_type=asbool
-+        )
-+        self.assigned_issues = self.config.get(
-+            'assigned_issues', default=False, to_type=asbool
-+        )
-+        self.monitored_issues = self.config.get(
-+            'monitored_issues', default=False, to_type=asbool
-+        )
-+        self.reported_issues = self.config.get(
-+            'reported_issues', default=False, to_type=asbool
-+        )
-+        self.tag_template = self.config.get(
-+            'tag_template', default='{{tag}}', to_type=six.text_type
-+        )
-+        self.annotation_template = self.config.get(
-+            'annotation_template', default='{{date}} {{author}} ({{view}}): {{text}}', to_type=six.text_type
-+        )
-+
-+    def get_service_metadata(self):
-+        return {
-+            'tag_template': self.tag_template,
-+            'annotation_template': self.annotation_template,
-+        }
-+
-+    def filter_involved_issues(self, issue):
-+        _, issue = issue
-+        user = self.client.get_user()
-+        uid = user["id"]
-+        if issue["reporter"]["id"] != uid and \
-+                issue.get("handler", {}).get("id") != uid and \
-+                all([ x.get("user", {}).get("id") != uid for x in issue.get("history", [])]) and \
-+                all([ x.get("user", {}).get("id") != uid for x in issue.get("monitors", [])]):
-+            return False
-+        return self.filter_project_name(issue["project"]["name"])
-+
-+    def filter_issues(self, issue):
-+        _, issue = issue
-+        return self.filter_project_name(issue["project"]["name"])
-+
-+    def filter_project_name(self, name):
-+        if self.exclude_projects:
-+            if name in self.exclude_projects:
-+                return False
-+
-+        if self.include_projects:
-+            if name in self.include_projects:
-+                return True
-+            else:
-+                return False
-+
-+        return True
-+
-+    @staticmethod
-+    def get_keyring_service(service_config):
-+        host = service_config.get('host', 'www.mantisbt.org/bugs/')
-+        username = service_config.get('username', default='nousername')
-+        return "mantisbt://{username}@{host}".format(username=username,
-+                host=host)
-+
-+    @staticmethod
-+    def to_issue_dict(issues):
-+        return { i['id']: i for i in issues }
-+
-+    def get_owner(self, issue):
-+        return issue.get("handler", {}).get("name")
-+
-+    def get_author(self, issue):
-+        return issue.get("reporter", {}).get("name")
-+
-+    def issues(self):
-+        issues = {}
-+        is_limited = self.assigned_issues or self.monitored_issues or self.reported_issues
-+
-+        if self.assigned_issues:
-+            issues.update(
-+                filter(self.filter_issues, self.to_issue_dict(self.client.get_assigned_issues()).items())
-+            )
-+        if self.monitored_issues:
-+            issues.update(
-+                filter(self.filter_issues, self.to_issue_dict(self.client.get_monitored_issues()).items())
-+            )
-+        if self.reported_issues:
-+            issues.update(
-+                filter(self.filter_issues, self.to_issue_dict(self.client.get_reported_issues()).items())
-+            )
-+
-+        if not is_limited:
-+            all_issues = self.to_issue_dict(self.client.get_issues())
-+            if self.involved_issues:
-+                issues.update(
-+                    filter(self.filter_involved_issues, all_issues.items())
-+                )
-+            else:
-+                issues.update(
-+                    filter(self.filter_issues, all_issues.items())
-+                )
-+
-+        log.debug(" Found %i issues.", len(issues))
-+        if not is_limited:
-+            issues = list(filter(self.include, issues.values()))
-+        else:
-+            issues = list(issues.values())
-+        log.debug(" Pruned down to %i issues.", len(issues))
-+
-+        for issue in issues:
-+            issue_obj = self.get_issue_for_record(issue)
-+            extra = {
-+                'host': self.host
-+            }
-+            issue_obj.update_extra(extra)
-+            yield issue_obj
-+
-+    @classmethod
-+    def validate_config(cls, service_config, target):
-+        if 'token' not in service_config:
-+            die("[%s] has no 'mantisbt.token'" % target)
-+
-+        super(MantisbtService, cls).validate_config(service_config, target)
-diff --git a/setup.py b/setup.py
-index d6d957a..665e36e 100644
---- a/setup.py
-+++ b/setup.py
-@@ -80,6 +80,7 @@ setup(name='bugwarrior',
-       activecollab2=bugwarrior.services.activecollab2:ActiveCollab2Service
-       activecollab=bugwarrior.services.activecollab:ActiveCollabService
-       jira=bugwarrior.services.jira:JiraService
-+      mantisbt=bugwarrior.services.mantisbt:MantisbtService
-       megaplan=bugwarrior.services.megaplan:MegaplanService
-       phabricator=bugwarrior.services.phab:PhabricatorService
-       versionone=bugwarrior.services.versionone:VersionOneService