Skip to content
85 changes: 64 additions & 21 deletions blurb_it/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,28 +159,71 @@ async def handle_add_blurb_post(request):
"path": path,
"message": "📜🤖 Added by blurb_it.",
}
try:
response = await gh.put(
f"/repos/{pr_repo_full_name}/contents/{path}", data=put_data
)
except gidgethub.BadRequest as bac:
print("BadRequest")
print(int(bac.status_code))
print(bac)
context[
"pr_url"
] = f"https://github.com/python/cpython/pull/{pr_number}"
context["pr_number"] = pr_number
context["status"] = "failure"
if pr["user"]["login"] != session_context["username"]:
async with aiohttp.ClientSession() as session:
mi_gh = GitHubAPI(
session,
"python/cpython",
oauth_token=os.getenv("MI_GH_AUTH"),
)
is_core_dev = await util.is_core_dev(
mi_gh, session_context["username"]
)
print(f"{session_context['username']} is core dev {is_core_dev} ")
if is_core_dev:
try:
# put_data["author"] = {"name": "Miss Islington (bot)", "email": "[email protected]"}
# put_data["committer"] = {"name": "Miss Islington (bot)", "email": "[email protected]"}
response = await mi_gh.put(
f"/repos/{pr_repo_full_name}/contents/{path}",
data=put_data,
)
except gidgethub.BadRequest as bac:
print("BadRequest, error using miss-islington's oauth token")
print(int(bac.status_code))
print(bac)
context[
"pr_url"
] = f"https://github.com/python/cpython/pull/{pr_number}"
context["pr_number"] = pr_number
context["status"] = "failure"
await mi_gh.post(f"/repos/python/cpython/issues/{pr_number}/comments", data={"body": "Ping!"})
else:
print("response")
print(response)
commit_url = response["commit"]["html_url"]
context["commit_url"] = commit_url
context["path"] = response["content"]["path"]
context[
"pr_url"
] = f"https://github.com/python/cpython/pull/{pr_number}"
context["pr_number"] = pr_number
context["status"] = "success"
else:
commit_url = response["commit"]["html_url"]
context["commit_url"] = commit_url
context["path"] = response["content"]["path"]
context[
"pr_url"
] = f"https://github.com/python/cpython/pull/{pr_number}"
context["pr_number"] = pr_number
context["status"] = "success"
try:
response = await gh.put(
f"/repos/{pr_repo_full_name}/contents/{path}", data=put_data
)
except gidgethub.BadRequest as bac:
print("BadRequest, using blurb-it")
print(int(bac.status_code))
print(bac)
context[
"pr_url"
] = f"https://github.com/python/cpython/pull/{pr_number}"
context["pr_number"] = pr_number
context["status"] = "failure"
else:
print("response")
print(response)
commit_url = response["commit"]["html_url"]
context["commit_url"] = commit_url
context["path"] = response["content"]["path"]
context[
"pr_url"
] = f"https://github.com/python/cpython/pull/{pr_number}"
context["pr_number"] = pr_number
context["status"] = "success"

template = "add_blurb.html"
response = aiohttp_jinja2.render_template(template, request, context=context)
Expand Down
25 changes: 25 additions & 0 deletions blurb_it/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import time

import jwt
import gidgethub

from aiohttp_session import get_session

from blurb_it import error
Expand Down Expand Up @@ -80,3 +82,26 @@ async def get_installation_access_token(gh, jwt, installation_id):
# }

return response


async def is_core_dev(gh, username):
"""Check if the user is a CPython core developer."""
org_teams = "/orgs/python/teams"
team_name = "python core"
async for team in gh.getiter(org_teams):
if team["name"].lower() == team_name:
break
else:
raise ValueError(f"{team_name!r} not found at {org_teams!r}")
# The 'teams' object only provides a URL to a deprecated endpoint,
# so manually construct the URL to the non-deprecated team membership
# endpoint.
membership_url = f"/teams/{team['id']}/memberships/{username}"
try:
await gh.getitem(membership_url)
except gidgethub.BadRequest as exc:
if exc.status_code == 404:
return False
raise
else:
return True
87 changes: 86 additions & 1 deletion tests/test_util.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,61 @@
import http
import pytest
import gidgethub


from blurb_it import util


class FakeGH:
def __init__(self, *, getiter=None, getitem=None, post=None, patch=None):
self._getitem_return = getitem
self._getiter_return = getiter
self._post_return = post
self._patch_return = patch
self.getitem_url = None
self.getiter_url = None
self.patch_url = self.patch_data = None
self.post_url = self.post_data = None

async def getitem(self, url):
self.getitem_url = url
to_return = self._getitem_return[self.getitem_url]
if isinstance(to_return, Exception):
raise to_return
else:
return to_return

async def getiter(self, url):
self.getiter_url = url
to_iterate = self._getiter_return[url]
for item in to_iterate:
yield item

async def patch(self, url, *, data):
self.patch_url = url
self.patch_data = data
return self._patch_return

async def post(self, url, *, data):
self.post_url = url
self.post_data = data
if isinstance(self._post_return, Exception):
raise self._post_return
else:
return self._post_return


async def test_nonceify():
body = "Lorem ipsum dolor amet flannel squid normcore tbh raclette enim" "pabst tumblr wolf farm-to-table bitters. Bitters keffiyeh next" "level proident normcore, et all of +1 90's in blue bottle" "chillwave lorem. Id keffiyeh microdosing cupidatat pour-over" "paleo farm-to-table tumeric sriracha +1. Raclette in poutine," "bushwick kitsch id pariatur hexagon. Thundercats shaman beard," "nulla swag echo park organic microdosing. Hot chicken tbh pop-up" "tacos, asymmetrical tilde veniam bespoke reprehenderit ut do."
body = (
"Lorem ipsum dolor amet flannel squid normcore tbh raclette enim"
"pabst tumblr wolf farm-to-table bitters. Bitters keffiyeh next"
"level proident normcore, et all of +1 90's in blue bottle"
"chillwave lorem. Id keffiyeh microdosing cupidatat pour-over"
"paleo farm-to-table tumeric sriracha +1. Raclette in poutine,"
"bushwick kitsch id pariatur hexagon. Thundercats shaman beard,"
"nulla swag echo park organic microdosing. Hot chicken tbh pop-up"
"tacos, asymmetrical tilde veniam bespoke reprehenderit ut do."
)

nonce = await util.nonceify(body)
assert nonce == "Ps4kgC"
Expand All @@ -24,3 +77,35 @@ async def test_get_misc_news_filename():

assert path.startswith("Misc/NEWS.d/next/Library/")
assert path.endswith(".bpo-123.Ps4kgC.rst")


async def test_is_core_dev():
teams = [{"name": "not Python core"}]
gh = FakeGH(getiter={"/orgs/python/teams": teams})
with pytest.raises(ValueError):
await util.is_core_dev(gh, "mariatta")

teams = [{"name": "python core", "id": 42}]
getitem = {"/teams/42/memberships/mariatta": True}
gh = FakeGH(getiter={"/orgs/python/teams": teams}, getitem=getitem)
assert await util.is_core_dev(gh, "mariatta")
assert gh.getiter_url == "/orgs/python/teams"

teams = [{"name": "python core", "id": 42}]
getitem = {
"/teams/42/memberships/miss-islington": gidgethub.BadRequest(
status_code=http.HTTPStatus(404)
)
}
gh = FakeGH(getiter={"/orgs/python/teams": teams}, getitem=getitem)
assert not await util.is_core_dev(gh, "miss-islington")

teams = [{"name": "python core", "id": 42}]
getitem = {
"/teams/42/memberships/miss-islington": gidgethub.BadRequest(
status_code=http.HTTPStatus(400)
)
}
gh = FakeGH(getiter={"/orgs/python/teams": teams}, getitem=getitem)
with pytest.raises(gidgethub.BadRequest):
await util.is_core_dev(gh, "miss-islington")