示例#1
0
    def create_issue(self, request, group, form_data, **kwargs):
        json_data = {
            'story_type':
            'bug',
            'name':
            force_text(form_data['title'], encoding='utf-8', errors='replace'),
            'description':
            force_text(form_data['description'],
                       encoding='utf-8',
                       errors='replace'),
            'labels': ['sentry'],
        }

        try:
            _url = self.build_api_url(group, 'stories')
            req = self.make_api_request(group.project,
                                        _url,
                                        json_data=json_data)
            body = safe_urlread(req)
        except requests.RequestException as e:
            msg = six.text_type(e)
            raise PluginError('Error communicating with Pivotal: %s' % (msg, ))

        try:
            json_resp = json.loads(body)
        except ValueError as e:
            msg = six.text_type(e)
            raise PluginError('Error communicating with Pivotal: %s' % (msg, ))

        if req.status_code > 399:
            raise PluginError(json_resp['error'])

        return json_resp['id']
示例#2
0
    def create_issue(self, request, group, form_data, **kwargs):
        json_data = {
            "story_type":
            "bug",
            "name":
            force_text(form_data["title"], encoding="utf-8", errors="replace"),
            "description":
            force_text(form_data["description"],
                       encoding="utf-8",
                       errors="replace"),
            "labels": ["sentry"],
        }

        try:
            _url = self.build_api_url(group, "stories")
            req = self.make_api_request(group.project,
                                        _url,
                                        json_data=json_data)
            body = safe_urlread(req)
        except requests.RequestException as e:
            msg = str(e)
            raise PluginError(f"Error communicating with Pivotal: {msg}")

        try:
            json_resp = json.loads(body)
        except ValueError as e:
            msg = str(e)
            raise PluginError(f"Error communicating with Pivotal: {msg}")

        if req.status_code > 399:
            raise PluginError(json_resp["error"])

        return json_resp["id"]
示例#3
0
    def link_issue(self, request, group, form_data, **kwargs):
        comment = form_data.get("comment")
        if not comment:
            return
        _url = "%s/%s/comments" % (self.build_api_url(group, "stories"), form_data["issue_id"])
        try:
            req = self.make_api_request(group.project, _url, json_data={"text": comment})
            body = safe_urlread(req)
        except requests.RequestException as e:
            msg = str(e)
            raise PluginError("Error communicating with Pivotal: %s" % (msg,))

        try:
            json_resp = json.loads(body)
        except ValueError as e:
            msg = str(e)
            raise PluginError("Error communicating with Pivotal: %s" % (msg,))

        if req.status_code > 399:
            raise PluginError(json_resp["error"])
示例#4
0
    def link_issue(self, request, group, form_data, **kwargs):
        comment = form_data.get('comment')
        if not comment:
            return
        _url = '%s/%s/comments' % (self.build_api_url(
            group, 'stories'), form_data['issue_id'])
        try:
            req = self.make_api_request(group.project,
                                        _url,
                                        json_data={"text": comment})
            body = safe_urlread(req)
        except requests.RequestException as e:
            msg = six.text_type(e)
            raise PluginError('Error communicating with Pivotal: %s' % (msg, ))

        try:
            json_resp = json.loads(body)
        except ValueError as e:
            msg = six.text_type(e)
            raise PluginError('Error communicating with Pivotal: %s' % (msg, ))

        if req.status_code > 399:
            raise PluginError(json_resp['error'])
示例#5
0
    def create_issue(self, request, group, form_data, **kwargs):
        cleaned_data = {}

        # protect against mis-configured plugin submitting a form without an
        # issuetype assigned.
        if not form_data.get("issuetype"):
            raise PluginError("Issue Type is required.")

        jira_project_key = self.get_option("default_project", group.project)
        client = self.get_jira_client(group.project)
        meta = client.get_create_meta_for_project(jira_project_key)

        if not meta:
            raise PluginError(
                "Something went wrong. Check your plugin configuration.")

        issue_type_meta = self.get_issue_type_meta(form_data["issuetype"],
                                                   meta)

        fs = issue_type_meta["fields"]
        for field in fs.keys():
            f = fs[field]
            if field == "description":
                cleaned_data[field] = form_data[field]
                continue
            elif field == "summary":
                cleaned_data["summary"] = form_data["title"]
                continue
            if field in form_data.keys():
                v = form_data.get(field)
                if v:
                    schema = f["schema"]
                    if schema.get(
                            "type") == "string" and not schema.get("custom"):
                        cleaned_data[field] = v
                        continue
                    if schema["type"] == "user" or schema.get(
                            "items") == "user":
                        v = {"name": v}
                    elif schema.get("custom") == JIRA_CUSTOM_FIELD_TYPES.get(
                            "multiuserpicker"):
                        # custom multi-picker
                        v = [{"name": v}]
                    elif schema["type"] == "array" and schema.get(
                            "items") != "string":
                        v = [{"id": vx} for vx in v]
                    elif schema["type"] == "array" and schema.get(
                            "items") == "string":
                        v = [v]
                    elif schema.get("custom") == JIRA_CUSTOM_FIELD_TYPES.get(
                            "textarea"):
                        v = v
                    elif (schema["type"] == "number" or schema.get("custom")
                          == JIRA_CUSTOM_FIELD_TYPES["tempo_account"]):
                        try:
                            if "." in v:
                                v = float(v)
                            else:
                                v = int(v)
                        except ValueError:
                            pass
                    elif (schema.get("type") != "string"
                          or (schema.get("items")
                              and schema.get("items") != "string")
                          or schema.get("custom")
                          == JIRA_CUSTOM_FIELD_TYPES.get("select")):
                        v = {"id": v}
                    cleaned_data[field] = v

        if not (isinstance(cleaned_data["issuetype"], dict)
                and "id" in cleaned_data["issuetype"]):
            # something fishy is going on with this field, working on some JIRA
            # instances, and some not.
            # testing against 5.1.5 and 5.1.4 does not convert (perhaps is no longer included
            # in the projectmeta API call, and would normally be converted in the
            # above clean method.)
            cleaned_data["issuetype"] = {"id": cleaned_data["issuetype"]}

        try:
            response = client.create_issue(cleaned_data)
        except Exception as e:
            self.raise_error(e)

        return response.get("key")
示例#6
0
    def get_new_issue_fields(self, request, group, event, **kwargs):
        fields = super().get_new_issue_fields(request, group, event, **kwargs)

        jira_project_key = self.get_option("default_project", group.project)

        client = self.get_jira_client(group.project)
        try:
            meta = client.get_create_meta_for_project(jira_project_key)
        except ApiError as e:
            raise PluginError(
                "JIRA responded with an error. We received a status code of {}"
                .format(e.code))
        except ApiUnauthorized:
            raise PluginError(
                "JIRA returned: Unauthorized. "
                "Please check your username, password, "
                "instance and project in your configuration settings.")

        if not meta:
            raise PluginError("Error in JIRA configuration, no projects "
                              "found for user %s." % client.username)

        # check if the issuetype was passed as a GET parameter
        issue_type = None
        if request is not None:
            if request.method == "POST":
                issue_type = request.data.get("issuetype")
            else:
                issue_type = request.GET.get("issuetype")

        if issue_type is None:
            issue_type = self.get_option("default_issue_type", group.project)

        issue_type_meta = self.get_issue_type_meta(issue_type, meta)

        issue_type_choices = self.make_choices(meta["issuetypes"])

        # make sure default issue type is actually
        # one that is allowed for project
        if issue_type:
            if not any(c for c in issue_type_choices if c[0] == issue_type):
                issue_type = issue_type_meta["id"]

        fields = ([{
            "name": "project",
            "label": "Jira Project",
            "choices": ((meta["id"], jira_project_key), ),
            "default": meta["id"],
            "type": "select",
            "readonly": True,
        }] + fields + [{
            "name": "issuetype",
            "label": "Issue Type",
            "default": issue_type or issue_type_meta["id"],
            "type": "select",
            "choices": issue_type_choices,
        }])

        # title is renamed to summary before sending to JIRA
        standard_fields = [f["name"] for f in fields] + ["summary"]
        ignored_fields = (self.get_option("ignored_fields", group.project)
                          or "").split(",")

        # apply ordering to fields based on some known built-in JIRA fields.
        # otherwise weird ordering occurs.
        anti_gravity = {
            "priority": -150,
            "fixVersions": -125,
            "components": -100,
            "security": -50
        }

        dynamic_fields = list(issue_type_meta.get("fields").keys())
        dynamic_fields.sort(key=lambda f: anti_gravity.get(f) or 0)
        # build up some dynamic fields based on required shit.
        for field in dynamic_fields:
            if field in standard_fields or field in [
                    x.strip() for x in ignored_fields
            ]:
                # don't overwrite the fixed fields for the form.
                continue
            mb_field = self.build_dynamic_field(
                group, issue_type_meta["fields"][field])
            if mb_field:
                mb_field["name"] = field
                fields.append(mb_field)

        for field in fields:
            if field["name"] == "priority":
                # whenever priorities are available, put the available ones in the list.
                # allowedValues for some reason doesn't pass enough info.
                field["choices"] = self.make_choices(client.get_priorities())
                field["default"] = self.get_option("default_priority",
                                                   group.project) or ""
            elif field["name"] == "fixVersions":
                field["choices"] = self.make_choices(
                    client.get_versions(jira_project_key))

        return fields
示例#7
0
    def create_issue(self, request, group, form_data, **kwargs):
        cleaned_data = {}

        # protect against mis-configured plugin submitting a form without an
        # issuetype assigned.
        if not form_data.get('issuetype'):
            raise PluginError('Issue Type is required.')

        jira_project_key = self.get_option('default_project', group.project)
        client = self.get_jira_client(group.project)
        meta = client.get_create_meta_for_project(jira_project_key)

        if not meta:
            raise PluginError(
                'Something went wrong. Check your plugin configuration.')

        issue_type_meta = self.get_issue_type_meta(form_data['issuetype'],
                                                   meta)

        fs = issue_type_meta['fields']
        for field in fs.keys():
            f = fs[field]
            if field == 'description':
                cleaned_data[field] = form_data[field]
            elif field == 'summary':
                cleaned_data['summary'] = form_data['title']
            if field in form_data.keys():
                v = form_data.get(field)
                if v:
                    schema = f['schema']
                    if schema.get('type') == 'string' and not schema.get(
                            'custom') == JIRA_CUSTOM_FIELD_TYPES['select']:
                        continue  # noop
                    if schema['type'] == 'user' or schema.get(
                            'items') == 'user':
                        v = {'name': v}
                    elif schema.get('custom') == JIRA_CUSTOM_FIELD_TYPES.get(
                            'multiuserpicker'):
                        # custom multi-picker
                        v = [{'name': v}]
                    elif schema['type'] == 'array' and schema.get(
                            'items') != 'string':
                        v = [{'id': vx} for vx in v]
                    elif schema['type'] == 'array' and schema.get(
                            'items') == 'string':
                        v = [v]
                    elif schema.get('custom') == JIRA_CUSTOM_FIELD_TYPES.get(
                            'textarea'):
                        v = v
                    elif schema['type'] == 'number' or \
                            schema.get('custom') == JIRA_CUSTOM_FIELD_TYPES['tempo_account']:
                        try:
                            if '.' in v:
                                v = float(v)
                            else:
                                v = int(v)
                        except ValueError:
                            pass
                    elif (schema.get('type') != 'string'
                          or schema.get('items') != 'string'
                          or schema.get('custom')
                          == JIRA_CUSTOM_FIELD_TYPES.get('select')):
                        v = {'id': v}
                    cleaned_data[field] = v

        if not (isinstance(cleaned_data['issuetype'], dict)
                and 'id' in cleaned_data['issuetype']):
            # something fishy is going on with this field, working on some JIRA
            # instances, and some not.
            # testing against 5.1.5 and 5.1.4 does not convert (perhaps is no longer included
            # in the projectmeta API call, and would normally be converted in the
            # above clean method.)
            cleaned_data['issuetype'] = {'id': cleaned_data['issuetype']}

        try:
            response = client.create_issue(cleaned_data)
        except Exception as e:
            self.raise_error(e)

        return response.json.get('key')
示例#8
0
 def raise_error(self, exc):
     # TODO(jess): switch this from JIRAError to the standard
     # shared exeption classes
     if not isinstance(exc, JIRAError):
         self.logger.exception(six.text_type(exc))
     raise PluginError(self.message_from_error(exc))
示例#9
0
    def get_new_issue_fields(self, request, group, event, **kwargs):
        fields = super(JiraPlugin,
                       self).get_new_issue_fields(request, group, event,
                                                  **kwargs)

        jira_project_key = self.get_option('default_project', group.project)

        client = self.get_jira_client(group.project)
        try:
            meta = client.get_create_meta_for_project(jira_project_key)
        except JIRAUnauthorized:
            raise PluginError(
                'Something went wrong. Please check your configuration.')

        if not meta:
            raise PluginError('Error in JIRA configuration, no projects '
                              'found for user %s.' % client.username)

        # check if the issuetype was passed as a GET parameter
        issue_type = None
        if request is not None:
            issue_type = request.GET.get('issue_type')

        if issue_type is None:
            issue_type = self.get_option('default_issue_type', group.project)

        issue_type_meta = self.get_issue_type_meta(issue_type, meta)
        issue_type_choices = self.make_choices(meta['issuetypes'])

        # make sure default issue type is actually
        # one that is allowed for project
        if issue_type:
            if not any((c for c in issue_type_choices if c[0] == issue_type)):
                issue_type = issue_type_meta['id']

        fields = [{
            'name': 'project',
            'label': 'Jira Project',
            'choices': ((meta['id'], jira_project_key), ),
            'default': meta['id'],
            'type': 'select',
            'readonly': True
        }] + fields + [{
            'name': 'issuetype',
            'label': 'Issue Type',
            'default': issue_type or issue_type_meta['id'],
            'type': 'select',
            'choices': issue_type_choices
        }]

        # title is renamed to summary before sending to JIRA
        standard_fields = [f['name'] for f in fields] + ['summary']
        ignored_fields = (self.get_option('ignored_fields', group.project)
                          or '').split(',')

        # apply ordering to fields based on some known built-in JIRA fields.
        # otherwise weird ordering occurs.
        anti_gravity = {
            "priority": -150,
            "fixVersions": -125,
            "components": -100,
            "security": -50
        }

        dynamic_fields = issue_type_meta.get('fields').keys()
        dynamic_fields.sort(key=lambda f: anti_gravity.get(f) or 0)
        # build up some dynamic fields based on required shit.
        for field in dynamic_fields:
            if field in standard_fields or field in [
                    x.strip() for x in ignored_fields
            ]:
                # don't overwrite the fixed fields for the form.
                continue
            mb_field = self.build_dynamic_field(
                group, issue_type_meta['fields'][field])
            if mb_field:
                mb_field['name'] = field
                fields.append(mb_field)

        for field in fields:
            if field['name'] == 'priority':
                # whenever priorities are available, put the available ones in the list.
                # allowedValues for some reason doesn't pass enough info.
                field['choices'] = self.make_choices(
                    client.get_priorities().json)
                field['default'] = self.get_option('default_priority',
                                                   group.project) or ''
            elif field['name'] == 'fixVersions':
                field['choices'] = self.make_choices(
                    client.get_versions(jira_project_key).json)

        return fields