def _update(resource, data=None, query_args={}, *args, **kwargs): """Generate a PUT request on a resource. Unlike other methods, any additional query args must be passed in using the 'query_args' parameter, since kwargs is used for the fields which will be sent. Review Board expects ``extra_data`` fields to be sent as ``extra_data.field_name``, which cannot be passed as a raw literal in Python. Fields like this would have to be added to a dict and splatted. However, this function also accepts keyword arguments of the form ``extra_data__field_name``, which will be rewritten to fields of the form ``extra_data.field_name``. """ request = HttpRequest(resource._links['update']['href'], method='PUT', query_args=query_args) if data is None: data = {} kwargs.update(data) for name, value in _preprocess_fields(kwargs): request.add_field(name, value) return request
def upload_attachment(self, filename, content, caption=None, **kwargs): """Uploads a new attachment. The content argument should contain the body of the file to be uploaded, in string format. """ request = HttpRequest(self._url, method="POST", query_args=kwargs) request.add_file("path", filename, content) if caption: request.add_field("caption", caption) return request
def upload_screenshot(self, filename, content, caption=None, **kwargs): """Uploads a new screenshot. The content argument should contain the body of the screenshot to be uploaded, in string format. """ request = HttpRequest(self.url, method='POST', query_args=kwargs) request.add_file('path', filename, content) if caption: request.add_field('caption', caption) return request
def test_post_form_data(self): """Test the multipart form data generation.""" request = HttpRequest('/', 'POST') request.add_field('foo', 'bar') request.add_field('bar', 42) request.add_field('err', 'must-be-deleted') request.add_field('name', 'somestring') request.del_field('err') ctype, content = request.encode_multipart_formdata() m = re.match('^multipart/form-data; boundary=(.*)$', ctype) self.assertFalse(m is None) fields = [l.strip() for l in content.split('--' + m.group(1))][1:-1] d = {} for f in fields: lst = f.split('\r\n\r\n') self.assertEquals(len(lst), 2) k, v = lst m = re.match('Content-Disposition: form-data; name="(.*?)"$', k) self.assertFalse(m is None) d[m.group(1)] = v self.assertEquals(d, {'foo': 'bar', 'bar': '42', 'name': 'somestring'})
def upload_diff(self, diff, parent_diff=None, base_dir=None, **kwargs): """Uploads a new diff. The diff and parent_diff arguments should be strings containing the diff output. """ request = HttpRequest(self.url, method='POST', query_args=kwargs) request.add_file('path', 'diff', diff) if parent_diff: request.add_file('parent_diff_path', 'parent_diff', parent_diff) if base_dir: request.add_field("basedir", base_dir) return request
def _update(resource, data={}, query_args={}, *args, **kwargs): """Generate a PUT request on a resource. Unlike other methods, any additional query args must be passed in using the 'query_args' parameter, since kwargs is used for the fields which will be sent. """ request = HttpRequest(resource._links['update']['href'], method='PUT', query_args=query_args) data.update(kwargs) for name, value in data.iteritems(): request.add_field(name, value) return request
def _update(resource, data=None, query_args={}, *args, **kwargs): """Generate a PUT request on a resource. Unlike other methods, any additional query args must be passed in using the 'query_args' parameter, since kwargs is used for the fields which will be sent. """ request = HttpRequest(resource._links["update"]["href"], method="PUT", query_args=query_args) if data is None: data = {} kwargs.update(data) for name, value in kwargs.iteritems(): request.add_field(name, value) return request
def upload_diff(self, diff, parent_diff=None, base_dir=None, base_commit_id=None, **kwargs): """Uploads a new diff. The diff and parent_diff arguments should be strings containing the diff output. """ request = HttpRequest(self._url, method="POST", query_args=kwargs) request.add_file("path", "diff", diff) if parent_diff: request.add_file("parent_diff_path", "parent_diff", parent_diff) if base_dir: request.add_field("basedir", base_dir) if base_commit_id: request.add_field("base_commit_id", base_commit_id) return request
def finalize_commit_series(self, cumulative_diff, validation_info, parent_diff=None): """Finalize a commit series. Args: cumulative_diff (bytes): The cumulative diff of the entire commit series. validation_info (unicode): The validation information returned by validatin the last commit in the series with the :py:class:`ValidateDiffCommitResource`. parent_diff (bytes, optional): An optional parent diff. This will be the same parent diff uploaded with each commit. Returns: DiffItemResource: The finalized diff resource. """ if not isinstance(cumulative_diff, bytes): raise TypeError('cumulative_diff must be byte string, not %s' % type(cumulative_diff)) if parent_diff is not None and not isinstance(parent_diff, bytes): raise TypeError('parent_diff must be byte string, not %s' % type(cumulative_diff)) request = HttpRequest(self.links['self']['href'], method='PUT') request.add_field('finalize_commit_series', True) request.add_file('cumulative_diff', 'cumulative_diff', cumulative_diff) request.add_field('validation_info', validation_info) if parent_diff is not None: request.add_file('parent_diff', 'parent_diff', parent_diff) return request
def create_empty(self, base_commit_id=None, **kwargs): """Create an empty DiffSet that commits can be added to. Args: base_commit_id (unicode, optional): The base commit ID of the diff. **kwargs (dict): Keyword arguments to encode into the querystring of the request URL. Returns: DiffItemResource: The created resource. """ request = HttpRequest(self._url, method=b'POST', query_args=kwargs) if base_commit_id: request.add_field('base_commit_id', base_commit_id) return request
def validate_diff(self, repository, diff, parent_diff=None, base_dir=None, **kwargs): """Validates a diff. The diff and parent_diff arguments should be strings containing the diff output. """ # TODO: This method should be unified with upload_diff() method of # DiffListResource, since they both perform the same operation. request = HttpRequest(self._url, method='POST', query_args=kwargs) request.add_field('repository', repository) request.add_file('path', 'diff', diff) if parent_diff: request.add_file('parent_diff_path', 'parent_diff', parent_diff) if base_dir: request.add_field('basedir', base_dir) return request
def prepare_upload_diff_request(self, diff, parent_diff=None, base_dir=None, base_commit_id=None, **kwargs): """Create a request that can be used to upload a diff. The diff and parent_diff arguments should be strings containing the diff output. """ request = HttpRequest(self._url, method='POST', query_args=kwargs) request.add_file('path', 'diff', diff) if parent_diff: request.add_file('parent_diff_path', 'parent_diff', parent_diff) if base_dir: request.add_field('basedir', base_dir) if base_commit_id: request.add_field('base_commit_id', base_commit_id) return request
def validate_commit(self, repository, diff, commit_id, parent_id, parent_diff=None, base_commit_id=None, validation_info=None, **kwargs): """Validate the diff for a commit. Args: repository (unicode): The name of the repository. diff (bytes): The contents of the diff to validate. commit_id (unicode): The ID of the commit being validated. parent_id (unicode): The ID of the parent commit. parent_diff (bytes, optional): The contents of the parent diff. base_commit_id (unicode, optional): The base commit ID. validation_info (unicode, optional): Validation information from a previous call to this resource. **kwargs (dict): Keyword arguments used to build the querystring. Returns: ValidateDiffCommitResource: The validation result. """ request = HttpRequest(self._url, method=b'POST', query_args=kwargs) request.add_file('diff', 'diff', diff) request.add_field('repository', repository) request.add_field('commit_id', commit_id) request.add_field('parent_id', parent_id) if parent_diff: request.add_file('parent_diff', 'parent_diff', parent_diff) if base_commit_id: request.add_field('base_commit_id', base_commit_id) if validation_info: request.add_field('validation_info', validation_info) return request
def upload_diff(self, diff, parent_diff=None, base_dir=None, base_commit_id=None, **kwargs): """Uploads a new diff. The diff and parent_diff arguments should be strings containing the diff output. """ # TODO: This method should be unified with validate_diff() method of # ValidateDiffResource, since they both perform the same operation. request = HttpRequest(self._url, method='POST', query_args=kwargs) request.add_file('path', 'diff', diff) if parent_diff: request.add_file('parent_diff_path', 'parent_diff', parent_diff) if base_dir: request.add_field("basedir", base_dir) if base_commit_id: request.add_field('base_commit_id', base_commit_id) return request
def test_post_form_data(self): """Testing the multipart form data generation.""" request = HttpRequest('/', 'POST') request.add_field('foo', 'bar') request.add_field('bar', 42) request.add_field('err', 'must-be-deleted') request.add_field('name', 'somestring') request.del_field('err') ctype, content = request.encode_multipart_formdata() d = self._get_fields_as_dict(ctype, content) self.assertEqual( d, {b'foo': b'bar', b'bar': b'42', b'name': b'somestring'})
def test_post_form_data(self): """Testing the multipart form data generation.""" request = HttpRequest('/', 'POST') request.add_field('foo', 'bar') request.add_field('bar', 42) request.add_field('err', 'must-be-deleted') request.add_field('name', 'somestring') request.del_field('err') ctype, content = request.encode_multipart_formdata() d = self._get_fields_as_dict(ctype, content) self.assertEqual(d, { b'foo': b'bar', b'bar': b'42', b'name': b'somestring' })
def test_post_unicode_data(self): """Testing the encoding of multipart form data with unicode and binary field data """ konnichiwa = '\u3053\u3093\u306b\u3061\u306f' request = HttpRequest('/', 'POST') request.add_field('foo', konnichiwa) request.add_field('bar', konnichiwa.encode('utf-8')) request.add_field('baz', b'\xff') ctype, content = request.encode_multipart_formdata() fields = self._get_fields_as_dict(ctype, content) self.assertTrue('foo' in fields) self.assertEqual(fields['foo'], konnichiwa.encode('utf-8')) self.assertEqual(fields['bar'], konnichiwa.encode('utf-8')) self.assertEqual(fields['baz'], b'\xff')
def test_post_unicode_data(self): """Testing the encoding of multipart form data with unicode and binary field data """ konnichiwa = '\u3053\u3093\u306b\u3061\u306f' request = HttpRequest('/', 'POST') request.add_field('foo', konnichiwa) request.add_field('bar', konnichiwa.encode('utf-8')) request.add_field('baz', b'\xff') ctype, content = request.encode_multipart_formdata() fields = self._get_fields_as_dict(ctype, content) self.assertTrue('foo' in fields) self.assertEqual(fields['foo'], konnichiwa.encode('utf-8')) self.assertEqual(fields['bar'], konnichiwa.encode('utf-8')) self.assertEqual(fields['baz'], b'\xff')
def test_encode_multipart_formdata(self): """Testing HttpRequest.encode_multipart_formdata""" request = HttpRequest(url='/', method='POST') request.add_field('foo', 'bar') request.add_field('bar', 42) request.add_field('name', 'somestring') request.add_file(name='my-file', filename='filename.txt', content=b'This is a test.') self.spy_on(request._make_mime_boundary, call_fake=lambda r: b'BOUNDARY') ctype, content = request.encode_multipart_formdata() self.assertEqual(ctype, 'multipart/form-data; boundary=BOUNDARY') self.assertEqual( content, b'--BOUNDARY\r\n' b'Content-Disposition: form-data; name="foo"\r\n' b'\r\n' b'bar' b'\r\n' b'--BOUNDARY\r\n' b'Content-Disposition: form-data; name="bar"\r\n' b'\r\n' b'42' b'\r\n' b'--BOUNDARY\r\n' b'Content-Disposition: form-data; name="name"\r\n' b'\r\n' b'somestring' b'\r\n' b'--BOUNDARY\r\n' b'Content-Disposition: form-data; name="my-file";' b' filename="filename.txt"\r\n' b'Content-Type: text/plain\r\n' b'\r\n' b'This is a test.' b'\r\n' b'--BOUNDARY--\r\n\r\n')
def test_encode_multipart_formdata_normalizes_string_types(self): """Testing HttpRequest.encode_multipart_formdata normalizes Unicode and byte strings """ konnichiwa = '\u3053\u3093\u306b\u3061\u306f' request = HttpRequest(url='/', method='POST') request.add_field('foo', konnichiwa) request.add_field('bar', konnichiwa.encode('utf-8')) request.add_field('baz', b'\xff') self.spy_on(request._make_mime_boundary, call_fake=lambda r: b'BOUNDARY') ctype, content = request.encode_multipart_formdata() self.assertEqual(ctype, 'multipart/form-data; boundary=BOUNDARY') self.assertEqual( content, b'--BOUNDARY\r\n' b'Content-Disposition: form-data; name="foo"\r\n' b'\r\n' b'\xe3\x81\x93\xe3\x82\x93\xe3\x81\xab\xe3\x81\xa1\xe3\x81\xaf' b'\r\n' b'--BOUNDARY\r\n' b'Content-Disposition: form-data; name="bar"\r\n' b'\r\n' b'\xe3\x81\x93\xe3\x82\x93\xe3\x81\xab\xe3\x81\xa1\xe3\x81\xaf' b'\r\n' b'--BOUNDARY\r\n' b'Content-Disposition: form-data; name="baz"\r\n' b'\r\n' b'\xff' b'\r\n' b'--BOUNDARY--\r\n\r\n')
def upload_commit(self, validation_info, diff, commit_id, parent_id, author_name, author_email, author_date, commit_message, committer_name=None, committer_email=None, committer_date=None, parent_diff=None, **kwargs): """Upload a commit. Args: validation_info (unicode): The validation info, or ``None`` if this is the first commit in a series. diff (bytes): The diff contents. commit_id (unicode): The ID of the commit being uploaded. parent_id (unicode): The ID of the parent commit. author_name (unicode): The name of the author. author_email (unicode): The e-mail address of the author. author_date (unicode): The date and time the commit was authored in ISO 8601 format. committer_name (unicode, optional): The name of the committer (if applicable). committer_email (unicode, optional): The e-mail address of the committer (if applicable). committer_date (unicode, optional): The date and time the commit was committed in ISO 8601 format (if applicable). parent_diff (bytes, optional): The contents of the parent diff. **kwargs (dict): Keyword argument used to build the querystring for the request URL. Returns: DraftDiffCommitItemResource: The created resource. Raises: rbtools.api.errors.APIError: An error occurred while uploading the commit. """ request = HttpRequest(self._url, method=b'POST', query_args=kwargs) request.add_file('diff', 'diff', diff) request.add_field('commit_id', commit_id) request.add_field('parent_id', parent_id) request.add_field('commit_message', commit_message) request.add_field('author_name', author_name) request.add_field('author_email', author_email) request.add_field('author_date', author_date) if validation_info: request.add_field('validation_info', validation_info) if committer_name and committer_email and committer_date: request.add_field('committer_name', committer_name) request.add_field('committer_email', committer_email) request.add_field('committer_date', committer_date) elif committer_name or committer_email or committer_name: logging.warning( 'Either all or none of committer_name, committer_email, and ' 'committer_date must be provided to upload_commit. None of ' 'these fields will be submitted.' ) if parent_diff: request.add_file('parent_diff', 'parent_diff', parent_diff) return request
def upload_commit(self, validation_info, diff, commit_id, parent_id, author_name, author_email, author_date, commit_message, committer_name=None, committer_email=None, committer_date=None, parent_diff=None, **kwargs): """Upload a commit. Args: validation_info (unicode): The validation info, or ``None`` if this is the first commit in a series. diff (bytes): The diff contents. commit_id (unicode): The ID of the commit being uploaded. parent_id (unicode): The ID of the parent commit. author_name (unicode): The name of the author. author_email (unicode): The e-mail address of the author. author_date (unicode): The date and time the commit was authored in ISO 8601 format. committer_name (unicode, optional): The name of the committer (if applicable). committer_email (unicode, optional): The e-mail address of the committer (if applicable). committer_date (unicode, optional): The date and time the commit was committed in ISO 8601 format (if applicable). parent_diff (bytes, optional): The contents of the parent diff. **kwargs (dict): Keyword argument used to build the querystring for the request URL. Returns: DraftDiffCommitItemResource: The created resource. Raises: rbtools.api.errors.APIError: An error occurred while uploading the commit. """ request = HttpRequest(self._url, method=b'POST', query_args=kwargs) request.add_file('diff', 'diff', diff) request.add_field('commit_id', commit_id) request.add_field('parent_id', parent_id) request.add_field('commit_message', commit_message) request.add_field('author_name', author_name) request.add_field('author_email', author_email) request.add_field('author_date', author_date) if validation_info: request.add_field('validation_info', validation_info) if committer_name and committer_email and committer_date: request.add_field('committer_name', committer_name) request.add_field('committer_email', committer_email) request.add_field('committer_date', committer_date) elif committer_name or committer_email or committer_name: logging.warning( 'Either all or none of committer_name, committer_email, and ' 'committer_date must be provided to upload_commit. None of ' 'these fields will be submitted.') if parent_diff: request.add_file('parent_diff', 'parent_diff', parent_diff) return request