This repository has been archived by the owner on May 3, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
90 lines (75 loc) · 2.91 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
from typing import Union, Deque, List
from cachetools import TTLCache, cached
from fastapi import FastAPI
from collections import deque
from fastapi_utils.tasks import repeat_every
from random import choice
from aiohttp import ClientSession
from ormsgpack import packb, unpackb
app = FastAPI()
class Memes:
def __init__(self):
self.subreddits = (
"memes",
"dankmemes",
"me_irl",
"funny",
"wholesomememes",
"antimeme",
)
self.memecache: TTLCache[str, Deque[bytes]] = TTLCache(100, 3600)
@property
@cached(cache=TTLCache(1, 3600))
def allmemes(self) -> List:
meme_list = []
for meme_subreddit in self.memecache.keys():
for meme in self.memecache[meme_subreddit]:
meme_list.append(meme)
return meme_list
async def get_random(self, subreddit: str = None, amount: int = 0):
if subreddit and not self.memecache.get(subreddit):
await self.get_memes_from_sub(subreddit)
if not amount:
if not subreddit:
return unpackb(choice(self.allmemes))
return unpackb(choice(self.memecache.get(subreddit)))
return [unpackb(choice(self.allmemes)) for _ in range(amount)]
async def get_memes_from_sub(self, sub: str):
async with ClientSession() as session:
d = await session.get(f"https://www.reddit.com/r/{sub}/hot.json?limit=100")
data = await d.json()
memes = (
i["data"] for i in data["data"]["children"] if not i.get("over_18")
)
if sub not in self.memecache:
self.memecache[sub] = deque(maxlen=1024)
for meme in memes:
m = packb(
{
"title": meme["title"],
"author": meme["author"],
"subreddit": sub,
"postLink": f"https://reddit.com{meme['permalink']}",
"ups": meme["ups"],
"imageUrl": None
if (not meme.get("url", None))
or meme["permalink"] in meme["url"]
else meme["url"],
}
)
self.memecache[sub].appendleft(m)
meme = Memes()
@app.on_event("startup")
@repeat_every(seconds=3600)
async def refresh_cache() -> dict:
print("fetching memes!")
for subreddit in meme.subreddits:
print(f"getting memes from r/{subreddit}!")
await meme.get_memes_from_sub(subreddit)
print(f"done! got {len(meme.allmemes)} memes :>")
@app.get("/")
async def random_meme(amount: Union[int, None] = None):
return await meme.get_random(amount=amount)
@app.get("/{subreddit}")
async def random_meme_from_subreddit(subreddit: str, amount: Union[int, None] = None):
return await meme.get_random(subreddit, amount)