def test_get_marker_position_small(self): tb = TimeBar(100, 10) assert tb.get_marker_postion(0) == 0 assert tb.get_marker_postion(1) == 0 assert tb.get_marker_postion(10) == 1 assert tb.get_marker_postion(20) == 2 assert tb.get_marker_postion(30) == 2 assert tb.get_marker_postion(40) == 3 assert tb.get_marker_postion(50) == 4 assert tb.get_marker_postion(99) == 8 assert tb.get_marker_postion(100) == 8
def test_get_marker_position_harder(self): tb = TimeBar(100, 100) assert tb.get_marker_postion(0) == 0 assert tb.get_marker_postion(1) == 1 assert tb.get_marker_postion(10) == 10 assert tb.get_marker_postion(20) == 20 assert tb.get_marker_postion(30) == 29 assert tb.get_marker_postion(40) == 39 assert tb.get_marker_postion(50) == 49 assert tb.get_marker_postion(99) == 97 assert tb.get_marker_postion(100) == 98
def test_get_marker_position_easy(self): tb = TimeBar(100, 102) assert tb.get_marker_postion(0) == 0 assert tb.get_marker_postion(1) == 1 assert tb.get_marker_postion(10) == 10 assert tb.get_marker_postion(20) == 20 assert tb.get_marker_postion(30) == 30 assert tb.get_marker_postion(40) == 40 assert tb.get_marker_postion(50) == 50 assert tb.get_marker_postion(99) == 99 assert tb.get_marker_postion(100) == 100
def __init__(self, movie): """ Player class plays a movie. It also stores the current position. It exposes the all frame numbers in real values. Therefore not encoded. Args: movie (ascii_movie.Movie): Movie Object that the player will play. """ self._movie = movie self._cursor = 0 # virtual cursor pointing to the current frame self._frame_count = 0 self._stopped = False self._clear_screen_setup_done = False for f in self._movie.frames: self._frame_count += f.display_time self.timebar = TimeBar(self._frame_count, self._movie.screen_width)
def test_timebar_with_marker_short(self): tb = TimeBar(100, 8) assert len(tb.get_timebar(0)) == 8 assert tb.get_timebar(0).index("o") == 1 assert tb.get_timebar(0) == "<o >" assert len(tb.get_timebar(10)) == 8 assert tb.get_timebar(10).index("o") == 2 assert tb.get_timebar(10) == "< o >" assert len(tb.get_timebar(50)) == 8 assert tb.get_timebar(50).index("o") == 4 assert tb.get_timebar(50) == "< o >" assert len(tb.get_timebar(99)) == 8 assert tb.get_timebar(99).index("o") == 6 assert tb.get_timebar(99) == "< o>" assert len(tb.get_timebar(100)) == 8 assert tb.get_timebar(100).index("o") == 6 assert tb.get_timebar(100) == "< o>"
def test_timebar_with_marker(self): tb = TimeBar(100, 102) assert len(tb.get_timebar(0)) == 102 assert tb.get_timebar(0).index("o") == 1 assert tb.get_timebar(0) == "<o >" assert len(tb.get_timebar(10)) == 102 assert tb.get_timebar(10).index("o") == 11 assert tb.get_timebar(10) == "< o >" assert len(tb.get_timebar(99)) == 102 assert tb.get_timebar(99).index("o") == 100 assert len(tb.get_timebar(100)) == 102 assert tb.get_timebar(100).index("o") == 100
def test_frame_num_larger_than_timebar_frame_count(self): tb = TimeBar(100, 102) bad_frame_timebar = tb.get_timebar(104) assert len(bad_frame_timebar) == 102 assert bad_frame_timebar == "< o>"
class VT100Player(object): """ Some escape codes used within VT100 Streams @see: http://ascii-table.com/ansi-escape-sequences-vt-100.php """ ESC = chr(27) # VT100 escape character constant JMPHOME = ESC + "[H" # Move cursor to upper left corner CLEARSCRN = ESC + "[2J" # Clear entire screen CLEARDOWN = ESC + "[J" # Clear screen from cursor down def __init__(self, movie): """ Player class plays a movie. It also stores the current position. It exposes the all frame numbers in real values. Therefore not encoded. Args: movie (ascii_movie.Movie): Movie Object that the player will play. """ self._movie = movie self._cursor = 0 # virtual cursor pointing to the current frame self._frame_count = 0 self._stopped = False self._clear_screen_setup_done = False for f in self._movie.frames: self._frame_count += f.display_time self.timebar = TimeBar(self._frame_count, self._movie.screen_width) def play(self): """ Plays the movie """ self._stopped = False for frame in self._movie.frames: if self._stopped: return self._cursor += frame.display_time self._load_frame(frame, self._cursor) time.sleep(frame.display_time / 15) def stop(self): """ Stop the movie """ self._stopped = True def _load_frame(self, frame, frame_pos): """ Buffer the the frame and then call draw_frame to display it Args: frame (ascii_movie.Frame): Frame data to display frame_pos (int): Where the frame falls in the movie """ screenbuf = BytesIO() if not self._clear_screen_setup_done: screenbuf.write(self.CLEARSCRN.encode()) self._clear_screen_setup_done = True # center vertical, with respect to the time bar (like letter boxing) screenbuf.write(self._move_cursor(1, self._movie.top_margin)) for line in frame.data: screenbuf.write((line + "\r\n").encode()) self._update_timebar(screenbuf, frame_pos) # now rewind the internal buffer and fire the public event screenbuf.seek(0) self.draw_frame(screenbuf) def draw_frame(self, screen_buffer): """ Public event method, which can be used to get new Screens. This must be implemented by the user. Args: screen_buffer: its a file like object containing the VT100 screen buffer """ raise NotImplementedError("You must specify how to draw the frame.") def _update_timebar(self, screen_buffer, frame_pos): """ Writes at the bottom of the screen a line like this <.......o.....................> It should visualize a timeline with 'o' is the current position. Args: screen_buffer: file like object, where the data is written to frame_pos (int): current cursor position on frame """ # Move cursor to the bottom of the screen screen_buffer.write(self._move_cursor(1, self._movie.screen_height)) screen_buffer.write(self.timebar.get_timebar(frame_pos).encode()) def _move_cursor(self, x, y): """ Send VT100 commands: go to position X,Y Args: x (int): x coordinate (starting at 1) y (int): y coordinate (starting at 1) Returns: str: the VT100 code as a string """ if 0 >= x > self._movie.screen_width or 0 >= y > self._movie.screen_height: sys.stderr.write("Warning, coordinates out of range. ({0}, {1})\n".format(x, y)) return "".encode() else: return (self.ESC + "[{0};{1}H".format(y, x)).encode()