initial draft by AI, 2 lines added by me (top and bottom)
commit
25f49e344f
@ -0,0 +1,91 @@
|
||||
#!/usr/bin/env python3
|
||||
#import curses
|
||||
import curses
|
||||
import requests
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
def main(stdscr):
|
||||
stdscr.clear()
|
||||
stdscr.addstr("Hacker News Browsing\n")
|
||||
stdscr.refresh()
|
||||
|
||||
# Initialize variables
|
||||
stories = []
|
||||
story_index = 0
|
||||
search_term = ""
|
||||
author_name = ""
|
||||
|
||||
while True:
|
||||
# Fetch stories from HN API
|
||||
if not stories:
|
||||
url = "https://hacker-news.firebaseio.com/v0/topstories.json"
|
||||
r = requests.get(url)
|
||||
data = r.json()
|
||||
stories = [story for story in data]
|
||||
|
||||
# Display current story title
|
||||
story_id = stories[story_index]
|
||||
url = f"https://hacker-news.firebaseio.com/v0/item/{story_id}.json"
|
||||
r = requests.get(url)
|
||||
data = r.json()
|
||||
stdscr.move(1, 0) # Move cursor back up top of screen
|
||||
stdscr.clrtobot() # Clear entire screen (including status bar)
|
||||
stdscr.addstr(f"\nTitle: {data['title']}\n")
|
||||
|
||||
# Display current story score
|
||||
stdscr.addstr(f"Score: {data['score']} points | ")
|
||||
|
||||
# Display current story URL
|
||||
stdscr.addstr(f"URL: https://news.ycombinator.com/item?id={data['id']}")
|
||||
|
||||
# Display current story author name
|
||||
stdscr.addstr("\nAuthor: ")
|
||||
if data["by"] == None:
|
||||
stdscr.addstr("<Unknown>")
|
||||
else:
|
||||
stdscr.addstr(data["by"])
|
||||
|
||||
# Display current story comments count
|
||||
stdscr.addstr(f"\nComments: {len(data['kids']) if 'kids' in data else 0} | ")
|
||||
|
||||
# Display current story time ago string
|
||||
soup = BeautifulSoup(requests.get(f"https://news.ycombinator.com/item?id={data['id']}").text, "html.parser")
|
||||
timeago = soup.find("span", {"class": "age"} )["title"].replace(",","")
|
||||
stdscr.addstr(f"{timeago}\n")
|
||||
|
||||
# Display search and author prompts on bottom row
|
||||
stdscr.addstr(3, 0, "\x1b[6 q", curses.A_REVERSE + curses.A_BOLD) # Enable reverse video mode for highlighted characters
|
||||
stdscr.addstr(4, 0, f"Search: {search_term}", curses.color_pair(2)) # Set color pair to green for search term
|
||||
stdscr.addstr(5, 0, f"Author: {author_name}", curses.color_pair(3)) # Set color pair to blue for author name
|
||||
|
||||
# Refresh screen
|
||||
stdscr.refresh()
|
||||
|
||||
# Wait for user input
|
||||
key = stdscr.getch()
|
||||
|
||||
# Process input
|
||||
if key == ord('q'):
|
||||
break
|
||||
elif key == curses.KEY_UP:
|
||||
story_index -= 1
|
||||
if story_index < 0:
|
||||
story_index = len(stories)-1
|
||||
elif key == curses.KEY_DOWN:
|
||||
story_index += 1
|
||||
if story_index >= len(stories):
|
||||
story_index = 0
|
||||
elif key == curses.KEY_LEFT:
|
||||
pass # TODO: Implement previous page navigation
|
||||
elif key == curses.KEY_RIGHT:
|
||||
pass # TODO: Implement next page navigation
|
||||
#elif key == ord('/') or key == ord('?'):
|
||||
# search_prompt(stdscr)
|
||||
#elif key == ord('a') or key == ord('A'):
|
||||
# author_prompt(stdscr)
|
||||
|
||||
# Update colors for selected item in list
|
||||
stdscr.addstr(1+story_index, 0, chr(27)+chr(91)+"7"+chr(27)+chr(91)+"m", curses.color_pair(1)) # Highlight selected item with yellow background
|
||||
stdscr.addstr(1+(story_index+1)%len(stories), 0, chr(27)+chr(91)+"4"+chr(27)+chr(91)+"m", curses.color_pair(1)) # Reset background of all unselected items
|
||||
|
||||
curses.wrapper(main)
|
Loading…
Reference in New Issue