def __init__(self, stdscr): self.stdscr = stdscr self.reddit_client = RedditClient() self.current_posts = [] # get screen dimensions self.__max_y, self.__max_x = self.stdscr.getmaxyx()
class CursesClient(object): """ Handles drawing the text based UI """ __FLUSH = 0 __MARGIN_Y = 2 __MARGIN_X = 2 def __init__(self, stdscr): self.stdscr = stdscr self.reddit_client = RedditClient() self.current_posts = [] # get screen dimensions self.__max_y, self.__max_x = self.stdscr.getmaxyx() def __draw_scr_size(self): """ Debug output to determine drawable screen size :return: void """ str_scr_size = "{0}, {1}".format(self.__FLUSH, self.__max_x) self.stdscr.addstr( self.__FLUSH, self.__max_x - self.__MARGIN_X - len(str_scr_size), str_scr_size ) def __draw_prompt(self): """ Draw placeholder prompt :return: void """ self.stdscr.addstr( self.__max_y - self.__MARGIN_Y, self.__FLUSH, ">" ) def __draw_ch(self, input_char): """ Debug output to draw last pressed key :param input_char: char of last input key :return: void """ self.stdscr.addstr( self.__max_y - self.__MARGIN_Y, self.__FLUSH, ">{0}".format(str(input_char)) ) def __draw_page_num(self, page): """ Draw placeholder current page number :param page: int page number :return: void """ str_page_num = "page: {0}".format(page) self.stdscr.addstr( self.__max_y - self.__MARGIN_Y, self.__max_x - self.__MARGIN_X - len(str_page_num), str_page_num ) def __draw_subreddit_name(self, subreddit, sort): """ Draw placeholder subreddit name :param subreddit: string subreddit :param sort: string sort e.g. new, top, hot, etc :return: """ str_scr_size = "r/{subreddit}/{sort}".format( subreddit=subreddit, sort=sort ) self.stdscr.addstr( self.__FLUSH, self.__max_x - self.__MARGIN_X - len(str_scr_size), str_scr_size ) def __subreddit_menu(self): """ Switch to buffered input and prompt for subreddit name :return: void """ #flush input buffer flushinp() str_input_subreddit = "subreddit:" self.stdscr.addstr( self.__max_y - self.__MARGIN_Y, self.__FLUSH, str_input_subreddit ) # disable cinput mode and enter buffered input mode and echo nocbreak() echo() input_buffer = self.stdscr.getstr() if input_buffer == "back": # enable cinput mode and disable echo cbreak() noecho() else: self.__posts_menu(input_buffer) def __posts_menu(self, subreddit): """ Return to cinput mode and wait for key input :param subreddit: subreddit string :return: void """ # enable cinput mode and disable echo cbreak() noecho() input_char = '_' direction = None anchor = None while input_char != ord('q'): # paging if input_char == KEY_RIGHT: direction = "after" anchor = self.current_posts[9]["data"]["name"] elif input_char == KEY_LEFT: direction = "before" anchor = self.current_posts[0]["data"]["name"] # post selection elif input_char >= 48 and input_char <= 57: self.__post_detail(self.current_posts[input_char - 48]) # subreddit sorting elif input_char == ord('n'): sort = "new" elif input_char == ord('t'): sort = "top" elif input_char == ord('c'): sort = "controversial" elif input_char == ord('h'): sort = "hot" else: sort = "hot" self.current_posts = self.reddit_client.get_subreddit_posts( subreddit, sort, direction=direction, anchor=anchor ) self.stdscr.clear() self.__draw_subreddit_name(subreddit, sort) self.__draw_ch(input_char) self.__draw_page_num(1) for post_num in range(len(self.current_posts)): post_title = filter_unicode( self.current_posts[post_num]["data"]["title"] ) self.stdscr.addstr( post_num, self.__FLUSH, "{post_num} -> {title}".format( post_num=post_num, title=post_title ) ) input_char = self.stdscr.getch() def __post_detail(self, post): """ Placeholder display of post text, with placeholder text limit :param post: post self text string :return: void """ input_char = '' while input_char != ord('q'): self.stdscr.clear() self.__draw_ch(input_char) # filter out unicode str_post = filter_unicode(post["data"]["selftext"]) self.stdscr.addstr( self.__FLUSH, self.__FLUSH, str_post[:2000] or "No text found" ) input_char = self.stdscr.getch() def top_menu(self): """ Placeholder top level menu, only r for subreddits and q to quit :return: void """ input_char = '' while input_char != ord('q'): self.stdscr.clear() self.__draw_scr_size() self.__draw_prompt() input_char = self.stdscr.getch() if input_char == ord('r'): self.__subreddit_menu() def run(self): """ Main entry point :return: void """ self.top_menu()
class TestRedditClient(object): @classmethod def setup_class(self): self.reddit_client = RedditClient() def test_access_token_not_none(self): assert_is_not_none(self.reddit_client.access_token) pprint(self.reddit_client.access_token) def test_get_subreddit_sidebar(self): json = self.reddit_client.get_subreddit_sidebar("civ") assert_is_not_none(json) assert_is_not_none(json["data"]["description"]) assert_is_not_none(json["data"]["header_title"]) assert_is_not_none(json["data"]["public_description"]) pprint(json) def test_get_subreddit_hot(self): json = self.reddit_client.get_subreddit_posts("civ", "hot") assert_is_not_none(json) assert_is_not_none(json[0]["data"]["name"]) assert_is_not_none(json[0]["data"]["title"]) assert_is_not_none(json[0]["data"]["selftext"]) pprint(json) def test_get_subreddit_top(self): json = self.reddit_client.get_subreddit_posts("civ", "top") assert_is_not_none(json) assert_is_not_none(json[0]["data"]["name"]) assert_is_not_none(json[0]["data"]["title"]) assert_is_not_none(json[0]["data"]["selftext"]) pprint(json) def test_get_subreddit_new(self): json = self.reddit_client.get_subreddit_posts("civ", "new") assert_is_not_none(json) assert_is_not_none(json[0]["data"]["name"]) assert_is_not_none(json[0]["data"]["title"]) assert_is_not_none(json[0]["data"]["selftext"]) pprint(json) def test_get_subreddit_controversial(self): json = self.reddit_client.get_subreddit_posts("civ", "controversial") assert_is_not_none(json) assert_is_not_none(json[0]["data"]["name"]) assert_is_not_none(json[0]["data"]["title"]) assert_is_not_none(json[0]["data"]["selftext"]) pprint(json) def test_get_subreddit_page_after(self): anchor_json = self.reddit_client.get_subreddit_posts("civ", "new") anchor = anchor_json[0]["data"]["name"] json = self.reddit_client.get_subreddit_posts( "civ", "new", "after", anchor ) assert_is_not_none(json) assert_is_not_none(json[0]["data"]["name"]) assert_is_not_none(json[0]["data"]["title"]) assert_is_not_none(json[0]["data"]["selftext"]) pprint(json) def test_get_subreddit_page_before(self): anchor_after_json = self.reddit_client.get_subreddit_posts("civ", "new") anchor_after = anchor_after_json[0]["data"]["name"] anchor_before_json = self.reddit_client.get_subreddit_posts( "civ", "new", "after", anchor_after ) anchor_before = anchor_before_json[0]["data"]["name"] json = self.reddit_client.get_subreddit_posts( "civ", "new", "before", anchor_before ) assert_is_not_none(json) assert_is_not_none(json[0]["data"]["name"]) assert_is_not_none(json[0]["data"]["title"]) assert_is_not_none(json[0]["data"]["selftext"]) pprint(json)
def setup_class(self): self.reddit_client = RedditClient()