diff --git a/swh/graphql/resolvers/directory.py b/swh/graphql/resolvers/directory.py index 94599c2..9e6757e 100644 --- a/swh/graphql/resolvers/directory.py +++ b/swh/graphql/resolvers/directory.py @@ -1,47 +1,48 @@ from .base_node import BaseNode class BaseDirectoryNode(BaseNode): def _get_directory_by_id(self, directory_id): # Now not fetching any data (schema is exposing just id) # same pattern is used in snapshot resolver # FIXME, use the right API to fetch metadata like name, path return { "id": directory_id, } def is_type_of(self): return "Directory" class DirectoryNode(BaseDirectoryNode): def _get_node_data(self): """ When a directory is requested directly with an id """ - directory_id = self.kwargs.get("Sha1") + # FXIME, query to make sure directory exists + directory_id = self.kwargs.get("SWHID") # path = "" return self._get_directory_by_id(directory_id) class RevisionDirectoryNode(BaseDirectoryNode): def _get_node_data(self): """ When a directory is requested from a revision self.obj is revision here self.obj.directoryId is the required dir id (set from resolvers.revision.py:BaseRevisionNode) """ directory_id = self.obj.directoryId return self._get_directory_by_id(directory_id) class TargetDirectoryNode(BaseDirectoryNode): def _get_node_data(self): """ When a directory is requested as a target self.obj can be a Release or a DirectoryEntry obj.target is the requested directory id here """ return self._get_directory_by_id(self.obj.target) diff --git a/swh/graphql/resolvers/release.py b/swh/graphql/resolvers/release.py index d4029d4..887acd4 100644 --- a/swh/graphql/resolvers/release.py +++ b/swh/graphql/resolvers/release.py @@ -1,45 +1,45 @@ from swh.graphql.backends import archive from .base_node import BaseNode class BaseReleaseNode(BaseNode): def _get_release_by_id(self, release_id): return (archive.Archive().get_releases([release_id]) or None)[0] @property def targetId(self): # To support the schema naming convention return self._node.target @property def targetType(self): # To support the schema naming convention return self._node.target_type.value def is_type_of(self): """ is_type_of is required only when resolving a UNION type This is for ariadne to return the right type """ return "Release" class ReleaseNode(BaseReleaseNode): """ When the release is requested directly with an id """ def _get_node_data(self): - return self._get_release_by_id(self.kwargs.get("Sha1")) + return self._get_release_by_id(self.kwargs.get("SWHID")) class TargetReleaseNode(BaseReleaseNode): """ When a release is requested as a target self.obj could be a snapshotbranch or a release self.obj.target is the requested release id here """ def _get_node_data(self): return self._get_release_by_id(self.obj.target) diff --git a/swh/graphql/resolvers/revision.py b/swh/graphql/resolvers/revision.py index d3ad410..affbac6 100644 --- a/swh/graphql/resolvers/revision.py +++ b/swh/graphql/resolvers/revision.py @@ -1,92 +1,92 @@ from swh.graphql.backends import archive from swh.graphql.utils import utils from .base_connection import BaseConnection from .base_node import BaseNode class BaseRevisionNode(BaseNode): def _get_revision_by_id(self, revision_id): return (archive.Archive().get_revisions([revision_id]) or None)[0] @property def parentIds(self): # To support the schema naming convention return self._node.parents @property def directoryId(self): # To support the schema naming convention """ """ return self._node.directory @property def type(self): return self._node.type.value def is_type_of(self): """ is_type_of is required only when resolving a UNION type This is for ariadne to return the right type """ return "Revision" class RevisionNode(BaseRevisionNode): """ When the revision is requested directly with its id (hash) """ def _get_node_data(self): - return self._get_revision_by_id(self.kwargs.get("Sha1")) + return self._get_revision_by_id(self.kwargs.get("SWHID")) class TargetRevisionNode(BaseRevisionNode): """ When a revision is requested as a target self.obj could be a snapshotbranch or a release self.obj.target is the requested revision id here """ def _get_node_data(self): """ self.obj.target is the Revision id """ return self._get_revision_by_id(self.obj.target) class ParentRevisionConnection(BaseConnection): """ When parent revisions requested from a revision self.obj is the current(child) revision self.obj.parentIds is the list of requested revisions """ _node_class = BaseRevisionNode def _get_paged_result(self): # FIXME, using dummy(local) pagination, move pagination to backend # To remove localpagination, just drop the paginated call # STORAGE-TODO (pagination) parents = archive.Archive().get_revisions(self.obj.parentIds) return utils.paginated(parents, self._get_first_arg(), self._get_after_arg()) class LogRevisionConnection(BaseConnection): """ When revisionslog is requested from a revision self.obj is the current revision id """ _node_class = BaseRevisionNode def _get_paged_result(self): # STORAGE-TODO (date in revisionlog is a dict) log = archive.Archive().get_revision_log([self.obj.id]) # FIXME, using dummy(local) pagination, move pagination to backend # To remove localpagination, just drop the paginated call # STORAGE-TODO (pagination) return utils.paginated(log, self._get_first_arg(), self._get_after_arg()) diff --git a/swh/graphql/resolvers/snapshot.py b/swh/graphql/resolvers/snapshot.py index 9e3023a..07dd72e 100644 --- a/swh/graphql/resolvers/snapshot.py +++ b/swh/graphql/resolvers/snapshot.py @@ -1,50 +1,51 @@ from swh.graphql.backends import archive from swh.graphql.utils import utils from .base_connection import BaseConnection from .base_node import BaseNode class BaseSnapshotNode(BaseNode): def _get_snapshot_by_id(self, snapshot_id): # Now not fetching any data (schema is exposing just id) # same pattern is used in directory resolver return { "id": snapshot_id, } class SnapshotNode(BaseSnapshotNode): """ For directly accessing a snapshot with an Id """ def _get_node_data(self): """ """ - return self._get_snapshot_by_id(self.kwargs.get("Sha1")) + # FXIME, query to make sure snapshot exists + return self._get_snapshot_by_id(self.kwargs.get("SWHID")) class VisitSnapshotNode(BaseSnapshotNode): """ For accessing a snapshot from a visitstatus type """ def _get_node_data(self): """ self.obj is visitstatus here self.obj.snapshot is the requested snapshot id """ return self._get_snapshot_by_id(self.obj.snapshot) class OriginSnapshotConnection(BaseConnection): _node_class = BaseSnapshotNode def _get_paged_result(self): """ """ results = archive.Archive().get_origin_snapshots(self.obj.url) snapshots = [{"id": snapshot} for snapshot in results] # FIXME, using dummy(local) pagination, move pagination to backend # To remove localpagination, just drop the paginated call # STORAGE-TODO return utils.paginated(snapshots, self._get_first_arg(), self._get_after_arg()) diff --git a/swh/graphql/schema/schema.graphql b/swh/graphql/schema/schema.graphql index aa3b0c6..115581d 100644 --- a/swh/graphql/schema/schema.graphql +++ b/swh/graphql/schema/schema.graphql @@ -1,347 +1,341 @@ scalar SWHID scalar Sha1 scalar DateTime scalar DateTimeZone scalar BinaryText interface Node { id: ID! } interface SWHNode { id: Sha1! } type PageInfo { endCursor: String hasNextPage: Boolean! } type OriginConnection { edges: [OriginEdge] nodes: [Origin] pageInfo: PageInfo! totalCount: Int } type OriginEdge { cursor: String! node: Origin } type Origin implements SWHNode { id: Sha1! url: String! visits( first: Int! after: String ): VisitConnection! latestVisit: Visit snapshots( first: Int! after: String ): SnapshotConnection } type VisitConnection { edges: [VisitEdge] nodes: [Visit] pageInfo: PageInfo! totalCount: Int } type VisitEdge { cursor: String! node: Visit } type Visit implements Node { id: ID! visitId: Int date: DateTime! type: String status( first: Int after: String ): VisitStatusConnection latestStatus: VisitStatus } type VisitStatusConnection { edges: [VisitStatusEdge] nodes: [VisitStatus] pageInfo: PageInfo! totalCount: Int } type VisitStatusEdge { cursor: String! node: VisitStatus } type VisitStatus { status: String! date: DateTime! snapshotId: Sha1 snapshot: Snapshot type: String } type SnapshotConnection { edges: [SnapshotEdge] nodes: [Snapshot] pageInfo: PageInfo! totalCount: Int } type SnapshotEdge { cursor: String! node: Snapshot } type Snapshot implements SWHNode { id: Sha1! branches( first: Int! after: String types: [BranchTypes] nameInclude: String ): BranchConnection } type BranchConnection { edges: [BranchConnectionEdge] nodes: [Branch] pageInfo: PageInfo! totalCount: Int } type BranchConnectionEdge { cursor: String! node: Branch } type Person { email: BinaryText name: BinaryText fullname: BinaryText } # FIXME, this can be Content, Directory, Snapshot, or Alias as well union BranchTarget = Revision | Release enum BranchTypes { revision release alias content directory snapshot } type Branch { name: BinaryText type: BranchTypes targetId: Sha1 target: BranchTarget } type RevisionConnection { edges: [RevisionEdge] nodes: [Revision] pageInfo: PageInfo! totalCount: Int } type RevisionEdge { cursor: String! node: Revision } type Revision implements SWHNode { id: Sha1! message: BinaryText author: Person committer: Person date: DateTimeZone type: String # Revision type: FIXME, change to an enum directoryId: Sha1 directory: Directory parentIds: [Sha1] parents( first: Int after: String ): RevisionConnection revisionLog( first: Int! after: String ): RevisionConnection } union ReleaseTarget = Release | Revision | Directory | Content enum ReleaseTargetType { release revision content directory } type Release implements SWHNode { id: Sha1! name: BinaryText message: BinaryText author: Person date: DateTimeZone targetId: Sha1 targetType: ReleaseTargetType target: ReleaseTarget } type DirectoryEntryConnection { edges: [DirectoryEntryEdge] nodes: [DirectoryEntry] pageInfo: PageInfo! totalCount: Int } type DirectoryEntryEdge { cursor: String! node: DirectoryEntry } union DirectoryEntryTarget = Directory | Content enum DirectoryEntryType { dir file rev } type DirectoryEntry { name: BinaryText type: DirectoryEntryType targetId: Sha1 target: DirectoryEntryTarget } type Directory implements SWHNode { id: Sha1! entries( first: Int after: String ): DirectoryEntryConnection } type ContentChecksum { # FIXME, temp types blake2s256: Sha1 sha1: Sha1 sha1_git: Sha1 sha256: Sha1 } # type ContentType { # test: String # } # type ContentLanguage { # test: String # } # type ContentLicense { # test: String # } type Content implements SWHNode { id: Sha1! swhId: String checksum: ContentChecksum # data: # filetype: ContentType # language: ContentLanguage # license: ContentLicense length: Int status: String data: BinaryText } -input ReviewInput { - stars: Int! - commentary: String -} - type Query { """ Get an origin with its url """ origin( url: String! - sha1: Sha1 ): Origin """ Get a list of origins matching the given filters Can also be used to search for an origin """ # FIMXE, use Input types to make this cleaner origins( first: Int! after: String urlPattern: String ): OriginConnection """ Get a visit object with its id and/or origin and visit id """ visit( originUrl: String! visitId: Int! ): Visit """ Get a snapshot with Sha1 """ snapshot( - Sha1: Sha1! + SWHID: SWHID! ): Snapshot """ Get the revision with the given Sha1 """ revision( - Sha1: Sha1! + SWHID: SWHID! ): Revision """ Get the release with the given Sha1 """ release( - Sha1: Sha1! + SWHID: SWHID! ): Release """ Get the directory with the given Sha1 """ directory( - Sha1: Sha1! + SWHID: SWHID! ): Directory """ Get the content with the given Sha1 """ content( SWHID: SWHID! ): Content # """ # Search with the given swhid # """ # searchWithSwhid }