Exemple #1
0
def api_resolve_swh_pid(request, swh_id):
    """
    .. http:get:: /api/1/resolve/(swh_id)/

        Resolve a Software Heritage persistent identifier.

        Try to resolve a provided `persistent identifier <https://docs.softwareheritage.org/devel/swh-model/persistent-identifiers.html>`_
        into an url for browsing the pointed archive object. If the provided
        identifier is valid, the existence of the object in the archive
        will also be checked.

        :param string swh_id: a Software Heritage presistent identifier

        :>json string browse_url: the url for browsing the pointed object
        :>json object metadata: object holding optional parts of the persistent identifier
        :>json string namespace: the persistent identifier namespace
        :>json string object_id: the hash identifier of the pointed object
        :>json string object_type: the type of the pointed object
        :>json number scheme_version: the scheme version of the persistent identifier

        :reqheader Accept: the requested response content type,
            either ``application/json`` (default) or ``application/yaml``
        :resheader Content-Type: this depends on :http:header:`Accept` header of request

        **Allowed HTTP Methods:** :http:method:`get`, :http:method:`head`, :http:method:`options`

        :statuscode 200: no error
        :statuscode 400: an invalid persistent identifier has been provided
        :statuscode 404: the pointed object does not exist in the archive

        **Example:**

        .. parsed-literal::

            :swh_web_api:`resolve/swh:1:rev:96db9023b881d7cd9f379b0c154650d6c108e9a3;origin=https://github.com/openssl/openssl/`
    """  # noqa
    # try to resolve the provided pid
    swh_id_resolved = resolve_swh_persistent_id(swh_id)
    # id is well-formed, now check that the pointed
    # object is present in the archive, NotFoundExc
    # will be raised otherwise
    swh_id_parsed = swh_id_resolved['swh_id_parsed']
    object_type = swh_id_parsed.object_type
    object_id = swh_id_parsed.object_id
    if object_type == CONTENT:
        service.lookup_content('sha1_git:%s' % object_id)
    elif object_type == DIRECTORY:
        service.lookup_directory(object_id)
    elif object_type == RELEASE:
        service.lookup_release(object_id)
    elif object_type == REVISION:
        service.lookup_revision(object_id)
    elif object_type == SNAPSHOT:
        service.lookup_snapshot(object_id)
    # id is well-formed and the pointed object exists
    swh_id_data = swh_id_parsed._asdict()
    swh_id_data['browse_url'] = swh_id_resolved['browse_url']
    return swh_id_data
Exemple #2
0
def _revision_diff(request, sha1_git):
    """
    Browse internal endpoint to compute revision diff
    """
    try:
        revision = service.lookup_revision(sha1_git)
        snapshot_context = None
        origin_type = request.GET.get('origin_type', None)
        origin_url = request.GET.get('origin_url', None)
        if not origin_url:
            origin_url = request.GET.get('origin', None)
        timestamp = request.GET.get('timestamp', None)
        visit_id = request.GET.get('visit_id', None)
        if origin_url:
            snapshot_context = get_snapshot_context(None, origin_type,
                                                    origin_url, timestamp,
                                                    visit_id)
    except Exception as exc:
        return handle_view_exception(request, exc)

    changes = service.diff_revision(sha1_git)
    changes_msg = _gen_revision_changes_list(revision, changes,
                                             snapshot_context)

    diff_data = {
        'total_nb_changes': len(changes),
        'changes': changes[:_max_displayed_file_diffs],
        'changes_msg': changes_msg
    }
    diff_data_json = json.dumps(diff_data, separators=(',', ': '))
    return HttpResponse(diff_data_json, content_type='application/json')
Exemple #3
0
    def test_lookup_revision_invalid_msg(self, new_revision):

        new_revision['message'] = b'elegant fix for bug \xff'
        self.storage.revision_add([new_revision])

        revision = service.lookup_revision(hash_to_hex(new_revision['id']))
        self.assertEqual(revision['message'], None)
        self.assertEqual(revision['message_decoding_failed'], True)
Exemple #4
0
def release_browse(request, sha1_git):
    """
    Django view that produces an HTML display of a release
    identified by its id.

    The url that points to it is :http:get:`/browse/release/(sha1_git)/`.
    """
    try:
        release = service.lookup_release(sha1_git)
        snapshot_context = None
        origin_info = None
        snapshot_id = request.GET.get('snapshot_id', None)
        origin_type = request.GET.get('origin_type', None)
        origin_url = request.GET.get('origin_url', None)
        if not origin_url:
            origin_url = request.GET.get('origin', None)
        timestamp = request.GET.get('timestamp', None)
        visit_id = request.GET.get('visit_id', None)
        if origin_url:
            try:
                snapshot_context = \
                    get_snapshot_context(snapshot_id, origin_type,
                                         origin_url, timestamp,
                                         visit_id)
            except Exception:
                raw_rel_url = reverse('browse-release',
                                      url_args={'sha1_git': sha1_git})
                error_message = \
                    ('The Software Heritage archive has a release '
                     'with the hash you provided but the origin '
                     'mentioned in your request appears broken: %s. '
                     'Please check the URL and try again.\n\n'
                     'Nevertheless, you can still browse the release '
                     'without origin information: %s'
                        % (gen_link(origin_url), gen_link(raw_rel_url)))

                raise NotFoundExc(error_message)
            origin_info = snapshot_context['origin_info']
        elif snapshot_id:
            snapshot_context = get_snapshot_context(snapshot_id)
    except Exception as exc:
        return handle_view_exception(request, exc)

    release_data = {}

    author_name = 'None'
    release_data['author'] = 'None'
    if release['author']:
        author_name = release['author']['name'] or \
                      release['author']['fullname']
        release_data['author'] = \
            gen_person_link(release['author']['id'], author_name,
                            snapshot_context)
    release_data['date'] = format_utc_iso_date(release['date'])
    release_data['id'] = sha1_git
    release_data['name'] = release['name']
    release_data['synthetic'] = release['synthetic']
    release_data['target type'] = release['target_type']

    if release['target_type'] == 'revision':
        release_data['target'] = \
            gen_revision_link(release['target'],
                              snapshot_context=snapshot_context)
    elif release['target_type'] == 'content':
        content_url = \
            reverse('browse-content',
                    url_args={'query_string': 'sha1_git:' + release['target']})
        release_data['target'] = gen_link(content_url, release['target'])
    elif release['target_type'] == 'directory':
        directory_url = \
            reverse('browse-directory',
                    url_args={'sha1_git': release['target']})
        release_data['target'] = gen_link(directory_url, release['target'])
    elif release['target_type'] == 'release':
        release_url = \
            reverse('browse-release',
                    url_args={'sha1_git': release['target']})
        release_data['target'] = gen_link(release_url, release['target'])

    release_note_lines = []
    if release['message']:
        release_note_lines = release['message'].split('\n')

    vault_cooking = None

    query_params = {}
    if snapshot_id:
        query_params = {'snapshot_id': snapshot_id}
    elif origin_info:
        query_params = {'origin': origin_info['url']}

    target_url = ''
    if release['target_type'] == 'revision':
        target_url = reverse('browse-revision',
                             url_args={'sha1_git': release['target']},
                             query_params=query_params)
        try:
            revision = service.lookup_revision(release['target'])
            vault_cooking = {
                'directory_context': True,
                'directory_id': revision['directory'],
                'revision_context': True,
                'revision_id': release['target']
            }
        except Exception:
            pass
    elif release['target_type'] == 'directory':
        target_url = reverse('browse-directory',
                             url_args={'sha1_git': release['target']},
                             query_params=query_params)
        try:
            revision = service.lookup_directory(release['target'])
            vault_cooking = {
                'directory_context': True,
                'directory_id': revision['directory'],
                'revision_context': False,
                'revision_id': None
            }
        except Exception:
            pass
    elif release['target_type'] == 'content':
        target_url = reverse('browse-content',
                             url_args={'query_string': release['target']},
                             query_params=query_params)
    elif release['target_type'] == 'release':
        target_url = reverse('browse-release',
                             url_args={'sha1_git': release['target']},
                             query_params=query_params)

    release['target_url'] = target_url

    if snapshot_context:
        release_data['snapshot id'] = snapshot_context['snapshot_id']

    if origin_info:
        release_url = reverse('browse-release',
                              url_args={'sha1_git': release['id']})
        release_data['context-independent release'] = \
            gen_link(release_url, link_text='Browse',
                     link_attrs={'class': 'btn btn-default btn-sm',
                                 'role': 'button'})
        release_data['origin id'] = origin_info['id']
        release_data['origin type'] = origin_info['type']
        release_data['origin url'] = gen_link(origin_info['url'],
                                              origin_info['url'])
        browse_snapshot_link = \
            gen_snapshot_link(snapshot_context['snapshot_id'],
                              link_text='Browse',
                              link_attrs={'class': 'btn btn-default btn-sm',
                                          'role': 'button'})
        release_data['snapshot'] = browse_snapshot_link

    swh_objects = [{'type': 'release',
                    'id': sha1_git}]

    if snapshot_context:
        snapshot_id = snapshot_context['snapshot_id']

    if snapshot_id:
        swh_objects.append({'type': 'snapshot',
                            'id': snapshot_id})

    swh_ids = get_swh_persistent_ids(swh_objects, snapshot_context)

    note_header = 'None'
    if len(release_note_lines) > 0:
        note_header = release_note_lines[0]

    release['note_header'] = note_header
    release['note_body'] = '\n'.join(release_note_lines[1:])

    heading = 'Release - %s' % release['name']
    if snapshot_context:
        context_found = 'snapshot: %s' % snapshot_context['snapshot_id']
        if origin_info:
            context_found = 'origin: %s' % origin_info['url']
        heading += ' - %s' % context_found

    return render(request, 'browse/release.html',
                  {'heading': heading,
                   'swh_object_id': swh_ids[0]['swh_id'],
                   'swh_object_name': 'Release',
                   'swh_object_metadata': release_data,
                   'release': release,
                   'snapshot_context': snapshot_context,
                   'show_actions_menu': True,
                   'breadcrumbs': None,
                   'vault_cooking': vault_cooking,
                   'top_right_link': None,
                   'swh_ids': swh_ids})
Exemple #5
0
def _process_snapshot_request(request,
                              snapshot_id=None,
                              origin_type=None,
                              origin_url=None,
                              timestamp=None,
                              path=None,
                              browse_context='directory'):
    """
    Utility function to perform common input request processing
    for snapshot context views.
    """

    visit_id = request.GET.get('visit_id', None)

    snapshot_context = get_snapshot_context(snapshot_id, origin_type,
                                            origin_url, timestamp, visit_id)

    swh_type = snapshot_context['swh_type']
    origin_info = snapshot_context['origin_info']
    branches = snapshot_context['branches']
    releases = snapshot_context['releases']
    url_args = snapshot_context['url_args']
    query_params = snapshot_context['query_params']

    if snapshot_context['visit_info']:
        timestamp = format_utc_iso_date(snapshot_context['visit_info']['date'],
                                        '%Y-%m-%dT%H:%M:%SZ')
        snapshot_context['timestamp'] = \
            format_utc_iso_date(snapshot_context['visit_info']['date'])

    browse_view_name = 'browse-' + swh_type + '-' + browse_context

    root_sha1_git = None
    revision_id = request.GET.get('revision', None)
    release_name = request.GET.get('release', None)
    release_id = None
    branch_name = None

    snapshot_total_size = sum(snapshot_context['snapshot_size'].values())

    if snapshot_total_size and revision_id:
        revision = service.lookup_revision(revision_id)
        root_sha1_git = revision['directory']
        branches.append({
            'name': revision_id,
            'revision': revision_id,
            'directory': root_sha1_git,
            'url': None
        })
        branch_name = revision_id
        query_params['revision'] = revision_id
    elif snapshot_total_size and release_name:
        release = _get_release(releases, release_name)
        try:
            root_sha1_git = release['directory']
            revision_id = release['target']
            release_id = release['id']
            query_params['release'] = release_name
        except Exception:
            _branch_not_found("release", release_name, releases, snapshot_id,
                              origin_info, timestamp, visit_id)
    elif snapshot_total_size:
        branch_name = request.GET.get('branch', None)
        if branch_name:
            query_params['branch'] = branch_name
        branch = _get_branch(branches, branch_name or 'HEAD',
                             snapshot_context['snapshot_id'])
        try:
            branch_name = branch['name']
            revision_id = branch['revision']
            root_sha1_git = branch['directory']
        except Exception:
            _branch_not_found("branch", branch_name, branches, snapshot_id,
                              origin_info, timestamp, visit_id)

    for b in branches:
        branch_url_args = dict(url_args)
        branch_query_params = dict(query_params)
        if 'release' in branch_query_params:
            del branch_query_params['release']
        branch_query_params['branch'] = b['name']
        if path:
            b['path'] = path
            branch_url_args['path'] = path
        b['url'] = reverse(browse_view_name,
                           url_args=branch_url_args,
                           query_params=branch_query_params)

    for r in releases:
        release_url_args = dict(url_args)
        release_query_params = dict(query_params)
        if 'branch' in release_query_params:
            del release_query_params['branch']
        release_query_params['release'] = r['name']
        if path:
            r['path'] = path
            release_url_args['path'] = path
        r['url'] = reverse(browse_view_name,
                           url_args=release_url_args,
                           query_params=release_query_params)

    snapshot_context['query_params'] = query_params
    snapshot_context['root_sha1_git'] = root_sha1_git
    snapshot_context['revision_id'] = revision_id
    snapshot_context['branch'] = branch_name
    snapshot_context['release'] = release_name
    snapshot_context['release_id'] = release_id

    return snapshot_context
Exemple #6
0
    def test_lookup_revision_through_with_revision(self, revision):

        self.assertEqual(
            service.lookup_revision_through({'sha1_git': revision}),
            service.lookup_revision(revision))
Exemple #7
0
 def test_lookup_revision(self, revision):
     actual_revision = service.lookup_revision(revision)
     self.assertEqual(actual_revision, self.revision_get(revision))
Exemple #8
0
def _gen_revision_changes_list(revision, changes, snapshot_context):
    """
    Returns a HTML string describing the file changes
    introduced in a revision.
    As this string will be displayed in the browse revision view,
    links to adequate file diffs are also generated.

    Args:
        revision (str): hexadecimal representation of a revision identifier
        changes (list): list of file changes in the revision
        snapshot_context (dict): optional origin context used to reverse
            the content urls

    Returns:
        A string to insert in a revision HTML view.

    """
    changes_msg = []
    for i, change in enumerate(changes):
        hasher = hashlib.sha1()
        from_query_string = ''
        to_query_string = ''
        diff_id = 'diff-'
        if change['from']:
            from_query_string = 'sha1_git:' + change['from']['target']
            diff_id += change['from']['target'] + '-' + change['from_path']
        diff_id += '-'
        if change['to']:
            to_query_string = 'sha1_git:' + change['to']['target']
            diff_id += change['to']['target'] + change['to_path']
        change['path'] = change['to_path'] or change['from_path']
        url_args = {
            'from_query_string': from_query_string,
            'to_query_string': to_query_string
        }
        query_params = {'path': change['path']}
        change['diff_url'] = reverse('diff-contents',
                                     url_args=url_args,
                                     query_params=query_params)

        hasher.update(diff_id.encode('utf-8'))
        diff_id = hasher.hexdigest()
        change['id'] = diff_id
        panel_diff_link = '#panel_' + diff_id

        if change['type'] == 'modify':
            change['content_url'] = \
                _gen_content_url(revision, to_query_string,
                                 change['to_path'], snapshot_context)
            changes_msg.append(
                'modified:  %s' %
                _gen_diff_link(i, panel_diff_link, change['to_path']))
        elif change['type'] == 'insert':
            change['content_url'] = \
                _gen_content_url(revision, to_query_string,
                                 change['to_path'], snapshot_context)
            changes_msg.append(
                'new file:  %s' %
                _gen_diff_link(i, panel_diff_link, change['to_path']))
        elif change['type'] == 'delete':
            parent = service.lookup_revision(revision['parents'][0])
            change['content_url'] = \
                _gen_content_url(parent,
                                 from_query_string,
                                 change['from_path'], snapshot_context)
            changes_msg.append(
                'deleted:   %s' %
                _gen_diff_link(i, panel_diff_link, change['from_path']))
        elif change['type'] == 'rename':
            change['content_url'] = \
                _gen_content_url(revision, to_query_string,
                                 change['to_path'], snapshot_context)
            link_text = change['from_path'] + ' &rarr; ' + change['to_path']
            changes_msg.append('renamed:   %s' %
                               _gen_diff_link(i, panel_diff_link, link_text))
    if not changes:
        changes_msg.append('No changes')
    return mark_safe('\n'.join(changes_msg))
Exemple #9
0
def revision_browse(request, sha1_git, extra_path=None):
    """
    Django view that produces an HTML display of a revision
    identified by its id.

    The url that points to it is :http:get:`/browse/revision/(sha1_git)/`.
    """
    try:
        revision = service.lookup_revision(sha1_git)
        # some readme files can reference assets reachable from the
        # browsed directory, handle that special case in order to
        # correctly displayed them
        if extra_path:
            dir_info = \
                service.lookup_directory_with_path(revision['directory'],
                                                   extra_path)
            if dir_info and dir_info['type'] == 'file':
                file_raw_url = reverse(
                    'browse-content-raw',
                    url_args={'query_string': dir_info['checksums']['sha1']})
                return redirect(file_raw_url)
        origin_info = None
        snapshot_context = None
        origin_type = request.GET.get('origin_type', None)
        origin_url = request.GET.get('origin_url', None)
        if not origin_url:
            origin_url = request.GET.get('origin', None)
        timestamp = request.GET.get('timestamp', None)
        visit_id = request.GET.get('visit_id', None)
        snapshot_id = request.GET.get('snapshot_id', None)
        path = request.GET.get('path', None)
        dir_id = None
        dirs, files = None, None
        content_data = None
        if origin_url:
            try:
                snapshot_context = get_snapshot_context(
                    None, origin_type, origin_url, timestamp, visit_id)
            except Exception:
                raw_rev_url = reverse('browse-revision',
                                      url_args={'sha1_git': sha1_git})
                error_message = \
                    ('The Software Heritage archive has a revision '
                     'with the hash you provided but the origin '
                     'mentioned in your request appears broken: %s. '
                     'Please check the URL and try again.\n\n'
                     'Nevertheless, you can still browse the revision '
                     'without origin information: %s'
                        % (gen_link(origin_url), gen_link(raw_rev_url)))
                raise NotFoundExc(error_message)
            origin_info = snapshot_context['origin_info']
            snapshot_id = snapshot_context['snapshot_id']
        elif snapshot_id:
            snapshot_context = get_snapshot_context(snapshot_id)
        if path:
            file_info = \
                service.lookup_directory_with_path(revision['directory'], path)
            if file_info['type'] == 'dir':
                dir_id = file_info['target']
            else:
                query_string = 'sha1_git:' + file_info['target']
                content_data = request_content(query_string,
                                               raise_if_unavailable=False)
        else:
            dir_id = revision['directory']

        if dir_id:
            path = '' if path is None else (path + '/')
            dirs, files = get_directory_entries(dir_id)
    except Exception as exc:
        return handle_view_exception(request, exc)

    revision_data = {}

    author_name = 'None'
    revision_data['author'] = 'None'
    if revision['author']:
        author_name = revision['author']['name'] or \
                      revision['author']['fullname']
        revision_data['author'] = \
            gen_person_link(revision['author']['id'], author_name,
                            snapshot_context)
    revision_data['committer'] = 'None'
    if revision['committer']:
        revision_data['committer'] = \
            gen_person_link(revision['committer']['id'],
                            revision['committer']['name'], snapshot_context)
    revision_data['committer date'] = \
        format_utc_iso_date(revision['committer_date'])
    revision_data['date'] = format_utc_iso_date(revision['date'])
    if snapshot_context:
        revision_data['snapshot id'] = snapshot_id
        revision_data['directory'] = \
            gen_snapshot_directory_link(snapshot_context, sha1_git,
                                        link_text='Browse',
                                        link_attrs={'class': 'btn btn-default btn-sm', # noqa
                                                    'role': 'button'})
    else:
        revision_data['directory'] = \
            gen_directory_link(revision['directory'], link_text='Browse',
                               link_attrs={'class': 'btn btn-default btn-sm',
                                           'role': 'button'})
    revision_data['id'] = sha1_git
    revision_data['merge'] = revision['merge']
    revision_data['metadata'] = escape(
        json.dumps(revision['metadata'],
                   sort_keys=True,
                   indent=4,
                   separators=(',', ': ')))

    if origin_info:
        revision_data['context-independent revision'] = \
            gen_revision_link(sha1_git, link_text='Browse',
                              link_attrs={'class': 'btn btn-default btn-sm',
                                          'role': 'button'})
        revision_data['origin id'] = origin_info['id']
        revision_data['origin type'] = origin_info['type']
        revision_data['origin url'] = gen_link(origin_info['url'],
                                               origin_info['url'])
        browse_snapshot_link = \
            gen_snapshot_link(snapshot_id, link_text='Browse',
                              link_attrs={'class': 'btn btn-default btn-sm',
                                          'role': 'button'})
        revision_data['snapshot'] = browse_snapshot_link

    parents = ''
    for p in revision['parents']:
        parent_link = gen_revision_link(p, snapshot_context=snapshot_context)
        parents += parent_link + '<br/>'

    revision_data['parents'] = mark_safe(parents)
    revision_data['synthetic'] = revision['synthetic']
    revision_data['type'] = revision['type']

    message_lines = ['None']
    if revision['message']:
        message_lines = revision['message'].split('\n')

    parents = []
    for p in revision['parents']:
        parent_url = gen_revision_url(p, snapshot_context)
        parents.append({'id': p, 'url': parent_url})

    path_info = gen_path_info(path)

    query_params = {
        'snapshot_id': snapshot_id,
        'origin_type': origin_type,
        'origin': origin_url,
        'timestamp': timestamp,
        'visit_id': visit_id
    }

    breadcrumbs = []
    breadcrumbs.append({
        'name':
        revision['directory'][:7],
        'url':
        reverse('browse-revision',
                url_args={'sha1_git': sha1_git},
                query_params=query_params)
    })
    for pi in path_info:
        query_params['path'] = pi['path']
        breadcrumbs.append({
            'name':
            pi['name'],
            'url':
            reverse('browse-revision',
                    url_args={'sha1_git': sha1_git},
                    query_params=query_params)
        })

    vault_cooking = {
        'directory_context': False,
        'directory_id': None,
        'revision_context': True,
        'revision_id': sha1_git
    }

    swh_objects = [{'type': 'revision', 'id': sha1_git}]

    content = None
    content_size = None
    mimetype = None
    language = None
    readme_name = None
    readme_url = None
    readme_html = None
    readmes = {}
    error_code = 200
    error_message = ''
    error_description = ''

    if content_data:
        breadcrumbs[-1]['url'] = None
        content_size = content_data['length']
        mimetype = content_data['mimetype']
        if content_data['raw_data']:
            content_display_data = prepare_content_for_display(
                content_data['raw_data'], content_data['mimetype'], path)
            content = content_display_data['content_data']
            language = content_display_data['language']
            mimetype = content_display_data['mimetype']
        query_params = {}
        if path:
            filename = path_info[-1]['name']
            query_params['filename'] = path_info[-1]['name']
            revision_data['filename'] = filename

        top_right_link = {
            'url':
            reverse('browse-content-raw',
                    url_args={'query_string': query_string},
                    query_params=query_params),
            'icon':
            swh_object_icons['content'],
            'text':
            'Raw File'
        }

        swh_objects.append({'type': 'content', 'id': file_info['target']})

        error_code = content_data['error_code']
        error_message = content_data['error_message']
        error_description = content_data['error_description']
    else:
        for d in dirs:
            if d['type'] == 'rev':
                d['url'] = reverse('browse-revision',
                                   url_args={'sha1_git': d['target']})
            else:
                query_params['path'] = path + d['name']
                d['url'] = reverse('browse-revision',
                                   url_args={'sha1_git': sha1_git},
                                   query_params=query_params)
        for f in files:
            query_params['path'] = path + f['name']
            f['url'] = reverse('browse-revision',
                               url_args={'sha1_git': sha1_git},
                               query_params=query_params)
            if f['length'] is not None:
                f['length'] = filesizeformat(f['length'])
            if f['name'].lower().startswith('readme'):
                readmes[f['name']] = f['checksums']['sha1']

        readme_name, readme_url, readme_html = get_readme_to_display(readmes)

        top_right_link = {
            'url': get_revision_log_url(sha1_git, snapshot_context),
            'icon': swh_object_icons['revisions history'],
            'text': 'History'
        }

        vault_cooking['directory_context'] = True
        vault_cooking['directory_id'] = dir_id

        swh_objects.append({'type': 'directory', 'id': dir_id})

    diff_revision_url = reverse('diff-revision',
                                url_args={'sha1_git': sha1_git},
                                query_params={
                                    'origin_type': origin_type,
                                    'origin': origin_url,
                                    'timestamp': timestamp,
                                    'visit_id': visit_id
                                })

    if snapshot_id:
        swh_objects.append({'type': 'snapshot', 'id': snapshot_id})

    swh_ids = get_swh_persistent_ids(swh_objects, snapshot_context)

    heading = 'Revision - %s - %s' %\
        (sha1_git[:7], textwrap.shorten(message_lines[0], width=70))
    if snapshot_context:
        context_found = 'snapshot: %s' % snapshot_context['snapshot_id']
        if origin_info:
            context_found = 'origin: %s' % origin_info['url']
        heading += ' - %s' % context_found

    return render(request,
                  'browse/revision.html', {
                      'heading': heading,
                      'swh_object_id': swh_ids[0]['swh_id'],
                      'swh_object_name': 'Revision',
                      'swh_object_metadata': revision_data,
                      'message_header': message_lines[0],
                      'message_body': '\n'.join(message_lines[1:]),
                      'parents': parents,
                      'snapshot_context': snapshot_context,
                      'dirs': dirs,
                      'files': files,
                      'content': content,
                      'content_size': content_size,
                      'max_content_size': content_display_max_size,
                      'mimetype': mimetype,
                      'language': language,
                      'readme_name': readme_name,
                      'readme_url': readme_url,
                      'readme_html': readme_html,
                      'breadcrumbs': breadcrumbs,
                      'top_right_link': top_right_link,
                      'vault_cooking': vault_cooking,
                      'diff_revision_url': diff_revision_url,
                      'show_actions_menu': True,
                      'swh_ids': swh_ids,
                      'error_code': error_code,
                      'error_message': error_message,
                      'error_description': error_description
                  },
                  status=error_code)
Exemple #10
0
def process_snapshot_branches(snapshot):
    """
    Process a dictionary describing snapshot branches: extract those
    targeting revisions and releases, put them in two different lists,
    then sort those lists in lexicographical order of the branches' names.

    Args:
        snapshot_branches (dict): A dict describing the branches of a snapshot
            as returned for instance by :func:`swh.web.common.service.lookup_snapshot`

    Returns:
        tuple: A tuple whose first member is the sorted list of branches
            targeting revisions and second member the sorted list of branches
            targeting releases
    """ # noqa
    snapshot_branches = snapshot['branches']
    branches = {}
    branch_aliases = {}
    releases = {}
    revision_to_branch = defaultdict(set)
    revision_to_release = defaultdict(set)
    release_to_branch = defaultdict(set)
    for branch_name, target in snapshot_branches.items():
        if not target:
            # FIXME: display branches with an unknown target anyway
            continue
        target_id = target['target']
        target_type = target['target_type']
        if target_type == 'revision':
            branches[branch_name] = {
                'name': branch_name,
                'revision': target_id,
            }
            revision_to_branch[target_id].add(branch_name)
        elif target_type == 'release':
            release_to_branch[target_id].add(branch_name)
        elif target_type == 'alias':
            branch_aliases[branch_name] = target_id
        # FIXME: handle pointers to other object types

    def _enrich_release_branch(branch, release):
        releases[branch] = {
            'name': release['name'],
            'branch_name': branch,
            'date': format_utc_iso_date(release['date']),
            'id': release['id'],
            'message': release['message'],
            'target_type': release['target_type'],
            'target': release['target'],
        }

    def _enrich_revision_branch(branch, revision):
        branches[branch].update({
            'revision': revision['id'],
            'directory': revision['directory'],
            'date': format_utc_iso_date(revision['date']),
            'message': revision['message']
        })

    releases_info = service.lookup_release_multiple(release_to_branch.keys())
    for release in releases_info:
        branches_to_update = release_to_branch[release['id']]
        for branch in branches_to_update:
            _enrich_release_branch(branch, release)
        if release['target_type'] == 'revision':
            revision_to_release[release['target']].update(branches_to_update)

    revisions = service.lookup_revision_multiple(
        set(revision_to_branch.keys()) | set(revision_to_release.keys()))

    for revision in revisions:
        if not revision:
            continue
        for branch in revision_to_branch[revision['id']]:
            _enrich_revision_branch(branch, revision)
        for release in revision_to_release[revision['id']]:
            releases[release]['directory'] = revision['directory']

    for branch_alias, branch_target in branch_aliases.items():
        if branch_target in branches:
            branches[branch_alias] = dict(branches[branch_target])
        else:
            snp = service.lookup_snapshot(snapshot['id'],
                                          branches_from=branch_target,
                                          branches_count=1)
            if snp and branch_target in snp['branches']:

                target_type = snp['branches'][branch_target]['target_type']
                target = snp['branches'][branch_target]['target']
                if target_type == 'revision':
                    branches[branch_alias] = snp['branches'][branch_target]
                    revision = service.lookup_revision(target)
                    _enrich_revision_branch(branch_alias, revision)
                elif target_type == 'release':
                    release = service.lookup_release(target)
                    _enrich_release_branch(branch_alias, release)

        if branch_alias in branches:
            branches[branch_alias]['name'] = branch_alias

    ret_branches = list(sorted(branches.values(), key=lambda b: b['name']))
    ret_releases = list(sorted(releases.values(), key=lambda b: b['name']))

    return ret_branches, ret_releases