-
-
Save pybites/9717243b4d573ffa4e6f5ff987f22e2f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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