Skip to content

Commit 330016d

Browse files
committed
Check ETag when updating blocklist
1 parent 75713ec commit 330016d

1 file changed

Lines changed: 25 additions & 8 deletions

File tree

lib/blocklist.py

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,50 @@
11
"""Code related to blocklists."""
2+
from dataclasses import dataclass
23
import requests
34
import logging
45

56
logger = logging.getLogger(__name__)
67

78

8-
def _parse_block_list_from_url(url: str) -> list[str]:
9-
block_list = requests.get(url).text.strip()
10-
return [username.strip() for username in block_list.split("\n")]
9+
@dataclass
10+
class BlocklistData:
11+
users: list[str]
12+
etag: str | None
13+
14+
15+
def _parse_block_list_from_url(url: str, old_data: BlocklistData) -> BlocklistData:
16+
headers = {"If-None-Match": old_data.etag} if old_data.etag else {}
17+
response = requests.get(url, headers=headers)
18+
19+
response.raise_for_status()
20+
21+
if response.status_code == 304:
22+
return old_data
23+
24+
block_list = [username.strip() for username in response.text.strip().split("\n")]
25+
26+
return BlocklistData(block_list, response.headers.get("ETag"))
1127

1228

1329
class OnlineBlocklist:
1430
"""Manage online blocklists."""
1531

1632
def __init__(self, urls: list[str]) -> None:
1733
"""Initialize the OnlineBlockList class."""
18-
self.blocklist: dict[str, list[str]] = {url : [] for url in urls}
19-
self.refresh()
34+
self.blocklist: dict[str, BlocklistData] = {url : BlocklistData([], None) for url in urls}
35+
for _ in range(5):
36+
self.refresh()
2037

2138
def refresh(self) -> None:
2239
"""Pull updated blocklists from the list of blocklist urls."""
2340
logger.info(f"Refreshing {len(self.blocklist)} online blocklists")
2441

25-
for url in self.blocklist.keys():
42+
for url, data in self.blocklist.items():
2643
try:
27-
self.blocklist[url] = _parse_block_list_from_url(url)
44+
self.blocklist[url] = _parse_block_list_from_url(url, data)
2845
except Exception:
2946
logger.warning(f"Failed to refresh online blocklist {url}")
3047

3148
def __contains__(self, item: str) -> bool:
3249
"""Check if an username is in the blocklist."""
33-
return any(item in blocklist for blocklist in self.blocklist)
50+
return any(item in blocklist.users for blocklist in self.blocklist.values())

0 commit comments

Comments
 (0)