diff --git a/swh/graphql/resolvers/content.py b/swh/graphql/resolvers/content.py index 0f34901..aa3f28e 100644 --- a/swh/graphql/resolvers/content.py +++ b/swh/graphql/resolvers/content.py @@ -1,52 +1,52 @@ from swh.graphql.backends import archive from .base_node import BaseNode class BaseContentNode(BaseNode): """ """ def _get_content_by_id(self, content_id): content = archive.Archive().get_content(content_id) return content[0] if content else None @property def id(self): return self._node.unique_key() @property def swhId(self): # To support the schema naming convention return self._node.swhid() @property def checksum(self): # FIXME, return a Node object return self._node.hashes() @property def data(self): return def is_type_of(self): return "Content" class ContentNode(BaseContentNode): def _get_node_data(self): """ When a content is requested directly with an id """ - return self._get_content_by_id(self.kwargs.get("Sha1")) + return self._get_content_by_id(self.kwargs.get("SWHID")) class TargetContentNode(BaseContentNode): def _get_node_data(self): """ When a content is requested from a directory entry or from a release target content id is obj.target here """ content_id = self.obj.target return self._get_content_by_id(content_id) diff --git a/swh/graphql/resolvers/scalars.py b/swh/graphql/resolvers/scalars.py index 89ba314..23ef947 100644 --- a/swh/graphql/resolvers/scalars.py +++ b/swh/graphql/resolvers/scalars.py @@ -1,44 +1,49 @@ from ariadne import ScalarType from swh.graphql.utils import utils from swh.model.fields.hashes import validate_sha1_git from swh.model.model import TimestampWithTimezone - -# from swh.model.swhids import QualifiedSWHID +from swh.model.swhids import QualifiedSWHID datetime_scalar = ScalarType("DateTime") swhid_scalar = ScalarType("SWHID") sha1_scalar = ScalarType("Sha1") binary_text_scalar = ScalarType("BinaryText") datetimezone_scalar = ScalarType("DateTimeZone") @datetime_scalar.serializer def serialize_datetime(value): return utils.get_formatted_date(value) @sha1_scalar.serializer def serialize_sha1(value): return value.hex() @sha1_scalar.value_parser def validate_and_get_sha1_git(value): # FIXME, handle the error and raise a Graphql one validate_sha1_git(value) return bytearray.fromhex(value) @binary_text_scalar.serializer def serialize_binary_text(value): return value.decode("utf-8") @datetimezone_scalar.serializer def serialize_datetimezone(value): # FIXME, handle error and return None if type(value) == TimestampWithTimezone: date = value.to_datetime() return utils.get_formatted_date(date) return None + + +@swhid_scalar.value_parser +def validate_swhid(value): + swhid = QualifiedSWHID.from_string(value) + return swhid.object_id diff --git a/swh/graphql/schema/schema.graphql b/swh/graphql/schema/schema.graphql index 08758cb..aa3b0c6 100644 --- a/swh/graphql/schema/schema.graphql +++ b/swh/graphql/schema/schema.graphql @@ -1,341 +1,347 @@ 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! ): Snapshot """ Get the revision with the given Sha1 """ revision( Sha1: Sha1! ): Revision """ Get the release with the given Sha1 """ release( Sha1: Sha1! ): Release """ Get the directory with the given Sha1 """ directory( Sha1: Sha1! ): Directory """ Get the content with the given Sha1 """ content( - Sha1: Sha1! + SWHID: SWHID! ): Content # """ # Search with the given swhid # """ # searchWithSwhid }