Refactor to not use curses.wrapper

This commit is contained in:
Nguyễn Gia Phong 2017-03-24 21:57:19 +07:00
parent 202280f760
commit 082cdc3222
3 changed files with 132 additions and 128 deletions

View file

@ -2,4 +2,4 @@
comp
====
console/curses online media player
Curses Online Media Player

254
comp.py
View file

@ -22,135 +22,76 @@ def mpv_wrapper(media, video=True):
del player
def interface(stdscr):
def reattr(y):
track = DATA[start + y - 1]
invert = 8 if track['highlight'] else 0
if track['error']:
stdscr.chgat(y, 0, curses.color_pair(1 + invert) | curses.A_BOLD)
elif track['playing']:
stdscr.chgat(y, 0, curses.color_pair(3 + invert) | curses.A_BOLD)
elif track['selected']:
stdscr.chgat(y, 0, curses.color_pair(5 + invert) | curses.A_BOLD)
elif invert:
stdscr.chgat(y, 0, curses.color_pair(12) | curses.A_BOLD)
else:
stdscr.chgat(y, 0, curses.color_pair(0) | curses.A_NORMAL)
def reattr(stdscr, y):
track = DATA[start + y - 1]
invert = 8 if track['highlight'] else 0
if track['error']:
stdscr.chgat(y, 0, curses.color_pair(1 + invert) | curses.A_BOLD)
elif track['playing']:
stdscr.chgat(y, 0, curses.color_pair(3 + invert) | curses.A_BOLD)
elif track['selected']:
stdscr.chgat(y, 0, curses.color_pair(5 + invert) | curses.A_BOLD)
elif invert:
stdscr.chgat(y, 0, curses.color_pair(12) | curses.A_BOLD)
else:
stdscr.chgat(y, 0, curses.color_pair(0) | curses.A_NORMAL)
def reprint():
stdscr.clear()
stdscr.addstr(0, curses.COLS-12, 'URL')
stdscr.addstr(0, 0, 'Title')
stdscr.chgat(0, 0, curses.color_pair(10) | curses.A_BOLD)
for i, d in enumerate(DATA[start : start+curses.LINES-3]):
stdscr.addstr(i + 1, 0, d['url'].rjust(curses.COLS - 1))
stdscr.addstr(i + 1, 0, d['title'][:curses.COLS-12])
reattr(i + 1)
stdscr.addstr(
curses.LINES - 2,
curses.COLS - 16,
'{:7} {:8}'.format(mode, 'selected' if selected else 'all')
)
stdscr.chgat(curses.LINES - 2, 0, curses.color_pair(8))
stdscr.refresh()
def move(y, delta):
nonlocal start
reattr(y)
if start + y + delta < 1:
start = 0
reprint()
stdscr.move(1, 0)
DATA[0]['highlight'] = True
reattr(1)
DATA[0]['highlight'] = False
return 1
elif start + y + delta > len(DATA):
start = len(DATA) - curses.LINES + 3
reprint()
y = curses.LINES - 3
stdscr.move(y, 0)
DATA[-1]['highlight'] = True
reattr(y)
DATA[-1]['highlight'] = False
return y
def reprint(stdscr):
stdscr.clear()
stdscr.addstr(0, curses.COLS-12, 'URL')
stdscr.addstr(0, 0, 'Title')
stdscr.chgat(0, 0, curses.color_pair(10) | curses.A_BOLD)
for i, d in enumerate(DATA[start : start+curses.LINES-3]):
stdscr.addstr(i + 1, 0, d['url'].rjust(curses.COLS - 1))
stdscr.addstr(i + 1, 0, d['title'][:curses.COLS-12])
reattr(stdscr, i + 1)
stdscr.addstr(
curses.LINES - 2,
curses.COLS - 16,
'{:7} {:8}'.format(mode, 'selected' if selected else 'all')
)
stdscr.chgat(curses.LINES - 2, 0, curses.color_pair(8))
stdscr.refresh()
if 0 < y + delta < curses.LINES - 2:
y = y + delta
elif y + delta < 1:
start += y + delta - 1
reprint()
y = 1
else:
start += y + delta - curses.LINES + 3
reprint()
y = curses.LINES - 3
stdscr.move(y, 0)
DATA[start + y - 1]['highlight'] = True
reattr(y)
DATA[start + y - 1]['highlight'] = False
stdscr.refresh()
def move(stdscr, y, delta):
global start
reattr(stdscr, y)
if start + y + delta < 1:
start = 0
reprint(stdscr)
stdscr.move(stdscr, 1, 0)
DATA[0]['highlight'] = True
reattr(stdscr, 1)
DATA[0]['highlight'] = False
return 1
elif start + y + delta > len(DATA):
start = len(DATA) - curses.LINES + 3
reprint(stdscr)
y = curses.LINES - 3
stdscr.move(stdscr, y, 0)
DATA[-1]['highlight'] = True
reattr(stdscr, y)
DATA[-1]['highlight'] = False
return y
# Init color pairs
curses.use_default_colors()
curses.init_pair(1, 1, -1)
curses.init_pair(2, 2, -1)
curses.init_pair(3, 3, -1)
curses.init_pair(4, 4, -1)
curses.init_pair(5, 5, -1)
curses.init_pair(6, 6, -1)
curses.init_pair(7, 7, -1)
curses.init_pair(8, -1, 7)
curses.init_pair(9, -1, 1)
curses.init_pair(10, -1, 2)
curses.init_pair(11, -1, 3)
curses.init_pair(12, -1, 4)
curses.init_pair(13, -1, 5)
curses.init_pair(14, -1, 6)
curses.curs_set(False)
# Print initial content
start = 0
reprint()
y = 1
DATA[0]['highlight'] = True
stdscr.move(1, 0)
reattr(1)
DATA[0]['highlight'] = False
while True:
c = stdscr.getch()
if c == curses.KEY_RESIZE:
curses.update_lines_cols()
reprint()
y = 1
reattr(y)
elif c in (ord('j'), curses.KEY_DOWN):
y = move(y, 1)
elif c in (ord('k'), curses.KEY_UP):
y = move(y, -1)
elif c == curses.KEY_PPAGE:
y = move(y, -curses.LINES)
elif c == curses.KEY_NPAGE:
y = move(y, curses.LINES)
elif c == curses.KEY_HOME:
y = move(y, -len(DATA))
elif c == curses.KEY_END:
y = move(y, len(DATA))
elif c == ord(' '):
DATA[start + y - 1]['selected'] = not DATA[start + y - 1]['selected']
y = move(y, 1)
elif c == ord('x'): # temporally behavior
mpv_wrapper('https://youtu.be/' + DATA[start + y - 1]['url'], video)
elif c == ord('v'):
player.quit_watch_later()
elif c in (ord('q'), 27): # 27 is Escape key
stdscr.addstr(curses.LINES - 1, 0, 'Quit comp? [y/N]')
if stdscr.getch() == ord('y'):
break
reprint()
stdscr.refresh()
if 0 < y + delta < curses.LINES - 2:
y = y + delta
elif y + delta < 1:
start += y + delta - 1
reprint(stdscr)
y = 1
else:
start += y + delta - curses.LINES + 3
reprint(stdscr)
y = curses.LINES - 3
stdscr.move(stdscr, y, 0)
DATA[start + y - 1]['highlight'] = True
reattr(stdscr, y)
DATA[start + y - 1]['highlight'] = False
stdscr.refresh()
return y
parser = ArgumentParser(description="console/curses online media player")
@ -172,4 +113,67 @@ for i in DATA:
i['playing'] = False
i['selected'] = False
i['highlight'] = False
curses.wrapper(interface)
stdscr = curses.initscr()
curses.noecho()
curses.cbreak()
stdscr.keypad(True)
curses.curs_set(False)
curses.start_color()
curses.use_default_colors()
curses.init_pair(1, 1, -1)
curses.init_pair(2, 2, -1)
curses.init_pair(3, 3, -1)
curses.init_pair(4, 4, -1)
curses.init_pair(5, 5, -1)
curses.init_pair(6, 6, -1)
curses.init_pair(7, 7, -1)
curses.init_pair(8, -1, 7)
curses.init_pair(9, -1, 1)
curses.init_pair(10, -1, 2)
curses.init_pair(11, -1, 3)
curses.init_pair(12, -1, 4)
curses.init_pair(13, -1, 5)
curses.init_pair(14, -1, 6)
# Print initial content
start = 0
reprint(stdscr)
y = 1
DATA[0]['highlight'] = True
stdscr.move(stdscr, 1, 0)
reattr(stdscr, 1)
DATA[0]['highlight'] = False
c = stdscr.getch()
while c != 113: # letter q
if c == curses.KEY_RESIZE:
curses.update_lines_cols()
reprint(stdscr)
y = 1
reattr(stdscr, y)
elif c in (ord('j'), curses.KEY_DOWN):
y = move(stdscr, y, 1)
elif c in (ord('k'), curses.KEY_UP):
y = move(stdscr, y, -1)
elif c == curses.KEY_PPAGE:
y = move(stdscr, y, -curses.LINES)
elif c == curses.KEY_NPAGE:
y = move(stdscr, y, curses.LINES)
elif c == curses.KEY_HOME:
y = move(stdscr, y, -len(DATA))
elif c == curses.KEY_END:
y = move(stdscr, y, len(DATA))
elif c == ord(' '):
DATA[start + y - 1]['selected'] = not DATA[start + y - 1]['selected']
y = move(stdscr, y, 1)
elif c == ord('x'): # temporally behavior
mpv_wrapper('https://youtu.be/' + DATA[start + y - 1]['url'], video)
stdscr.refresh()
c = stdscr.getch()
curses.nocbreak()
stdscr.keypad(False)
curses.echo()
curses.endwin()

View file

@ -8,12 +8,12 @@ with open('README.rst') as f:
setup(name = 'comp',
version = '0.1.0a1',
url = 'https://github.com/McSinyx/comp',
description = ('console/curses online media player'),
description = ('Curses Online Media Player'),
long_description=long_description,
author = 'McSinyx',
author_email = 'vn.mcsinyx@gmail.com',
py_modules = ['mpv'],
scripts=['comp'],
scripts=['comp.py'],
classifiers = ['Development Status :: 1 - Planning',
'Environment :: Console :: Curses',
'Intended Audience :: End Users/Desktop',