diff --git a/api.py b/api.py new file mode 100644 index 0000000..57b1be8 --- /dev/null +++ b/api.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python3 +import requests +from dataclasses import dataclass +@dataclass +class Story: + id: int + title: str + link: str + author: str + votes: int + comments: int + +def get_topstories(): + # Query Hacker News API for top stories and their titles/links + # returns the top 500 stories, so quite enough. + url = 'https://hacker-news.firebaseio.com/v0/topstories.json' + r = requests.get(url) + if not r.ok: + raise Exception('Error fetching data from Hacker News API') + return r.json() + +def get_story(story_id): + story_url = f'https://hacker-news.firebaseio.com/v0/item/{story_id}.json' + s = requests.get(story_url).json() + return Story(s['id'], + s['title'], + s['url'] if 'url' in s else 'No URL', + s['by'], + s['score'], + len(s['kids']) if 'kids' in s else 0) + +def main(): + ts = get_topstories() + s = get_story(ts[0]) + print(s) + +if __name__ == '__main__': + main() diff --git a/hn.py b/hn.py index 09ebfd2..7957442 100755 --- a/hn.py +++ b/hn.py @@ -1,46 +1,19 @@ #!/usr/bin/env python3 #TODO: make sure things dont explode no matter what terminal size -# -> prevent linebreaks in a single story -# -> only load as many stories as fit +# x prevent linebreaks in a single story +# x only load as many stories as fit +# -> refresh on resize import requests from bs4 import BeautifulSoup as Soup import curses import webbrowser -from dataclasses import dataclass +import api spinner_states = ['-', '\\', '|', '/'] -@dataclass -class Story: - id: int - title: str - link: str - author: str - votes: int - comments: int - -def get_topstories(): - # Query Hacker News API for top stories and their titles/links - # returns the top 500 stories, so quite enough. - url = 'https://hacker-news.firebaseio.com/v0/topstories.json' - r = requests.get(url) - if not r.ok: - raise Exception('Error fetching data from Hacker News API') - return r.json() - -def get_story(story_id): - story_url = f'https://hacker-news.firebaseio.com/v0/item/{story_id}.json' - s = requests.get(story_url).json() - return Story(s['id'], - s['title'], - s['url'] if 'url' in s else 'No URL', - s['by'], - s['score'], - len(s['kids']) if 'kids' in s else 0) - def footer(stdscr, content): stdscr.addstr(curses.LINES-1, 0, content, curses.A_REVERSE) @@ -50,15 +23,15 @@ def main(stdscr): stdscr.clear() _, width = stdscr.getmaxyx(); - num_stories = curses.LINES - 3 # headline, detail, footer - topstories = get_topstories() + + topstories = api.get_topstories() stories = [] for idx, i in enumerate(topstories[:num_stories]): stdscr.clear() - footer(stdscr, f'[{spinner_states[idx%4]}] Getting stories...') + footer(stdscr, f'[{spinner_states[idx%4]}] Loading stories...') stdscr.refresh() - stories.append(get_story(i)) + stories.append(api.get_story(i)) # Display list of stories in terminal window with arrow key navigation current_pos = 0