Skip to content

Commit a62e478

Browse files
author
Ask Solem
committed
Initial commit
0 parents  commit a62e478

4 files changed

Lines changed: 207 additions & 0 deletions

File tree

.gitignore

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
.DS_Store
2+
*.pyc
3+
*~
4+
*.sqlite
5+
*.sqlite-journal
6+
settings_local.py
7+
local_settings.py
8+
.*.sw[po]
9+
dist/
10+
*.egg-info
11+
doc/__build/*
12+
build/
13+
locale/
14+
pip-log.txt

github2/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
VERSION = (0, 1, 0)
2+
__author__ = "Ask Solem"
3+
__contact__ = "[email protected]"
4+
__homepage__ = "http://github.com/ask/pygithub-issues"
5+
__version__ = ".".join(map(str, VERSION))
6+

github2/client.py

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
from github2.request import GithubRequest
2+
3+
class GithubData(object):
4+
def __init__(self, **kwargs):
5+
for attr_name in self.attributes:
6+
if attr_name in kwargs:
7+
setattr(self, attr_name, kwargs[attr_name])
8+
else:
9+
setattr(self, attr_name, None)
10+
11+
def to_dict(self):
12+
dict_ = {}
13+
for attr_name in self.attributes:
14+
attr_value = getattr(self, attr_name, None)
15+
if attr_value is not None:
16+
dict_[attr_name] = attr_value
17+
return dict_
18+
19+
20+
class Issue(GithubData):
21+
attributes = ("position", "number", "votes", "body", "title",
22+
"created_at", "updated_at", "user", "state")
23+
24+
class User(GithubData):
25+
attributes = ("id", "login", "name", "company", "location", "email",
26+
"blog", "following_count", "followers_count",
27+
"public_gist_count", "public_repo_count",
28+
"total_private_repo_count", "collaborators", "disk_usage",
29+
"owned_private_repo_count", "private_gist_count",
30+
"plan")
31+
32+
def is_authenticated(self):
33+
return self.plan is not None
34+
35+
36+
class GithubCommand(object):
37+
38+
def __init__(self, request):
39+
self.request = request
40+
41+
def make_request(self, command, *args, **kwargs):
42+
filter = kwargs.get("filter")
43+
post_data = kwargs.get("post_data")
44+
if post_data:
45+
response = self.request.post(self.domain, command, *args,
46+
**post_data)
47+
else:
48+
response = self.request.get(self.domain, command, *args)
49+
if filter:
50+
return response[filter]
51+
return response
52+
53+
54+
class Users(GithubCommand):
55+
domain = "user"
56+
57+
def search(self, query):
58+
return self.make_request("search", query, filter="users")
59+
60+
def show(self, username):
61+
user_data = self.make_request("show", username, filter="user")
62+
return User(**user_data)
63+
64+
def followers(self, username):
65+
return self.make_request("show", username, "followers")
66+
67+
def following(self, username):
68+
return self.make_request("show", username, "following")
69+
70+
def follow(self, other_user):
71+
return self.make_request("follow", other_user)
72+
73+
def unfollow(self, other_user):
74+
return self.make_request("unfollow", other_user)
75+
76+
class Issues(GithubCommand):
77+
domain = "issues"
78+
79+
def list(self, project, state="open"):
80+
"""Get all issues for project' with state'.
81+
82+
``project`` is a string with the project owner username and repository
83+
name separated by ``/`` (e.g. ``ask/pygithub2``).
84+
``state`` can be either ``open`` or ``closed``.
85+
"""
86+
return [Issue(**issue)
87+
for issue in self.make_request("list", project, state,
88+
filter="issues")]
89+
90+
def show(self, project, number):
91+
"""Get all the data for issue by issue-number."""
92+
issue_data = self.make_request("show", project, str(number),
93+
filter="issue")
94+
return Issue(**issue_data)
95+
96+
def open(self, project, title, body):
97+
"""Open up a new issue."""
98+
issue_data = {"title": title, "body": body}
99+
r = self.make_request("open", project, post_data=issue_data,
100+
filter="issue")
101+
return Issue(**r)
102+
103+
def close(self, project, number):
104+
issue_data = self.make_request("close", project, str(number),
105+
filter="issue")
106+
return Issue(**issue_data)
107+
108+
def add_label(self, project, number, label):
109+
return self.make_request("label/add", project, label, str(number),
110+
filter="labels")
111+
112+
def remove_label(self, project, number, label):
113+
return self.make_request("label/remove", project, label, str(number),
114+
filter="labels")
115+
class Github(object):
116+
117+
def __init__(self, username, api_token):
118+
self.request = GithubRequest(username=username, api_token=api_token)
119+
self.issues = Issues(self.request)
120+
self.users = Users(self.request)
121+
122+
def project_for_user_repo(self, user, repo):
123+
return "/".join([user, repo])
124+

github2/request.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import sys
2+
import httplib
3+
import simplejson
4+
from urlparse import urlparse
5+
from urllib import urlencode
6+
7+
URL_PREFIX = "https://github.com/api/v2/json"
8+
9+
class GithubError(Exception):
10+
"""An error occured when making a request to the Github API."""
11+
12+
class GithubRequest(object):
13+
url_prefix = URL_PREFIX
14+
GithubError = GithubError
15+
16+
connector_for_scheme = {
17+
"http": httplib.HTTPConnection,
18+
"https": httplib.HTTPSConnection,
19+
}
20+
21+
def __init__(self, username, api_token, url_prefix=None):
22+
self.username = username
23+
self.api_token = api_token
24+
self.url_prefix = url_prefix or self.url_prefix
25+
26+
def encode_authentication_data(self, extra_post_data):
27+
post_data = {"user": self.username,
28+
"token": self.api_token}
29+
post_data.update(extra_post_data)
30+
return urlencode(post_data)
31+
32+
def get(self, *path_components):
33+
return self.make_request("/".join(path_components))
34+
35+
def post(self, *path_components, **extra_post_data):
36+
return self.make_request("/".join(path_components), extra_post_data)
37+
38+
def make_request(self, path, extra_post_data=None):
39+
extra_post_data = extra_post_data or {}
40+
url = "/".join([self.url_prefix, path])
41+
print("URL: %s" % url)
42+
resource = urlparse(url)
43+
post_data = self.encode_authentication_data(extra_post_data)
44+
print("POST_DATA: %s" % post_data)
45+
connector = self.connector_for_scheme[resource.scheme]
46+
headers = self.http_headers
47+
headers["Accept"] = "text/html"
48+
headers["Content-Length"] = str(len(post_data))
49+
connection = connector(resource.hostname, resource.port)
50+
connection.request("POST", resource.path, post_data, headers)
51+
response = connection.getresponse()
52+
response_text = response.read()
53+
print(response_text)
54+
json = simplejson.loads(response_text)
55+
if json.get("error"):
56+
raise self.GithubError(json["error"][0]["error"])
57+
58+
return json
59+
60+
@property
61+
def http_headers(self):
62+
return {"User-Agent": "pygithub2 v1",
63+
"Accept-Encoding": "application/json"}

0 commit comments

Comments
 (0)