Skip to content

Instantly share code, notes, and snippets.

@pybites
Created June 6, 2024 10:35
Show Gist options
  • Save pybites/9717243b4d573ffa4e6f5ff987f22e2f to your computer and use it in GitHub Desktop.
Save pybites/9717243b4d573ffa4e6f5ff987f22e2f to your computer and use it in GitHub Desktop.
import re
import sys
import os
import json
import time
from pathlib import Path
from typing import List, Optional, NamedTuple
import requests
TIMEOUT = 10
ENDPOINT = "https://codechalleng.es/api/content/"
CACHE_FILE_NAME = ".pybites-search-cache-pyversion-test.json"
DEFAULT_CACHE_DURATION = 3600 # Default cache duration in seconds (1 hour)
class Item(NamedTuple):
content_type: str
title: str
summary: str
link: str
def main():
args = sys.argv
if len(args) < 2 or len(args) > 4:
print("Usage: search <search_term> [<content_type>] [--title-only]")
return
search_term = args[1]
content_type = args[2] if len(args) >= 3 and not args[2].startswith("--") else None
title_only = "--title-only" in args
cache_duration = int(os.getenv("CACHE_DURATION", DEFAULT_CACHE_DURATION))
items = fetch_items(ENDPOINT, cache_duration)
search_items(items, search_term, content_type, title_only)
def fetch_items(endpoint: str, cache_duration: int) -> List[Item]:
cached_items = load_from_cache(cache_duration)
if cached_items:
return cached_items
response = requests.get(endpoint, timeout=TIMEOUT)
response.raise_for_status()
items_data = response.json()
items = [Item(**item) for item in items_data]
save_to_cache(items)
return items
def save_to_cache(items: List[Item]):
cache_path = get_cache_file_path()
cache_data = {
"timestamp": int(time.time()),
"items": items
}
with open(cache_path, "w") as f:
json.dump(cache_data, f)
def load_from_cache(cache_duration: int) -> List[Item]:
cache_path = get_cache_file_path()
try:
with open(cache_path, "r") as f:
cache_data = json.load(f)
except FileNotFoundError:
return []
current_time = int(time.time())
if current_time - cache_data["timestamp"] <= cache_duration:
return [Item(*item) for item in cache_data["items"]]
else:
return []
def search_items(
items: List[Item], search_term: str, content_type: Optional[str], title_only: bool
):
re_pattern = re.compile(re.escape(search_term), re.IGNORECASE)
for item in items:
if title_only:
matches = re_pattern.search(item.title)
else:
matches = re_pattern.search(item.title) or re_pattern.search(item.summary)
if (
content_type is None or content_type.lower() == item.content_type.lower()
) and matches:
if content_type is None:
print(f"Type: {item.content_type}")
print(f"Title: {item.title}")
print(f"Link: {item.link}\n")
def get_cache_file_path() -> Path:
return Path.home() / CACHE_FILE_NAME
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment