diff --git a/IntegrationTest.py b/IntegrationTest.py index e2800f04..953890f1 100644 --- a/IntegrationTest.py +++ b/IntegrationTest.py @@ -115,8 +115,8 @@ class IntegrationTest: exit( 1 ) def playScenario( self ): - self.doSomeReads() self.doSomeWrites() + self.doSomeReads() def doSomeReads( self ): self.dumpUser( self.g.get_user(), doPrivateThings = True ) @@ -129,6 +129,7 @@ class IntegrationTest: def doSomeWrites( self ): self.doSomeWritesToUser() self.doSomeWritesToRepository() + self.doSomeWritesToGist() def doSomeWritesToUser( self ): u = self.g.get_user() @@ -199,8 +200,21 @@ class IntegrationTest: self.dumpRepository( r ) + def doSomeWritesToGist( self ): + u = self.g.get_user() + g = u.create_gist( True, { "foobar.txt": { "content": "Gist created by PyGithub" } }, "Gist created by PyGithub" ) + g.edit( "Gist edited by PyGithub" ) + g.create_comment( "Gist comment created by PyGithub" ) + g.set_starred() + assert g.is_starred() + g.reset_starred() + assert not g.is_starred() + def dumpUser( self, u, doPrivateThings ): print u.login, "(", u.name, ")" + print " Gists:", ", ".join( g.description + "(" + ", ".join( c.body for c in g.get_comments() ) + ")" for g in u.get_gists() ) + if doPrivateThings: + print " Starred gists:", ", ".join( g.description for g in u.get_starred_gists() ) print " Repos:" for r in u.get_repos(): print " ", r.name, diff --git a/ReferenceOfApis.md b/ReferenceOfApis.md index 4e32e71a..5c071266 100644 --- a/ReferenceOfApis.md +++ b/ReferenceOfApis.md @@ -15,43 +15,43 @@ API `/events` API `/gists` ============ -* GET: (TODO SOON) -* POST: (TODO SOON) - -API `/gists/:gist_id/comments` -============================== -* GET: (TODO SOON) -* POST: (TODO SOON) +* GET: `AuthenticatedUser.get_gists` +* POST: `AuthenticatedUser.create_gist` API `/gists/:id` ================ -* GET: (TODO SOON) -* PATCH: (TODO SOON) -* DELETE: (TODO SOON) +* GET: `Github.get_gist` +* PATCH: `Gist.edit` +* DELETE: `Gist.delete` + +API `/gists/:id/comments` +============================== +* GET: `Gist.get_comments` +* POST: `Gist.create_comment` API `/gists/:id/fork` ===================== -* POST: (TODO SOON) +* POST: `Gist.create_fork` API `/gists/:id/star` ===================== -* GET: (TODO SOON) -* PUT: (TODO SOON) -* DELETE: (TODO SOON) +* GET: `Gist.is_starred` +* PUT: `Gist.set_starred` +* DELETE: `Gist.reset_starred` API `/gists/comments/:id` ========================= -* GET: (TODO SOON) -* PATCH: (TODO SOON) -* DELETE: (TODO SOON) +* GET: `Gist.get_comment` +* PATCH: `GistComment.edit` +* DELETE: `GistComment.delete` API `/gists/public` =================== -* GET: (TODO SOON) +* GET: (TODO) (Almost useless: huge fast-changing list, so I will have to re-re-implement pagination, with detection of duplicates caused by shifts, and a real iteration, not construction of the full list...) API `/gists/starred` ==================== -* GET: (TODO SOON) +* GET: `AuthenticatedUser.get_starred_gists` API `/issues` ============= @@ -471,7 +471,7 @@ API `/users/:user/following` API `/users/:user/gists` ======================== -* GET: (TODO SOON) +* GET: `NamedUser.get_gists` API `/users/:user/orgs` ======================= diff --git a/ReferenceOfClasses.md b/ReferenceOfClasses.md index d38498be..1b9079b9 100644 --- a/ReferenceOfClasses.md +++ b/ReferenceOfClasses.md @@ -96,6 +96,12 @@ Forking ------- * `create_fork( repo )`: `Repository` +Gists +----- +* `get_gists()`: list of `Gist` +* `create_gist( public, files, [description] )`: `Gist` +* `get_starred_gists()`: list of `Gist` + Class `Branch` ============== @@ -178,6 +184,70 @@ Deletion -------- * `delete()` +Class `Gist` +============ + +Attributes +---------- +* `url` +* `id` +* `description` +* `public` +* `files` +* `comments` +* `html_url` +* `git_pull_url` +* `git_push_url` +* `created_at` +* `forks` +* `history` +* `updated_at` +* `user`: `NamedUser` + +Modification +------------ +* `edit( [description, files] )` + +Deletion +-------- +* `delete()` + +Comments +-------- +* `get_comments()`: list of `GistComment` +* `get_comment( id )`: `GistComment` +* `create_comment( body )`: `GistComment` + +Starring +-------- +* `is_starred()`: bool +* `set_starred()` +* `reset_starred()` + +Forking +------- +* `create_fork()`: `Gist` + +Class `GistComment` +=================== + +Attributes +---------- +* `id` +* `url` +* `body` +* `created_at` +* `updated_at` +* `user`: `NamedUser` + +Modification +------------ +* `edit( body )` + +Deletion +-------- +* `delete()` + Class `GitBlob` =============== @@ -398,6 +468,10 @@ Watched ------- * `get_watched()`: list of `Repository` +Gists +----- +* `get_gists()`: list of `Gist` + Class `Organization` ==================== diff --git a/github/Github.py b/github/Github.py index 9446f6ba..03781a5d 100644 --- a/github/Github.py +++ b/github/Github.py @@ -19,3 +19,6 @@ class Github: def get_organization( self, login ): return Organization( self, { "login": login }, lazy = False ) + + def get_gist( self, id ): + return Gist( self, { "id": id }, lazy = False ) diff --git a/github/GithubObjects.py b/github/GithubObjects.py index e95e0836..f8d1e603 100644 --- a/github/GithubObjects.py +++ b/github/GithubObjects.py @@ -521,3 +521,72 @@ Repository._addAttributePolicy( ListGetable( [], [] ) ) ) + +GistComment = GithubObject( + "GistComment", + BaseUrl( lambda obj: "/gists/comments/" + str( obj.id ) ), + InternalSimpleAttributes( + "id", "url", "body", "created_at", + "updated_at", + ), + InternalObjectAttribute( "user", NamedUser ), + Editable( [ "body" ], [] ), + Deletable(), +) + +def __isStarred( gist ): + return gist._github._statusRequest( "GET", gist._baseUrl + "/star", None, None ) == 204 +def __setStarred( gist ): + gist._github._statusRequest( "PUT", gist._baseUrl + "/star", None, None ) +def __resetStarred( gist ): + gist._github._statusRequest( "DELETE", gist._baseUrl + "/star", None, None ) +Gist = GithubObject( + "Gist", + BaseUrl( lambda obj: "/gists/" + str( obj.id ) ), + InternalSimpleAttributes( + "url", "id", "description", "public", "files", "comments", "html_url", + "git_pull_url", "git_push_url", "created_at", "forks", "history", + "updated_at", + ), + InternalObjectAttribute( "user", NamedUser ), + Editable( [], [ "description", "files" ] ), + Deletable(), + ExternalListOfObjects( "comments", "comment", GistComment, + ListGetable( [], [] ), + ElementGetable( [ "id" ], [] ), + ElementCreatable( [ "body" ], [] ), + ), + SeveralAttributePolicies( [ + MethodFromCallable( "is_starred", [], [], __isStarred, SimpleTypePolicy( "bool" ) ), + MethodFromCallable( "set_starred", [], [], __setStarred, SimpleTypePolicy( None ) ), + MethodFromCallable( "reset_starred", [], [], __resetStarred, SimpleTypePolicy( None ) ), + ], "Starring" ), +) +def __createFork( gist ): + return Gist( gitst._github, gist._github._dataRequest( "POST", gist._baseUrl + "/fork", None, None ), lazy = True ) +Gist._addAttributePolicy( SeveralAttributePolicies( [ + MethodFromCallable( "create_fork", [], [], __createFork, ObjectTypePolicy( Gist ) ), + ], "Forking" ), +) + +NamedUser._addAttributePolicy( + ExternalListOfObjects( "gists", "gist", Gist, + ListGetable( [], [] ), + ) +) + +AuthenticatedUser._addAttributePolicy( + ExternalListOfObjects( "gists", "gist", Gist, + ListGetable( [], [] ), + ElementCreatable( [ "public", "files", ], [ "description" ] ), + url = "/gists", + ) +) +def __getStaredGists( user ): + return [ + Gist( user._github, attributes, lazy = True ) + for attributes in user._github._dataRequest( "GET", "/gists/starred", None, None ) + ] +AuthenticatedUser._addAttributePolicy( + MethodFromCallable( "get_starred_gists", [], [], __getStaredGists, SimpleTypePolicy( "list of `Gist`" ) ), +) diff --git a/github/ObjectCapacities/List.py b/github/ObjectCapacities/List.py index 24014fa8..76547bd7 100644 --- a/github/ObjectCapacities/List.py +++ b/github/ObjectCapacities/List.py @@ -5,12 +5,19 @@ from TypePolicies import * from ArgumentsChecker import * class ListCapacity: - def setList( self, attributeName, singularName, typePolicy ): + def setList( self, attributeName, singularName, typePolicy, url = None ): self.attributeName = attributeName self.singularName = singularName self.safeAttributeName = attributeName.replace( "/", "_" ) self.safeSingularName = singularName.replace( "/", "_" ) self.typePolicy = typePolicy + self.__url = url + + def baseUrl( self, obj ): + if self.__url is None: + return obj._baseUrl + "/" + self.attributeName + else: + return self.__url class ElementAddable( ListCapacity ): def apply( self, cls ): @@ -19,7 +26,7 @@ class ElementAddable( ListCapacity ): def __execute( self, obj, toBeAdded ): obj._github._statusRequest( "PUT", - obj._baseUrl + "/" + self.attributeName + "/" + self.typePolicy.getIdentity( toBeAdded ), + self.baseUrl( obj ) + "/" + self.typePolicy.getIdentity( toBeAdded ), None, None ) @@ -34,7 +41,7 @@ class ElementRemovable( ListCapacity ): def __execute( self, obj, toBeDeleted ): obj._github._statusRequest( "DELETE", - obj._baseUrl + "/" + self.attributeName + "/" + self.typePolicy.getIdentity( toBeDeleted ), + self.baseUrl( obj ) + "/" + self.typePolicy.getIdentity( toBeDeleted ), None, None ) @@ -49,12 +56,13 @@ class ElementHasable( ListCapacity ): def __execute( self, obj, toBeQueried ): return obj._github._statusRequest( "GET", - obj._baseUrl + "/" + self.attributeName + "/" + self.typePolicy.getIdentity( toBeQueried ), + self.baseUrl( obj ) + "/" + self.typePolicy.getIdentity( toBeQueried ), None, None ) == 204 def autoDocument( self ): + ### @todo `bool` -> bool return "* `has_in_" + self.safeAttributeName + "( " + self.singularName + " )`: `bool`\n * `" + self.singularName + "`: " + self.typePolicy.documentTypeName() + "\n" class ElementCreatable( ListCapacity ): @@ -72,7 +80,7 @@ class ElementCreatable( ListCapacity ): obj, obj._github._dataRequest( "POST", - obj._baseUrl + "/" + self.attributeName, + self.baseUrl( obj ), None, self.__argumentsChecker.check( args, kwds ) ) @@ -119,7 +127,7 @@ class SeveralElementsAddable( ListCapacity ): def __execute( self, obj, *toBeAddeds ): obj._github._statusRequest( "POST", - obj._baseUrl + "/" + self.attributeName, + self.baseUrl( obj ), None, [ self.typePolicy.getIdentity( toBeAdded ) @@ -137,7 +145,7 @@ class SeveralElementsRemovable( ListCapacity ): def __execute( self, obj, *toBeDeleteds ): obj._github._statusRequest( "DELETE", - obj._baseUrl + "/" + self.attributeName, + self.baseUrl( obj ), None, [ self.typePolicy.getIdentity( toBeDeleted ) @@ -165,7 +173,7 @@ class ListGetable( ListCapacity ): ) for attributes in obj._github._dataRequest( "GET", - obj._baseUrl + "/" + self.attributeName, + self.baseUrl( obj ), params, None ) @@ -186,7 +194,7 @@ class ListSetable( ListCapacity ): def __execute( self, obj, *toBeSets ): obj._github._statusRequest( "PUT", - obj._baseUrl + "/" + self.attributeName, + self.baseUrl( obj ), None, [ self.typePolicy.getIdentity( toBeSet ) @@ -204,7 +212,7 @@ class ListDeletable( ListCapacity ): def __execute( self, obj ): obj._github._statusRequest( "DELETE", - obj._baseUrl + "/" + self.attributeName, + self.baseUrl( obj ), None, None ) @@ -212,9 +220,9 @@ class ListDeletable( ListCapacity ): def autoDocument( self ): return "* `delete_" + self.safeAttributeName + "()`\n" -def ExternalListOfObjects( attributeName, singularName, type, *capacities ): +def ExternalListOfObjects( attributeName, singularName, type, *capacities, **kwds ): for capacity in capacities: - capacity.setList( attributeName, singularName, ObjectTypePolicy( type ) ) + capacity.setList( attributeName, singularName, ObjectTypePolicy( type ), **kwds ) return SeveralAttributePolicies( capacities, attributeName.capitalize().replace( "_", " " ).replace( "/", " " ) ) def ExternalListOfSimpleTypes( attributeName, singularName, type, *capacities ):