Navigation and adding favorites working
This commit is contained in:
parent
feaf05c11d
commit
379085f971
211
main.lua
211
main.lua
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue