#!/usr/bin/env python
## Free Libraries Gopher Client (see version number in below tuple)
## Jul 2012
## License: Public Domain
## Very Very Beta

geo=(80, 24, "<-' go <- back ^ v scroll    Free Libraries Gopher Client 0.1 (Public Domain)")
import curses
from os import popen
from os import system
from sys import argv

yescurl = int(popen("which curl | wc -l").readline())
if not yescurl:
    print "This program will not work without curl."
    print
    print "Suggestion: sudo apt-get install curl (for Debian/Ubuntu/Trisquel/GNewSense)"
    print "                sudo yum install curl (for Fedora/Freedora/etc)"
    print ""
    exit()
text = ""

url = ""
try:
    url = argv[1]
except:
    pass
if url == "":
    print "enter the name of a gopher site:", ; url = raw_input().strip()

def c(p):
    global url
    if not "gopher://" in url.lower():
        url = "gopher://" + url
    if url.lower()[:9] != "gopher://":
        url = "gopher://" + url    
    global text # for debugging output
    text = url
    history = []
    yescaca = int(popen("which cacaview | wc -l").readline())
    x = 0 
    while x not in [27, ord("x"), ord("q"), ord("Q"), ord("X")]:
        yindex = 0
        yib = 0
        global geo
        thistype = "1"
        rurl = url
        if rurl[:9].lower() == "gopher://":
            rurl = rurl[9:]
        try:
            thistype = rurl.split("/")[1]
            text = thistype
        except:
            pass
        f = list(popen("curl -s \"" + url + "\" 2> /dev/null").readlines())
        history += [url]
        if len(history) > 50: 
            history = history[-50:] ## conservative ; try 1000 or even remove
        for lenf in range(3):
            f = [""] + f
        if len(f) < geo[1]:
            while len(f) < geo[1]:
                f += [""]
        for lenf in range(geo[1]):
            f += [""]
        x = 0
        while x not in [27, curses.KEY_ENTER, 10, ord("x"), ord("X"), ord("q"), ord("Q")]:
            ## because curses.KEY_ENTER wasn't being trapped; LF was, go figure
            if x == curses.KEY_PPAGE:
                yindex -= (geo[1] - 1)
                if yindex < 0: 
                    yindex = 0            
            if x == curses.KEY_NPAGE:
                yindex += geo[1] - 1
                if yindex > len(f) - geo[1]: 
                    yindex = len(f) - geo[1] 
            if x == curses.KEY_UP:
                yindex -= 1
                if yindex < 0: 
                    yindex = 0            
            if x == curses.KEY_DOWN:
                yindex += 1
                if yindex > len(f) - geo[1]: 
                    yindex = len(f) - geo[1] 
            if x == curses.KEY_HOME:
                yindex = 0
            if x == curses.KEY_LEFT:
                if len(history) > 1:
                    try: ## lazy
                        history = history[:-1]
                        newurl = history[len(history) - 1]
                        history = history[:-1]
                        url = newurl
                        text = newurl
                    except: 
                        pass 
                else:
                    x = 126
            if x == curses.KEY_END:
                yindex = len(f) - geo[1] -1
            if yindex != yib or yib == 0:
                p.clear()
                for pp in range(0, geo[1] - 1):
                    thisline = f[pp + yindex].rstrip()
                    if thistype == "1" and len(thisline):
                        hint = ""
                        if thisline[0] == "0": 
                            hint = "(TEXT) "
                        elif thisline[0] == "1":
                            hint = " (DIR) "
                        elif thisline[0] == "i":
                            hint = ""
                        elif thisline[0] == "I": 
                            hint = " (IMG) "
                        if thisline[0] in "01iI":
                            thisline = hint + thisline.split("\t")[0][1:]
                    if pp == 3:
                        bar = thisline + (" " * geo[0])
                        ## for whatever reason, this doesn't exactly
                        p.addstr(pp, 0, bar[:geo[0]], curses.A_REVERSE)
                        p.addstr(pp + 1, 0, " " * geo[0])
                    else:
                        p.addstr(pp, 0, thisline[:geo[0]])
                yib = yindex
                p.refresh()
            p.addstr(geo[1] - 1, 0, " " * (geo[0] - 1), curses.A_REVERSE)
            p.addstr(geo[1] - 1, 0, " " + geo[2], curses.A_REVERSE)
            p.addstr(geo[1] - 1, geo[0] - 1, "", curses.A_REVERSE)
            p.refresh()  
            spaghetti = 0
            if x != curses.KEY_LEFT: 
                x = p.getch()
            else:
                spaghetti = 1 ## sorry
                x = 10
            if x == 10 or x == curses.KEY_ENTER:
                if spaghetti == 0:                    
                    rstr = f[yindex + 3] ## the contents of the selected line
                    typifany = ""
                    ## typifany: derived from link you're hovering over
                    ## thistype: type / page you're already viewing
                    if len(rstr) and thistype == "1":
                        ## if thistype isn't 1,  ^ parsed line doesn't count
                        ## (i.e. because you're viewing type 0)
                        typifany = rstr[0] ## get gophertype, (or " ", or "")
                    if typifany == "0":
                        if len(rstr.split("\t")) > 3:
                            typs = "/" + typifany
                            desc = rstr.split("\t")[0][1:]
                            rsel = rstr.split("\t")[1]
                            serv = rstr.split("\t")[2]
                            ## port field is often last, so remove \r\n
                            port = rstr.split("\t")[3].rstrip()
                            newurl = "gopher://" + serv + ":" + port + typs + rsel
                            url = newurl
                    elif typifany == "1":
                        if len(rstr.split("\t")) > 3:
                            typs = "/" + typifany
                            desc = rstr.split("\t")[0][1:]
                            rsel = rstr.split("\t")[1]
                            serv = rstr.split("\t")[2]
                            ## port field is often last, so remove \r\n
                            port = rstr.split("\t")[3].rstrip()
                            newurl = "gopher://" + serv + ":" + port + typs + rsel
                            url = newurl
                    elif typifany == "I":
                        if len(rstr.split("\t")) > 3:
                            typs = "/" + typifany
                            desc = rstr.split("\t")[0][1:]
                            rsel = rstr.split("\t")[1]
                            serv = rstr.split("\t")[2]
                            ## port field is often last, so remove \r\n
                            port = rstr.split("\t")[3].rstrip()
                            newurl = "gopher://" + serv + ":" + port + typs + rsel
                            system("curl -s \"" + newurl + "\" > /tmp/cacav 2> /dev/null ; cacaview /tmp/cacav 2> /dev/null")                        
                        else:
                            x = 126 ## pretend enter wasn't pressed 
                    else:
                        x = 126 ## no plans to map this
curses.wrapper(c)