Changeset View
Changeset View
Standalone View
Standalone View
swh/graph/graph.py
# Copyright (C) 2019 The Software Heritage developers | # Copyright (C) 2019 The Software Heritage developers | ||||
# See the AUTHORS file at the top-level directory of this distribution | # See the AUTHORS file at the top-level directory of this distribution | ||||
# License: GNU General Public License version 3, or any later version | # License: GNU General Public License version 3, or any later version | ||||
# See top-level LICENSE file for more information | # See top-level LICENSE file for more information | ||||
import asyncio | import asyncio | ||||
import contextlib | import contextlib | ||||
import functools | |||||
from swh.graph.backend import Backend | from swh.graph.backend import Backend | ||||
from swh.graph.dot import dot_to_svg, graph_dot, KIND_TO_SHAPE | from swh.graph.dot import dot_to_svg, graph_dot, KIND_TO_SHAPE | ||||
KIND_TO_URL = { | BASE_URL = 'https://archive.softwareheritage.org/browse' | ||||
'ori': 'https://archive.softwareheritage.org/browse/origin/{}', | KIND_TO_URL_FRAGMENT = { | ||||
'snp': 'https://archive.softwareheritage.org/browse/snapshot/{}', | 'ori': '/origin/{}', | ||||
'rel': 'https://archive.softwareheritage.org/browse/release/{}', | 'snp': '/snapshot/{}', | ||||
'rev': 'https://archive.softwareheritage.org/browse/revision/{}', | 'rel': '/release/{}', | ||||
'dir': 'https://archive.softwareheritage.org/browse/directory/{}', | 'rev': '/revision/{}', | ||||
'cnt': 'https://archive.softwareheritage.org/browse/content/sha1_git:{}/', | 'dir': '/directory/{}', | ||||
'cnt': '/content/sha1_git:{}/', | |||||
} | } | ||||
def call_async_gen(generator, *args, **kwargs): | def call_async_gen(generator, *args, **kwargs): | ||||
loop = asyncio.get_event_loop() | loop = asyncio.get_event_loop() | ||||
it = generator(*args, **kwargs).__aiter__() | it = generator(*args, **kwargs).__aiter__() | ||||
while True: | while True: | ||||
try: | try: | ||||
▲ Show 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | class GraphNode: | ||||
def walk(self, dst, direction='forward', edges='*', traversal='dfs'): | def walk(self, dst, direction='forward', edges='*', traversal='dfs'): | ||||
for node in call_async_gen( | for node in call_async_gen( | ||||
self.graph.backend.walk, | self.graph.backend.walk, | ||||
direction, edges, traversal, self.id, dst | direction, edges, traversal, self.id, dst | ||||
): | ): | ||||
yield self.graph[node] | yield self.graph[node] | ||||
def _count(self, ttype, direction='forward', edges='*'): | |||||
return self.graph.backend.count(ttype, direction, edges, self.id) | |||||
count_leaves = functools.partialmethod(_count, ttype='leaves') | |||||
count_neighbors = functools.partialmethod(_count, ttype='neighbors') | |||||
count_visit_nodes = functools.partialmethod(_count, ttype='visit_nodes') | |||||
@property | @property | ||||
def pid(self): | def pid(self): | ||||
return self.graph.node2pid[self.id] | return self.graph.node2pid[self.id] | ||||
@property | @property | ||||
def kind(self): | def kind(self): | ||||
return self.pid.split(':')[2] | return self.pid.split(':')[2] | ||||
def __str__(self): | def __str__(self): | ||||
return self.pid | return self.pid | ||||
def __repr__(self): | def __repr__(self): | ||||
return '<{}>'.format(self.pid) | return '<{}>'.format(self.pid) | ||||
def dot_fragment(self): | def dot_fragment(self): | ||||
swh, version, kind, hash = self.pid.split(':') | swh, version, kind, hash = self.pid.split(':') | ||||
label = '{}:{}..{}'.format(kind, hash[0:2], hash[-2:]) | label = '{}:{}..{}'.format(kind, hash[0:2], hash[-2:]) | ||||
url = KIND_TO_URL[kind].format(hash) | url = BASE_URL + KIND_TO_URL_FRAGMENT[kind].format(hash) | ||||
shape = KIND_TO_SHAPE[kind] | shape = KIND_TO_SHAPE[kind] | ||||
return ('{} [label="{}", href="{}", target="_blank", shape="{}"];' | return ('{} [label="{}", href="{}", target="_blank", shape="{}"];' | ||||
.format(self.id, label, url, shape)) | .format(self.id, label, url, shape)) | ||||
def _repr_svg_(self): | def _repr_svg_(self): | ||||
nodes = [self, *list(self.children()), *list(self.parents())] | nodes = [self, *list(self.children()), *list(self.parents())] | ||||
dot = graph_dot(nodes) | dot = graph_dot(nodes) | ||||
svg = dot_to_svg(dot) | svg = dot_to_svg(dot) | ||||
Show All 33 Lines |