diff --git a/rtv/history.py b/rtv/history.py new file mode 100644 index 0000000..8db031e --- /dev/null +++ b/rtv/history.py @@ -0,0 +1,65 @@ +import os + + +__all__ = ['load_history', 'save_history'] + + +def history_path(): + """ + Create the path to the history log + """ + HOME = os.path.expanduser('~') + XDG_CONFIG_HOME = os.getenv('XDG_CACHE_HOME', os.path.join(HOME, '.config')) + path = os.path.join(XDG_CONFIG_HOME, 'rtv') + if not os.path.exists(path): + os.makedirs(path) + return os.path.join(path, 'history.log') + + +def load_history(): + """ + Load the history file into memory if it exists + """ + path = history_path() + if os.path.exists(path): + with open(path) as history_file: + # reverse the list so the newest ones are first + history = [line.strip() for line in history_file][::-1] + return OrderedSet(history) + return OrderedSet() + + +def save_history(history): + """ + Save the visited links to the history log + """ + path = history_path() + with open(path, 'w+') as history_file: + for i in range(200): + if not history: + break + history_file.write(history.pop() + '\n') + + +class OrderedSet(object): + """ + A simple implementation of an ordered set. A set is used to check + for membership, and a list is used to maintain ordering. + """ + + def __init__(self, elements=[]): + self._set = set(elements) + self._list = elements + + def __contains__(self, item): + return item in self._set + + def __len__(self): + return len(self._list) + + def add(self, item): + self._set.add(item) + self._list.append(item) + + def pop(self): + return self._list.pop() diff --git a/rtv/subreddit.py b/rtv/subreddit.py index d1f7ff3..9ce4322 100644 --- a/rtv/subreddit.py +++ b/rtv/subreddit.py @@ -1,7 +1,7 @@ import curses import time import logging - +import atexit import requests import praw @@ -10,16 +10,22 @@ from .page import BasePage, Navigator, BaseController from .submission import SubmissionPage from .content import SubredditContent from .helpers import clean, open_browser, open_editor +from .history import load_history, save_history from .docs import SUBMISSION_FILE from .curses_helpers import (BULLET, UARROW, DARROW, GOLD, Color, LoadScreen, show_notification, prompt_input) -__all__ = ['opened_links', 'SubredditController', 'SubredditPage'] +__all__ = ['history', 'SubredditController', 'SubredditPage'] _logger = logging.getLogger(__name__) -# Used to keep track of browsing history across the current session -opened_links = set() +history = load_history() + + +@atexit.register +def save_links(): + global history + save_history(history) class SubredditController(BaseController): @@ -96,8 +102,8 @@ class SubredditPage(BasePage): page.loop() if data['url'] == 'selfpost': - global opened_links - opened_links.add(data['url_full']) + global history + history.add(data['url_full']) @SubredditController.register(curses.KEY_ENTER, 10, 'o') def open_link(self): @@ -106,8 +112,8 @@ class SubredditPage(BasePage): url = self.content.get(self.nav.absolute_index)['url_full'] open_browser(url) - global opened_links - opened_links.add(url) + global history + history.add(url) @SubredditController.register('p') def post_submission(self): @@ -168,7 +174,7 @@ class SubredditPage(BasePage): row = n_title + offset if row in valid_rows: - seen = (data['url_full'] in opened_links) + seen = (data['url_full'] in history) link_color = Color.MAGENTA if seen else Color.BLUE attr = curses.A_UNDERLINE | link_color text = clean(u'{url}'.format(**data))