mirror of
https://github.com/status-im/PyGithub.git
synced 2026-09-01 19:31:10 +00:00
Merge branch 'develop'
This commit is contained in:
+1
-1
@@ -3,4 +3,4 @@ GithubCredentials.py
|
||||
.coverage
|
||||
/dist
|
||||
/MANIFEST
|
||||
ReplayDataForIntegrationTest.txt
|
||||
ReplayDataForIntegrationTest*.txt
|
||||
|
||||
+507
-202
@@ -1,5 +1,6 @@
|
||||
#!/bin/env python
|
||||
|
||||
import re
|
||||
import time
|
||||
import sys
|
||||
import httplib
|
||||
@@ -7,22 +8,25 @@ import base64
|
||||
|
||||
from github import Github
|
||||
|
||||
class RecordingHttpResponse( object ):
|
||||
def __init__( self, file, res ):
|
||||
self.status = res.status
|
||||
self.__headers = res.getheaders()
|
||||
self.__output = res.read()
|
||||
file.write( str( self.status ) + "\n" )
|
||||
file.write( str( self.__headers ) + "\n" )
|
||||
file.write( str( self.__output ) + "\n" )
|
||||
|
||||
def getheaders( self ):
|
||||
return self.__headers
|
||||
|
||||
def read( self ):
|
||||
return self.__output
|
||||
class RecordReplayException( Exception ):
|
||||
pass
|
||||
|
||||
class RecordingHttpsConnection:
|
||||
class HttpResponse( object ):
|
||||
def __init__( self, file, res ):
|
||||
self.status = res.status
|
||||
self.__headers = res.getheaders()
|
||||
self.__output = res.read()
|
||||
file.write( str( self.status ) + "\n" )
|
||||
file.write( str( self.__headers ) + "\n" )
|
||||
file.write( str( self.__output ) + "\n" )
|
||||
|
||||
def getheaders( self ):
|
||||
return self.__headers
|
||||
|
||||
def read( self ):
|
||||
return self.__output
|
||||
|
||||
__realHttpsConnection = httplib.HTTPSConnection
|
||||
|
||||
def __init__( self, file, *args, **kwds ):
|
||||
@@ -30,238 +34,539 @@ class RecordingHttpsConnection:
|
||||
self.__cnx = self.__realHttpsConnection( *args, **kwds )
|
||||
|
||||
def request( self, verb, url, input, headers ):
|
||||
print verb, url
|
||||
self.__cnx.request( verb, url, input, headers )
|
||||
del headers[ "Authorization" ] # Do not let sensitive info in git :-p
|
||||
self.__file.write( verb + " " + url + " " + str( headers ) + " " + input + "\n" )
|
||||
|
||||
def getresponse( self ):
|
||||
return RecordingHttpResponse( self.__file, self.__cnx.getresponse() )
|
||||
return RecordingHttpsConnection.HttpResponse( self.__file, self.__cnx.getresponse() )
|
||||
|
||||
def close( self ):
|
||||
self.__file.write( "\n" )
|
||||
return self.__cnx.close()
|
||||
|
||||
class ReplayingHttpResponse( object ):
|
||||
def __init__( self, file ):
|
||||
self.status = int( file.readline().strip() )
|
||||
self.__headers = eval( file.readline().strip() )
|
||||
self.__output = file.readline().strip()
|
||||
|
||||
def getheaders( self ):
|
||||
return self.__headers
|
||||
|
||||
def read( self ):
|
||||
return self.__output
|
||||
|
||||
class ReplayingHttpsConnection:
|
||||
class HttpResponse( object ):
|
||||
def __init__( self, file ):
|
||||
self.status = int( file.readline().strip() )
|
||||
self.__headers = eval( file.readline().strip() )
|
||||
self.__output = file.readline().strip()
|
||||
|
||||
def getheaders( self ):
|
||||
return self.__headers
|
||||
|
||||
def read( self ):
|
||||
return self.__output
|
||||
|
||||
def __init__( self, file ):
|
||||
self.__file = file
|
||||
|
||||
def request( self, verb, url, input, headers ):
|
||||
del headers[ "Authorization" ]
|
||||
assert self.__file.readline().strip() == verb + " " + url + " " + str( headers ) + " " + input
|
||||
if( self.__file.readline().strip() != verb + " " + url + " " + str( headers ) + " " + input ):
|
||||
raise RecordReplayException( "This test has been changed since last record. Please re-run this script with argument '--record'" )
|
||||
|
||||
def getresponse( self ):
|
||||
return ReplayingHttpResponse( self.__file )
|
||||
return ReplayingHttpsConnection.HttpResponse( self.__file )
|
||||
|
||||
def close( self ):
|
||||
self.__file.readline()
|
||||
|
||||
class IntegrationTest:
|
||||
__fileName = "ReplayDataForIntegrationTest.txt"
|
||||
cobayeUser = "Lyloa"
|
||||
cobayeOrganization = "BeaverSoftware"
|
||||
|
||||
def main( self ):
|
||||
if len( sys.argv ) == 2 and sys.argv[ 1 ] == "--record":
|
||||
print "Record mode: I'm really going to do requests to github.com. Please type 'yes' and return"
|
||||
sys.stdout.flush()
|
||||
confirm = sys.stdin.readline().strip()
|
||||
if confirm != "yes":
|
||||
exit( 1 )
|
||||
self.record()
|
||||
def main( self, argv ):
|
||||
record = False
|
||||
if len( argv ) >= 1:
|
||||
if argv[ 0 ] == "--record":
|
||||
argv = argv[ 1: ]
|
||||
record = True
|
||||
elif argv[ 0 ] == "--list":
|
||||
print "List of available tests:"
|
||||
print "\n".join( self.listTests() )
|
||||
return
|
||||
|
||||
if record:
|
||||
print "Record mode: this script is really going to do requests to github.com"
|
||||
else:
|
||||
self.replay()
|
||||
print "Replay mode: this script will use requests to and replies from github.com recorded in previous runs in record mode"
|
||||
|
||||
exit()
|
||||
if len( argv ) == 0:
|
||||
tests = self.listTests()
|
||||
else:
|
||||
tests = argv
|
||||
self.runTests( tests, record )
|
||||
|
||||
def record( self ):
|
||||
self.prepareRecord()
|
||||
self.playScenario()
|
||||
if self.succeeded:
|
||||
self.analyseCoverage()
|
||||
|
||||
def replay( self ):
|
||||
self.prepareReplay()
|
||||
self.playScenario()
|
||||
|
||||
def prepareRecord( self ):
|
||||
def prepareRecord( self, test ):
|
||||
self.avoidError500FromGithub = lambda: time.sleep( 1 )
|
||||
try:
|
||||
import GithubCredentials
|
||||
self.g = Github( GithubCredentials.login, GithubCredentials.password )
|
||||
file = open( self.__fileName, "w" )
|
||||
httplib.HTTPSConnection = lambda *args, **kwds: RecordingHttpsConnection( file, *args, **kwds )
|
||||
self.__file = open( self.__fileName( test ), "w" )
|
||||
httplib.HTTPSConnection = lambda *args, **kwds: RecordingHttpsConnection( self.__file, *args, **kwds )
|
||||
except ImportError:
|
||||
print "Please create a 'GithubCredentials.py' file containing:"
|
||||
print "login = '<your github login>'"
|
||||
print "password = '<your github password>'"
|
||||
exit( 1 )
|
||||
raise RecordReplayException( textwrap.dedent( """\
|
||||
Please create a 'GithubCredentials.py' file containing:"
|
||||
login = '<your github login>'"
|
||||
password = '<your github password>'""" ) )
|
||||
|
||||
def prepareReplay( self ):
|
||||
def prepareReplay( self, test ):
|
||||
self.avoidError500FromGithub = lambda: 0
|
||||
try:
|
||||
file = open( self.__fileName )
|
||||
httplib.HTTPSConnection = lambda *args, **kwds: ReplayingHttpsConnection( file )
|
||||
self.__file = None
|
||||
self.__file = open( self.__fileName( test ) )
|
||||
httplib.HTTPSConnection = lambda *args, **kwds: ReplayingHttpsConnection( self.__file )
|
||||
self.g = Github( "login", "password" )
|
||||
except IOError:
|
||||
print "Please re-run this script with argument '--record' to be able to replay the integration tests based on recorded first execution"
|
||||
exit( 1 )
|
||||
raise RecordReplayException( "This test has never been recorded. Please re-run this script with argument '--record'" )
|
||||
|
||||
def playScenario( self ):
|
||||
self.doSomeReads()
|
||||
self.doSomeWrites()
|
||||
def __fileName( self, test ):
|
||||
return "ReplayDataForIntegrationTest." + test + ".txt"
|
||||
|
||||
def doSomeReads( self ):
|
||||
self.dumpUser( self.g.get_user(), doPrivateThings = True )
|
||||
jacquev6 = self.g.get_user( "jacquev6" )
|
||||
self.dumpUser( jacquev6, doPrivateThings = False )
|
||||
self.dumpOrganization( self.g.get_organization( "github" ), doTeams = False )
|
||||
self.dumpOrganization( self.g.get_organization( "BeaverSoftware" ), doTeams = True )
|
||||
self.dumpRepository( jacquev6.get_repo( "PyGithub" ) )
|
||||
def listTests( self ):
|
||||
return [ f[ 4: ] for f in dir( self ) if f.startswith( "test" ) ]
|
||||
|
||||
def doSomeWrites( self ):
|
||||
self.doSomeWritesToUser()
|
||||
self.doSomeWritesToRepository()
|
||||
|
||||
def doSomeWritesToUser( self ):
|
||||
u = self.g.get_user()
|
||||
oldBio = u.bio
|
||||
u.edit( bio = oldBio + " (Edited by PyGithub)" )
|
||||
u.edit( bio = oldBio )
|
||||
jacquev6 = self.g.get_user( "jacquev6" )
|
||||
u.remove_from_following( jacquev6 )
|
||||
u.add_to_following( jacquev6 )
|
||||
PyGithub = jacquev6.get_repo( "PyGithub" )
|
||||
u.remove_from_watched( PyGithub )
|
||||
u.add_to_watched( PyGithub )
|
||||
|
||||
def doSomeWritesToRepository( self ):
|
||||
u = self.g.get_user()
|
||||
r = u.create_repo( name = "TestPyGithub", description = "Created by PyGithub", has_wiki = False )
|
||||
self.avoidError500FromGithub()
|
||||
|
||||
# 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, [] )
|
||||
master = r.create_git_ref( "refs/heads/master", c1.sha )
|
||||
b2 = r.create_git_blob( "This blob was also created by PyGithub", encoding = "latin1" )
|
||||
t2 = r.create_git_tree( [ { "path": "foo.bar", "mode": "100644", "type": "blob", "sha": b2.sha }, { "path": "old", "mode": "040000", "type": "tree", "sha": t1.sha } ] )
|
||||
c2 = r.create_git_commit( "This commit was also created by PyGithub", t2.sha, [ c1.sha ] )
|
||||
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 )
|
||||
|
||||
c = r.get_commit( c2.sha )
|
||||
c.create_comment( "Commented with PyGithub", c.sha, 1, "foo.bar", 1 )
|
||||
|
||||
# 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" )
|
||||
m.delete()
|
||||
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 )
|
||||
|
||||
i.create_comment( "Commented from PyGithub" )
|
||||
|
||||
# Downloads
|
||||
r.create_download( "MyDownloadCreatedByPyGithub", 1000 )
|
||||
|
||||
# Forking, commiting and requesting merge
|
||||
o = self.g.get_organization( "BeaverSoftware" )
|
||||
|
||||
rf = o.create_fork( r )
|
||||
self.avoidError500FromGithub()
|
||||
b3 = rf.create_git_blob( "This blob was ter created by PyGithub", encoding = "latin1" )
|
||||
t3 = rf.create_git_tree( [ { "path": "foo.bar", "mode": "100644", "type": "blob", "sha": b3.sha } ] )
|
||||
c3 = rf.create_git_commit( "This commit was ter created by PyGithub", t3.sha, [ c2.sha ] )
|
||||
rf.get_git_ref( "refs/heads/master" ).edit( c3.sha )
|
||||
|
||||
p = r.create_pull( "Pull request created by PyGithub", "", "jacquev6:master", "BeaverSoftware:master" )
|
||||
|
||||
self.dumpRepository( r )
|
||||
|
||||
def dumpUser( self, u, doPrivateThings ):
|
||||
print u.login, "(", u.name, ")"
|
||||
print " Repos:"
|
||||
for r in u.get_repos():
|
||||
print " ", r.name,
|
||||
if r.fork:
|
||||
print "<-", r.parent.owner.login + "/" + r.parent.name,
|
||||
print "<-", r.source.owner.login + "/" + r.source.name,
|
||||
def runTests( self, tests, record ):
|
||||
self.succeeded = True
|
||||
for test in tests:
|
||||
print
|
||||
if doPrivateThings:
|
||||
print " Emails:", ", ".join( u.get_emails() )
|
||||
print " Watched:", ", ".join( r.name for r in u.get_watched() )
|
||||
print " Organizations:", ", ".join( o.login for o in u.get_orgs() )
|
||||
print " Following:", ", ".join( f.login for f in u.get_following() )
|
||||
if doPrivateThings:
|
||||
print " Is following jacquev6:", u.has_in_following( self.g.get_user( "jacquev6" ) )
|
||||
print " Followers:", ", ".join( f.login for f in u.get_followers() )
|
||||
print
|
||||
sys.stdout.flush()
|
||||
print test
|
||||
print "=" * len( test )
|
||||
try:
|
||||
if record:
|
||||
self.prepareRecord( test )
|
||||
else:
|
||||
self.prepareReplay( test )
|
||||
getattr( self, "test" + test )()
|
||||
if not record:
|
||||
if self.__file.readline():
|
||||
raise RecordReplayException( "This test has been changed since last record. Please re-run this script with argument '--record'" )
|
||||
except RecordReplayException, e:
|
||||
print "*" * len( str( e ) )
|
||||
print e
|
||||
print "*" * len( str( e ) )
|
||||
self.succeeded = False
|
||||
finally:
|
||||
if self.__file is not None:
|
||||
self.__file.close()
|
||||
|
||||
def dumpOrganization( self, o, doTeams ):
|
||||
print o.login, "(", o.name, ")"
|
||||
print " Members:", ", ".join( u.login for u in o.get_members() )
|
||||
print " Repos:", ", ".join( r.name for r in o.get_repos() )
|
||||
if doTeams:
|
||||
print " Teams:"
|
||||
for team in o.get_teams():
|
||||
print " ", team.name, "(" + team.permission + "):", ", ".join( u.login for u in team.get_members() ), "->", ", ".join( r.name for r in team.get_repos() )
|
||||
print
|
||||
sys.stdout.flush()
|
||||
def analyseCoverage( self ):
|
||||
coveredUrls = dict()
|
||||
for test in self.listTests():
|
||||
with open( self.__fileName( test ) ) as file:
|
||||
requests = [ line.strip() for line in file.readlines() ][ 0 : : 5 ]
|
||||
for request in requests:
|
||||
verb, url = request.split( " " )[ 0 : 2 ]
|
||||
if url not in coveredUrls:
|
||||
coveredUrls[ url ] = set()
|
||||
coveredUrls[ url ].add( verb )
|
||||
|
||||
def dumpRepository( self, r ):
|
||||
print r.owner.login + "/" + r.name
|
||||
print " Collaborators:", ", ".join( u.login for u in r.get_collaborators() )
|
||||
print " Contributors:", ", ".join( u.login for u in r.get_contributors() )
|
||||
print " Watchers:", ", ".join( u.login for u in r.get_watchers() )
|
||||
print " Forks:", ", ".join( f.owner.login + "/" + f.name for f in r.get_forks() )
|
||||
print " Languages:", r.get_languages()
|
||||
print " Downloads:", ", ".join( d.name for d in r.get_downloads() )
|
||||
print " Tags:", ", ".join( t.name + " (" + t.commit.sha + ")" for t in r.get_tags() )
|
||||
print " Branches:", ", ".join( b.name + " (" + b.commit.sha + ")" for b in r.get_branches() )
|
||||
print " Commits:", ", ".join( c.commit.message + " (" + str( c.stats ) + " ".join( comment.body for comment in c.get_comments() ) + ")" for c in r.get_commits()[ : 10 ] )
|
||||
print " Git references:", ", ".join( ref.ref + " (" + ref.object[ "sha" ][ :7 ] + ")" for ref in r.get_git_refs() )
|
||||
masterCommitSha = r.get_git_ref( "refs/heads/master" ).object[ "sha" ]
|
||||
masterCommit = r.get_git_commit( masterCommitSha )
|
||||
masterTreeSha = masterCommit.tree[ "sha" ]
|
||||
masterTree = r.get_git_tree( masterTreeSha )
|
||||
uncoveredMethods = set()
|
||||
uncoveredApis = set()
|
||||
with open( "ReferenceOfApis.md" ) as file:
|
||||
for line in file.readlines():
|
||||
line = line.strip()
|
||||
if line.startswith( "API" ):
|
||||
currentApi = line[ 5 : -1 ]
|
||||
apiRegex = re.sub( ":\w+", "\w+", currentApi )
|
||||
if line.startswith( "* " ):
|
||||
verb = line[ 2 : line.find( ":" ) ]
|
||||
for url, verbs in coveredUrls.iteritems():
|
||||
if re.match( apiRegex, url ) and verb in verbs:
|
||||
break
|
||||
else:
|
||||
if "`" in line:
|
||||
uncoveredMethods.add( line[ line.find( "`" ) + 1 : -1 ] )
|
||||
else:
|
||||
uncoveredApis.add( verb + " " + currentApi )
|
||||
|
||||
print
|
||||
if len( uncoveredMethods ) != 0:
|
||||
print "Not covered (" + str( len( uncoveredMethods ) ) + "):"
|
||||
print "\n".join( sorted( uncoveredMethods ) )
|
||||
if len( uncoveredApis ) != 0:
|
||||
print "Not implemented (" + str( len( uncoveredApis ) ) + "):"
|
||||
print "\n".join( sorted( uncoveredApis ) )
|
||||
|
||||
def testAuthenticatedUserDetails( self ):
|
||||
u = self.g.get_user()
|
||||
self.printList( "Organizations", u.get_orgs(), lambda o: o.login )
|
||||
|
||||
def testColaborators( self ):
|
||||
r = self.g.get_user().get_repo( "TestPyGithub" )
|
||||
cobaye = self.g.get_user( self.cobayeUser )
|
||||
self.printList( "Collaborators", r.get_collaborators(), lambda m: m.login )
|
||||
r.add_to_collaborators( cobaye )
|
||||
assert r.has_in_collaborators( cobaye )
|
||||
self.printList( "Collaborators", r.get_collaborators(), lambda m: m.login )
|
||||
r.remove_from_collaborators( cobaye )
|
||||
assert not r.has_in_collaborators( cobaye )
|
||||
self.printList( "Collaborators", r.get_collaborators(), lambda m: m.login )
|
||||
|
||||
def testCommentCommit( self ):
|
||||
r = self.g.get_user().get_repo( "TestPyGithub" )
|
||||
c = r.get_commits()[ 0 ]
|
||||
self.printList( "Comments", c.get_comments(), lambda c: c.body )
|
||||
com1 = c.create_comment( "Comment created by PyGithub" )
|
||||
self.printList( "Comments", c.get_comments(), lambda c: c.body )
|
||||
com2 = c.create_comment( "Comment also created by PyGithub", path = "ReadMe.md", line = 1 )
|
||||
self.printList( "Comments", c.get_comments(), lambda c: c.body )
|
||||
com2.delete()
|
||||
com1.edit( body = "Comment edited by PyGithub" )
|
||||
self.printList( "Comments", c.get_comments(), lambda c: c.body )
|
||||
|
||||
def testCreateForkForOrganization( self ):
|
||||
o = self.g.get_organization( self.cobayeOrganization )
|
||||
r = self.g.get_user().get_repo( "TestPyGithub" )
|
||||
rf = o.create_fork( r )
|
||||
print r.owner.login + "/" + r.name, "->", rf.owner.login + "/" + rf.name
|
||||
|
||||
def testCreateRepoForOrganization( self ):
|
||||
o = self.g.get_organization( self.cobayeOrganization )
|
||||
self.printList( "Repos", o.get_repos(), lambda r: r.name )
|
||||
r = o.create_repo( "CreatedByPyGithub", has_wiki = False )
|
||||
self.printList( "Repos", o.get_repos(), lambda r: r.name )
|
||||
|
||||
def testCreateRepoForUser( self ):
|
||||
u = self.g.get_user()
|
||||
self.printList( "Repos", u.get_repos(), lambda r: r.name )
|
||||
r = u.create_repo( "CreatedByPyGithub", has_wiki = False )
|
||||
self.printList( "Repos", u.get_repos(), lambda r: r.name )
|
||||
|
||||
def testDownloads( self ):
|
||||
r = self.g.get_user().get_repo( "TestPyGithub" )
|
||||
self.printList( "Downloads", r.get_downloads(), lambda d: d.name )
|
||||
d = r.create_download( "DownloadCreatedByPyGithub.txt", 1024 )
|
||||
self.printList( "Downloads", r.get_downloads(), lambda d: d.name )
|
||||
sameDownload = r.get_download( d.id )
|
||||
sameDownload.delete()
|
||||
self.printList( "Downloads", r.get_downloads(), lambda d: d.name )
|
||||
|
||||
def testEditAuthenticatedUser( self ):
|
||||
u = self.g.get_user()
|
||||
originalName = u.name
|
||||
print u.name
|
||||
u.edit( name = u.name + " (edited by PyGithub)" )
|
||||
print u.name
|
||||
u.edit( name = originalName )
|
||||
print u.name
|
||||
|
||||
def testEditOrganization( self ):
|
||||
o = self.g.get_organization( self.cobayeOrganization )
|
||||
originalName = o.name
|
||||
print o.name
|
||||
o.edit( name = str( o.name ) + " (edited by PyGithub)" )
|
||||
print o.name
|
||||
o.edit( name = originalName )
|
||||
print o.name
|
||||
|
||||
def testEditOrganizationTeamAndMembers( self ):
|
||||
o = self.g.get_organization( self.cobayeOrganization )
|
||||
r = o.get_repo( "TestPyGithub" )
|
||||
|
||||
self.printList( "Teams", o.get_teams(), lambda t: t.name )
|
||||
t = o.create_team( "PyGithubTesters" )
|
||||
t.edit( "PyGithubTesters", permission = "push" )
|
||||
self.printList( "Teams", o.get_teams(), lambda t: t.name )
|
||||
|
||||
u = self.g.get_user( self.cobayeUser )
|
||||
|
||||
self.printList( "Team members", t.get_members(), lambda m: m.login )
|
||||
self.printList( "Team repos", t.get_repos(), lambda r: r.name )
|
||||
assert not t.has_in_repos( r )
|
||||
assert not t.has_in_members( u )
|
||||
t.add_to_members( u )
|
||||
t.add_to_repos( r )
|
||||
assert t.has_in_repos( r )
|
||||
assert t.has_in_members( u )
|
||||
self.printList( "Team members", t.get_members(), lambda m: m.login )
|
||||
self.printList( "Team repos", t.get_repos(), lambda r: r.name )
|
||||
|
||||
self.printList( "Public members", o.get_public_members(), lambda m: m.login )
|
||||
o.add_to_public_members( u )
|
||||
assert o.has_in_public_members( u )
|
||||
self.printList( "Public members", o.get_public_members(), lambda m: m.login )
|
||||
o.remove_from_public_members( u )
|
||||
assert not o.has_in_public_members( u )
|
||||
self.printList( "Public members", o.get_public_members(), lambda m: m.login )
|
||||
|
||||
self.printList( "Members", o.get_members(), lambda m: m.login )
|
||||
assert o.has_in_members( u )
|
||||
o.remove_from_members( u )
|
||||
assert not o.has_in_members( u )
|
||||
self.printList( "Members", o.get_members(), lambda m: m.login )
|
||||
|
||||
self.printList( "Team members", t.get_members(), lambda m: m.login )
|
||||
self.printList( "Team repos", t.get_repos(), lambda r: r.name )
|
||||
t.remove_from_members( u )
|
||||
t.remove_from_repos( r )
|
||||
assert not t.has_in_repos( r )
|
||||
assert not t.has_in_members( u )
|
||||
self.printList( "Team members", t.get_members(), lambda m: m.login )
|
||||
self.printList( "Team repos", t.get_repos(), lambda r: r.name )
|
||||
|
||||
t.delete()
|
||||
self.printList( "Teams", o.get_teams(), lambda t: t.name )
|
||||
|
||||
def testEvents( self ):
|
||||
self.printList( "User events", self.g.get_user( self.cobayeUser ).get_events(), lambda e: e.type )
|
||||
self.printList( "User public events", self.g.get_user( self.cobayeUser ).get_public_events(), lambda e: e.type )
|
||||
self.printList( "User public received events", self.g.get_user( self.cobayeUser ).get_public_received_events(), lambda e: e.type )
|
||||
self.printList( "User received events", self.g.get_user( self.cobayeUser ).get_received_events(), lambda e: e.type )
|
||||
|
||||
self.printList( "Organization events", self.g.get_organization( self.cobayeOrganization ).get_events(), lambda e: e.type )
|
||||
|
||||
self.printList( "User events", self.g.get_user().get_events(), lambda e: e.type )
|
||||
o = self.g.get_organization( self.cobayeOrganization )
|
||||
self.printList( "Organization events", self.g.get_user().get_organization_events( o ), lambda e: e.type )
|
||||
|
||||
self.printList( "Repo events", self.g.get_user().get_repo( "TestPyGithub" ).get_events(), lambda e: e.type )
|
||||
self.printList( "Repo issues events", self.g.get_user().get_repo( "TestPyGithub" ).get_issues_events(), lambda e: e.event )
|
||||
print self.g.get_user().get_repo( "TestPyGithub" ).get_issues_event( 10693379 ).event
|
||||
self.printList( "Repo network events", self.g.get_user().get_repo( "TestPyGithub" ).get_network_events(), lambda e: e.type )
|
||||
|
||||
self.printList( "Issue events", self.g.get_user().get_repo( "TestPyGithub" ).get_issue( 23 ).get_events(), lambda e: e.event )
|
||||
|
||||
def testFollow( self ):
|
||||
cobaye = self.g.get_user( self.cobayeUser )
|
||||
u = self.g.get_user()
|
||||
u.remove_from_following( cobaye )
|
||||
assert not u.has_in_following( cobaye )
|
||||
u.add_to_following( cobaye )
|
||||
assert u.has_in_following( cobaye )
|
||||
self.printList( "Following", u.get_following(), lambda f: f.login )
|
||||
self.printList( "Followers", u.get_followers(), lambda f: f.login )
|
||||
|
||||
def testGists( self ):
|
||||
u = self.g.get_user()
|
||||
self.printList( "Gists", u.get_gists(), lambda g: g.description )
|
||||
g = u.create_gist( public = True, description = "Gist created by PyGithub", files = { "foo.bar": { "content": "This gist was created by PyGithub" } } )
|
||||
self.printList( "Gists", u.get_gists(), lambda g: g.description )
|
||||
g.edit( description = "Gist edited by PyGithub" )
|
||||
self.printList( "Gists", u.get_gists(), lambda g: g.description )
|
||||
|
||||
self.printList( "Starred gists", u.get_starred_gists(), lambda g: g.description )
|
||||
g.set_starred()
|
||||
assert g.is_starred()
|
||||
self.printList( "Starred gists", u.get_starred_gists(), lambda g: g.description )
|
||||
g.reset_starred()
|
||||
self.printList( "Starred gists", u.get_starred_gists(), lambda g: g.description )
|
||||
|
||||
self.printList( "Gist comments", g.get_comments(), lambda c: c.body )
|
||||
c = g.create_comment( "Comment created by PyGithub" )
|
||||
self.printList( "Gist comments", g.get_comments(), lambda c: c.body )
|
||||
c.edit( "Comment edited by PyGithub" )
|
||||
self.printList( "Gist comments", g.get_comments(), lambda c: c.body )
|
||||
sameComment = g.get_comment( c.id )
|
||||
c.delete()
|
||||
self.printList( "Gist comments", g.get_comments(), lambda c: c.body )
|
||||
|
||||
otherGist = self.g.get_gist( 1965703 ).create_fork() # Origin gist picked up randomly
|
||||
self.printList( "Gists", u.get_gists(), lambda g: g.description or "None" )
|
||||
otherGist.delete()
|
||||
self.printList( "Gists", u.get_gists(), lambda g: g.description )
|
||||
|
||||
g.delete()
|
||||
self.printList( "Gists", u.get_gists(), lambda g: g.description )
|
||||
|
||||
def testGitObjects( self ):
|
||||
o = self.g.get_organization( self.cobayeOrganization )
|
||||
r = o.get_repo( "TestPyGithub" )
|
||||
|
||||
masterRef = r.get_git_ref( "refs/heads/master" )
|
||||
masterCommit = r.get_git_commit( masterRef.object[ "sha" ] )
|
||||
masterTree = r.get_git_tree( masterCommit.tree.sha )
|
||||
readmeBlob = None
|
||||
for element in masterTree.tree:
|
||||
if element[ "type" ] == "blob":
|
||||
blobSha = element[ "sha" ]
|
||||
if element[ "path" ] == "ReadMe.md":
|
||||
readmeBlob = r.get_git_blob( element[ "sha" ] )
|
||||
break
|
||||
blob = r.get_git_blob( blobSha )
|
||||
print " Master:", masterCommitSha, masterCommit.message, ", ".join( element[ "path" ] + " (" + element[ "type" ] + ")" for element in masterTree.tree )
|
||||
print " blob:", blob.content, blob.encoding,
|
||||
if blob.encoding == "base64":
|
||||
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() ) + ") (" + ", ".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 " Merge requests:", ", ".join( p.title + "(" + ", ".join( f.filename for f in p.get_files() ) + ")" for p in r.get_pulls() )
|
||||
print
|
||||
sys.stdout.flush()
|
||||
|
||||
IntegrationTest().main()
|
||||
blob = r.create_git_blob( "This blob was created by PyGithub", encoding = "latin1" )
|
||||
tree = r.create_git_tree( [ { "path": "foo.bar", "mode": "100644", "type": "blob", "sha": blob.sha }, { "path": "ReadMe.md", "mode": "100644", "type": "blob", "sha": readmeBlob.sha } ] )
|
||||
commit = r.create_git_commit( "This commit was created by PyGithub", tree.sha, [ masterCommit.sha ] )
|
||||
r.create_git_ref( "refs/heads/previous_master", masterRef.object[ "sha" ] )
|
||||
masterRef.edit( commit.sha )
|
||||
|
||||
tag = r.create_git_tag( "tagCreatedByPyGithub", "This tag was created by PyGithub", commit.sha, "commit" )
|
||||
r.create_git_ref( "refs/tags/tagCreatedByPyGithub", tag.sha )
|
||||
reTag = r.get_git_tag( tag.sha )
|
||||
|
||||
def testHooks( self ):
|
||||
u = self.g.get_user()
|
||||
r = u.get_repo( "TestPyGithub" )
|
||||
|
||||
self.printList( "Hooks", r.get_hooks(), lambda h: h.name + str( h.config ) )
|
||||
h = r.create_hook( "web", { "url": "http://www.invalid.org" } )
|
||||
self.printList( "Hooks", r.get_hooks(), lambda h: h.name + str( h.config ) )
|
||||
h.edit( "web", { "url": "http://www.postbin.org/w5cgjr" } )
|
||||
self.printList( "Hooks", r.get_hooks(), lambda h: h.name + str( h.config ) )
|
||||
|
||||
sameHook = r.get_hook( h.id )
|
||||
|
||||
h.test()
|
||||
|
||||
h.delete()
|
||||
self.printList( "Hooks", r.get_hooks(), lambda h: h.name + str( h.config ) )
|
||||
|
||||
def testIssuesAndMilestones( self ):
|
||||
u = self.g.get_user()
|
||||
r = u.get_repo( "TestPyGithub" )
|
||||
|
||||
self.printList( "Issues", r.get_issues(), lambda i: i.title )
|
||||
i = r.create_issue( "Issue created by PyGithub" )
|
||||
self.printList( "Issues", r.get_issues(), lambda i: i.title )
|
||||
i.edit( body = "Issue edited by PyGithub" )
|
||||
|
||||
self.printList( "Comments on issue", i.get_comments(), lambda c: c.body )
|
||||
c = i.create_comment( "Comment created by PyGithub" )
|
||||
self.printList( "Comments on issue", i.get_comments(), lambda c: c.body )
|
||||
c.edit( "Comment edited by PyGithub" )
|
||||
sameComment = i.get_comment( c.id )
|
||||
self.printList( "Comments on issue", i.get_comments(), lambda c: c.body )
|
||||
c.delete()
|
||||
self.printList( "Comments on issue", i.get_comments(), lambda c: c.body )
|
||||
|
||||
self.printList( "Milestones", r.get_milestones(), lambda m: m.title )
|
||||
m = r.create_milestone( "Milestone created by PyGithub" )
|
||||
self.printList( "Milestones", r.get_milestones(), lambda m: m.title )
|
||||
m.edit( title = "Milestone edited by PyGithub" )
|
||||
self.printList( "Milestones", r.get_milestones(), lambda m: m.title )
|
||||
|
||||
self.printList( "Issues of milestone", r.get_issues( milestone = m.number ), lambda i: i.title )
|
||||
i.edit( milestone = m.number )
|
||||
self.printList( "Issues of milestone", r.get_issues( milestone = m.number ), lambda i: i.title )
|
||||
|
||||
self.printList( "Repository labels", r.get_labels(), lambda l: l.name )
|
||||
labelD = r.create_label( "D", "FF0000" )
|
||||
self.printList( "Repository labels", r.get_labels(), lambda l: l.name )
|
||||
labelD.edit( "Dada", "00FF00" )
|
||||
self.printList( "Repository labels", r.get_labels(), lambda l: l.name )
|
||||
labelD.delete()
|
||||
self.printList( "Repository labels", r.get_labels(), lambda l: l.name )
|
||||
|
||||
labelA = r.get_label( "bug" )
|
||||
labelB = r.get_label( "duplicate" )
|
||||
labelC = r.get_label( "invalid" )
|
||||
|
||||
self.printList( "Labels", i.get_labels(), lambda l: l.name )
|
||||
i.set_labels( labelA, labelB )
|
||||
self.printList( "Labels", i.get_labels(), lambda l: l.name )
|
||||
i.remove_from_labels( labelB )
|
||||
self.printList( "Labels", i.get_labels(), lambda l: l.name )
|
||||
i.delete_labels()
|
||||
self.printList( "Labels", i.get_labels(), lambda l: l.name )
|
||||
i.add_to_labels( labelB, labelC )
|
||||
self.printList( "Labels", i.get_labels(), lambda l: l.name )
|
||||
|
||||
self.printList( "Milestone labels", r.get_milestone( m.number ).get_labels(), lambda l: l.name )
|
||||
|
||||
m.delete()
|
||||
self.printList( "Milestones", r.get_milestones(), lambda m: m.title )
|
||||
|
||||
def testKeys( self ):
|
||||
u = self.g.get_user()
|
||||
self.printList( "Keys", u.get_keys(), lambda k: k.title )
|
||||
k = u.create_key( u.login + "@PyGithub", "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAvborozfBBn2a+JETqPekTWZ1tmYjpfH9wTKFPLjIXQmxXjNye6HVgvi+iMI436RdoLsPEFDe3cjrQ6CJa7KzhRJKNTPh5EZbKI13CXfMGr7V1i3tOokXBFSRQKnDx2dj2hnswqxGUk2jXpgC/KA1q71yqnL45CBlWr50eDpwUIEPnmqSrPpRV/0ZGwIlh4o7+6HwPUF9aBhWj945WSkjZubR4UFWlDZl7ROafpkJHs2cQzaxtmBOZnu6dzmfyro0zJsvhZKD2K6d9eKgpDeKaw5rWr6FeOZPd4xyDaV1gctG0YEui8uuSPKhpcykgREUAFf+vmOKt+yXnOoq8P4vIQ==" )
|
||||
self.printList( "Keys", u.get_keys(), lambda k: k.title )
|
||||
k.edit( title = u.login + "@PyGithub2" )
|
||||
k = u.get_key( k.id )
|
||||
self.printList( "Keys", u.get_keys(), lambda k: k.title )
|
||||
k.delete()
|
||||
self.printList( "Keys", u.get_keys(), lambda k: k.title )
|
||||
|
||||
def testMergePullRequest( self ):
|
||||
r = self.g.get_user().get_repo( "TestPyGithub" )
|
||||
p = r.get_pull( 26 )
|
||||
assert not p.is_merged()
|
||||
p.merge()
|
||||
assert p.is_merged()
|
||||
|
||||
def testNamedUserDetails( self ):
|
||||
u = self.g.get_user( "jacquev6" )
|
||||
print u.login, "(" + u.name + ") is from", u.location
|
||||
self.printList( "Repos", u.get_repos(), lambda r: r.name )
|
||||
self.printList( "Followers", u.get_followers(), lambda m: m.login )
|
||||
self.printList( "Following", u.get_following(), lambda m: m.login )
|
||||
self.printList( "Watched", u.get_watched(), lambda r: r.owner.login + "/" + r.name )
|
||||
self.printList( "Organizations", u.get_orgs(), lambda o: o.login )
|
||||
self.printList( "Gists", u.get_gists(), lambda g: g.description )
|
||||
|
||||
def testOrganizationDetails( self ):
|
||||
o = self.g.get_organization( "github" )
|
||||
print o.login, "(" + o.name + ") is in", o.location
|
||||
|
||||
def testPullRequest( self ):
|
||||
r = self.g.get_user().get_repo( "TestPyGithub" )
|
||||
self.printList( "Pull requests", r.get_pulls(), lambda p: p.title )
|
||||
p1 = r.create_pull( "Pull request created by PyGithub", "", "master", "BeaverSoftware:master" )
|
||||
self.printList( "Pull requests", r.get_pulls(), lambda p: p.title )
|
||||
p1.edit( state = "closed" )
|
||||
self.printList( "Pull requests", r.get_pulls(), lambda p: p.title )
|
||||
p2 = r.create_pull( "Pull request also created by PyGithub", "", "master", "BeaverSoftware:master" )
|
||||
self.printList( "Pull requests", r.get_pulls(), lambda p: p.title )
|
||||
self.printList( "Files", p2.get_files(), lambda f: f.filename )
|
||||
self.printList( "Commits", p2.get_commits(), lambda c: c.commit.message )
|
||||
self.printList( "Comments", p2.get_comments(), lambda c: c.body )
|
||||
com = p2.create_comment( "Comment created by PyGithub", "e4e84560cb5e87f3c0e9f710dae1ddab0eef487b", "foo.bar", 1 )
|
||||
self.printList( "Comments", p2.get_comments(), lambda c: c.body )
|
||||
com.edit( body = "Comment edited by PyGithub" )
|
||||
self.printList( "Comments", p2.get_comments(), lambda c: c.body )
|
||||
sameCom = p2.get_comment( com.id )
|
||||
sameCom.delete()
|
||||
self.printList( "Comments", p2.get_comments(), lambda c: c.body )
|
||||
p2.edit( state = "closed" )
|
||||
self.printList( "Pull requests", r.get_pulls(), lambda p: p.title )
|
||||
|
||||
def testRepositoryDetails( self ):
|
||||
r1 = self.g.get_user().get_repo( "PyGithub" )
|
||||
r2 = self.g.get_user().get_repo( "TestPyGithub" )
|
||||
self.printList( "Branches", r1.get_branches(), lambda b: b.name )
|
||||
self.printList( "Comments", r2.get_comments(), lambda c: c.body )
|
||||
r2.get_comment( r2.get_comments()[ 0 ].id )
|
||||
self.printList( "Contributors", r1.get_contributors(), lambda m: m.login )
|
||||
self.printList( "Forks", r2.get_forks(), lambda r: r.owner.login )
|
||||
print "Languages:", r1.get_languages()
|
||||
self.printList( "Tags", r1.get_tags(), lambda t: t.name )
|
||||
self.printList( "Watchers", r1.get_watchers(), lambda m: m.login )
|
||||
|
||||
r3 = self.g.get_organization( "BeaverSoftware" ).get_repo( "TestPyGithub" )
|
||||
self.printList( "Teams", r3.get_teams(), lambda t: t.name )
|
||||
|
||||
def testRepositoryKeys( self ):
|
||||
r = self.g.get_user().get_repo( "TestPyGithub" )
|
||||
self.printList( "Keys", r.get_keys(), lambda k: k.title )
|
||||
k = r.create_key( "Key created by PyGithub", "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAvborozfBBn2a+JETqPekTWZ1tmYjpfH9wTKFPLjIXQmxXjNye6HVgvi+iMI436RdoLsPEFDe3cjrQ6CJa7KzhRJKNTPh5EZbKI13CXfMGr7V1i3tOokXBFSRQKnDx2dj2hnswqxGUk2jXpgC/KA1q71yqnL45CBlWr50eDpwUIEPnmqSrPpRV/0ZGwIlh4o7+6HwPUF9aBhWj945WSkjZubR4UFWlDZl7ROafpkJHs2cQzaxtmBOZnu6dzmfyro0zJsvhZKD2K6d9eKgpDeKaw5rWr6FeOZPd4xyDaV1gctG0YEui8uuSPKhpcykgREUAFf+vmOKt+yXnOoq8P4vIQ==" )
|
||||
self.printList( "Keys", r.get_keys(), lambda k: k.title )
|
||||
k.edit( "Key edited by PyGithub", "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAvborozfBBn2a+JETqPekTWZ1tmYjpfH9wTKFPLjIXQmxXjNye6HVgvi+iMI436RdoLsPEFDe3cjrQ6CJa7KzhRJKNTPh5EZbKI13CXfMGr7V1i3tOokXBFSRQKnDx2dj2hnswqxGUk2jXpgC/KA1q71yqnL45CBlWr50eDpwUIEPnmqSrPpRV/0ZGwIlh4o7+6HwPUF9aBhWj945WSkjZubR4UFWlDZl7ROafpkJHs2cQzaxtmBOZnu6dzmfyro0zJsvhZKD2K6d9eKgpDeKaw5rWr6FeOZPd4xyDaV1gctG0YEui8uuSPKhpcykgREUAFf+vmOKt+yXnOoq8P4vIQ==" )
|
||||
self.printList( "Keys", r.get_keys(), lambda k: k.title )
|
||||
sameKey = r.get_key( k.id )
|
||||
sameKey.delete()
|
||||
self.printList( "Keys", r.get_keys(), lambda k: k.title )
|
||||
|
||||
def testWatch( self ):
|
||||
r = self.g.get_user( "jacquev6" ).get_repo( "PyGithub" )
|
||||
u = self.g.get_user()
|
||||
u.remove_from_watched( r )
|
||||
assert not u.has_in_watched( r )
|
||||
u.add_to_watched( r )
|
||||
assert u.has_in_watched( r )
|
||||
self.printList( "Watched", u.get_watched(), lambda r: r.name )
|
||||
|
||||
def testEmails( self ):
|
||||
u = self.g.get_user()
|
||||
self.printList( "Emails", u.get_emails() )
|
||||
u.add_to_emails( "ab@xxx.com", "cd@xxx.com" )
|
||||
self.printList( "Emails", u.get_emails() )
|
||||
u.remove_from_emails( "ab@xxx.com", "cd@xxx.com" )
|
||||
self.printList( "Emails", u.get_emails() )
|
||||
|
||||
def printList( self, title, iterable, f = lambda x: x ):
|
||||
print title + ":", ", ".join( str( f( x ) ) for x in iterable[ :10 ] ), "..." if len( iterable ) > 10 else ""
|
||||
|
||||
IntegrationTest().main( sys.argv[ 1: ] )
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
This is a Python library to access the [Gitub API v3](http://developer.github.com/v3).
|
||||
This is a Python library to access the [Github API v3](http://developer.github.com/v3).
|
||||
|
||||
With it, you can manage your Github resources (repositories, user profiles, organizations, etc.) from Python scripts.
|
||||
|
||||
|
||||
+56
-56
@@ -1,57 +1,57 @@
|
||||
API `/authorizations`
|
||||
=====================
|
||||
* GET: (TODO)
|
||||
* POST: (TODO)
|
||||
* GET: `AuthenticatedUser.get_authorizations`
|
||||
* POST: `AuthenticatedUser.create_authorization`
|
||||
|
||||
API `/authorizations/:id`
|
||||
=========================
|
||||
* GET: (TODO)
|
||||
* PATCH: (TODO)
|
||||
* DELETE: (TODO)
|
||||
* GET: `AuthenticatedUser.get_authorization`
|
||||
* PATCH: `Authorization.edit`
|
||||
* DELETE: `Authorization.delete`
|
||||
|
||||
API `/events`
|
||||
=============
|
||||
* GET: (TODO)
|
||||
* GET: `AuthenticatedUser.get_events`
|
||||
|
||||
API `/gists`
|
||||
============
|
||||
* GET: (TODO)
|
||||
* POST: (TODO)
|
||||
|
||||
API `/gists/:gist_id/comments`
|
||||
==============================
|
||||
* GET: (TODO)
|
||||
* POST: (TODO)
|
||||
* GET: `AuthenticatedUser.get_gists`
|
||||
* POST: `AuthenticatedUser.create_gist`
|
||||
|
||||
API `/gists/:id`
|
||||
================
|
||||
* GET: (TODO)
|
||||
* PATCH: (TODO)
|
||||
* DELETE: (TODO)
|
||||
* 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)
|
||||
* POST: `Gist.create_fork`
|
||||
|
||||
API `/gists/:id/star`
|
||||
=====================
|
||||
* GET: (TODO)
|
||||
* PUT: (TODO)
|
||||
* DELETE: (TODO)
|
||||
* GET: `Gist.is_starred`
|
||||
* PUT: `Gist.set_starred`
|
||||
* DELETE: `Gist.reset_starred`
|
||||
|
||||
API `/gists/comments/:id`
|
||||
=========================
|
||||
* GET: (TODO)
|
||||
* PATCH: (TODO)
|
||||
* DELETE: (TODO)
|
||||
* GET: `Gist.get_comment`
|
||||
* PATCH: `GistComment.edit`
|
||||
* DELETE: `GistComment.delete`
|
||||
|
||||
API `/gists/public`
|
||||
===================
|
||||
* GET: (TODO)
|
||||
* 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)
|
||||
* GET: `AuthenticatedUser.get_starred_gists`
|
||||
|
||||
API `/issues`
|
||||
=============
|
||||
@@ -59,7 +59,7 @@ API `/issues`
|
||||
|
||||
API `/networks/:user/:repo/events`
|
||||
==================================
|
||||
* GET: (TODO)
|
||||
* GET: `Repository.get_network_events`
|
||||
|
||||
API `/orgs/:org`
|
||||
================
|
||||
@@ -68,7 +68,7 @@ API `/orgs/:org`
|
||||
|
||||
API `/orgs/:org/events`
|
||||
=======================
|
||||
* GET: (TODO)
|
||||
* GET: `Organization.get_events`
|
||||
|
||||
API `/orgs/:org/members`
|
||||
========================
|
||||
@@ -161,7 +161,7 @@ API `/repos/:user/:repo/downloads/:id`
|
||||
|
||||
API `/repos/:user/:repo/events`
|
||||
===============================
|
||||
* GET: (TODO)
|
||||
* GET: `Repository.get_events`
|
||||
|
||||
API `/repos/:user/:repo/forks`
|
||||
==============================
|
||||
@@ -208,7 +208,7 @@ API `/repos/:user/:repo/git/trees`
|
||||
|
||||
API `/repos/:user/:repo/git/trees?base_tree=`
|
||||
=============================================
|
||||
* POST: `GitTree.create_update` (TODO)
|
||||
* POST: (TODO)
|
||||
|
||||
API `/repos/:user/:repo/git/trees/:sha`
|
||||
=======================================
|
||||
@@ -220,18 +220,18 @@ API `/repos/:user/:repo/git/trees/:sha?recursive=1`
|
||||
|
||||
API `/repos/:user/:repo/hooks`
|
||||
==============================
|
||||
* GET: (TODO)
|
||||
* POST: (TODO)
|
||||
* GET: `Repository.get_hooks`
|
||||
* POST: `Repository.create_hook`
|
||||
|
||||
API `/repos/:user/:repo/hooks/:id`
|
||||
==================================
|
||||
* GET: (TODO)
|
||||
* PATCH: (TODO)
|
||||
* DELETE: (TODO)
|
||||
* GET: `Repository.get_hook`
|
||||
* PATCH: `Hook.edit`
|
||||
* DELETE: `Hook.delete`
|
||||
|
||||
API `/repos/:user/:repo/hooks/:id/test`
|
||||
=======================================
|
||||
* POST: (TODO)
|
||||
* POST: `Hook.test`
|
||||
|
||||
API `/repos/:user/:repo/issues`
|
||||
===============================
|
||||
@@ -261,7 +261,7 @@ API `/repos/:user/:repo/issues/:id/labels/:name`
|
||||
|
||||
API `/repos/:user/:repo/issues/:id/events`
|
||||
==========================================
|
||||
* GET: (TODO)
|
||||
* GET: `Issue.get_events`
|
||||
|
||||
API `/repos/:user/:repo/issues/comments/:id`
|
||||
============================================
|
||||
@@ -271,22 +271,22 @@ API `/repos/:user/:repo/issues/comments/:id`
|
||||
|
||||
API `/repos/:user/:repo/issues/events`
|
||||
======================================
|
||||
* GET: (TODO)
|
||||
* GET: `Repository.get_issues_events`
|
||||
|
||||
API `/repos/:user/:repo/issues/events/:id`
|
||||
==========================================
|
||||
* GET: (TODO)
|
||||
* GET: `Repository.get_issues_event`
|
||||
|
||||
API `/repos/:user/:repo/keys`
|
||||
=============================
|
||||
* GET: (TODO)
|
||||
* POST: (TODO)
|
||||
* GET: `Repository.get_keys`
|
||||
* POST: `Repository.create_key`
|
||||
|
||||
API `/repos/:user/:repo/keys/:id`
|
||||
=================================
|
||||
* GET: (TODO)
|
||||
* PATCH: (TODO)
|
||||
* DELETE: (TODO)
|
||||
* GET: `Repository.get_key`
|
||||
* PATCH: `RepositoryKey.edit`
|
||||
* DELETE: `RepositoryKey.delete`
|
||||
|
||||
API `/repos/:user/:repo/labels`
|
||||
===============================
|
||||
@@ -343,8 +343,8 @@ API `/repos/:user/:repo/pulls/:id/files`
|
||||
|
||||
API `/repos/:user/:repo/pulls/:id/merge`
|
||||
========================================
|
||||
* GET: (TODO)
|
||||
* PUT: (TODO)
|
||||
* GET: `PullRequest.is_merged`
|
||||
* PUT: `PullRequest.merge`
|
||||
|
||||
API `/repos/:user/:repo/pulls/comments/:id`
|
||||
===========================================
|
||||
@@ -417,14 +417,14 @@ API `/user/following/:user`
|
||||
|
||||
API `/user/keys`
|
||||
================
|
||||
* GET: (TODO)
|
||||
* POST: (TODO)
|
||||
* GET: `AuthenticatedUser.get_keys`
|
||||
* POST: `AuthenticatedUser.create_key`
|
||||
|
||||
API `/user/keys/:id`
|
||||
====================
|
||||
* GET: (TODO)
|
||||
* PATCH: (TODO)
|
||||
* DELETE: (TODO)
|
||||
* GET: `AuthenticatedUser.get_key`
|
||||
* PATCH: `UserKey.edit`
|
||||
* DELETE: `UserKey.delete`
|
||||
|
||||
API `/user/orgs`
|
||||
================
|
||||
@@ -451,15 +451,15 @@ API `/users/:user`
|
||||
|
||||
API `/users/:user/events`
|
||||
=========================
|
||||
* GET: (TODO)
|
||||
* GET: `NamedUser.get_events`
|
||||
|
||||
API `/users/:user/events/orgs/:org`
|
||||
===================================
|
||||
* GET: (TODO)
|
||||
* GET: `AuthenticatedUser.get_organization_events`
|
||||
|
||||
API `/users/:user/events/public`
|
||||
================================
|
||||
* GET: (TODO)
|
||||
* GET: `NamedUser.get_public_events`
|
||||
|
||||
API `/users/:user/followers`
|
||||
============================
|
||||
@@ -471,7 +471,7 @@ API `/users/:user/following`
|
||||
|
||||
API `/users/:user/gists`
|
||||
========================
|
||||
* GET: (TODO)
|
||||
* GET: `NamedUser.get_gists`
|
||||
|
||||
API `/users/:user/orgs`
|
||||
=======================
|
||||
@@ -479,11 +479,11 @@ API `/users/:user/orgs`
|
||||
|
||||
API `/users/:user/received_events`
|
||||
==================================
|
||||
* GET: (TODO)
|
||||
* GET: `NamedUser.get_received_events`
|
||||
|
||||
API `/users/:user/received_events/public`
|
||||
=========================================
|
||||
* GET: (TODO)
|
||||
* GET: `NamedUser.get_public_received_events`
|
||||
|
||||
API `/users/:user/repos`
|
||||
========================
|
||||
|
||||
+229
-4
@@ -58,6 +58,22 @@ Emails
|
||||
* `remove_from_emails( email, ... )`
|
||||
* `email`: string
|
||||
|
||||
Authorizations
|
||||
--------------
|
||||
* `get_authorizations()`: list of `Authorization`
|
||||
* `get_authorization( id )`: `Authorization`
|
||||
* `create_authorization( [scopes, note, note_url] )`: `Authorization`
|
||||
|
||||
Keys
|
||||
----
|
||||
* `get_keys()`: list of `UserKey`
|
||||
* `get_key( id )`: `UserKey`
|
||||
* `create_key( title, key )`: `UserKey`
|
||||
|
||||
Events
|
||||
------
|
||||
* `get_events()`: list of `Event`
|
||||
|
||||
Followers
|
||||
---------
|
||||
* `get_followers()`: list of `NamedUser`
|
||||
@@ -96,6 +112,35 @@ Forking
|
||||
-------
|
||||
* `create_fork( repo )`: `Repository`
|
||||
|
||||
Gists
|
||||
-----
|
||||
* `get_gists()`: list of `Gist`
|
||||
* `create_gist( public, files, [description] )`: `Gist`
|
||||
* `get_starred_gists()`: list of `Gist`
|
||||
|
||||
Class `Authorization`
|
||||
=====================
|
||||
|
||||
Attributes
|
||||
----------
|
||||
* `id`
|
||||
* `url`
|
||||
* `scopes`
|
||||
* `token`
|
||||
* `app`
|
||||
* `note`
|
||||
* `note_url`
|
||||
* `updated_at`
|
||||
* `created_at`
|
||||
|
||||
Modification
|
||||
------------
|
||||
* `edit( [scopes, add_scopes, remove_scopes, note, note_url] )`
|
||||
|
||||
Deletion
|
||||
--------
|
||||
* `delete()`
|
||||
|
||||
Class `Branch`
|
||||
==============
|
||||
|
||||
@@ -121,7 +166,7 @@ Attributes
|
||||
Comments
|
||||
--------
|
||||
* `get_comments()`: list of `CommitComment`
|
||||
* `create_comment( body, commit_id, line, path, position )`: `CommitComment`
|
||||
* `create_comment( body, [commit_id, line, path, position] )`: `CommitComment`
|
||||
|
||||
Class `CommitComment`
|
||||
=====================
|
||||
@@ -178,6 +223,83 @@ Deletion
|
||||
--------
|
||||
* `delete()`
|
||||
|
||||
Class `Event`
|
||||
=============
|
||||
|
||||
Attributes
|
||||
----------
|
||||
* `type`
|
||||
* `public`
|
||||
* `payload`
|
||||
* `created_at`
|
||||
* `repo`: `Repository`
|
||||
* `actor`: `NamedUser`
|
||||
* `org`: `Organization`
|
||||
|
||||
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`
|
||||
===============
|
||||
|
||||
@@ -197,10 +319,10 @@ Attributes
|
||||
* `sha`
|
||||
* `url`
|
||||
* `message`
|
||||
* `parents`
|
||||
* `author`
|
||||
* `committer`
|
||||
* `tree`
|
||||
* `parents`
|
||||
* `tree`: `GitTree`
|
||||
|
||||
Class `GitRef`
|
||||
==============
|
||||
@@ -236,6 +358,33 @@ Attributes
|
||||
* `url`
|
||||
* `tree`
|
||||
|
||||
Class `Hook`
|
||||
============
|
||||
|
||||
Attributes
|
||||
----------
|
||||
* `url`
|
||||
* `updated_at`
|
||||
* `created_at`
|
||||
* `name`
|
||||
* `events`
|
||||
* `active`
|
||||
* `config`
|
||||
* `id`
|
||||
* `last_response`
|
||||
|
||||
Modification
|
||||
------------
|
||||
* `edit( name, config, [events, add_events, remove_events, active] )`
|
||||
|
||||
Deletion
|
||||
--------
|
||||
* `delete()`
|
||||
|
||||
Testing
|
||||
-------
|
||||
* `test()`
|
||||
|
||||
Class `Issue`
|
||||
=============
|
||||
|
||||
@@ -280,6 +429,10 @@ Comments
|
||||
* `get_comment( id )`: `IssueComment`
|
||||
* `create_comment( body )`: `IssueComment`
|
||||
|
||||
Events
|
||||
------
|
||||
* `get_events()`: list of `Event`
|
||||
|
||||
Class `IssueComment`
|
||||
====================
|
||||
|
||||
@@ -385,6 +538,13 @@ Following
|
||||
---------
|
||||
* `get_following()`: list of `NamedUser`
|
||||
|
||||
Events
|
||||
------
|
||||
* `get_events()`: list of `Event`
|
||||
* `get_public_events()`: list of `Event`
|
||||
* `get_received_events()`: list of `Event`
|
||||
* `get_public_received_events()`: list of `Event`
|
||||
|
||||
Orgs
|
||||
----
|
||||
* `get_orgs()`: list of `Organization`
|
||||
@@ -398,6 +558,10 @@ Watched
|
||||
-------
|
||||
* `get_watched()`: list of `Repository`
|
||||
|
||||
Gists
|
||||
-----
|
||||
* `get_gists()`: list of `Gist`
|
||||
|
||||
Class `Organization`
|
||||
====================
|
||||
|
||||
@@ -449,6 +613,10 @@ Members
|
||||
* `has_in_members( member )`: `bool`
|
||||
* `member`: `NamedUser`
|
||||
|
||||
Events
|
||||
------
|
||||
* `get_events()`: list of `Event`
|
||||
|
||||
Repos
|
||||
-----
|
||||
* `get_repos( [type] )`: list of `Repository`
|
||||
@@ -492,6 +660,9 @@ Attributes
|
||||
* `changed_files`
|
||||
* `head`
|
||||
* `base`
|
||||
* `merged_by`
|
||||
* `review_comments`
|
||||
* `user`: `NamedUser`
|
||||
|
||||
Modification
|
||||
------------
|
||||
@@ -586,6 +757,12 @@ Attributes
|
||||
* `parent`: `Repository`
|
||||
* `source`: `Repository`
|
||||
|
||||
Events
|
||||
------
|
||||
* `get_events()`: list of `Event`
|
||||
* `get_network_events()`: list of `Event`
|
||||
* `get_issues_events()`: list of `Event`
|
||||
|
||||
Forks
|
||||
-----
|
||||
* `get_forks()`: list of `Repository`
|
||||
@@ -598,6 +775,18 @@ Languages
|
||||
---------
|
||||
* `get_languages()`: dictionary of strings to integers
|
||||
|
||||
Hooks
|
||||
-----
|
||||
* `get_hooks()`: list of `Hook`
|
||||
* `get_hook( id )`: `Hook`
|
||||
* `create_hook( name, config, [events, active] )`: `Hook`
|
||||
|
||||
Keys
|
||||
----
|
||||
* `get_keys()`: list of `RepositoryKey`
|
||||
* `get_key( id )`: `RepositoryKey`
|
||||
* `create_key( title, key )`: `RepositoryKey`
|
||||
|
||||
Collaborators
|
||||
-------------
|
||||
* `get_collaborators()`: list of `NamedUser`
|
||||
@@ -625,7 +814,7 @@ Git refs
|
||||
Git commits
|
||||
-----------
|
||||
* `get_git_commit( sha )`: `GitCommit`
|
||||
* `create_git_commit( message, tree, parents, [author, commiter] )`: `GitCommit`
|
||||
* `create_git_commit( message, tree, parents, [author, committer] )`: `GitCommit`
|
||||
|
||||
Git trees
|
||||
---------
|
||||
@@ -694,6 +883,24 @@ Teams
|
||||
-----
|
||||
* `get_teams()`: list of `Team`
|
||||
|
||||
Class `RepositoryKey`
|
||||
=====================
|
||||
|
||||
Attributes
|
||||
----------
|
||||
* `url`
|
||||
* `id`
|
||||
* `title`
|
||||
* `key`
|
||||
|
||||
Modification
|
||||
------------
|
||||
* `edit( title, key )`
|
||||
|
||||
Deletion
|
||||
--------
|
||||
* `delete()`
|
||||
|
||||
Class `Tag`
|
||||
===========
|
||||
|
||||
@@ -744,4 +951,22 @@ Repos
|
||||
* `has_in_repos( repo )`: `bool`
|
||||
* `repo`: `Repository`
|
||||
|
||||
Class `UserKey`
|
||||
===============
|
||||
|
||||
Attributes
|
||||
----------
|
||||
* `url`
|
||||
* `id`
|
||||
* `title`
|
||||
* `key`
|
||||
|
||||
Modification
|
||||
------------
|
||||
* `edit( [title, key] )`
|
||||
|
||||
Deletion
|
||||
--------
|
||||
* `delete()`
|
||||
|
||||
|
||||
|
||||
@@ -37,4 +37,70 @@ class TestCase( unittest.TestCase ):
|
||||
self.assertFalse( self.g.get_user().has_in_following( self.g.get_user( "xxx" ) ) )
|
||||
self.assertTrue( self.g.get_user().has_in_following( self.g.get_user( "yyy" ) ) )
|
||||
|
||||
def testGist( self ):
|
||||
self.requester.expect.dataRequest( "GET", "/gists/123456", None, None ).andReturn( { "description": "xxx" } )
|
||||
g = self.g.get_gist( 123456 )
|
||||
self.assertEqual( g.description, "xxx" )
|
||||
self.requester.expect.statusRequest( "GET", "/gists/123456/star", None, None ).andReturn( 404 )
|
||||
self.assertFalse( g.is_starred() )
|
||||
self.requester.expect.statusRequest( "PUT", "/gists/123456/star", None, None ).andReturn( 204 )
|
||||
g.set_starred()
|
||||
self.requester.expect.statusRequest( "DELETE", "/gists/123456/star", None, None ).andReturn( 204 )
|
||||
g.reset_starred()
|
||||
self.requester.expect.dataRequest( "POST", "/gists/123456/fork", None, None ).andReturn( { "description": "yyy" } )
|
||||
self.assertEqual( g.create_fork().description, "yyy" )
|
||||
self.requester.expect.dataRequest( "GET", "/gists/starred", None, None ).andReturn( [ { "description": "xxx" }, { "description": "yyy" } ] )
|
||||
self.assertEqual( len( self.g.get_user().get_starred_gists() ), 2 )
|
||||
|
||||
def testRepositoryReference( self ):
|
||||
self.requester.expect.dataRequest( "GET", "/user", None, None ).andReturn( { "login": "xxx" } )
|
||||
self.requester.expect.dataRequest( "GET", "/repos/xxx/yyy", None, None ).andReturn( { "name": "yyy", "owner": { "login": "xxx" } } )
|
||||
r = self.g.get_user().get_repo( "yyy" )
|
||||
self.requester.expect.dataRequest( "GET", "/repos/xxx/yyy/milestones/1", None, None ).andReturn( { "number": 1 } )
|
||||
self.requester.expect.dataRequest( "GET", "/repos/xxx/yyy/milestones/1/labels", {}, None ).andReturn( [ { "name": "a" } ] )
|
||||
self.assertIs( r.get_milestone( 1 ).get_labels()[ 0 ]._repo, r )
|
||||
|
||||
def testHooks( self ):
|
||||
self.requester.expect.dataRequest( "GET", "/user", None, None ).andReturn( { "login": "xxx" } )
|
||||
self.requester.expect.dataRequest( "GET", "/repos/xxx/yyy", None, None ).andReturn( { "name": "yyy", "owner": { "login": "xxx" } } )
|
||||
self.requester.expect.dataRequest( "GET", "/repos/xxx/yyy/hooks/1", None, None ).andReturn( { "name": "web", "id": 1 } )
|
||||
h = self.g.get_user().get_repo( "yyy" ).get_hook( 1 )
|
||||
self.requester.expect.statusRequest( "POST", "/repos/xxx/yyy/hooks/1/test", None, None ).andReturn( 204 )
|
||||
h.test()
|
||||
|
||||
def testUserEvents( self ):
|
||||
self.requester.expect.dataRequest( "GET", "/users/xxx", None, None ).andReturn( { "login": "xxx" } )
|
||||
self.requester.expect.dataRequest( "GET", "/users/xxx/events/public", None, None ).andReturn( [] )
|
||||
self.requester.expect.dataRequest( "GET", "/users/xxx/received_events/public", None, None ).andReturn( [] )
|
||||
u = self.g.get_user( "xxx" )
|
||||
u.get_public_events()
|
||||
u.get_public_received_events()
|
||||
|
||||
def testRepoEvents( self ):
|
||||
self.requester.expect.dataRequest( "GET", "/user", None, None ).andReturn( { "login": "xxx" } )
|
||||
self.requester.expect.dataRequest( "GET", "/repos/xxx/yyy", None, None ).andReturn( { "name": "yyy", "owner": { "login": "xxx" } } )
|
||||
self.requester.expect.dataRequest( "GET", "/networks/xxx/yyy/events", None, None ).andReturn( [] )
|
||||
r = self.g.get_user().get_repo( "yyy" )
|
||||
r.get_network_events()
|
||||
|
||||
def testOrgEvents( self ):
|
||||
self.requester.expect.dataRequest( "GET", "/orgs/ooo", None, None ).andReturn( { "login": "ooo" } )
|
||||
self.requester.expect.dataRequest( "GET", "/user", None, None ).andReturn( { "login": "xxx" } )
|
||||
self.requester.expect.dataRequest( "GET", "/users/xxx/events/orgs/ooo", None, None ).andReturn( [] )
|
||||
u = self.g.get_user()
|
||||
o = self.g.get_organization( "ooo" )
|
||||
u.get_organization_events( o )
|
||||
|
||||
def testMergePullRequest( self ):
|
||||
self.requester.expect.dataRequest( "GET", "/user", None, None ).andReturn( { "login": "xxx" } )
|
||||
self.requester.expect.dataRequest( "GET", "/repos/xxx/yyy", None, None ).andReturn( { "name": "yyy", "owner": { "login": "xxx" } } )
|
||||
self.requester.expect.dataRequest( "GET", "/repos/xxx/yyy/pulls/42", None, None ).andReturn( { "number": 42 } )
|
||||
self.requester.expect.statusRequest( "GET", "/repos/xxx/yyy/pulls/42/merge", None, None ).andReturn( 404 )
|
||||
self.requester.expect.statusRequest( "PUT", "/repos/xxx/yyy/pulls/42/merge", None, {} ).andReturn( 204 )
|
||||
self.requester.expect.statusRequest( "GET", "/repos/xxx/yyy/pulls/42/merge", None, None ).andReturn( 204 )
|
||||
p = self.g.get_user().get_repo( "yyy" ).get_pull( 42 )
|
||||
self.assertFalse( p.is_merged() )
|
||||
p.merge()
|
||||
self.assertTrue( p.is_merged() )
|
||||
|
||||
unittest.main()
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -17,6 +17,7 @@ class TestCaseWithGithubTestObject( unittest.TestCase ):
|
||||
unittest.TestCase.setUp( self )
|
||||
self.g = MockMockMock.Mock( "github" )
|
||||
self.o = self.GithubTestObject( self.g.object, { "a1": 1, "a2": 2 }, lazy = True )
|
||||
self.GithubTestObject._autoDocument() # Only for coverage
|
||||
|
||||
def tearDown( self ):
|
||||
self.g.tearDown()
|
||||
@@ -43,6 +44,32 @@ class TestCaseWithGithubTestObject( unittest.TestCase ):
|
||||
def expectStatusDelete( self, url, data = None ):
|
||||
return self.g.expect._statusRequest( "DELETE", url, None, data )
|
||||
|
||||
class GithubObjectWithDocumentationCoveringSpecialCases( TestCaseWithGithubTestObject ):
|
||||
GithubTestObject = GithubObject(
|
||||
"GithubTestObject",
|
||||
BaseUrl( lambda obj: "/test" ),
|
||||
InternalSimpleAttributes( "a1", "a2", "_a3" ),
|
||||
MethodFromCallable( "myMethod", [ "mock", "arg" ], [], lambda obj: 42, ObjectTypePolicy( GithubObject ) ),
|
||||
AttributeFromCallable( "myAttr", lambda obj: 42 )
|
||||
)
|
||||
|
||||
def testNothing( self ):
|
||||
pass
|
||||
|
||||
class GithubObjectWithBaseUrlDependingOnAttribute( TestCaseWithGithubTestObject ):
|
||||
GithubTestObject = GithubObject(
|
||||
"GithubTestObject",
|
||||
BaseUrl( lambda obj: "/test/" + str( obj.a1 ) ),
|
||||
InternalSimpleAttributes( "a1", "a2", "a3", "a4" ),
|
||||
Editable( [ "a1" ], [] )
|
||||
)
|
||||
|
||||
def test( self ):
|
||||
self.expectDataPatch( "/test/1", { "a1": 11 } ).andReturn( { "a1": 110 } )
|
||||
self.expectDataPatch( "/test/110", { "a1": 111 } ).andReturn( { "a1": 1110 } )
|
||||
self.o.edit( 11 )
|
||||
self.o.edit( 111 )
|
||||
|
||||
class GithubObjectWithOnlyInternalSimpleAttributes( TestCaseWithGithubTestObject ):
|
||||
GithubTestObject = GithubObject(
|
||||
"GithubTestObject",
|
||||
@@ -228,6 +255,51 @@ class GithubObjectWithListGetableExternalListOfObjects( TestCaseWithGithubTestOb
|
||||
a3s = self.o.get_a3s( "foobar" )
|
||||
self.assertEqual( len( a3s ), 3 )
|
||||
|
||||
class GithubObjectWithListGetableExternalListOfObjectsWithOtherUrl( TestCaseWithGithubTestObject ):
|
||||
ContainedObject = GithubObject(
|
||||
"ContainedObject",
|
||||
BaseUrl( lambda obj: "/other/" + obj.id ),
|
||||
InternalSimpleAttributes( "id", "name" )
|
||||
)
|
||||
|
||||
GithubTestObject = GithubObject(
|
||||
"GithubTestObject",
|
||||
BaseUrl( lambda obj: "/test" ),
|
||||
InternalSimpleAttributes( "a1", "a2" ),
|
||||
ExternalListOfObjects( "a3s", "a3", ContainedObject, ListGetable( [], [ "type" ] ), url = "/other" )
|
||||
)
|
||||
|
||||
def testGetList( self ):
|
||||
self.expectDataGet( "/other", {} ).andReturn( [ { "id": "id1" }, { "id": "id2" }, { "id": "id3" } ] )
|
||||
a3s = self.o.get_a3s()
|
||||
self.assertEqual( len( a3s ), 3 )
|
||||
self.assertEqual( a3s[ 0 ].id, "id1" )
|
||||
self.expectDataGet( "/other/id1" ).andReturn( { "name": "name1" } )
|
||||
self.assertEqual( a3s[ 0 ].name, "name1" )
|
||||
|
||||
class GithubObjectWithListGetableExternalListOfObjectsWithAttributeModifier( TestCaseWithGithubTestObject ):
|
||||
ContainedObject = GithubObject(
|
||||
"ContainedObject",
|
||||
BaseUrl( lambda obj: "/test/a3s/" + obj.id ),
|
||||
InternalSimpleAttributes( "id", "name", "_a" )
|
||||
)
|
||||
|
||||
GithubTestObject = GithubObject(
|
||||
"GithubTestObject",
|
||||
BaseUrl( lambda obj: "/test" ),
|
||||
InternalSimpleAttributes( "a1", "a2" ),
|
||||
ExternalListOfObjects( "a3s", "a3", ContainedObject, ListGetable( [], [ "type" ], { "_a": lambda obj: 42 } ) )
|
||||
)
|
||||
|
||||
def testGetList( self ):
|
||||
self.expectDataGet( "/test/a3s", {} ).andReturn( [ { "id": "id1" }, { "id": "id2" }, { "id": "id3" } ] )
|
||||
a3s = self.o.get_a3s()
|
||||
self.assertEqual( len( a3s ), 3 )
|
||||
self.assertEqual( a3s[ 0 ].id, "id1" )
|
||||
self.assertEqual( a3s[ 0 ]._a, 42 )
|
||||
self.expectDataGet( "/test/a3s/id1" ).andReturn( { "name": "name1" } )
|
||||
self.assertEqual( a3s[ 0 ].name, "name1" )
|
||||
|
||||
class GithubObjectWithElementAddableExternalListOfObjects( TestCaseWithGithubTestObject ):
|
||||
ContainedObject = GithubObject(
|
||||
"ContainedObject",
|
||||
|
||||
@@ -21,20 +21,20 @@ def ExternalSimpleAttribute( attributeName, type ):
|
||||
return ExternalAttribute( attributeName, SimpleTypePolicy( type ) )
|
||||
|
||||
def BaseUrl( baseUrl ):
|
||||
return AttributeFromCallable( "_baseUrl", baseUrl )
|
||||
return MethodFromCallable( "_baseUrl", [], [], baseUrl, SimpleTypePolicy( None ) )
|
||||
|
||||
def Identity( identity ):
|
||||
return AttributeFromCallable( "_identity", identity )
|
||||
|
||||
def Editable( mandatoryParameters, optionalParameters ):
|
||||
def __execute( obj, **data ):
|
||||
attributes = obj._github._dataRequest( "PATCH", obj._baseUrl, None, data )
|
||||
attributes = obj._github._dataRequest( "PATCH", obj._baseUrl(), None, data )
|
||||
obj._updateAttributes( attributes )
|
||||
return SeveralAttributePolicies( [ MethodFromCallable( "edit", mandatoryParameters, optionalParameters, __execute, SimpleTypePolicy( None ) ) ], "Modification" )
|
||||
|
||||
def Deletable():
|
||||
def __execute( obj ):
|
||||
obj._github._statusRequest( "DELETE", obj._baseUrl, None, None )
|
||||
obj._github._statusRequest( "DELETE", obj._baseUrl(), None, None )
|
||||
return SeveralAttributePolicies( [ MethodFromCallable( "delete", [], [], __execute, SimpleTypePolicy( None ) ) ], "Deletion" )
|
||||
|
||||
def GithubObject( className, *attributePolicies ):
|
||||
|
||||
+271
-33
@@ -3,6 +3,50 @@ import urllib
|
||||
|
||||
from GithubObject import *
|
||||
|
||||
Event = GithubObject(
|
||||
"Event",
|
||||
InternalSimpleAttributes(
|
||||
"type", "public", "payload", "created_at", "id", "commit_id", "url",
|
||||
"event", "issue",
|
||||
),
|
||||
)
|
||||
|
||||
def __testHook( hook ):
|
||||
hook._github._statusRequest( "POST", hook._baseUrl() + "/test", None, None )
|
||||
Hook = GithubObject(
|
||||
"Hook",
|
||||
BaseUrl( lambda obj: obj._repo._baseUrl() + "/hooks/" + str( obj.id ) ),
|
||||
InternalSimpleAttributes(
|
||||
"url", "updated_at", "created_at", "name", "events", "active", "config",
|
||||
"id", "last_response",
|
||||
"_repo", ### Ugly hack
|
||||
),
|
||||
Editable( [ "name", "config" ], [ "events", "add_events", "remove_events", "active" ] ),
|
||||
Deletable(),
|
||||
SeveralAttributePolicies( [ MethodFromCallable( "test", [], [], __testHook, SimpleTypePolicy( None ) ) ], "Testing" )
|
||||
)
|
||||
|
||||
Authorization = GithubObject(
|
||||
"Authorization",
|
||||
BaseUrl( lambda obj: "/authorizations/" + str( obj.id ) ), ### @todo make the lambda return a tuple, and BaseUrl convert elements to strings and join them with "/"
|
||||
InternalSimpleAttributes(
|
||||
"id", "url", "scopes", "token", "app", "note", "note_url", "updated_at",
|
||||
"created_at",
|
||||
),
|
||||
Editable( [], [ "scopes", "add_scopes", "remove_scopes", "note", "note_url" ] ),
|
||||
Deletable(),
|
||||
)
|
||||
|
||||
UserKey = GithubObject(
|
||||
"UserKey",
|
||||
BaseUrl( lambda obj: "/user/keys/" + str( obj.id ) ),
|
||||
InternalSimpleAttributes(
|
||||
"url", "id", "title", "key",
|
||||
),
|
||||
Editable( [], [ "title", "key" ] ),
|
||||
Deletable(),
|
||||
)
|
||||
|
||||
AuthenticatedUser = GithubObject(
|
||||
"AuthenticatedUser",
|
||||
BaseUrl( lambda obj: "/user" ),
|
||||
@@ -20,6 +64,21 @@ AuthenticatedUser = GithubObject(
|
||||
SeveralElementsAddable(),
|
||||
SeveralElementsRemovable()
|
||||
),
|
||||
ExternalListOfObjects( "authorizations", "authorization", Authorization,
|
||||
ListGetable( [], [] ),
|
||||
ElementGetable( [ "id" ], [] ),
|
||||
ElementCreatable( [], [ "scopes", "note", "note_url" ] ),
|
||||
url = "/authorizations",
|
||||
),
|
||||
ExternalListOfObjects( "keys", "key", UserKey,
|
||||
ListGetable( [], [] ),
|
||||
ElementGetable( [ "id" ], [] ),
|
||||
ElementCreatable( [ "title", "key" ], [] ),
|
||||
),
|
||||
ExternalListOfObjects( "events", "event", Event,
|
||||
ListGetable( [], [] ),
|
||||
url = "/events"
|
||||
),
|
||||
)
|
||||
|
||||
NamedUser = GithubObject(
|
||||
@@ -63,6 +122,34 @@ NamedUser._addAttributePolicy(
|
||||
ListGetable( [], [] )
|
||||
)
|
||||
)
|
||||
NamedUser._addAttributePolicy(
|
||||
ExternalListOfObjects( "events", "event", Event,
|
||||
ListGetable( [], [] )
|
||||
),
|
||||
)
|
||||
def __getPublicEvents( user ):
|
||||
return [
|
||||
Event( user._github, attributes, lazy = True )
|
||||
for attributes
|
||||
in user._github._dataRequest( "GET", user._baseUrl() + "/events/public", None, None )
|
||||
]
|
||||
NamedUser._addAttributePolicy(
|
||||
MethodFromCallable( "get_public_events", [], [], __getPublicEvents, SimpleTypePolicy( "list of `Event`" ) )
|
||||
)
|
||||
NamedUser._addAttributePolicy(
|
||||
ExternalListOfObjects( "received_events", "received_event", Event,
|
||||
ListGetable( [], [] )
|
||||
)
|
||||
)
|
||||
def __getPublicReceivedEvents( user ):
|
||||
return [
|
||||
Event( user._github, attributes, lazy = True )
|
||||
for attributes
|
||||
in user._github._dataRequest( "GET", user._baseUrl() + "/received_events/public", None, None )
|
||||
]
|
||||
NamedUser._addAttributePolicy(
|
||||
MethodFromCallable( "get_public_received_events", [], [], __getPublicReceivedEvents, SimpleTypePolicy( "list of `Event`" ) )
|
||||
)
|
||||
|
||||
Organization = GithubObject(
|
||||
"Organization",
|
||||
@@ -71,7 +158,7 @@ Organization = GithubObject(
|
||||
InternalSimpleAttributes(
|
||||
"login", "id", "url", "avatar_url", "name", "company", "blog",
|
||||
"location", "email", "public_repos", "public_gists", "followers",
|
||||
"following", "html_url", "created_at", "type",
|
||||
"following", "html_url", "created_at", "type", "gravatar_id",
|
||||
# Seen only by owners
|
||||
"disk_usage", "collaborators", "billing_email", "plan", "private_gists",
|
||||
"total_private_repos", "owned_private_repos",
|
||||
@@ -88,6 +175,9 @@ Organization = GithubObject(
|
||||
ElementRemovable(),
|
||||
ElementHasable()
|
||||
),
|
||||
ExternalListOfObjects( "events", "event", Event,
|
||||
ListGetable( [], [] )
|
||||
),
|
||||
)
|
||||
|
||||
AuthenticatedUser._addAttributePolicy(
|
||||
@@ -101,9 +191,19 @@ NamedUser._addAttributePolicy(
|
||||
)
|
||||
)
|
||||
|
||||
def __getOrganizationEvents( user, org ):
|
||||
return [
|
||||
Event( user._github, attributes, lazy = True )
|
||||
for attributes
|
||||
in user._github._dataRequest( "GET", "/users/" + user.login + "/events/orgs/" + org.login, None, None )
|
||||
]
|
||||
AuthenticatedUser._addAttributePolicy(
|
||||
MethodFromCallable( "get_organization_events", [ "org" ], [], __getOrganizationEvents, SimpleTypePolicy( "list of `Event`" ) )
|
||||
)
|
||||
|
||||
GitRef = GithubObject(
|
||||
"GitRef",
|
||||
BaseUrl( lambda obj: obj._repo._baseUrl + "/git/" + obj.ref ),
|
||||
BaseUrl( lambda obj: obj._repo._baseUrl() + "/git/" + obj.ref ),
|
||||
InternalSimpleAttributes(
|
||||
"ref", "url",
|
||||
"object", ### @todo Structure
|
||||
@@ -112,22 +212,9 @@ GitRef = GithubObject(
|
||||
Editable( [ "sha" ], [ "force" ] ),
|
||||
)
|
||||
|
||||
GitCommit = GithubObject(
|
||||
"GitCommit",
|
||||
BaseUrl( lambda obj: obj._repo._baseUrl + "/git/commits/" + obj.sha ),
|
||||
InternalSimpleAttributes(
|
||||
"sha", "url", "message",
|
||||
"author", ### @todo Structure
|
||||
"committer", ### @todo Structure
|
||||
"tree", ### @todo Structure
|
||||
"parents", ### @todo Structure
|
||||
"_repo", ### Ugly hack
|
||||
),
|
||||
)
|
||||
|
||||
GitTree = GithubObject(
|
||||
"GitTree",
|
||||
BaseUrl( lambda obj: obj._repo._baseUrl + "/git/trees/" + obj.sha ),
|
||||
BaseUrl( lambda obj: obj._repo._baseUrl() + "/git/trees/" + obj.sha ),
|
||||
InternalSimpleAttributes(
|
||||
"sha", "url",
|
||||
"tree", ### @todo Structure
|
||||
@@ -135,9 +222,21 @@ GitTree = GithubObject(
|
||||
),
|
||||
)
|
||||
|
||||
GitCommit = GithubObject(
|
||||
"GitCommit",
|
||||
BaseUrl( lambda obj: obj._repo._baseUrl() + "/git/commits/" + obj.sha ),
|
||||
InternalSimpleAttributes(
|
||||
"sha", "url", "message",
|
||||
"parents", ### @todo Structure
|
||||
"author", "committer",
|
||||
"_repo", ### Ugly hack
|
||||
),
|
||||
InternalObjectAttribute( "tree", GitTree ),
|
||||
)
|
||||
|
||||
GitBlob = GithubObject(
|
||||
"GitBlob",
|
||||
BaseUrl( lambda obj: obj._repo._baseUrl + "/git/blobs/" + obj.sha ),
|
||||
BaseUrl( lambda obj: obj._repo._baseUrl() + "/git/blobs/" + obj.sha ),
|
||||
InternalSimpleAttributes(
|
||||
"sha", "size", "url",
|
||||
"content", "encoding",
|
||||
@@ -147,7 +246,7 @@ GitBlob = GithubObject(
|
||||
|
||||
GitTag = GithubObject(
|
||||
"GitTag",
|
||||
BaseUrl( lambda obj: obj._repo._baseUrl + "/git/tags/" + obj.sha ),
|
||||
BaseUrl( lambda obj: obj._repo._baseUrl() + "/git/tags/" + obj.sha ),
|
||||
InternalSimpleAttributes(
|
||||
"tag", "sha", "url",
|
||||
"message",
|
||||
@@ -159,7 +258,7 @@ GitTag = GithubObject(
|
||||
|
||||
Label = GithubObject(
|
||||
"Label",
|
||||
BaseUrl( lambda obj: obj._repo._baseUrl + "/labels/" + obj._identity ),
|
||||
BaseUrl( lambda obj: obj._repo._baseUrl() + "/labels/" + obj._identity ),
|
||||
Identity( lambda obj: urllib.quote( obj.name ) ),
|
||||
InternalSimpleAttributes(
|
||||
"url", "name", "color",
|
||||
@@ -173,7 +272,7 @@ __modifyAttributesForObjectsReferingReferedRepo = { "_repo": lambda obj: obj._re
|
||||
|
||||
Milestone = GithubObject(
|
||||
"Milestone",
|
||||
BaseUrl( lambda obj: obj._repo._baseUrl + "/milestones/" + str( obj.number ) ),
|
||||
BaseUrl( lambda obj: obj._repo._baseUrl() + "/milestones/" + str( obj.number ) ),
|
||||
InternalSimpleAttributes(
|
||||
"url", "number", "state", "title", "description", "open_issues",
|
||||
"closed_issues", "created_at", "due_on",
|
||||
@@ -189,7 +288,7 @@ Milestone = GithubObject(
|
||||
|
||||
IssueComment = GithubObject(
|
||||
"IssueComment",
|
||||
BaseUrl( lambda obj: obj._repo._baseUrl + "/issues/comment" + str( obj.id ) ),
|
||||
BaseUrl( lambda obj: obj._repo._baseUrl() + "/issues/comments/" + str( obj.id ) ),
|
||||
InternalSimpleAttributes(
|
||||
"url", "body", "created_at", "updated_at", "id",
|
||||
"_repo", ### Ugly hack
|
||||
@@ -199,9 +298,19 @@ IssueComment = GithubObject(
|
||||
Deletable(),
|
||||
)
|
||||
|
||||
IssueEvent = GithubObject(
|
||||
"IssueEvent",
|
||||
BaseUrl( lambda obj: obj._repo._baseUrl() + "/issues/events/" + str( obj.id ) ),
|
||||
InternalSimpleAttributes(
|
||||
"id", "url", "created_at", "issue", "event", "commit_id",
|
||||
"_repo", # Ugly hack
|
||||
),
|
||||
InternalObjectAttribute( "actor", NamedUser ),
|
||||
)
|
||||
|
||||
Issue = GithubObject(
|
||||
"Issue",
|
||||
BaseUrl( lambda obj: obj._repo._baseUrl + "/issues/" + str( obj.number ) ),
|
||||
BaseUrl( lambda obj: obj._repo._baseUrl() + "/issues/" + str( obj.number ) ),
|
||||
InternalSimpleAttributes(
|
||||
"url", "html_url", "number", "state", "title", "body", "labels",
|
||||
"comments", "closed_at", "created_at", "updated_at", "id", "closed_by",
|
||||
@@ -224,11 +333,14 @@ Issue = GithubObject(
|
||||
ElementGetable( [ "id" ], [], __modifyAttributesForObjectsReferingReferedRepo ),
|
||||
ElementCreatable( [ "body" ], [], __modifyAttributesForObjectsReferingReferedRepo ),
|
||||
),
|
||||
ExternalListOfObjects( "events", "event", IssueEvent,
|
||||
ListGetable( [], [], __modifyAttributesForObjectsReferingReferedRepo )
|
||||
),
|
||||
)
|
||||
|
||||
Download = GithubObject(
|
||||
"Download",
|
||||
BaseUrl( lambda obj: obj._repo._baseUrl + "/downloads/" + str( obj.id ) ),
|
||||
BaseUrl( lambda obj: obj._repo._baseUrl() + "/downloads/" + str( obj.id ) ),
|
||||
InternalSimpleAttributes(
|
||||
"url", "html_url", "id", "name", "description", "size",
|
||||
"download_count", "content_type", "policy", "signature", "bucket",
|
||||
@@ -241,7 +353,7 @@ Download = GithubObject(
|
||||
|
||||
CommitComment = GithubObject(
|
||||
"CommitComment",
|
||||
BaseUrl( lambda obj: obj._repo._baseUrl + "/comments/" + str( obj.id ) ),
|
||||
BaseUrl( lambda obj: obj._repo._baseUrl() + "/comments/" + str( obj.id ) ),
|
||||
InternalSimpleAttributes(
|
||||
"url", "id", "body", "path", "position", "commit_id",
|
||||
"created_at", "updated_at", "html_url", "line",
|
||||
@@ -254,7 +366,7 @@ CommitComment = GithubObject(
|
||||
|
||||
Commit = GithubObject(
|
||||
"Commit",
|
||||
BaseUrl( lambda obj: obj._repo._baseUrl + "/commits/" + str( obj.sha ) ),
|
||||
BaseUrl( lambda obj: obj._repo._baseUrl() + "/commits/" + str( obj.sha ) ),
|
||||
InternalSimpleAttributes(
|
||||
"sha", "url",
|
||||
"parents", ### @todo Structure
|
||||
@@ -266,8 +378,8 @@ Commit = GithubObject(
|
||||
InternalObjectAttribute( "author", NamedUser ),
|
||||
InternalObjectAttribute( "committer", NamedUser ),
|
||||
ExternalListOfObjects( "comments", "comment", CommitComment,
|
||||
ListGetable( [], [] ),
|
||||
ElementCreatable( [ "body", "commit_id", "line", "path", "position" ], [] ),
|
||||
ListGetable( [], [], __modifyAttributesForObjectsReferingReferedRepo ),
|
||||
ElementCreatable( [ "body" ], [ "commit_id", "line", "path", "position" ], __modifyAttributesForObjectsReferingReferedRepo ),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -300,7 +412,7 @@ PullRequestFile = GithubObject(
|
||||
|
||||
PullRequestComment = GithubObject(
|
||||
"PullRequestComment",
|
||||
BaseUrl( lambda obj: obj._repo._baseUrl + "/pulls/comments/" + str( obj.id ) ),
|
||||
BaseUrl( lambda obj: obj._repo._baseUrl() + "/pulls/comments/" + str( obj.id ) ),
|
||||
InternalSimpleAttributes(
|
||||
"url", "id", "body", "path", "position", "commit_id",
|
||||
"created_at", "updated_at", "html_url", "line",
|
||||
@@ -311,9 +423,13 @@ PullRequestComment = GithubObject(
|
||||
Deletable(),
|
||||
)
|
||||
|
||||
def __pullRequestIsMerged( r ):
|
||||
return r._github._statusRequest( "GET", r._baseUrl() + "/merge", None, None ) == 204
|
||||
def __mergePullRequest( r, **data ):
|
||||
r._github._statusRequest( "PUT", r._baseUrl() + "/merge", None, data )
|
||||
PullRequest = GithubObject(
|
||||
"PullRequest",
|
||||
BaseUrl( lambda obj: obj._repo._baseUrl + "/pulls/" + str( obj.number ) ),
|
||||
BaseUrl( lambda obj: obj._repo._baseUrl() + "/pulls/" + str( obj.number ) ),
|
||||
InternalSimpleAttributes(
|
||||
"id", "url", "html_url", "diff_url", "patch_url", "issue_url", "number",
|
||||
"state", "title", "body", "created_at", "updated_at", "closed_at",
|
||||
@@ -335,6 +451,19 @@ PullRequest = GithubObject(
|
||||
ElementGetable( [ "id" ], [], __modifyAttributesForObjectsReferingReferedRepo ),
|
||||
ElementCreatable( [ "body", "commit_id", "path", "position" ], [], __modifyAttributesForObjectsReferingReferedRepo ),
|
||||
),
|
||||
MethodFromCallable( "is_merged", [], [], __pullRequestIsMerged, SimpleTypePolicy( "bool" ) ),
|
||||
MethodFromCallable( "merge", [], [ "commit_message" ], __mergePullRequest, SimpleTypePolicy( None ) ),
|
||||
)
|
||||
|
||||
RepositoryKey = GithubObject(
|
||||
"RepositoryKey",
|
||||
BaseUrl( lambda obj: obj._repo._baseUrl() + "/keys/" + str( obj.id ) ),
|
||||
InternalSimpleAttributes(
|
||||
"url", "id", "title", "key",
|
||||
"_repo", ### Ugly hack
|
||||
),
|
||||
Editable( [ "title", "key" ], [] ),
|
||||
Deletable()
|
||||
)
|
||||
|
||||
Repository = GithubObject(
|
||||
@@ -354,6 +483,26 @@ Repository = GithubObject(
|
||||
)
|
||||
Repository._addAttributePolicy( InternalObjectAttribute( "parent", Repository ) )
|
||||
Repository._addAttributePolicy( InternalObjectAttribute( "source", Repository ) )
|
||||
Repository._addAttributePolicy(
|
||||
ExternalListOfObjects( "events", "event", Event,
|
||||
ListGetable( [], [] )
|
||||
),
|
||||
)
|
||||
def __getNetworkEvents( repo ):
|
||||
return [
|
||||
Event( repo._github, attributes, lazy = True )
|
||||
for attributes
|
||||
in repo._github._dataRequest( "GET", "/networks/" + repo.owner.login + "/" + repo.name + "/events", None, None )
|
||||
]
|
||||
Repository._addAttributePolicy(
|
||||
MethodFromCallable( "get_network_events", [], [], __getNetworkEvents, SimpleTypePolicy( "list of `Event`" ) )
|
||||
)
|
||||
Repository._addAttributePolicy(
|
||||
ExternalListOfObjects( "issues/events", "issues_event", IssueEvent,
|
||||
ListGetable( [], [], __modifyAttributesForObjectsReferingRepo ),
|
||||
ElementGetable( [ "id" ], [], __modifyAttributesForObjectsReferingRepo ),
|
||||
)
|
||||
)
|
||||
Repository._addAttributePolicy(
|
||||
ExternalListOfObjects( "forks", "fork", Repository,
|
||||
ListGetable( [], [] )
|
||||
@@ -366,6 +515,16 @@ Repository._addAttributePolicy(
|
||||
SeveralAttributePolicies( [ ExternalSimpleAttribute( "languages", "dictionary of strings to integers" ) ], "Languages" )
|
||||
)
|
||||
Repository._addAttributePolicy( SeveralAttributePolicies( [
|
||||
ExternalListOfObjects( "hooks", "hook", Hook,
|
||||
ListGetable( [], [], __modifyAttributesForObjectsReferingRepo ),
|
||||
ElementGetable( [ "id" ], [], __modifyAttributesForObjectsReferingRepo ),
|
||||
ElementCreatable( [ "name", "config" ], [ "events", "active" ], __modifyAttributesForObjectsReferingRepo ),
|
||||
),
|
||||
ExternalListOfObjects( "keys", "key", RepositoryKey,
|
||||
ListGetable( [], [], __modifyAttributesForObjectsReferingRepo ),
|
||||
ElementGetable( [ "id" ], [], __modifyAttributesForObjectsReferingRepo ),
|
||||
ElementCreatable( [ "title", "key" ], [], __modifyAttributesForObjectsReferingRepo ),
|
||||
),
|
||||
ExternalListOfObjects( "collaborators", "collaborator", NamedUser,
|
||||
ListGetable( [], [] ),
|
||||
ElementAddable(),
|
||||
@@ -385,7 +544,7 @@ Repository._addAttributePolicy( SeveralAttributePolicies( [
|
||||
),
|
||||
ExternalListOfObjects( "git/commits", "git_commit", GitCommit,
|
||||
ElementGetable( [ "sha" ], [], __modifyAttributesForObjectsReferingRepo ),
|
||||
ElementCreatable( [ "message", "tree", "parents" ], [ "author", "commiter" ], __modifyAttributesForObjectsReferingRepo )
|
||||
ElementCreatable( [ "message", "tree", "parents" ], [ "author", "committer" ], __modifyAttributesForObjectsReferingRepo )
|
||||
),
|
||||
ExternalListOfObjects( "git/trees", "git_tree", GitTree,
|
||||
ElementGetable( [ "sha" ], [], __modifyAttributesForObjectsReferingRepo ),
|
||||
@@ -435,7 +594,7 @@ Repository._addAttributePolicy( SeveralAttributePolicies( [
|
||||
),
|
||||
ExternalListOfObjects( "pulls", "pull", PullRequest,
|
||||
ListGetable( [], [ "state" ], __modifyAttributesForObjectsReferingRepo ),
|
||||
ElementGetable( [ "id" ], [], __modifyAttributesForObjectsReferingRepo ),
|
||||
ElementGetable( [ "number" ], [], __modifyAttributesForObjectsReferingRepo ),
|
||||
ElementCreatable( [ "title", "body", "base", "head" ], [], __modifyAttributesForObjectsReferingRepo ),
|
||||
),
|
||||
] ) )
|
||||
@@ -480,11 +639,11 @@ NamedUser._addAttributePolicy(
|
||||
|
||||
def __createForkForUser( user, repo ):
|
||||
assert isinstance( repo, Repository )
|
||||
return Repository( user._github, user._github._dataRequest( "POST", repo._baseUrl + "/forks", None, None ), lazy = True )
|
||||
return Repository( user._github, user._github._dataRequest( "POST", repo._baseUrl() + "/forks", None, None ), lazy = True )
|
||||
AuthenticatedUser._addAttributePolicy( SeveralAttributePolicies( [ MethodFromCallable( "create_fork", [ "repo" ], [], __createForkForUser, ObjectTypePolicy( Repository ) ) ], "Forking" ) )
|
||||
def __createForkForOrg( org, repo ):
|
||||
assert isinstance( repo, Repository )
|
||||
return Repository( org._github, org._github._dataRequest( "POST", repo._baseUrl + "/forks", { "org": org.login }, None ), lazy = True )
|
||||
return Repository( org._github, org._github._dataRequest( "POST", repo._baseUrl() + "/forks", { "org": org.login }, None ), lazy = True )
|
||||
Organization._addAttributePolicy( SeveralAttributePolicies( [ MethodFromCallable( "create_fork", [ "repo" ], [], __createForkForOrg, ObjectTypePolicy( Repository ) ) ], "Forking" ) )
|
||||
|
||||
Team = GithubObject(
|
||||
@@ -521,3 +680,82 @@ 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( gist._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`" ) ),
|
||||
)
|
||||
|
||||
Event._addAttributePolicy(
|
||||
InternalObjectAttribute( "repo", Repository ),
|
||||
)
|
||||
Event._addAttributePolicy(
|
||||
InternalObjectAttribute( "actor", NamedUser ),
|
||||
)
|
||||
Event._addAttributePolicy(
|
||||
InternalObjectAttribute( "org", Organization ),
|
||||
)
|
||||
|
||||
@@ -24,7 +24,6 @@ class AttributeFromCallable:
|
||||
|
||||
def autoDocument( self ):
|
||||
return ""
|
||||
return "* `" + self.__name + "`\n"
|
||||
|
||||
### @todo include the ArgumentsChecker
|
||||
class MethodFromCallable:
|
||||
@@ -60,7 +59,7 @@ class InternalAttribute:
|
||||
return self.__typePolicy.createLazy( obj, rawValue )
|
||||
|
||||
def updateAttributes( self, obj ):
|
||||
attributes = obj._github._dataRequest( "GET", obj._baseUrl, None, None )
|
||||
attributes = obj._github._dataRequest( "GET", obj._baseUrl(), None, None )
|
||||
obj._updateAttributes( attributes )
|
||||
obj._markAsCompleted()
|
||||
|
||||
@@ -94,7 +93,7 @@ class ExternalAttribute:
|
||||
def __execute( self, obj ):
|
||||
return self.__typePolicy.createLazy(
|
||||
obj,
|
||||
obj._github._dataRequest( "GET", obj._baseUrl + "/" + self.__attributeName, None, None )
|
||||
obj._github._dataRequest( "GET", obj._baseUrl() + "/" + self.__attributeName, None, None )
|
||||
)
|
||||
|
||||
def autoDocument( self ):
|
||||
|
||||
@@ -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,48 +56,53 @@ 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 ):
|
||||
def __init__( self, mandatoryParameters, optionalParameters, attributeModifiers = {} ):
|
||||
self.__argumentsChecker = ArgumentsChecker( mandatoryParameters, optionalParameters )
|
||||
class ListCapacityWithModifier( ListCapacity ):
|
||||
def __init__( self, attributeModifiers ):
|
||||
self.__attributeModifiers = attributeModifiers
|
||||
|
||||
def _modifyAttributes( self, obj, attributes ):
|
||||
for attributeName, attributeModifier in self.__attributeModifiers.iteritems():
|
||||
attributes[ attributeName ] = attributeModifier( obj )
|
||||
return attributes
|
||||
|
||||
class ElementCreatable( ListCapacityWithModifier ):
|
||||
def __init__( self, mandatoryParameters, optionalParameters, attributeModifiers = {} ):
|
||||
ListCapacityWithModifier.__init__( self, attributeModifiers )
|
||||
self.__argumentsChecker = ArgumentsChecker( mandatoryParameters, optionalParameters )
|
||||
|
||||
def apply( self, cls ):
|
||||
cls._addMethod( "create_" + self.singularName, self.__execute )
|
||||
|
||||
def __execute( self, obj, *args, **kwds ):
|
||||
return self.typePolicy.createLazy(
|
||||
obj,
|
||||
self.__modifyAttributes(
|
||||
self._modifyAttributes(
|
||||
obj,
|
||||
obj._github._dataRequest(
|
||||
"POST",
|
||||
obj._baseUrl + "/" + self.attributeName,
|
||||
self.baseUrl( obj ),
|
||||
None,
|
||||
self.__argumentsChecker.check( args, kwds )
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
def __modifyAttributes( self, obj, attributes ):
|
||||
for attributeName, attributeModifier in self.__attributeModifiers.iteritems():
|
||||
attributes[ attributeName ] = attributeModifier( obj )
|
||||
return attributes
|
||||
|
||||
def autoDocument( self ):
|
||||
return "* `create_" + self.singularName + "(" + self.__argumentsChecker.documentParameters() + ")`: " + self.typePolicy.documentTypeName() + "\n"
|
||||
|
||||
class ElementGetable( ListCapacity ):
|
||||
class ElementGetable( ListCapacityWithModifier ):
|
||||
def __init__( self, mandatoryParameters, optionalParameters, attributeModifiers = {} ):
|
||||
ListCapacityWithModifier.__init__( self, attributeModifiers )
|
||||
self.__argumentsChecker = ArgumentsChecker( mandatoryParameters, optionalParameters )
|
||||
self.__attributeModifiers = attributeModifiers
|
||||
|
||||
def apply( self, cls ):
|
||||
cls._addMethod( "get_" + self.singularName, self.__execute )
|
||||
@@ -98,17 +110,12 @@ class ElementGetable( ListCapacity ):
|
||||
def __execute( self, obj, *args, **kwds ):
|
||||
return self.typePolicy.createNonLazy(
|
||||
obj,
|
||||
self.__modifyAttributes(
|
||||
self._modifyAttributes(
|
||||
obj,
|
||||
self.__argumentsChecker.check( args, kwds )
|
||||
)
|
||||
)
|
||||
|
||||
def __modifyAttributes( self, obj, attributes ):
|
||||
for attributeName, attributeModifier in self.__attributeModifiers.iteritems():
|
||||
attributes[ attributeName ] = attributeModifier( obj )
|
||||
return attributes
|
||||
|
||||
def autoDocument( self ):
|
||||
return "* `get_" + self.singularName + "(" + self.__argumentsChecker.documentParameters() + ")`: " + self.typePolicy.documentTypeName() + "\n"
|
||||
|
||||
@@ -119,7 +126,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 +144,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 )
|
||||
@@ -148,10 +155,10 @@ class SeveralElementsRemovable( ListCapacity ):
|
||||
def autoDocument( self ):
|
||||
return "* `remove_from_" + self.safeAttributeName + "( " + self.singularName + ", ... )`\n * `" + self.singularName + "`: " + self.typePolicy.documentTypeName() + "\n"
|
||||
|
||||
class ListGetable( ListCapacity ):
|
||||
class ListGetable( ListCapacityWithModifier ):
|
||||
def __init__( self, mandatoryParameters, optionalParameters, attributeModifiers = {} ):
|
||||
ListCapacityWithModifier.__init__( self, attributeModifiers )
|
||||
self.__argumentsChecker = ArgumentsChecker( mandatoryParameters, optionalParameters )
|
||||
self.__attributeModifiers = attributeModifiers
|
||||
|
||||
def apply( self, cls ):
|
||||
cls._addMethod( "get_" + self.safeAttributeName, self.__execute )
|
||||
@@ -161,11 +168,11 @@ class ListGetable( ListCapacity ):
|
||||
return [
|
||||
self.typePolicy.createLazy(
|
||||
obj,
|
||||
self.__modifyAttributes( obj, attributes )
|
||||
self._modifyAttributes( obj, attributes )
|
||||
)
|
||||
for attributes in obj._github._dataRequest(
|
||||
"GET",
|
||||
obj._baseUrl + "/" + self.attributeName,
|
||||
self.baseUrl( obj ),
|
||||
params,
|
||||
None
|
||||
)
|
||||
@@ -174,11 +181,6 @@ class ListGetable( ListCapacity ):
|
||||
def autoDocument( self ):
|
||||
return "* `get_" + self.safeAttributeName + "(" + self.__argumentsChecker.documentParameters() + ")`: list of " + self.typePolicy.documentTypeName() + "\n"
|
||||
|
||||
def __modifyAttributes( self, obj, attributes ):
|
||||
for attributeName, attributeModifier in self.__attributeModifiers.iteritems():
|
||||
attributes[ attributeName ] = attributeModifier( obj )
|
||||
return attributes
|
||||
|
||||
class ListSetable( ListCapacity ):
|
||||
def apply( self, cls ):
|
||||
cls._addMethod( "set_" + self.safeAttributeName, self.__execute )
|
||||
@@ -186,7 +188,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 +206,7 @@ class ListDeletable( ListCapacity ):
|
||||
def __execute( self, obj ):
|
||||
obj._github._statusRequest(
|
||||
"DELETE",
|
||||
obj._baseUrl + "/" + self.attributeName,
|
||||
self.baseUrl( obj ),
|
||||
None,
|
||||
None
|
||||
)
|
||||
@@ -212,9 +214,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 ):
|
||||
|
||||
@@ -19,10 +19,7 @@ class ObjectTypePolicy:
|
||||
self.__type = type
|
||||
|
||||
def createLazy( self, obj, attributes ):
|
||||
if isinstance( attributes, self.__type ):
|
||||
return attributes
|
||||
else:
|
||||
return self.__type( obj._github, attributes, lazy = True )
|
||||
return self.__type( obj._github, attributes, lazy = True )
|
||||
|
||||
def createNonLazy( self, obj, attributes ):
|
||||
return self.__type( obj._github, attributes, lazy = False )
|
||||
|
||||
@@ -55,4 +55,10 @@ class TestCase( unittest.TestCase ):
|
||||
self.expect( "GET", "/test?page=3", 'null', 200, [ ( "link", "xxx; prev, xxx; first" ) ], '[ 5, 6 ]' )
|
||||
self.assertEqual( self.r.dataRequest( "GET", "/test", None, None ), [ 1, 2, 3, 4, 5, 6 ] )
|
||||
|
||||
def testPaginationObviouslyFinished( self ):
|
||||
self.expect( "GET", "/test", 'null', 200, [ ( "link", "<xxx?page=2>; next, xxx; last" ) ], '[ 1, 2 ]' )
|
||||
self.expect( "GET", "/test?page=2", 'null', 200, [ ( "link", "xxx; prev, xxx; first, <xxx?page=3>; next, xxx; last" ) ], '[ 3, 4 ]' )
|
||||
self.expect( "GET", "/test?page=3", 'null', 200, [ ( "link", "xxx; prev, xxx; first" ) ], '[]' )
|
||||
self.assertEqual( self.r.dataRequest( "GET", "/test", None, None ), [ 1, 2, 3, 4 ] )
|
||||
|
||||
unittest.main()
|
||||
|
||||
+4
-1
@@ -18,7 +18,8 @@ class Requester:
|
||||
|
||||
headers, output = self.__statusCheckedRequest( verb, url, parameters, input )
|
||||
|
||||
while "link" in headers and "next" in headers[ "link" ]:
|
||||
obviouslyFinished = False
|
||||
while "link" in headers and "next" in headers[ "link" ] and not obviouslyFinished:
|
||||
for link in headers[ "link" ].split( "," ):
|
||||
if "next" in link:
|
||||
linkUrl = link.split( ";" )[ 0 ][ : -1 ]
|
||||
@@ -26,6 +27,8 @@ class Requester:
|
||||
parameters.update( dict( p.split( "=" ) for p in params.split( "&" ) ) )
|
||||
break
|
||||
headers, newOutput = self.__statusCheckedRequest( verb, url, parameters, input )
|
||||
if len( newOutput ) == 0:
|
||||
obviouslyFinished = True
|
||||
output += newOutput
|
||||
|
||||
return output
|
||||
|
||||
Reference in New Issue
Block a user