Navigation and adding favorites working

This commit is contained in:
sloumdrone 2019-01-03 22:55:46 -08:00
parent feaf05c11d
commit 379085f971
1 changed files with 153 additions and 58 deletions

211
main.lua
View File

@ -1,10 +1,11 @@
#!/usr/bin/env lua
local version = 'v0.3.5'
local socket = require("socket")
local urlparser = require("socket.url")
local separator = '\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n'
local valid_types = {'0', '1', 'i'}
local links = {}
session = { history={ loc=0, items={} }, current_links = {}, favorites={} }
local save_file = string.format('%s/.stubbfaves', assert(os.getenv('HOME'), 'Unable to get home directory'))
string.split = function(inputstr, sep)
@ -30,32 +31,16 @@ table.has = function(t, item)
return false
end
table.join = function(inputtable, sep)
local s = ''
if type(inputtable) ~= 'table' then
do
return nil
end
table.truncate = function(t, i)
while t[i] do
table.remove(t, i)
end
for i, v in ipairs(inputtable) do
if type(v) == 'number' then
v = tostring(v)
end
if type(v) == 'string' then
s = s..v
s = s..sep
end
end
return s
end
--based on:
--https://stackoverflow.com/questions/9013290/lua-socket-client/9014261#9014261
function request_gopher(host, port, query)
--based on: https://stackoverflow.com/questions/9013290/lua-socket-client/9014261#9014261
local tcp = assert(socket.tcp())
local response = {}
@ -90,76 +75,152 @@ function display_gophermap_row(row)
local val = string.split(row, '\t')
local gophertype = string.sub(val[1], 1, 1)
local text = string.sub(val[1], 2)
local spacer = ' '
local spacer = ' '
if gophertype == 'i' then
print(spacer..text)
elseif table.has(valid_types, gophertype) then
local leader = gophertype == '0' and 'TXT' or 'MAP'
local url = string.format('%s:%s/%s%s', val[3], val[4], gophertype, val[2])
table.insert(links, url)
local linknum = string.format('[%d]', #links)
print(string.format(' %s %6s %s', leader, linknum, text))
local url = string.format('%s:%s/%s%s', val[3] or '', val[4] or '', gophertype, val[2] or '/')
table.insert(session.current_links, url)
local linknum = string.format('(%d)', #session.current_links)
print(string.format(' %s %5s %s', leader, linknum, text))
end
end
function getch()
-- taken from: http://lua.2524044.n2.nabble.com/How-to-get-one-keystroke-without-hitting-Enter-td5858614.html
os.execute("stty cbreak </dev/tty >/dev/tty 2>&1")
local key = io.read(1)
os.execute("stty -cbreak </dev/tty >/dev/tty 2>&1");
print('\27[1D ')
return(key);
end
function mainloop()
print('\n\27[7m * S t u b b * \27[0m')
print('| |')
print('| A gopher browser rendering gophermaps and |')
print('| text files. |')
print('| |')
print('\n')
while true do
print('\27[7m (G)o to url, (B)ack, (V)isit link, (Q)uit \27[0m')
local bar = string.format('\27[7m o--[ S t u b b ]--> (H)elp, (Q)uit %d/%d \27[0m', session.history.loc, #session.history.items)
print(bar)
-- print('\27[7m (G)o to url, (B)ack, (V)isit link, (Q)uit \27[0m')
local key = string.lower(getch())
io.write('\n')
if key == 'q' then
save_favorites()
os.exit(0)
elseif key == 'h' then
print_help()
elseif key == 'b' then
back()
elseif key == 'f' then
forward()
elseif key == 'a' then
local title
repeat
io.write('Enter title for favorite: ')
title = io.read()
until title
table.insert(session.favorites,{display = title, link = session.history.items[session.history.loc]})
elseif key == 'l' then
show_favorites()
elseif key == 'g' then
io.write('Enter gopher url: ')
io.write('Enter gopher url > ')
local url = io.read()
url = parse_url(url)
if not url.host or url.scheme ~= 'gopher' then
print(separator)
print(' I n v a l i d u r l')
print(separator)
if url ~= '0' and url ~= '' then
go_to_url(url, true)
else
filedata = request_gopher(url.host, url.port, url.path)
print(separator)
handle_response(filedata, url.gophertype)
print(separator)
print('\n')
end
elseif key == 'v' then
local linkid
local favorite
repeat
io.write('Enter link id: ')
io.flush()
linkid = tonumber(io.read())
favorite = false
io.write('Enter link id (0 to cancel) > ')
local inp = io.read()
linkid = tonumber(inp)
if not linkid and string.sub(inp, 1, 1) == 'f' then
linkid = tonumber(string.sub(inp, 2, 2))
favorite = true
end
until linkid
local linkurl = links[linkid]
print(separator)
print(linkurl or 'No such link')
print(separator)
local linkurl
if favorite then
linkurl = session.favorites[linkid].link
else
linkurl = session.current_links[linkid]
end
if linkurl then
table.truncate(session.history.items, session.history.loc + 1)
go_to_url(linkurl, true)
else
local out = string.format('Link id %d does not exist...', linkid)
print_gopher_error(out)
end
end
end
end
function back()
if session.history.loc > 1 and #session.history.items > 1 then
session.history.loc = session.history.loc - 1
go_to_url(session.history.items[session.history.loc])
end
end
function forward()
if session.history.loc < #session.history.items then
session.history.loc = session.history.loc + 1
go_to_url(session.history.items[session.history.loc])
end
end
function print_help()
print('\nStubb ' .. version)
print('\nA text based gopher client that\nsupports gophertypes 0, 1, and 7\n(text, gopher map, search).')
print('\nCommands:\n')
print('(G)o to url\n(V)iew link id\n(L)ist favorites\n(A)dd to favorites\n(R)emove from favorites\n(B)ack\n(F)orward\n(S)ave to disk\n(H)elp\n(Q)uit\n')
end
function print_gopher_error(text)
print(separator)
print(text)
print(separator)
end
function go_to_url(u, add2history)
url = parse_url(u)
if not url.host or url.scheme ~= 'gopher' then
print(separator)
print(' I n v a l i d u r l')
print(separator)
elseif table.has(valid_types, url.gophertype) then
filedata = request_gopher(url.host, url.port, url.path)
print(separator)
handle_response(filedata, url.gophertype)
print(separator)
local o = url.scheme .. '://' .. url.host .. ':' .. url.port .. '/' .. url.gophertype .. url.path
print(o)
if add2history then
table.truncate(session.history.items, session.history.loc + 1)
table.insert(session.history.items, o)
session.history.loc = session.history.loc + 1
end
end
end
function handle_response(res_table, gtype)
if gtype == 0 then
for i, v in ipairs(res_table) do
print(v)
end
if gtype == '0' or gtype == 0 then
local o = table.concat(res_table, '\n')
print(o)
else
links = {}
session.current_links = {}
for i, v in ipairs(res_table) do
display_gophermap_row(v)
end
@ -179,9 +240,9 @@ function parse_url(u)
if not parsed.path then
parsed.path = '/'
end
if string.find(parsed.path, '^/%d/') then
if string.find(parsed.path, '^/[%d%a]') then
parsed.gophertype = string.sub(parsed.path, 2, 2)
parsed.path = string.sub(parsed.path, 3)
parsed.path = string.sub(parsed.path, 3) or '/'
elseif string.sub(parsed.path, -1) == '/' then
parsed.gophertype = '1'
else
@ -192,5 +253,39 @@ function parse_url(u)
end
function show_favorites()
print(separator)
print('\n >---F A V O R I T E S--->\n\n')
for i, v in ipairs(session.favorites) do
print(string.format(' (f%d) %s', i, v.display))
end
print(separator)
end
function save_favorites()
local file = io.open(save_file, 'w+')
io.output(file)
io.write("session.favorites = {\n")
for _,v in ipairs(session.favorites) do
io.write(string.format(" {[%q] = %q, [%q] = %q},\n", 'display', v.display, 'link', v.link))
end
io.write("}\n")
io.close(file)
end
function file_exists(name)
local f=io.open(name,"r")
if f~=nil then io.close(f) return true else return false end
end
-- run the program
if file_exists(save_file) then
dofile(save_file)
end
mainloop()
-- end of program