Пример #1
0
        def remove(self, project_id):
            """Removes project from contact's project list"""
            url = '{0}/contacts/{1}/projects/{2}.json'.format(
                self._redmine.url, self._contact_id, project_id)

            try:
                return self._redmine.request('delete', url)
            except ResourceNotFoundError:
                raise ValidationError(
                    "Attempt to remove contact from a project that doesn't exist"
                )
            except ForbiddenError:
                raise ValidationError(
                    'Attempt to remove contact from a project that either has contacts module disabled or is read-only'
                )
Пример #2
0
    def update(self, resource_id, **fields):
        """Updates a Resource object by resource id (can be either integer id or string identifier)"""
        if self.resource_class.query_update is None or self.resource_class.container_update is None:
            raise ResourceBadMethodError()

        if not fields:
            raise ResourceNoFieldsProvidedError

        for index, upload in enumerate(fields.get('uploads', [])):
            fields['uploads'][index]['token'] = self.redmine.upload(
                upload.get('path', ''))

        formatter = MemorizeFormatter()

        try:
            query_update = formatter.format(self.resource_class.query_update,
                                            resource_id, **fields)
        except KeyError as exception:
            param = str(exception).replace("'", "")

            if param in self.params:
                fields[param] = self.params[param]
                query_update = formatter.format(
                    self.resource_class.query_update, resource_id, **fields)
            else:
                raise ValidationError(
                    '{0} argument is required'.format(exception))

        url = '{0}{1}'.format(self.redmine.url, query_update)
        data = {
            self.resource_class.container_update:
            self.prepare_params(formatter.unused_kwargs)
        }
        return self.redmine.request('put', url, data=data)
Пример #3
0
    def create(self, **fields):
        """Creates a new resource in Redmine database and returns resource object on success"""
        if self.resource_class.query_create is None or self.resource_class.container_create is None:
            raise ResourceBadMethodError()

        if not fields:
            raise ResourceNoFieldsProvidedError

        for index, upload in enumerate(fields.get('uploads', [])):
            fields['uploads'][index]['token'] = self.redmine.upload(
                upload.get('path', ''))

        formatter = MemorizeFormatter()

        try:
            url = '{0}{1}'.format(
                self.redmine.url,
                formatter.format(self.resource_class.query_create, **fields))
        except KeyError as exception:
            raise ValidationError('{0} field is required'.format(exception))

        self.container = self.resource_class.container_one
        data = {
            self.resource_class.container_create:
            self.prepare_params(formatter.unused_kwargs)
        }

        # Almost all resources are created via POST method, but some
        # resources are created via PUT, so we should check for this
        try:
            response = self.redmine.request('post', url, data=data)
        except ResourceNotFoundError:
            response = self.redmine.request('put', url, data=data)

        try:
            resource = self.to_resource(response[self.container])
        except TypeError:
            raise ValidationError(
                'Resource already exists')  # fix for repeated PUT requests

        self.params = formatter.used_kwargs
        self.url = '{0}{1}'.format(
            self.redmine.url,
            self.resource_class.query_one.format(resource.internal_id,
                                                 **fields))
        return resource
Пример #4
0
        def add(self, project_id):
            """Adds project to contact's project list"""
            url = '{0}/contacts/{1}/projects.json'.format(
                self._redmine.url, self._contact_id)

            try:
                return self._redmine.request(
                    'post', url, data={'project': {
                        'id': project_id
                    }})
            except ResourceNotFoundError:
                raise ValidationError(
                    "Attempt to add contact to a project that doesn't exist")
            except ForbiddenError:
                raise ValidationError(
                    'Attempt to add contact to a project that either has contacts module disabled or is read-only'
                )
Пример #5
0
    def request(self,
                method,
                url,
                headers=None,
                params=None,
                data=None,
                raw_response=False):
        """Makes requests to Redmine and returns result in json format"""
        kwargs = dict(
            self.requests, **{
                'headers': headers or {},
                'params': params or {},
                'data': data or {},
            })

        if 'Content-Type' not in kwargs['headers'] and method in ('post',
                                                                  'put'):
            kwargs['data'] = json.dumps(data)
            kwargs['headers']['Content-Type'] = 'application/json'

        if self.impersonate is not None:
            kwargs['headers']['X-Redmine-Switch-User'] = self.impersonate

        # We would like to be authenticated by API key by default
        if 'key' not in kwargs['params'] and self.key is not None:
            kwargs['params']['key'] = self.key
        else:
            kwargs['auth'] = (self.username, self.password)

        response = getattr(requests, method)(url, **kwargs)

        if response.status_code in (200, 201):
            if raw_response:
                return response
            elif not response.content.strip():
                return True
            else:
                return json_response(response.json)
        elif response.status_code == 401:
            raise AuthError
        elif response.status_code == 404:
            raise ResourceNotFoundError
        elif response.status_code == 409:
            raise ConflictError
        elif response.status_code == 412 and self.impersonate is not None:
            raise ImpersonateError
        elif response.status_code == 413:
            raise RequestEntityTooLargeError
        elif response.status_code == 422:
            errors = json_response(response.json)['errors']
            raise ValidationError(
                to_string(', '.join(e if is_string(e) else ': '.join(e)
                                    for e in errors)))
        elif response.status_code == 500:
            raise ServerError

        raise UnknownError(response.status_code)
Пример #6
0
    def delete(self, resource_id, **params):
        """Deletes a Resource object by resource id (can be either integer id or string identifier)"""
        if self.resource_class.query_delete is None:
            raise ResourceBadMethodError()

        try:
            url = '{0}{1}'.format(
                self.redmine.url,
                self.resource_class.query_delete.format(resource_id, **params))
        except KeyError as exception:
            raise ValidationError('{0} argument is required'.format(exception))

        return self.redmine.request('delete',
                                    url,
                                    params=self.prepare_params(params))
Пример #7
0
    def get(self, resource_id, **params):
        """Returns a Resource object directly by resource id (can be either integer id or string identifier)"""
        if self.resource_class.query_one is None or self.resource_class.container_one is None:
            raise ResourceBadMethodError()

        try:
            self.url = '{0}{1}'.format(
                self.redmine.url,
                self.resource_class.query_one.format(resource_id, **params))
        except KeyError as exception:
            raise ValidationError('{0} argument is required'.format(exception))

        self.params = self.prepare_params(params)
        self.container = self.resource_class.container_one
        return self.resource_class(self, self.retrieve()[0])