ADD: main logic
parent
6354291fe3
commit
fae0415440
@ -0,0 +1,245 @@
|
||||
import csv
|
||||
import curses
|
||||
from curses import wrapper
|
||||
from curses.textpad import Textbox, rectangle
|
||||
import sys
|
||||
|
||||
|
||||
## Initialization of bottomline dependencies
|
||||
|
||||
# Array of names
|
||||
files = []
|
||||
|
||||
# Make sure these are defined as global
|
||||
|
||||
# CSV fields
|
||||
fields = ["service", "user", "pswd"]
|
||||
|
||||
# Password file
|
||||
PASFILE="pastest.csv"
|
||||
|
||||
|
||||
# Initializes Curses' screen
|
||||
def main(stdscr):
|
||||
# Opens password file
|
||||
with open(PASFILE, mode='r+') as pasfile:
|
||||
# Creates reader and writer objects
|
||||
csvreader=csv.DictReader(pasfile)
|
||||
csvwriter=csv.DictWriter(pasfile, fields)
|
||||
for ids in csvreader:
|
||||
files.append(ids)
|
||||
## Initializes color pairs
|
||||
# Password pallete (Foreground = Background)
|
||||
curses.init_pair(1, curses.COLOR_BLACK, curses.COLOR_BLACK)
|
||||
pwd_pallete = curses.color_pair(1)
|
||||
# Main window pallete
|
||||
curses.init_pair(2, curses.COLOR_WHITE, curses.COLOR_BLACK)
|
||||
main_pallete = curses.color_pair(2)
|
||||
|
||||
# Clears screen
|
||||
stdscr.clear()
|
||||
# Determines terminal size
|
||||
global TERM_LINES
|
||||
TERM_LINES=curses.LINES - 1
|
||||
if TERM_LINES <= 15:
|
||||
sys.exit("ERROR: Your terminal is too small!")
|
||||
global TERM_COLS
|
||||
TERM_COLS=curses.COLS - 1
|
||||
if TERM_COLS <=60:
|
||||
sys.exit("ERROR: Your terminal is too small!")
|
||||
# Global (program-wide) variables for cursor position
|
||||
global LINE
|
||||
LINE = 0
|
||||
global COLUMN
|
||||
COLUMN = 0
|
||||
# Hard limit for the main window
|
||||
global WINLIMIT
|
||||
WINLIMIT = TERM_LINES - 3
|
||||
# Maximum amount of colums displayable on the main window, considering the terminal size
|
||||
global MAX_ROWS
|
||||
MAX_ROWS = int(TERM_COLS/17)
|
||||
# Maximum amount of lines (All lines, minus border and terminal break)
|
||||
global MAX_LINES
|
||||
MAX_LINES = TERM_LINES - 2
|
||||
# Maximum amount of items a given terminal space is able to display
|
||||
global MAX_ITEMS
|
||||
MAX_ITEMS = MAX_ROWS*MAX_LINES
|
||||
# Specifies what item to highlight
|
||||
global ITEM_CURSOR
|
||||
ITEM_CURSOR = 0
|
||||
# Defines the current page
|
||||
global CURR_PAGE
|
||||
CURR_PAGE = 1
|
||||
# Defines the amount of pages needed to house all files within the terminal space
|
||||
global MAX_PAGES
|
||||
MAX_PAGES = int(len(files)/MAX_ITEMS)
|
||||
# Status bar message
|
||||
global STATUS_MESSAGE
|
||||
STATUS_MESSAGE = ""
|
||||
# Global pointer for the cursor's item
|
||||
global GLOBAL_CURSOR
|
||||
GLOBAL_CURSOR = 0
|
||||
|
||||
|
||||
|
||||
# Initializes the main window
|
||||
mainwin = curses.newwin(TERM_LINES -1, TERM_COLS, 0, 0)
|
||||
mainwin.keypad(True)
|
||||
mainwin.bkgd(' ', main_pallete)
|
||||
mainwin.clear()
|
||||
|
||||
# Initializes the bottom window
|
||||
statusWin = curses.newwin(3, TERM_COLS, TERM_LINES, 0)
|
||||
statusWin.keypad(True)
|
||||
statusWin.border()
|
||||
statusWin.bkgd(' ', main_pallete)
|
||||
statusWin.clear()
|
||||
|
||||
|
||||
while True:
|
||||
# Creates a name list
|
||||
displayList = []
|
||||
# Makes sure the windows are properly clean
|
||||
mainwin.clear()
|
||||
statusWin.clear()
|
||||
mainwin.border()
|
||||
mainwin.refresh()
|
||||
statusWin.border()
|
||||
statusWin.refresh()
|
||||
# Reset global necessities
|
||||
LINE = 0
|
||||
COLUMN = 0
|
||||
currItem = 0
|
||||
highOpt = ()
|
||||
# Defines what to display
|
||||
startDisplay = (CURR_PAGE-1)*MAX_ITEMS
|
||||
stopDisplay = CURR_PAGE*MAX_ITEMS
|
||||
|
||||
# Appends the names in the CSV to display on the main window
|
||||
for ps_name in files:
|
||||
displayList.append(ps_name['service'][:15])
|
||||
for item in displayList[startDisplay:stopDisplay]:
|
||||
# If the item is the one with the cursor, highlight it
|
||||
if currItem == ITEM_CURSOR:
|
||||
mode = curses.A_REVERSE
|
||||
highOpt = mainwin.getyx()
|
||||
else:
|
||||
mode = curses.A_NORMAL
|
||||
mainwin.addstr(1 + LINE, 1 + COLUMN, item, mode)
|
||||
LINE+=1
|
||||
currItem+=1
|
||||
if LINE >= WINLIMIT:
|
||||
LINE = 0
|
||||
COLUMN+=16
|
||||
mainwin.refresh()
|
||||
STATUS_MESSAGE = "cmds: PrvPage(F1),NxtPage(F2),(q)uit,(e)xmn,(n)ew"
|
||||
statusWin.addstr(0,0, STATUS_MESSAGE)
|
||||
statusWin.refresh()
|
||||
|
||||
|
||||
## Command logic
|
||||
# The GLOBAL_CURSOR points to the main files object, so that it gets the right file.
|
||||
global c
|
||||
c = mainwin.getch()
|
||||
if c == ord('q'):
|
||||
return(0)
|
||||
elif c == curses.KEY_DOWN:
|
||||
ITEM_CURSOR+=1
|
||||
GLOBAL_CURSOR+=1
|
||||
elif c == curses.KEY_UP:
|
||||
ITEM_CURSOR-=1
|
||||
GLOBAL_CURSOR-=1
|
||||
elif c == curses.KEY_RIGHT:
|
||||
ITEM_CURSOR+=MAX_LINES
|
||||
GLOBAL_CURSOR+=MAX_LINES
|
||||
elif c == curses.KEY_LEFT:
|
||||
ITEM_CURSOR-=MAX_LINES
|
||||
GLOBAL_CURSOR-=MAX_LINES
|
||||
elif c == curses.KEY_F1 or c == curses.KEY_PPAGE:
|
||||
CURR_PAGE-=1
|
||||
GLOBAL_CURSOR-=MAX_ITEMS
|
||||
elif c == curses.KEY_F2 or c == curses.KEY_NPAGE:
|
||||
CURR_PAGE+=1
|
||||
GLOBAL_CURSOR+=MAX_ITEMS
|
||||
# For some reason, KEY_UP is 10, instead of the 343 the debbuger flags... Welp ¯\_(ツ)_/¯
|
||||
elif c == 10 or c == curses.KEY_ENTER or c == ord('e'):
|
||||
# highOpt = Coordinates of the first option's character
|
||||
LINE = highOpt[0]
|
||||
COLUMN = highOpt[1]
|
||||
# These if statements make it so files being shown will always do so inside the terminal screen
|
||||
if COLUMN+32 > TERM_COLS:
|
||||
COLUMN-=int(TERM_COLS/MAX_ROWS)
|
||||
if LINE+10 > TERM_LINES:
|
||||
LINE-=10
|
||||
# Initializes the file viewer window
|
||||
fileWin = curses.newwin(5, 40, LINE+5, COLUMN)
|
||||
fileWin.clear()
|
||||
fileWin.border()
|
||||
passService = files[GLOBAL_CURSOR]['service'][:15]
|
||||
passUser = files[GLOBAL_CURSOR]['user'][:32]
|
||||
passPswd = files[GLOBAL_CURSOR]['pswd'][:32]
|
||||
fileWin.addstr(1, 1, "SRVC: " + passService)
|
||||
fileWin.addstr(2, 1, "NAME: " + passUser)
|
||||
fileWin.addstr(3, 1, "PSWD: " + passPswd)
|
||||
fileWin.refresh()
|
||||
fileWin.getch()
|
||||
elif c == ord('n'):
|
||||
npWin = curses.newwin(4, 52,int(TERM_LINES/2)-2, int(TERM_COLS/2)-18)
|
||||
npWin.clear()
|
||||
npWin.border()
|
||||
curses.echo(True)
|
||||
npWin.addstr(1, 1, "SRVC:")
|
||||
npWin.addstr(2, 1, "USER:")
|
||||
npWin.addstr(3, 1, "PSWD:")
|
||||
passService = npWin.getstr(1, 6, 16)
|
||||
passUser = npWin.getstr(2, 6, 32)
|
||||
passPswd = npWin.getstr(3, 6, 32)
|
||||
# wtf = write to file
|
||||
|
||||
## TODO: solve this shit with curses.textpad.Textbox()
|
||||
wtf = {'service':passService[2:], 'user':passUser[2:], 'pswd':passPswd[2:]}
|
||||
filesOld = files
|
||||
files.clear()
|
||||
files.append(filesOld)
|
||||
files.append(wtf)
|
||||
with open(PASFILE, mode='r+') as pasfile:
|
||||
csvwriter=csv.DictWriter(pasfile, fields)
|
||||
csvwriter.writeheader()
|
||||
csvwriter.writerow(files)
|
||||
# Reopens the file
|
||||
pasfile.close()
|
||||
with open(PASFILE, mode='r+') as pasfile:
|
||||
# Creates reader and writer objects
|
||||
csvreader=csv.DictReader(pasfile)
|
||||
csvwriter=csv.DictWriter(pasfile, fields)
|
||||
for ids in csvreader:
|
||||
files.append(ids)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
mainwin.refresh()
|
||||
mainwin.getch()
|
||||
|
||||
|
||||
def close():
|
||||
# This makes sure the terminal gets completely "free of curses" when the application ends
|
||||
curses.nocbreak()
|
||||
curses.echo()
|
||||
curses.endwin()
|
||||
|
||||
# Debbuging
|
||||
print("LINES: ", TERM_LINES)
|
||||
print("COLS : ", TERM_COLS)
|
||||
print("MAX_ROWS :", MAX_ROWS)
|
||||
print("Goodbye! \n")
|
||||
|
||||
|
||||
wrapper(main)
|
||||
close()
|
Loading…
Reference in New Issue