2019-02-02 22:12:08 +01:00
|
|
|
from datetime import date
|
2019-02-03 14:10:17 +01:00
|
|
|
from typing import Iterable
|
2019-02-02 22:12:08 +01:00
|
|
|
from urllib.parse import urlencode
|
|
|
|
from warnings import warn
|
|
|
|
|
|
|
|
import requests
|
|
|
|
|
2019-02-03 14:10:17 +01:00
|
|
|
from generator import Event, Issue
|
2019-02-02 22:12:08 +01:00
|
|
|
|
|
|
|
|
|
|
|
class GithubAPI:
|
|
|
|
BASE_URL = "https://api.github.com"
|
|
|
|
|
|
|
|
def __init__(self, token=None):
|
|
|
|
self.s = requests.Session()
|
|
|
|
if token:
|
|
|
|
self.s.headers.update({'Authorization': 'token {}'.format(token)})
|
|
|
|
else:
|
|
|
|
warn("use Token!", stacklevel=2) # TODO
|
2019-02-03 16:33:44 +01:00
|
|
|
self.s.headers.update({'User-Agent': 'github-changelog-generator'})
|
2019-02-02 22:12:08 +01:00
|
|
|
|
|
|
|
def call(self, url, parameters=None):
|
|
|
|
if "//" not in url:
|
|
|
|
url = self.BASE_URL + url
|
|
|
|
print(url + "?" + urlencode(parameters))
|
2019-02-03 14:10:17 +01:00
|
|
|
else:
|
|
|
|
print(url)
|
2019-02-02 22:12:08 +01:00
|
|
|
r = self.s.get(url, params=parameters)
|
|
|
|
if isinstance(r.json(), dict):
|
|
|
|
yield r.json()
|
|
|
|
else:
|
|
|
|
yield from r.json()
|
|
|
|
while "next" in r.links:
|
|
|
|
print("fetching next page")
|
|
|
|
r = self.s.get(r.links["next"]["url"])
|
|
|
|
yield from r.json()
|
|
|
|
|
2019-02-03 14:10:17 +01:00
|
|
|
def fetch_issues_since(self, repo, since: date) -> Iterable[Issue]:
|
2019-02-02 22:12:08 +01:00
|
|
|
assert "/" in repo # e.g. "matomo-org/matomo"
|
|
|
|
path = "/repos/{}/issues".format(repo)
|
|
|
|
params = {
|
|
|
|
"state": "closed",
|
|
|
|
"direction": "asc",
|
|
|
|
"since": since.isoformat()
|
|
|
|
}
|
|
|
|
responses = self.call(path, params)
|
|
|
|
for response in responses:
|
|
|
|
yield Issue(response)
|
|
|
|
|
2019-02-03 14:10:17 +01:00
|
|
|
def fetch_pr_details(self, pr: Issue) -> dict:
|
2019-02-02 22:12:08 +01:00
|
|
|
data = list(self.call(pr.pr_url))[
|
|
|
|
0] # self.call is a generator even if there is only one result
|
|
|
|
return data
|
|
|
|
|
2019-02-03 14:10:17 +01:00
|
|
|
def fetch_events(self, issue: Issue) -> Iterable[Event]:
|
|
|
|
responses = self.call(issue.events_url)
|
|
|
|
for response in responses:
|
|
|
|
yield Event(response)
|
2019-02-03 19:07:33 +01:00
|
|
|
|
|
|
|
def get_stable_releases(self, repo):
|
|
|
|
url = self.BASE_URL + "/repos/{}/releases".format(repo)
|
|
|
|
r = self.s.get(url)
|
|
|
|
return [rel for rel in r.json() if not rel["prerelease"]]
|