diff --git a/swh/web/ui/converters.py b/swh/web/ui/converters.py index 7f3d0dcf..e7f382ea 100644 --- a/swh/web/ui/converters.py +++ b/swh/web/ui/converters.py @@ -1,99 +1,109 @@ # Copyright (C) 2015 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information from swh.core import hashutil -def from_origin(origin): - """Convert from an SWH origin to an origin dictionary. +def from_swh(dict_swh, hashess=[], bytess=[]): + """Convert from an swh dictionary to something reasonably json + serializable. + + Args: + - dict_swh: the origin dictionary needed to be transformed + - hashess: list/set of keys representing hashes values (sha1, sha256, + sha1_git, etc...) as bytes. Those need to be transformed in hexadecimal + string + - bytess: list/set of keys representing bytes values which needs to + be decoded + + The remaining keys are copied as is in the output. + + Returns: + dictionary equivalent as dict_swh only with its keys `converted`. """ - new_origin = {} - for key, value in origin.items(): - if key == 'revision': - new_origin[key] = hashutil.hash_to_hex(value) - elif key == 'path': - new_origin[key] = value.decode('utf-8') + new_dict = {} + for key, value in dict_swh.items(): + if key in hashess: + new_dict[key] = hashutil.hash_to_hex(value) if value else None + elif key in bytess: + new_dict[key] = value.decode('utf-8') else: - new_origin[key] = value + new_dict[key] = value + + return new_dict - return new_origin + +def from_origin(origin): + """Convert from an SWH origin to an origin dictionary. + + """ + return from_swh(origin, + hashess=set(['revision']), + bytess=set(['path'])) def from_release(release): """Convert from an SWH release to a json serializable release dictionary. Args: release: Dict with the following keys - id: identifier of the revision (sha1 in bytes) - revision: identifier of the revision the release points to (sha1 in bytes) - comment: release's comment message (bytes) - name: release's name (string) - author: release's author identifier (swh's id) - synthetic: the synthetic property (boolean) Returns: Release dictionary with the following keys: - id: hexadecimal sha1 (string) - revision: hexadecimal sha1 (string) - comment: release's comment message (string) - name: release's name (string) - author: release's author identifier (swh's id) - synthetic: the synthetic property (boolean) """ - new_release = {} - for key, value in release.items(): - if key in ['id', 'revision']: - new_release[key] = hashutil.hash_to_hex(value) if value else None - elif key == 'comment': - new_release[key] = value.decode('utf-8') - else: - new_release[key] = value - return new_release + return from_swh(release, + hashess=set(['id', 'revision']), + bytess=set(['comment'])) def from_revision(revision): """Convert from an SWH revision to a json serializable revision dictionary. Args: revision: Dict with the following keys - id: identifier of the revision (sha1 in bytes) - directory: identifier of the directory the revision points to (sha1 in bytes) - author_name, author_email: author's revision name and email - committer_name, committer_email: committer's revision name and email - message: revision's message - date, date_offset: revision's author date - committer_date, committer_date_offset: revision's commit date - parents: list of parents for such revision - synthetic: revision's property nature - type: revision's type (git, tar or dsc at the moment) - metadata: if the revision is synthetic, this can reference dynamic properties. Returns: Revision dictionary with the same keys as inputs, only: - sha1s are in hexadecimal strings (id, directory) - bytes are decoded in string (author_name, committer_name, author_email, committer_email, message) - remaining keys are left as is """ - new_revision = {} - for key, value in revision.items(): - if key in ['id', 'directory']: - new_revision[key] = hashutil.hash_to_hex(value) if value else None - elif key in ['author_name', - 'committer_name', - 'author_email', - 'committer_email', - 'message']: - new_revision[key] = value.decode('utf-8') - else: - new_revision[key] = value - - return new_revision + return from_swh(revision, + hashess=set(['id', 'directory']), + bytess=set(['author_name', + 'committer_name', + 'author_email', + 'committer_email', + 'message'])) diff --git a/swh/web/ui/tests/test_converters.py b/swh/web/ui/tests/test_converters.py index ca7582eb..ff153790 100644 --- a/swh/web/ui/tests/test_converters.py +++ b/swh/web/ui/tests/test_converters.py @@ -1,170 +1,194 @@ # Copyright (C) 2015 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information import datetime import unittest from nose.tools import istest from swh.core import hashutil from swh.web.ui import converters class ConvertersTestCase(unittest.TestCase): + @istest + def from_swh(self): + some_input = { + 'a': 'something', + 'b': 'someone', + 'c': b'sharp-0.3.4.tgz', + 'd': b'\xb0L\xaf\x10\xe9SQ`\xd9\x0e\x87KE\xaaBm\xe7b\xf1\x9f', + 'e': b'sharp.html/doc_002dS_005fISREG.html' + } + + expected_output = { + 'a': 'something', + 'b': 'someone', + 'c': 'sharp-0.3.4.tgz', + 'd': 'b04caf10e9535160d90e874b45aa426de762f19f', + 'e': 'sharp.html/doc_002dS_005fISREG.html' + } + + actual_output = converters.from_swh(some_input, + hashess=set(['d']), + bytess=set(['c', 'e'])) + + self.assertEquals(expected_output, actual_output) + @istest def from_origin(self): # given origin_input = { 'origin_type': 'ftp', 'origin_url': 'rsync://ftp.gnu.org/gnu/octave', 'branch': 'octave-3.4.0.tar.gz', 'revision': b'\xb0L\xaf\x10\xe9SQ`\xd9\x0e\x87KE\xaaBm\xe7b\xf1\x9f', # noqa 'path': b'octave-3.4.0/doc/interpreter/octave.html/doc_002dS_005fISREG.html' # noqa } expected_origin = { 'origin_type': 'ftp', 'origin_url': 'rsync://ftp.gnu.org/gnu/octave', 'branch': 'octave-3.4.0.tar.gz', 'revision': 'b04caf10e9535160d90e874b45aa426de762f19f', 'path': 'octave-3.4.0/doc/interpreter/octave.html/doc_002dS_005fISREG.html' # noqa } # when actual_origin = converters.from_origin(origin_input) # then self.assertEqual(actual_origin, expected_origin) @istest def from_release(self): release_input = { 'id': hashutil.hex_to_hash( 'aad23fa492a0c5fed0708a6703be875448c86884'), 'revision': hashutil.hex_to_hash( '5e46d564378afc44b31bb89f99d5675195fbdf67'), 'date': datetime.datetime(2015, 1, 1, 22, 0, 0, tzinfo=datetime.timezone.utc), 'date_offset': None, 'name': 'v0.0.1', 'comment': b'some comment on release', 'synthetic': True, } expected_release = { 'id': 'aad23fa492a0c5fed0708a6703be875448c86884', 'revision': '5e46d564378afc44b31bb89f99d5675195fbdf67', 'date': datetime.datetime(2015, 1, 1, 22, 0, 0, tzinfo=datetime.timezone.utc), 'date_offset': None, 'name': 'v0.0.1', 'comment': 'some comment on release', 'synthetic': True, } # when actual_release = converters.from_release(release_input) # then self.assertEqual(actual_release, expected_release) @istest def from_release_no_revision(self): release_input = { 'id': hashutil.hex_to_hash( 'b2171ee2bdf119cd99a7ec7eff32fa8013ef9a4e'), 'revision': None, 'date': datetime.datetime(2016, 3, 2, 10, 0, 0, tzinfo=datetime.timezone.utc), 'date_offset': 1, 'name': 'v0.1.1', 'comment': b'comment on release', 'synthetic': False, } expected_release = { 'id': 'b2171ee2bdf119cd99a7ec7eff32fa8013ef9a4e', 'revision': None, 'date': datetime.datetime(2016, 3, 2, 10, 0, 0, tzinfo=datetime.timezone.utc), 'date_offset': 1, 'name': 'v0.1.1', 'comment': 'comment on release', 'synthetic': False, } # when actual_release = converters.from_release(release_input) # then self.assertEqual(actual_release, expected_release) @istest def from_revision(self): revision_input = { 'id': hashutil.hex_to_hash( '18d8be353ed3480476f032475e7c233eff7371d5'), 'directory': hashutil.hex_to_hash( '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6'), 'author_name': b'Software Heritage', 'author_email': b'robot@softwareheritage.org', 'committer_name': b'Software Heritage', 'committer_email': b'robot@softwareheritage.org', 'message': b'synthetic revision message', 'date': datetime.datetime(2000, 1, 17, 11, 23, 54, tzinfo=None), 'date_offset': 0, 'committer_date': datetime.datetime(2000, 1, 17, 11, 23, 54, tzinfo=None), 'committer_date_offset': 0, 'synthetic': True, 'type': 'tar', 'parents': [], 'metadata': { 'original_artifact': [{ 'archive_type': 'tar', 'name': 'webbase-5.7.0.tar.gz', 'sha1': '147f73f369733d088b7a6fa9c4e0273dcd3c7ccd', 'sha1_git': '6a15ea8b881069adedf11feceec35588f2cfe8f1', 'sha256': '401d0df797110bea805d358b85bcc1ced29549d3d73f' '309d36484e7edf7bb912', }] }, } expected_revision = { 'id': '18d8be353ed3480476f032475e7c233eff7371d5', 'directory': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6', 'author_name': 'Software Heritage', 'author_email': 'robot@softwareheritage.org', 'committer_name': 'Software Heritage', 'committer_email': 'robot@softwareheritage.org', 'message': 'synthetic revision message', 'date': datetime.datetime(2000, 1, 17, 11, 23, 54, tzinfo=None), 'date_offset': 0, 'committer_date': datetime.datetime(2000, 1, 17, 11, 23, 54, tzinfo=None), 'committer_date_offset': 0, 'parents': [], 'type': 'tar', 'synthetic': True, 'metadata': { 'original_artifact': [{ 'archive_type': 'tar', 'name': 'webbase-5.7.0.tar.gz', 'sha1': '147f73f369733d088b7a6fa9c4e0273dcd3c7ccd', 'sha1_git': '6a15ea8b881069adedf11feceec35588f2cfe8f1', 'sha256': '401d0df797110bea805d358b85bcc1ced29549d3d73f' '309d36484e7edf7bb912' }] }, } # when actual_revision = converters.from_revision(revision_input) # then self.assertEqual(actual_revision, expected_revision)