From 4638bd68b957de83d044ed5258038fb19a3d5e86 Mon Sep 17 00:00:00 2001 From: Vincent Jacques Date: Thu, 23 Feb 2012 21:21:48 +0000 Subject: [PATCH 1/9] Todos for issues --- ReferenceOfApis.md | 58 +++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/ReferenceOfApis.md b/ReferenceOfApis.md index f20f830a..94691552 100644 --- a/ReferenceOfApis.md +++ b/ReferenceOfApis.md @@ -55,7 +55,7 @@ API `/gists/starred` API `/issues` ============= -* GET: (TODO) +* GET: (TODO SOON) API `/networks/:user/:repo/events` ================================== @@ -235,47 +235,47 @@ API `/repos/:user/:repo/hooks/:id/test` API `/repos/:user/:repo/issues` =============================== -* GET: (TODO) -* POST: (TODO) +* GET: (TODO SOON) +* POST: (TODO SOON) API `/repos/:user/:repo/issues/:id` =================================== -* GET: (TODO) -* PATCH: (TODO) +* GET: (TODO SOON) +* PATCH: (TODO SOON) API `/repos/:user/:repo/issues/:id/comments` ============================================ -* GET: (TODO) -* POST: (TODO) +* GET: (TODO SOON) +* POST: (TODO SOON) API `/repos/:user/:repo/issues/:id/labels` ========================================== -* GET: (TODO) -* POST: (TODO) -* PUT: (TODO) -* DELETE: (TODO) +* GET: (TODO SOON) +* POST: (TODO SOON) +* PUT: (TODO SOON) +* DELETE: (TODO SOON) API `/repos/:user/:repo/issues/:id/labels/:id` ============================================== -* DELETE: (TODO) +* DELETE: (TODO SOON) API `/repos/:user/:repo/issues/:issue_id/events` ================================================ -* GET: (TODO) +* GET: (TODO SOON) API `/repos/:user/:repo/issues/comments/:id` ============================================ -* GET: (TODO) -* PATCH: (TODO) -* DELETE: (TODO) +* GET: (TODO SOON) +* PATCH: (TODO SOON) +* DELETE: (TODO SOON) API `/repos/:user/:repo/issues/events` ====================================== -* GET: (TODO) +* GET: (TODO SOON) API `/repos/:user/:repo/issues/events/:id` ========================================== -* GET: (TODO) +* GET: (TODO SOON) API `/repos/:user/:repo/keys` ============================= @@ -290,14 +290,14 @@ API `/repos/:user/:repo/keys/:id` API `/repos/:user/:repo/labels` =============================== -* GET: (TODO) -* POST: (TODO) +* GET: (TODO SOON) +* POST: (TODO SOON) API `/repos/:user/:repo/labels/:id` =================================== -* GET: (TODO) -* PATCH: (TODO) -* DELETE: (TODO) +* GET: (TODO SOON) +* PATCH: (TODO SOON) +* DELETE: (TODO SOON) API `/repos/:user/:repo/languages` ================================== @@ -305,18 +305,18 @@ API `/repos/:user/:repo/languages` API `/repos/:user/:repo/milestones` =================================== -* GET: (TODO) -* POST: (TODO) +* GET: (TODO SOON) +* POST: (TODO SOON) API `/repos/:user/:repo/milestones/:id` ======================================= -* GET: (TODO) -* PATCH: (TODO) -* DELETE: (TODO) +* GET: (TODO SOON) +* PATCH: (TODO SOON) +* DELETE: (TODO SOON) API `/repos/:user/:repo/milestones/:id/labels` ============================================== -* GET: (TODO) +* GET: (TODO SOON) API `/repos/:user/:repo/pulls` ============================== From eac514210e6881ce1423a6c1b2d7203ccd8a546b Mon Sep 17 00:00:00 2001 From: Vincent Jacques Date: Fri, 24 Feb 2012 11:21:59 +0000 Subject: [PATCH 2/9] Milestones --- IntegrationTest.py | 11 +++++++++++ ReferenceOfApis.md | 14 +++++++------- ReferenceOfClasses.md | 12 ++++++++++++ github/GithubObjects.py | 32 +++++++++++++++++++++++++------- 4 files changed, 55 insertions(+), 14 deletions(-) diff --git a/IntegrationTest.py b/IntegrationTest.py index 0df02bce..29002251 100644 --- a/IntegrationTest.py +++ b/IntegrationTest.py @@ -143,6 +143,8 @@ class IntegrationTest: def doSomeWritesToRepository( self ): u = self.g.get_user() r = u.create_repo( name = "TestPyGithub", description = "Created by PyGithub", has_wiki = False ) + + # Git objects b1 = r.create_git_blob( "This blob was created by PyGithub", encoding = "latin1" ) t1 = r.create_git_tree( [ { "path": "foo.bar", "mode": "100644", "type": "blob", "sha": b1.sha } ] ) c1 = r.create_git_commit( "This commit was created by PyGithub", t1.sha, [] ) @@ -153,6 +155,13 @@ class IntegrationTest: master.edit( c2.sha ) tag = r.create_git_tag( "a_tag", "This tag was created by PyGithub", c2.sha, "commit" ) r.create_git_ref( "refs/tags/a_tag", tag.sha ) + + # Issues and milestones + m = r.create_milestone( title = "This milestone was created by PyGithub" ) + m.edit( title = m.title, description = "And the description was modified by PyGithub as well" ) + m = r.create_milestone( title = "This milestone was also created by PyGithub" ) + m.delete() + self.dumpRepository( r ) def dumpUser( self, u ): @@ -203,6 +212,8 @@ class IntegrationTest: if blob.encoding == "base64": print base64.b64decode( blob.content ), print + print " Milestones:", ", ".join( m.title + " (created by " + m.creator.login + ")" for m in r.get_milestones() ) + print " Closed milestones:", ", ".join( m.title for m in r.get_milestones( state = "closed" ) ) print sys.stdout.flush() diff --git a/ReferenceOfApis.md b/ReferenceOfApis.md index 94691552..34c99cf3 100644 --- a/ReferenceOfApis.md +++ b/ReferenceOfApis.md @@ -305,16 +305,16 @@ API `/repos/:user/:repo/languages` API `/repos/:user/:repo/milestones` =================================== -* GET: (TODO SOON) -* POST: (TODO SOON) +* GET: `Repository.get_milestones( ... )`: list of `Milestone` +* POST: `Repository.create_milestone( ... )`: `Milestone` -API `/repos/:user/:repo/milestones/:id` +API `/repos/:user/:repo/milestones/:number` ======================================= -* GET: (TODO SOON) -* PATCH: (TODO SOON) -* DELETE: (TODO SOON) +* GET: `Repository.get_milestone( number )`: `Milestone` +* PATCH: `Milestone.edit( ... )` +* DELETE: `Milestone.delete()` -API `/repos/:user/:repo/milestones/:id/labels` +API `/repos/:user/:repo/milestones/:number/labels` ============================================== * GET: (TODO SOON) diff --git a/ReferenceOfClasses.md b/ReferenceOfClasses.md index 930070fd..9e9ea7cf 100644 --- a/ReferenceOfClasses.md +++ b/ReferenceOfClasses.md @@ -137,6 +137,18 @@ Teams ----- * `get_teams()`: list of `Team` +Issues and milestones +--------------------- +* `get_milestones( ... )`: list of `Milestone`: see [API](http://developer.github.com/v3/issues/milestones/#list-milestones-for-a-repository) for parameters +* `create_milestone( ... )`: `Milestone`: see [API](http://developer.github.com/v3/issues/milestones/#create-a-milestone) for parameters +* `get_milestone( number )`: `Milestone` + +Class `Milestone` +================ +* Attributes: see [API](http://developer.github.com/v3/issues/milestones/#get-a-single-milestone) +* `edit( ... )`: see [API](http://developer.github.com/v3/issues/milestones/#update-a-milestone) for parameters +* `delete()` + Class `Team` ============ * Attributes: see [API](http://developer.github.com/v3/orgs/teams/#get-team) diff --git a/github/GithubObjects.py b/github/GithubObjects.py index a87e9460..454cc765 100644 --- a/github/GithubObjects.py +++ b/github/GithubObjects.py @@ -115,7 +115,20 @@ GitTag = GithubObject( ), ) -__modifyAttributesForGitObjects = lambda obj, attributes: dict( itertools.chain( attributes.iteritems(), { "_repo": obj }.iteritems() ) ) +Milestone = GithubObject( + "Milestone", + BaseUrl( lambda obj: obj._repo._baseUrl + "/milestones/" + str( obj.number ) ), + BasicAttributes( + "url", "number", "state", "title", "description", "open_issues", + "closed_issues", "created_at", "due_on", + "_repo", ### Ugly hack + ), + ComplexAttribute( "creator", NamedUser ), + Editable( [ "title" ], [ "state", "description", "due_on" ] ), + Deletable(), +) + +__modifyAttributesForObjectsReferingRepo = lambda obj, attributes: dict( itertools.chain( attributes.iteritems(), { "_repo": obj }.iteritems() ) ) Repository = GithubObject( "Repository", BaseUrl( lambda obj: "/repos/" + obj.owner.login + "/" + obj.name ), @@ -135,26 +148,31 @@ Repository = GithubObject( ListAttribute( "watchers", NamedUser, ListGetable( [], [] ) ), Editable( [ "name" ], [ "description", "homepage", "public", "has_issues", "has_wiki", "has_downloads" ] ), ListAttribute( "git/refs", GitRef, - ListGetable( [], [], __modifyAttributesForGitObjects ), + ListGetable( [], [], __modifyAttributesForObjectsReferingRepo ), ElementGetable( "git_ref", lambda repo, ref: { "_repo": repo, "ref": ref } ), - ElementCreatable( "git_ref", [ "ref", "sha" ], [], __modifyAttributesForGitObjects ) + ElementCreatable( "git_ref", [ "ref", "sha" ], [], __modifyAttributesForObjectsReferingRepo ) ), ListAttribute( "git/commits", GitCommit, ElementGetable( "git_commit", lambda repo, sha: { "_repo": repo, "sha": sha } ), - ElementCreatable( "git_commit", [ "message", "tree", "parents" ], [ "author", "commiter" ], __modifyAttributesForGitObjects ) + ElementCreatable( "git_commit", [ "message", "tree", "parents" ], [ "author", "commiter" ], __modifyAttributesForObjectsReferingRepo ) ), ListAttribute( "git/trees", GitTree, ElementGetable( "git_tree", lambda repo, sha: { "_repo": repo, "sha": sha } ), - ElementCreatable( "git_tree", [ "tree" ], [], __modifyAttributesForGitObjects ) + ElementCreatable( "git_tree", [ "tree" ], [], __modifyAttributesForObjectsReferingRepo ) ), ListAttribute( "git/blobs", GitBlob, ElementGetable( "git_blob", lambda repo, sha: { "_repo": repo, "sha": sha } ), - ElementCreatable( "git_blob", [ "content", "encoding" ], [], __modifyAttributesForGitObjects ) + ElementCreatable( "git_blob", [ "content", "encoding" ], [], __modifyAttributesForObjectsReferingRepo ) ), ListAttribute( "git/tags", GitTag, ElementGetable( "git_tag", lambda repo, sha: { "_repo": repo, "sha": sha } ), - ElementCreatable( "git_tag", [ "tag", "message", "object", "type" ], [ "tagger" ], __modifyAttributesForGitObjects ) + ElementCreatable( "git_tag", [ "tag", "message", "object", "type" ], [ "tagger" ], __modifyAttributesForObjectsReferingRepo ) ), + ListAttribute( "milestones", Milestone, + ListGetable( [], [ "state", "sort", "direction" ] ), + ElementGetable( "milestone", lambda repo, number: { "_repo": repo, "number": number } ), + ElementCreatable( "milestone", [ "title" ], [ "state", "description", "due_on" ], __modifyAttributesForObjectsReferingRepo ) + ) ) Repository._addAttributePolicy( ComplexAttribute( "parent", Repository ) ) Repository._addAttributePolicy( ComplexAttribute( "source", Repository ) ) From d5202efc25008ffa44c9049c578e652e989abd32 Mon Sep 17 00:00:00 2001 From: Vincent Jacques Date: Fri, 24 Feb 2012 11:46:34 +0000 Subject: [PATCH 3/9] Labels --- IntegrationTest.py | 3 +++ ReferenceOfApis.md | 10 +++++----- ReferenceOfClasses.md | 9 +++++++++ github/GithubObjects.py | 17 +++++++++++++++++ 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/IntegrationTest.py b/IntegrationTest.py index 29002251..5e145a1a 100644 --- a/IntegrationTest.py +++ b/IntegrationTest.py @@ -157,6 +157,8 @@ class IntegrationTest: r.create_git_ref( "refs/tags/a_tag", tag.sha ) # Issues and milestones + l = r.create_label( "Label created by PyGithub", "00FF00" ) + l.edit( "Label created and modified by PyGithub", "FFFF00" ) m = r.create_milestone( title = "This milestone was created by PyGithub" ) m.edit( title = m.title, description = "And the description was modified by PyGithub as well" ) m = r.create_milestone( title = "This milestone was also created by PyGithub" ) @@ -212,6 +214,7 @@ class IntegrationTest: if blob.encoding == "base64": print base64.b64decode( blob.content ), print + print " Labels:", ", ".join( l.name + " (" + l.color + ")" for l in r.get_labels() ) print " Milestones:", ", ".join( m.title + " (created by " + m.creator.login + ")" for m in r.get_milestones() ) print " Closed milestones:", ", ".join( m.title for m in r.get_milestones( state = "closed" ) ) print diff --git a/ReferenceOfApis.md b/ReferenceOfApis.md index 34c99cf3..8dd9b453 100644 --- a/ReferenceOfApis.md +++ b/ReferenceOfApis.md @@ -290,14 +290,14 @@ API `/repos/:user/:repo/keys/:id` API `/repos/:user/:repo/labels` =============================== -* GET: (TODO SOON) -* POST: (TODO SOON) +* GET: `Repository.get_labels()`: list of `Label` +* POST: `Repository.create_label( ... )`: `Label` API `/repos/:user/:repo/labels/:id` =================================== -* GET: (TODO SOON) -* PATCH: (TODO SOON) -* DELETE: (TODO SOON) +* GET: `Repository.get_label( id )`: `Label` +* PATCH: `Label.edit( ... )` +* DELETE: `Label.delete()` API `/repos/:user/:repo/languages` ================================== diff --git a/ReferenceOfClasses.md b/ReferenceOfClasses.md index 9e9ea7cf..b40bda2f 100644 --- a/ReferenceOfClasses.md +++ b/ReferenceOfClasses.md @@ -139,10 +139,19 @@ Teams Issues and milestones --------------------- +* `get_labels()`: list of `Label` +* `create_label( ... )`: `Label`: see [API](http://developer.github.com/v3/issues/labels/#create-a-label) for parameters +* `get_label( id )`: `Label` * `get_milestones( ... )`: list of `Milestone`: see [API](http://developer.github.com/v3/issues/milestones/#list-milestones-for-a-repository) for parameters * `create_milestone( ... )`: `Milestone`: see [API](http://developer.github.com/v3/issues/milestones/#create-a-milestone) for parameters * `get_milestone( number )`: `Milestone` +Class `Label` +================ +* Attributes: see [API](http://developer.github.com/v3/issues/labels/#get-a-single-label) +* `edit( ... )`: see [API](http://developer.github.com/v3/issues/labels/#update-a-label) for parameters +* `delete()` + Class `Milestone` ================ * Attributes: see [API](http://developer.github.com/v3/issues/milestones/#get-a-single-milestone) diff --git a/github/GithubObjects.py b/github/GithubObjects.py index 454cc765..f01897aa 100644 --- a/github/GithubObjects.py +++ b/github/GithubObjects.py @@ -1,4 +1,5 @@ import itertools +import urllib from GithubObject import * @@ -115,6 +116,17 @@ GitTag = GithubObject( ), ) +Label = GithubObject( + "Label", + BaseUrl( lambda obj: obj._repo._baseUrl + "/labels/" + urllib.quote( obj.name ) ), + BasicAttributes( + "url", "name", "color", + "_repo", ### Ugly hack + ), + Editable( [ "name", "color" ], [] ), + Deletable(), +) + Milestone = GithubObject( "Milestone", BaseUrl( lambda obj: obj._repo._baseUrl + "/milestones/" + str( obj.number ) ), @@ -168,6 +180,11 @@ Repository = GithubObject( ElementGetable( "git_tag", lambda repo, sha: { "_repo": repo, "sha": sha } ), ElementCreatable( "git_tag", [ "tag", "message", "object", "type" ], [ "tagger" ], __modifyAttributesForObjectsReferingRepo ) ), + ListAttribute( "labels", Label, + ListGetable( [], [] ), + ElementGetable( "label", lambda repo, name: { "_repo": repo, "name": name } ), + ElementCreatable( "label", [ "name", "color" ], [], __modifyAttributesForObjectsReferingRepo ), + ), ListAttribute( "milestones", Milestone, ListGetable( [], [ "state", "sort", "direction" ] ), ElementGetable( "milestone", lambda repo, number: { "_repo": repo, "number": number } ), From a7c81e9e2d98fed47676271dd79d0d76170e6c9b Mon Sep 17 00:00:00 2001 From: Vincent Jacques Date: Fri, 24 Feb 2012 11:49:57 +0000 Subject: [PATCH 4/9] Postpone events --- ReferenceOfApis.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ReferenceOfApis.md b/ReferenceOfApis.md index 8dd9b453..8ca9fba9 100644 --- a/ReferenceOfApis.md +++ b/ReferenceOfApis.md @@ -261,7 +261,7 @@ API `/repos/:user/:repo/issues/:id/labels/:id` API `/repos/:user/:repo/issues/:issue_id/events` ================================================ -* GET: (TODO SOON) +* GET: (TODO) API `/repos/:user/:repo/issues/comments/:id` ============================================ @@ -271,11 +271,11 @@ API `/repos/:user/:repo/issues/comments/:id` API `/repos/:user/:repo/issues/events` ====================================== -* GET: (TODO SOON) +* GET: (TODO) API `/repos/:user/:repo/issues/events/:id` ========================================== -* GET: (TODO SOON) +* GET: (TODO) API `/repos/:user/:repo/keys` ============================= From f9a882fcae5e07be8167de95acef6c50eb7edb25 Mon Sep 17 00:00:00 2001 From: Vincent Jacques Date: Fri, 24 Feb 2012 12:04:09 +0000 Subject: [PATCH 5/9] Milestone.get_labels --- IntegrationTest.py | 2 +- ReferenceOfApis.md | 2 +- ReferenceOfClasses.md | 1 + github/GithubObjects.py | 5 +++-- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/IntegrationTest.py b/IntegrationTest.py index 5e145a1a..9c4533b8 100644 --- a/IntegrationTest.py +++ b/IntegrationTest.py @@ -215,7 +215,7 @@ class IntegrationTest: print base64.b64decode( blob.content ), print print " Labels:", ", ".join( l.name + " (" + l.color + ")" for l in r.get_labels() ) - print " Milestones:", ", ".join( m.title + " (created by " + m.creator.login + ")" for m in r.get_milestones() ) + print " Milestones:", ", ".join( m.title + " (created by " + m.creator.login + ", " + ", ".join( l.name for l in m.get_labels() ) + ")" for m in r.get_milestones() ) print " Closed milestones:", ", ".join( m.title for m in r.get_milestones( state = "closed" ) ) print sys.stdout.flush() diff --git a/ReferenceOfApis.md b/ReferenceOfApis.md index 8ca9fba9..6a0938b2 100644 --- a/ReferenceOfApis.md +++ b/ReferenceOfApis.md @@ -316,7 +316,7 @@ API `/repos/:user/:repo/milestones/:number` API `/repos/:user/:repo/milestones/:number/labels` ============================================== -* GET: (TODO SOON) +* GET: `Milestone.get_labels()`: list of `Label` API `/repos/:user/:repo/pulls` ============================== diff --git a/ReferenceOfClasses.md b/ReferenceOfClasses.md index b40bda2f..40718b69 100644 --- a/ReferenceOfClasses.md +++ b/ReferenceOfClasses.md @@ -157,6 +157,7 @@ Class `Milestone` * Attributes: see [API](http://developer.github.com/v3/issues/milestones/#get-a-single-milestone) * `edit( ... )`: see [API](http://developer.github.com/v3/issues/milestones/#update-a-milestone) for parameters * `delete()` +* `get_labels()`: list of `Label` Class `Team` ============ diff --git a/github/GithubObjects.py b/github/GithubObjects.py index f01897aa..9de6fc0e 100644 --- a/github/GithubObjects.py +++ b/github/GithubObjects.py @@ -138,6 +138,7 @@ Milestone = GithubObject( ComplexAttribute( "creator", NamedUser ), Editable( [ "title" ], [ "state", "description", "due_on" ] ), Deletable(), + ListAttribute( "labels", Label, ListGetable( [], [], lambda obj, attributes: dict( itertools.chain( attributes.iteritems(), { "_repo": obj._repo }.iteritems() ) ) ) ), ) __modifyAttributesForObjectsReferingRepo = lambda obj, attributes: dict( itertools.chain( attributes.iteritems(), { "_repo": obj }.iteritems() ) ) @@ -181,12 +182,12 @@ Repository = GithubObject( ElementCreatable( "git_tag", [ "tag", "message", "object", "type" ], [ "tagger" ], __modifyAttributesForObjectsReferingRepo ) ), ListAttribute( "labels", Label, - ListGetable( [], [] ), + ListGetable( [], [], __modifyAttributesForObjectsReferingRepo ), ElementGetable( "label", lambda repo, name: { "_repo": repo, "name": name } ), ElementCreatable( "label", [ "name", "color" ], [], __modifyAttributesForObjectsReferingRepo ), ), ListAttribute( "milestones", Milestone, - ListGetable( [], [ "state", "sort", "direction" ] ), + ListGetable( [], [ "state", "sort", "direction" ], __modifyAttributesForObjectsReferingRepo ), ElementGetable( "milestone", lambda repo, number: { "_repo": repo, "number": number } ), ElementCreatable( "milestone", [ "title" ], [ "state", "description", "due_on" ], __modifyAttributesForObjectsReferingRepo ) ) From ce2135c9611bc191a289d68374df34b4b6b3da75 Mon Sep 17 00:00:00 2001 From: Vincent Jacques Date: Fri, 24 Feb 2012 14:57:26 +0000 Subject: [PATCH 6/9] Repository issues --- IntegrationTest.py | 3 +++ ReferenceOfApis.md | 12 ++++++------ ReferenceOfClasses.md | 10 +++++++++- github/GithubObject.py | 5 ++++- github/GithubObjects.py | 22 +++++++++++++++++++++- 5 files changed, 43 insertions(+), 9 deletions(-) diff --git a/IntegrationTest.py b/IntegrationTest.py index 9c4533b8..64692316 100644 --- a/IntegrationTest.py +++ b/IntegrationTest.py @@ -163,6 +163,8 @@ class IntegrationTest: m.edit( title = m.title, description = "And the description was modified by PyGithub as well" ) m = r.create_milestone( title = "This milestone was also created by PyGithub" ) m.delete() + i = r.create_issue( "Issue created by PyGithub" ) + i.edit( body = "Body edited by PyGithub" ) self.dumpRepository( r ) @@ -215,6 +217,7 @@ class IntegrationTest: print base64.b64decode( blob.content ), print print " Labels:", ", ".join( l.name + " (" + l.color + ")" for l in r.get_labels() ) + print " Issues:", ", ".join( i.title for i in r.get_issues() ) print " Milestones:", ", ".join( m.title + " (created by " + m.creator.login + ", " + ", ".join( l.name for l in m.get_labels() ) + ")" for m in r.get_milestones() ) print " Closed milestones:", ", ".join( m.title for m in r.get_milestones( state = "closed" ) ) print diff --git a/ReferenceOfApis.md b/ReferenceOfApis.md index 6a0938b2..afa1b277 100644 --- a/ReferenceOfApis.md +++ b/ReferenceOfApis.md @@ -235,13 +235,13 @@ API `/repos/:user/:repo/hooks/:id/test` API `/repos/:user/:repo/issues` =============================== -* GET: (TODO SOON) -* POST: (TODO SOON) +* GET: `Repository.get_issues( ... )`: list of `Issue` +* POST: `Repository.create_issue( ... )`: `Issue` API `/repos/:user/:repo/issues/:id` =================================== -* GET: (TODO SOON) -* PATCH: (TODO SOON) +* GET: `Repository.get_issue( id )`: `Issue` +* PATCH: `Issue.edit( ... )` API `/repos/:user/:repo/issues/:id/comments` ============================================ @@ -259,8 +259,8 @@ API `/repos/:user/:repo/issues/:id/labels/:id` ============================================== * DELETE: (TODO SOON) -API `/repos/:user/:repo/issues/:issue_id/events` -================================================ +API `/repos/:user/:repo/issues/:id/events` +========================================== * GET: (TODO) API `/repos/:user/:repo/issues/comments/:id` diff --git a/ReferenceOfClasses.md b/ReferenceOfClasses.md index 40718b69..938679f3 100644 --- a/ReferenceOfClasses.md +++ b/ReferenceOfClasses.md @@ -142,16 +142,24 @@ Issues and milestones * `get_labels()`: list of `Label` * `create_label( ... )`: `Label`: see [API](http://developer.github.com/v3/issues/labels/#create-a-label) for parameters * `get_label( id )`: `Label` +* `get_issues( ... )`: list of `Issue`: see [API](http://developer.github.com/v3/issues/#list-issues-for-a-repository) for parameters +* `create_issue( ... )`: `Issue`: see [API](http://developer.github.com/v3/issues/#create-an-issue) for parameters +* `get_issue( id )`: `Issue` * `get_milestones( ... )`: list of `Milestone`: see [API](http://developer.github.com/v3/issues/milestones/#list-milestones-for-a-repository) for parameters * `create_milestone( ... )`: `Milestone`: see [API](http://developer.github.com/v3/issues/milestones/#create-a-milestone) for parameters * `get_milestone( number )`: `Milestone` Class `Label` -================ +============= * Attributes: see [API](http://developer.github.com/v3/issues/labels/#get-a-single-label) * `edit( ... )`: see [API](http://developer.github.com/v3/issues/labels/#update-a-label) for parameters * `delete()` +Class `Issue` +============= +* Attributes: see [API](http://developer.github.com/v3/issues/#get-a-single-issue) +* `edit( ... )`: see [API](http://developer.github.com/v3/issues/#edit-an-issue) for parameters + Class `Milestone` ================ * Attributes: see [API](http://developer.github.com/v3/issues/milestones/#get-a-single-milestone) diff --git a/github/GithubObject.py b/github/GithubObject.py index 06017d71..11ae69c4 100644 --- a/github/GithubObject.py +++ b/github/GithubObject.py @@ -38,7 +38,10 @@ class ComplexAttribute: self.__type = type def getValueFromRawValue( self, obj, rawValue ): - return self.__type( obj._github, rawValue, lazy = True ) + if rawValue is None: + return None + else: + return self.__type( obj._github, rawValue, lazy = True ) def updateAttributes( self, obj ): attributes = obj._github._dataRequest( "GET", obj._baseUrl, None, None ) diff --git a/github/GithubObjects.py b/github/GithubObjects.py index 9de6fc0e..25c82053 100644 --- a/github/GithubObjects.py +++ b/github/GithubObjects.py @@ -141,6 +141,21 @@ Milestone = GithubObject( ListAttribute( "labels", Label, ListGetable( [], [], lambda obj, attributes: dict( itertools.chain( attributes.iteritems(), { "_repo": obj._repo }.iteritems() ) ) ) ), ) +Issue = GithubObject( + "Issue", + BaseUrl( lambda obj: obj._repo._baseUrl + "/issues/" + str( obj.number ) ), + BasicAttributes( + "url", "html_url", "number", "state", "title", "body", "labels", + "comments", "closed_at", "created_at", "updated_at", "id", "closed_by", + "pull_request", ### @todo Structure + "_repo", ### Ugly hack + ), + ComplexAttribute( "user", NamedUser ), + ComplexAttribute( "assignee", NamedUser ), + ComplexAttribute( "milestone", Milestone ), + Editable( [], [ "title", "body", "assignee", "state", "milestone", "labels" ] ), +) + __modifyAttributesForObjectsReferingRepo = lambda obj, attributes: dict( itertools.chain( attributes.iteritems(), { "_repo": obj }.iteritems() ) ) Repository = GithubObject( "Repository", @@ -190,7 +205,12 @@ Repository = GithubObject( ListGetable( [], [ "state", "sort", "direction" ], __modifyAttributesForObjectsReferingRepo ), ElementGetable( "milestone", lambda repo, number: { "_repo": repo, "number": number } ), ElementCreatable( "milestone", [ "title" ], [ "state", "description", "due_on" ], __modifyAttributesForObjectsReferingRepo ) - ) + ), + ListAttribute( "issues", Issue, + ListGetable( [], [ "milestone", "state", "assignee", "mentioned", "labels", "sort", "direction", "since" ], __modifyAttributesForObjectsReferingRepo ), + ElementGetable( "issue", lambda repo, number: { "_repo": repo, "number": number } ), + ElementCreatable( "issue", [ "title" ], [ "body", "assignee", "milestone", "labels", ], __modifyAttributesForObjectsReferingRepo ) + ), ) Repository._addAttributePolicy( ComplexAttribute( "parent", Repository ) ) Repository._addAttributePolicy( ComplexAttribute( "source", Repository ) ) From a03a9046926eef55046d74bad0ec6c62960ba115 Mon Sep 17 00:00:00 2001 From: Vincent Jacques Date: Fri, 24 Feb 2012 15:46:21 +0000 Subject: [PATCH 7/9] Issue.xxx_labels --- IntegrationTest.py | 10 +++++++++- ReferenceOfApis.md | 14 +++++++------- ReferenceOfClasses.md | 5 +++++ github/GithubObject.py | 2 +- github/GithubObjects.py | 10 +++++++++- github/ObjectCapacities/List.py | 31 +++++++++++++++++++++++++++++++ github/Requester.py | 2 ++ 7 files changed, 64 insertions(+), 10 deletions(-) diff --git a/IntegrationTest.py b/IntegrationTest.py index 64692316..13975aa2 100644 --- a/IntegrationTest.py +++ b/IntegrationTest.py @@ -166,6 +166,14 @@ class IntegrationTest: i = r.create_issue( "Issue created by PyGithub" ) i.edit( body = "Body edited by PyGithub" ) + la = r.create_label( "a", "00FF00" ) + lb = r.create_label( "b", "00FF00" ) + lc = r.create_label( "c", "00FF00" ) + i.set_labels( la, lb ) + i.remove_from_labels( lb ) + i.delete_labels() + i.add_to_labels( lc ) + self.dumpRepository( r ) def dumpUser( self, u ): @@ -217,7 +225,7 @@ class IntegrationTest: print base64.b64decode( blob.content ), print print " Labels:", ", ".join( l.name + " (" + l.color + ")" for l in r.get_labels() ) - print " Issues:", ", ".join( i.title for i in r.get_issues() ) + print " Issues:", ", ".join( i.title + " (" + ", ".join( l.name for l in i.get_labels() ) + ")" for i in r.get_issues() ) print " Milestones:", ", ".join( m.title + " (created by " + m.creator.login + ", " + ", ".join( l.name for l in m.get_labels() ) + ")" for m in r.get_milestones() ) print " Closed milestones:", ", ".join( m.title for m in r.get_milestones( state = "closed" ) ) print diff --git a/ReferenceOfApis.md b/ReferenceOfApis.md index afa1b277..af6b16cc 100644 --- a/ReferenceOfApis.md +++ b/ReferenceOfApis.md @@ -250,14 +250,14 @@ API `/repos/:user/:repo/issues/:id/comments` API `/repos/:user/:repo/issues/:id/labels` ========================================== -* GET: (TODO SOON) -* POST: (TODO SOON) -* PUT: (TODO SOON) -* DELETE: (TODO SOON) +* GET: `Issue.get_labels()`: list of `Label` +* POST: `Issue.add_to_labels( ... )` +* PUT: `Issue.set_labels( ... )` +* DELETE: `Issue.delete_labels()` -API `/repos/:user/:repo/issues/:id/labels/:id` -============================================== -* DELETE: (TODO SOON) +API `/repos/:user/:repo/issues/:id/labels/:name` +================================================ +* DELETE: `Issue.remove_from_labels( name )` API `/repos/:user/:repo/issues/:id/events` ========================================== diff --git a/ReferenceOfClasses.md b/ReferenceOfClasses.md index 938679f3..119529a2 100644 --- a/ReferenceOfClasses.md +++ b/ReferenceOfClasses.md @@ -159,6 +159,11 @@ Class `Issue` ============= * Attributes: see [API](http://developer.github.com/v3/issues/#get-a-single-issue) * `edit( ... )`: see [API](http://developer.github.com/v3/issues/#edit-an-issue) for parameters +* `get_labels()`: list of `Label` +* `add_to_labels( label, ... )` +* `set_labels( label, ... )` +* `delete_labels()` +* `remove_from_labels( label )` Class `Milestone` ================ diff --git a/github/GithubObject.py b/github/GithubObject.py index 11ae69c4..449268de 100644 --- a/github/GithubObject.py +++ b/github/GithubObject.py @@ -2,7 +2,7 @@ import itertools import ObjectCapacities.ArgumentsChecker as ArgumentsChecker from ObjectCapacities.Basic import AttributeFromCallable, MethodFromCallable -from ObjectCapacities.List import ListAttribute, ListGetable, ElementCreatable, ElementGetable, ElementAddable, ElementRemovable, ElementHasable +from ObjectCapacities.List import ListAttribute, ListGetable, ElementCreatable, ElementGetable, ElementAddable, ElementRemovable, ElementHasable, ListAddable, ListSetable, ListDeletable class BadGithubObjectException( Exception ): pass diff --git a/github/GithubObjects.py b/github/GithubObjects.py index 25c82053..e3649d2b 100644 --- a/github/GithubObjects.py +++ b/github/GithubObjects.py @@ -118,7 +118,8 @@ GitTag = GithubObject( Label = GithubObject( "Label", - BaseUrl( lambda obj: obj._repo._baseUrl + "/labels/" + urllib.quote( obj.name ) ), + BaseUrl( lambda obj: obj._repo._baseUrl + "/labels/" + obj._identity ), + Identity( lambda obj: urllib.quote( obj.name ) ), BasicAttributes( "url", "name", "color", "_repo", ### Ugly hack @@ -154,6 +155,13 @@ Issue = GithubObject( ComplexAttribute( "assignee", NamedUser ), ComplexAttribute( "milestone", Milestone ), Editable( [], [ "title", "body", "assignee", "state", "milestone", "labels" ] ), + ListAttribute( "labels", Label, + ListGetable( [], [], lambda obj, attributes: dict( itertools.chain( attributes.iteritems(), { "_repo": obj._repo }.iteritems() ) ) ), + ListAddable(), + ListSetable(), + ListDeletable(), + ElementRemovable(), + ), ) __modifyAttributesForObjectsReferingRepo = lambda obj, attributes: dict( itertools.chain( attributes.iteritems(), { "_repo": obj }.iteritems() ) ) diff --git a/github/ObjectCapacities/List.py b/github/ObjectCapacities/List.py index acc8dd9e..a3f05348 100644 --- a/github/ObjectCapacities/List.py +++ b/github/ObjectCapacities/List.py @@ -77,6 +77,37 @@ class ElementGetable: def __execute( self, obj, *args, **kwds ): return self.__type( obj._github, self.__attributes( obj, *args, **kwds ), lazy = False ) +class ListAddable: + def apply( self, list, cls ): + self.__type = list.type + self.__attributeName = list.attributeName + cls._addMethod( "add_to_" + list.attributeName.replace( "/", "_" ), self.__execute ) + + def __execute( self, obj, *toBeAddeds ): + for toBeAdded in toBeAddeds: + assert isinstance( toBeAdded, self.__type ) + obj._github._statusRequest( "POST", obj._baseUrl + "/" + self.__attributeName, None, [ toBeAdded._identity for toBeAdded in toBeAddeds ] ) + +class ListSetable: + def apply( self, list, cls ): + self.__type = list.type + self.__attributeName = list.attributeName + cls._addMethod( "set_" + list.attributeName.replace( "/", "_" ), self.__execute ) + + def __execute( self, obj, *toBeSets ): + for toBeSet in toBeSets: + assert isinstance( toBeSet, self.__type ) + obj._github._statusRequest( "PUT", obj._baseUrl + "/" + self.__attributeName, None, [ toBeSet._identity for toBeSet in toBeSets ] ) + +class ListDeletable: + def apply( self, list, cls ): + self.__type = list.type + self.__attributeName = list.attributeName + cls._addMethod( "delete_" + list.attributeName.replace( "/", "_" ), self.__execute ) + + def __execute( self, obj ): + obj._github._statusRequest( "DELETE", obj._baseUrl + "/" + self.__attributeName, None, None ) + class ListAttribute: def __init__( self, attributeName, type, *capacities ): self.attributeName = attributeName diff --git a/github/Requester.py b/github/Requester.py index 12aa1aeb..d37fd85b 100644 --- a/github/Requester.py +++ b/github/Requester.py @@ -1,3 +1,5 @@ +### @todo Add a copyright and license notice in all files + import httplib import json import base64 From 01e049391ae895833ab102f1a0a3e750e3e725e2 Mon Sep 17 00:00:00 2001 From: Vincent Jacques Date: Fri, 24 Feb 2012 15:59:12 +0000 Subject: [PATCH 8/9] Restore test coverage --- github/GithubObject.UnitTest.py | 67 ++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 2 deletions(-) diff --git a/github/GithubObject.UnitTest.py b/github/GithubObject.UnitTest.py index a1759d37..03cba3fd 100644 --- a/github/GithubObject.UnitTest.py +++ b/github/GithubObject.UnitTest.py @@ -25,8 +25,8 @@ class TestCaseWithGithubTestObject( unittest.TestCase ): def expectDataGet( self, url, arguments = None ): return self.g.expect._dataRequest( "GET", url, arguments, None ) - def expectStatusPut( self, url ): - return self.g.expect._statusRequest( "PUT", url, None, None ) + def expectStatusPut( self, url, data = None ): + return self.g.expect._statusRequest( "PUT", url, None, data ) def expectStatusGet( self, url ): return self.g.expect._statusRequest( "GET", url, None, None ) @@ -37,6 +37,9 @@ class TestCaseWithGithubTestObject( unittest.TestCase ): def expectDataPost( self, url, data ): return self.g.expect._dataRequest( "POST", url, None, data ) + def expectStatusPost( self, url, data ): + return self.g.expect._statusRequest( "POST", url, None, data ) + def expectStatusDelete( self, url ): return self.g.expect._statusRequest( "DELETE", url, None, None ) @@ -194,6 +197,10 @@ class GithubObjectWithComplexAttribute( TestCaseWithGithubTestObject ): self.expectDataGet( "/test/a3s/id1" ).andReturn( { "desc": "desc1" } ) self.assertEqual( self.o.a3.desc, "desc1" ) + def testCompletionWithNone( self ): + self.expectDataGet( "/test" ).andReturn( { "a3": None } ) + self.assertIsNone( self.o.a3 ) + class GithubObjectWithListGetableList( TestCaseWithGithubTestObject ): ContainedObject = GithubObject( "ContainedObject", @@ -322,6 +329,62 @@ class GithubObjectWithElementCreatableList( TestCaseWithGithubTestObject ): with self.assertRaises( TypeError ): self.o.create_a3( foobar = 42 ) +class GithubObjectWithListAddableList( TestCaseWithGithubTestObject ): + ContainedObject = GithubObject( + "ContainedObject", + BaseUrl( lambda obj: "/test/a3s/" + obj.id ), + Identity( lambda obj: obj.id ), + BasicAttributes( "id", "name" ) + ) + + GithubTestObject = GithubObject( + "GithubTestObject", + BaseUrl( lambda obj: "/test" ), + BasicAttributes( "a1", "a2" ), + ListAttribute( "a3s", ContainedObject, ListAddable() ) + ) + + def testAddToList( self ): + self.expectStatusPost( "/test/a3s", [ "id1", "id2" ] ) + self.o.add_to_a3s( self.ContainedObject( self.g, { "id": "id1" }, lazy = True ), self.ContainedObject( self.g, { "id": "id2" }, lazy = True ) ) + +class GithubObjectWithListSetableList( TestCaseWithGithubTestObject ): + ContainedObject = GithubObject( + "ContainedObject", + BaseUrl( lambda obj: "/test/a3s/" + obj.id ), + Identity( lambda obj: obj.id ), + BasicAttributes( "id", "name" ) + ) + + GithubTestObject = GithubObject( + "GithubTestObject", + BaseUrl( lambda obj: "/test" ), + BasicAttributes( "a1", "a2" ), + ListAttribute( "a3s", ContainedObject, ListSetable() ) + ) + + def testSetList( self ): + self.expectStatusPut( "/test/a3s", [ "id1", "id2" ] ) + self.o.set_a3s( self.ContainedObject( self.g, { "id": "id1" }, lazy = True ), self.ContainedObject( self.g, { "id": "id2" }, lazy = True ) ) + +class GithubObjectWithListDeletableList( TestCaseWithGithubTestObject ): + ContainedObject = GithubObject( + "ContainedObject", + BaseUrl( lambda obj: "/test/a3s/" + obj.id ), + BasicAttributes( "id", "name" ) + ) + + GithubTestObject = GithubObject( + "GithubTestObject", + BaseUrl( lambda obj: "/test" ), + BasicAttributes( "a1", "a2" ), + ListAttribute( "a3s", ContainedObject, ListDeletable() ) + ) + + def testGetList( self ): + self.expectStatusDelete( "/test/a3s" ) + self.o.delete_a3s() + class GithubObjectWithElementGetableList( TestCaseWithGithubTestObject ): ContainedObject = GithubObject( "ContainedObject", From c3db56f0fda42f5ff444bf7824f75c69353d33c7 Mon Sep 17 00:00:00 2001 From: Vincent Jacques Date: Fri, 24 Feb 2012 17:10:02 +0000 Subject: [PATCH 9/9] IssueComment --- IntegrationTest.py | 4 +++- ReferenceOfApis.md | 10 +++++----- ReferenceOfClasses.md | 9 +++++++++ github/GithubObjects.py | 17 +++++++++++++++++ 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/IntegrationTest.py b/IntegrationTest.py index 13975aa2..765706a9 100644 --- a/IntegrationTest.py +++ b/IntegrationTest.py @@ -174,6 +174,8 @@ class IntegrationTest: i.delete_labels() i.add_to_labels( lc ) + i.create_comment( "Commented from PyGithub" ) + self.dumpRepository( r ) def dumpUser( self, u ): @@ -225,7 +227,7 @@ class IntegrationTest: print base64.b64decode( blob.content ), print print " Labels:", ", ".join( l.name + " (" + l.color + ")" for l in r.get_labels() ) - print " Issues:", ", ".join( i.title + " (" + ", ".join( l.name for l in i.get_labels() ) + ")" for i in r.get_issues() ) + print " Issues:", ", ".join( i.title + " (" + ", ".join( l.name for l in i.get_labels() ) + ") (" + ", ".join( c.body for c in i.get_comments() ) + ")" for i in r.get_issues() ) print " Milestones:", ", ".join( m.title + " (created by " + m.creator.login + ", " + ", ".join( l.name for l in m.get_labels() ) + ")" for m in r.get_milestones() ) print " Closed milestones:", ", ".join( m.title for m in r.get_milestones( state = "closed" ) ) print diff --git a/ReferenceOfApis.md b/ReferenceOfApis.md index af6b16cc..32db733a 100644 --- a/ReferenceOfApis.md +++ b/ReferenceOfApis.md @@ -245,8 +245,8 @@ API `/repos/:user/:repo/issues/:id` API `/repos/:user/:repo/issues/:id/comments` ============================================ -* GET: (TODO SOON) -* POST: (TODO SOON) +* GET: `Issue.get_comments()`: list of `IssueComment` +* POST: `Issue.create_comment( ... )`: `IssueComment` API `/repos/:user/:repo/issues/:id/labels` ========================================== @@ -265,9 +265,9 @@ API `/repos/:user/:repo/issues/:id/events` API `/repos/:user/:repo/issues/comments/:id` ============================================ -* GET: (TODO SOON) -* PATCH: (TODO SOON) -* DELETE: (TODO SOON) +* GET: `Issue.get_comment( id )`: `IssueComment` +* PATCH: `IssueComment.edit( ... )` +* DELETE: `IssueComment.delete( ... )` API `/repos/:user/:repo/issues/events` ====================================== diff --git a/ReferenceOfClasses.md b/ReferenceOfClasses.md index 119529a2..9b51fea3 100644 --- a/ReferenceOfClasses.md +++ b/ReferenceOfClasses.md @@ -164,6 +164,15 @@ Class `Issue` * `set_labels( label, ... )` * `delete_labels()` * `remove_from_labels( label )` +* `get_comments()`: list of `IssueComment` +* `create_comment( ... )`: `IssueComment`: see [API](http://developer.github.com/v3/issues/comments/#create-a-comment) for parameters +* `get_comment( id )`: `IssueComment` + +Class `IssueComment` +==================== +* Attributes: see [API](http://developer.github.com/v3/issues/comments/#get-a-single-comment) +* `edit( ... )`: see [API](http://developer.github.com/v3/issues/comments/#edit-a-comment) for parameters +* `delete()` Class `Milestone` ================ diff --git a/github/GithubObjects.py b/github/GithubObjects.py index e3649d2b..9ec6f746 100644 --- a/github/GithubObjects.py +++ b/github/GithubObjects.py @@ -142,6 +142,18 @@ Milestone = GithubObject( ListAttribute( "labels", Label, ListGetable( [], [], lambda obj, attributes: dict( itertools.chain( attributes.iteritems(), { "_repo": obj._repo }.iteritems() ) ) ) ), ) +IssueComment = GithubObject( + "IssueComment", + BaseUrl( lambda obj: obj._repo._baseUrl + "/issues/comment" + str( obj.id ) ), + BasicAttributes( + "url", "body", "created_at", "updated_at", "id", + "_repo", ### Ugly hack + ), + ComplexAttribute( "user", NamedUser ), + Editable( [ "body" ], [] ), + Deletable(), +) + Issue = GithubObject( "Issue", BaseUrl( lambda obj: obj._repo._baseUrl + "/issues/" + str( obj.number ) ), @@ -162,6 +174,11 @@ Issue = GithubObject( ListDeletable(), ElementRemovable(), ), + ListAttribute( "comments", IssueComment, + ListGetable( [], [], lambda obj, attributes: dict( itertools.chain( attributes.iteritems(), { "_repo": obj._repo }.iteritems() ) ) ), + ElementGetable( "comment", lambda repo, id: { "_repo": repo, "id": id } ), + ElementCreatable( "comment", [ "body" ], [], lambda obj, attributes: dict( itertools.chain( attributes.iteritems(), { "_repo": obj._repo }.iteritems() ) ) ), + ), ) __modifyAttributesForObjectsReferingRepo = lambda obj, attributes: dict( itertools.chain( attributes.iteritems(), { "_repo": obj }.iteritems() ) )