mirror of
https://github.com/status-im/PyGithub.git
synced 2026-09-01 19:31:10 +00:00
304 lines
13 KiB
Python
304 lines
13 KiB
Python
#!/bin/env python
|
|
|
|
import os.path
|
|
import json
|
|
import itertools
|
|
|
|
def checkKeys( d, mandatory_keys, optional_keys = [] ):
|
|
assert set( d.keys() ) >= set( mandatory_keys ), d.keys()
|
|
assert set( d.keys() ) <= set( mandatory_keys ) | set( optional_keys ) | set( [ "@todo" ] ), d.keys()
|
|
|
|
class Type:
|
|
def __init__( self, arg ):
|
|
if isinstance( arg, ( str, unicode ) ):
|
|
self.__fromString( arg )
|
|
else:
|
|
self.__fromDesc( arg )
|
|
|
|
def ToJson( self ):
|
|
return {
|
|
"cardinality": self.cardinality,
|
|
"name": self.name,
|
|
"simple": self.name in [ "void", "string", "integer", "bool", "float", "@todo" ],
|
|
}
|
|
|
|
def __fromString( self, name ):
|
|
self.cardinality = "scalar"
|
|
self.name = name
|
|
|
|
def __fromDesc( self, desc ):
|
|
checkKeys( desc, [ "cardinality", "name" ] )
|
|
|
|
self.cardinality = desc[ "cardinality" ]
|
|
self.name = desc[ "name" ]
|
|
|
|
class Variable:
|
|
def __init__( self, desc ):
|
|
checkKeys( desc, [ "name", "type" ] )
|
|
|
|
self.name = desc[ "name" ]
|
|
self.type = Type( desc[ "type" ] )
|
|
|
|
def ToJson( self ):
|
|
return {
|
|
"name": self.name,
|
|
"type": self.type,
|
|
}
|
|
|
|
class Function:
|
|
# method
|
|
# input
|
|
# self
|
|
# arguments
|
|
# output
|
|
# type
|
|
# bool
|
|
# object
|
|
# fundamental type
|
|
# list of
|
|
# object
|
|
# fundamental type
|
|
# body
|
|
# status or data request
|
|
# url from input
|
|
# GET parameters from input
|
|
# POST parameters from input
|
|
|
|
def __init__( self, desc, *additional_descs ):
|
|
for additional_desc in additional_descs:
|
|
desc.update( additional_desc )
|
|
checkKeys( desc, [ "name", "type", "group" ], [ "is_mutation", "mandatory_parameters", "optional_parameters", "variadic_parameter", "parameter", "request" ] ) # @todo Move request to mandatory_keys
|
|
|
|
self.name = desc[ "name" ]
|
|
self.type = Type( desc[ "type" ] )
|
|
self.group = desc[ "group" ]
|
|
self.is_mutation = "is_mutation" in desc and desc[ "is_mutation" ]
|
|
self.mandatory_parameters = list()
|
|
if "mandatory_parameters" in desc:
|
|
for parameter in desc[ "mandatory_parameters" ]:
|
|
self.mandatory_parameters.append( Variable( parameter ) )
|
|
self.optional_parameters = list()
|
|
if "optional_parameters" in desc:
|
|
for parameter in desc[ "optional_parameters" ]:
|
|
self.optional_parameters.append( Variable( parameter ) )
|
|
if "variadic_parameter" in desc:
|
|
self.variadic_parameter = Variable( desc[ "variadic_parameter" ] )
|
|
else:
|
|
self.variadic_parameter = None
|
|
if "request" in desc:
|
|
self.request = desc[ "request" ]
|
|
else:
|
|
self.request = None
|
|
|
|
def ToJson( self ):
|
|
json = {
|
|
"name": self.name,
|
|
"type": self.type,
|
|
"group": self.group,
|
|
"is_mutation": self.is_mutation,
|
|
"mandatory_parameters": self.mandatory_parameters,
|
|
"optional_parameters": self.optional_parameters,
|
|
}
|
|
if self.variadic_parameter is not None:
|
|
json[ "variadic_parameter" ] = self.variadic_parameter
|
|
if self.request is not None:
|
|
json[ "request" ] = self.request
|
|
return json
|
|
|
|
class Collection:
|
|
def __init__( self, desc ):
|
|
checkKeys( desc, [ "name", "singular_name", "type" ], [ "add_element", "add_several_elements", "create_element", "delete_list", "get_element", "get_list", "has_element", "remove_element", "remove_several_elements", "set_list" ] )
|
|
|
|
name = desc[ "name" ] if isinstance( desc[ "name" ], list ) else [ desc[ "name" ] ]
|
|
self.methods = list()
|
|
if "add_element" in desc:
|
|
assert desc[ "add_element" ] is True
|
|
self.methods.append( Function(
|
|
{ "name": [ "add", "to" ] + name, "type": "void", "group": desc[ "name" ], "mandatory_parameters": [ { "name": desc[ "singular_name" ], "type": desc[ "type" ] } ] },
|
|
{
|
|
"request": {
|
|
"verb": "PUT",
|
|
"url": [
|
|
{ "type": "attribute", "value": [ "url" ] },
|
|
{ "type": "constant", "value": "/" + desc[ "name" ] + "/" },
|
|
{ "type": "argument", "value": [ desc[ "singular_name" ], "login" ] }, # @todo 'login' should be 'the attribute identifying the object'
|
|
],
|
|
"information": "status",
|
|
}
|
|
}
|
|
) )
|
|
if "add_several_elements" in desc:
|
|
assert desc[ "add_several_elements" ] is True
|
|
self.methods.append( Function( { "name": [ "add", "to" ] + name, "type": "void", "group": desc[ "name" ], "variadic_parameter": { "name": desc[ "singular_name" ], "type": desc[ "type" ] } } ) )
|
|
if "create_element" in desc:
|
|
self.methods.append( Function(
|
|
desc[ "create_element" ],
|
|
{ "name": [ "create", desc[ "singular_name" ] ], "type": desc[ "type" ], "group": desc[ "name" ] },
|
|
{
|
|
"request": {
|
|
"verb": "POST",
|
|
"url": [ { "type": "attribute", "value": [ "url" ] }, { "type": "constant", "value": "/" + desc[ "name" ] } ],
|
|
"information": "status",
|
|
"post_parameters": True,
|
|
}
|
|
}
|
|
) )
|
|
if "delete_list" in desc:
|
|
assert desc[ "delete_list" ] is True
|
|
self.methods.append( Function( { "name": [ "delete" ] + name, "type": "void", "group": desc[ "name" ] } ) )
|
|
if "get_element" in desc:
|
|
|
|
# @todo Generalize
|
|
if desc[ "name" ] == "repos":
|
|
hack = {
|
|
"request": {
|
|
"verb": "GET",
|
|
"url": [
|
|
{ "type": "constant", "value": "https://api.github.com/repos/" },
|
|
{ "type": "attribute", "value": [ "login" ] },
|
|
{ "type": "constant", "value": "/" },
|
|
{ "type": "argument", "value": [ "name" ] },
|
|
],
|
|
"information": "data",
|
|
}
|
|
}
|
|
else:
|
|
hack = dict()
|
|
|
|
self.methods.append( Function(
|
|
desc[ "get_element" ],
|
|
{ "name": [ "get", desc[ "singular_name" ] ], "type": desc[ "type" ], "group": desc[ "name" ], "mandatory_parameters": [ desc[ "get_element" ][ "parameter" ] ] },
|
|
hack
|
|
) )
|
|
if "get_list" in desc:
|
|
self.methods.append( Function(
|
|
desc[ "get_list" ] if desc[ "get_list" ] is not True else dict(),
|
|
{ "name": [ "get" ] + name, "type": { "cardinality": "list", "name": desc[ "type" ] }, "group": desc[ "name" ] },
|
|
{
|
|
"request": {
|
|
"verb": "GET",
|
|
"url": [ { "type": "attribute", "value": [ "url" ] }, { "type": "constant", "value": "/" + desc[ "name" ] } ],
|
|
"information": "data",
|
|
}
|
|
}
|
|
) )
|
|
if "has_element" in desc:
|
|
assert desc[ "has_element" ] is True
|
|
self.methods.append( Function(
|
|
{ "name": [ "has", "in" ] + name, "type": "bool", "group": desc[ "name" ], "mandatory_parameters": [ { "name": desc[ "singular_name" ], "type": desc[ "type" ] } ] },
|
|
{
|
|
"request": {
|
|
"verb": "GET",
|
|
"url": [
|
|
{ "type": "attribute", "value": [ "url" ] },
|
|
{ "type": "constant", "value": "/" + desc[ "name" ] + "/" },
|
|
{ "type": "argument", "value": [ desc[ "singular_name" ], "login" ] }, # @todo 'login' should be 'the attribute identifying the object'
|
|
],
|
|
"information": "status",
|
|
}
|
|
}
|
|
) )
|
|
if "remove_element" in desc:
|
|
assert desc[ "remove_element" ] is True
|
|
self.methods.append( Function(
|
|
{ "name": [ "remove", "from" ] + name, "type": "void", "group": desc[ "name" ], "mandatory_parameters": [ { "name": desc[ "singular_name" ], "type": desc[ "type" ] } ] },
|
|
{
|
|
"request": {
|
|
"verb": "DELETE",
|
|
"url": [
|
|
{ "type": "attribute", "value": [ "url" ] },
|
|
{ "type": "constant", "value": "/" + desc[ "name" ] + "/" },
|
|
{ "type": "argument", "value": [ desc[ "singular_name" ], "login" ] }, # @todo 'login' should be 'the attribute identifying the object'
|
|
],
|
|
"information": "status",
|
|
}
|
|
}
|
|
) )
|
|
if "remove_several_elements" in desc:
|
|
assert desc[ "remove_several_elements" ] is True
|
|
self.methods.append( Function( { "name": [ "remove", "from" ] + name, "type": "void", "group": desc[ "name" ], "variadic_parameter": { "name": desc[ "singular_name" ], "type": desc[ "type" ] } } ) )
|
|
if "set_list" in desc:
|
|
assert desc[ "set_list" ] is True
|
|
self.methods.append( Function( { "name": [ "set" ] + name, "type": "void", "group": desc[ "name" ], "variadic_parameter": { "name": desc[ "singular_name" ], "type": desc[ "type" ] } } ) )
|
|
|
|
class Class:
|
|
def __init__( self, desc ):
|
|
checkKeys( desc, [ "name", "attributes", "collections" ], [ "edit", "delete", "additional_methods" ] )
|
|
|
|
self.name = desc[ "name" ]
|
|
self.attributes = sorted(
|
|
[
|
|
Variable( attr )
|
|
for attr in desc[ "attributes" ]
|
|
],
|
|
key = lambda class_: class_.name
|
|
)
|
|
self.methods = []
|
|
if "edit" in desc:
|
|
self.methods.append( Function(
|
|
desc[ "edit" ],
|
|
{ "name": [ "edit" ], "type": "void", "group": "modification", "is_mutation": True },
|
|
{
|
|
"request": {
|
|
"verb": "PATCH",
|
|
"url": [ { "type": "constant", "value": "https://api.github.com/user" } if desc[ "name" ] == "AuthenticatedUser" else { "type": "attribute", "value": [ "url" ] } ], # @todo
|
|
"post_parameters": True, # @todo
|
|
"information": "data",
|
|
},
|
|
}
|
|
) )
|
|
if "delete" in desc:
|
|
self.methods.append( Function(
|
|
{ "name": [ "delete" ], "type": "void", "group": "deletion" },
|
|
{
|
|
"request": {
|
|
"verb": "DELETE",
|
|
"url": [ { "type": "attribute", "value": [ "url" ] } ],
|
|
"information": "data",
|
|
},
|
|
}
|
|
) )
|
|
for collection in [ Collection( collection ) for collection in desc[ "collections" ] ]:
|
|
self.methods += collection.methods
|
|
if "additional_methods" in desc:
|
|
self.methods += [ Function( method ) for method in desc[ "additional_methods" ] ]
|
|
|
|
def ToJson( self ):
|
|
return {
|
|
"name": self.name,
|
|
"attributes": self.attributes,
|
|
"methods": self.methods,
|
|
}
|
|
|
|
class Description:
|
|
def __init__( self, desc ):
|
|
checkKeys( desc, [ "classes" ] )
|
|
|
|
self.classes = sorted(
|
|
[
|
|
Class( class_ )
|
|
for class_ in desc[ "classes" ]
|
|
],
|
|
key = lambda class_: class_.name
|
|
)
|
|
|
|
def ToJson( self ):
|
|
return {
|
|
"classes": self.classes,
|
|
}
|
|
|
|
def save( self, fileName ):
|
|
class Encoder( json.JSONEncoder ):
|
|
def default( self, obj ):
|
|
if hasattr( obj, "ToJson" ):
|
|
return obj.ToJson()
|
|
return json.JSONEncoder.default( self, obj )
|
|
|
|
with open( os.path.join( os.path.dirname( __file__ ), fileName ), "w" ) as f:
|
|
json.dump( self, f, indent = 4, cls = Encoder )
|
|
|
|
with open( os.path.join( os.path.dirname( __file__ ), "description.000.human_readable.json" ) ) as f:
|
|
description = Description( json.load( f ) )
|
|
|
|
description.save( "description.001.normalized.json" )
|