Skip to content

Commit

Permalink
Merge pull request #597 from jacebrowning/get-custom-results
Browse files Browse the repository at this point in the history
Add an API to get previous custom results
  • Loading branch information
jacebrowning authored Mar 13, 2021
2 parents 2fd37f0 + 6de652a commit 15a9f3e
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 8 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Revision History

## 8.4

- Updated `/images/custom` to return previous results with `GET` requests.

## 8.3

- Added `filter` parameter to `/images` and `/templates` to query for matching names and examples.
Expand Down
43 changes: 41 additions & 2 deletions app/api/memes.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ async def create(request):
@doc.exclude(not settings.REMOTE_TRACKING_URL)
@doc.summary("Create a meme from word or phrase")
@doc.consumes(
doc.JsonBody({"text": str, "redirect": bool}),
doc.JsonBody({"text": str, "safe": bool, "redirect": bool}),
content_type="application/json",
location="body",
)
Expand All @@ -110,7 +110,7 @@ async def auto(request):
except KeyError:
return response.json({"error": '"text" is required'}, status=400)

results = await utils.meta.search(request, text)
results = await utils.meta.search(request, text, payload.get("safe", True))
logger.info(f"Found {len(results)} result(s)")
if not results:
return response.json({"message": f"No results matched: {text}"}, status=404)
Expand Down Expand Up @@ -165,6 +165,45 @@ async def custom(request):
return response.json({"url": url}, status=201)


@blueprint.get("/custom")
@doc.summary("List popular custom memes")
@doc.operation("Memes.list_custom")
# TODO: https://github.com/jacebrowning/memegen/issues/580
# @doc.consumes(
# doc.String(
# name="filter", description="Part of the meme's text to match"
# ),
# location="query",
# )
# @doc.consumes(
# doc.Boolean(
# name="safe", description="Exclude NSFW results"
# ),
# location="query",
# )
@doc.produces(
doc.List({"url": str}),
description="Successfully returned a list of custom memes",
content_type="application/json",
)
async def results(request):
query = request.args.get("filter", "").lower()
safe = request.args.get("safe", "true").lower() not in {"false", "no"}

results = await utils.meta.search(request, query, safe, mode="results")
logger.info(f"Found {len(results)} result(s)")
if not results:
return response.json({"message": f"No results matched: {query}"}, status=404)

items = []
for result in results:
url = utils.urls.normalize(request, result["image_url"])
url, _updated = await utils.meta.tokenize(request, url)
items.append({"url": url})

return response.json(items, status=200)


@blueprint.get("/<template_id>.png")
@doc.tag("Templates")
@doc.summary("Display a template background")
Expand Down
21 changes: 21 additions & 0 deletions app/tests/test_apis_memes.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,3 +290,24 @@ def it_redirects_if_requested(expect, client):
redirect = "http://localhost:5000/images/custom/abc.png?background=https://www.gstatic.com/webp/gallery/4.png"
expect(response.status) == 302
expect(response.headers["Location"]) == redirect

def describe_GET():
@patch(
"app.utils.meta.search",
AsyncMock(
return_value=[
{
"image_url": "http://example.com/images/example.png"
+ "?background=https://www.gstatic.com/webp/gallery/3.png"
}
]
),
)
def it_normalizes_the_urls(expect, client):
request, response = client.get("/images/custom")
expect(response.json) == [
{
"url": "http://localhost:5000/images/example.png"
+ "?background=https://www.gstatic.com/webp/gallery/3.png"
}
]
17 changes: 12 additions & 5 deletions app/utils/meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,22 +126,29 @@ async def track(request, lines: list[str]):
logger.error(f"Tracker response: {message}")


async def search(request, text: str) -> list[dict]:
async def search(request, text: str, safe: bool, *, mode="") -> list[dict]:
if settings.REMOTE_TRACKING_URL:
api = settings.REMOTE_TRACKING_URL
api = settings.REMOTE_TRACKING_URL + mode
else:
return []

async with aiohttp.ClientSession() as session:
params = dict(
text=text,
nsfw=0 if safe else 1,
client=_get_referer(request) or settings.BASE_URL,
)
logger.info(f"Searching for results: {text}")
logger.info(f"Searching for results: {text!r} (safe={safe})")
headers = {"X-API-KEY": _get_api_key(request) or ""}
response = await session.get(api, params=params, headers=headers)
assert response.status == 200
return await response.json()
assert response.status < 500, f"Invalid response: {response}"

data = await response.json()
if response.status == 200:
return data

logger.error(f"Search response: {data}")
return []


def _get_referer(request):
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[tool.poetry]

name = "memegen"
version = "8.3"
version = "8.4"
description = "The free and open source API to generate memes."
authors = ["Jace Browning <[email protected]>"]
license = "MIT"
Expand Down

0 comments on commit 15a9f3e

Please sign in to comment.