# links.py - lets user see links and related text from a web page
#            enhanced solution to Miller/Ranum Exercise 5.16
# cmc, 2/17/2015

import urllib.request

def getlinks(pagename, encoding='utf-8'):

    pagefile = None
    pagetext = ''
    try:
        pagefile = urllib.request.urlopen(pagename)
        pagedata = pagefile.read()
        pagetext = pagedata.decode(encoding)
    except OSError as err:
        print("error: " + str(err))
        return
    finally:
        if pagefile: pagefile.close()

    result = { }
    done = False
    start = 0
    length = len(pagetext)
    while start < length and not done:
        findresult = findlink(pagetext[start:])
        if findresult != None:
            link, st, fi = findresult # unpacks tuple returned from findlink
            start = start + st
            finish = start + fi
            linkurl, linktext = getlinkdata(link) # unpacks another tuple
            if linktext not in result:
                result[linktext] = linkurl
            else:
                extra = 0
                extratext = linktext
                while extratext in result:
                    extra = extra + 1
                    extratext = '%s [%d]' % (linktext, extra)
                result[extratext] = linkurl
            start = finish + 1
        else:
            done = True

    return result

def findlink(text):
    ltext = text.lower()
    start = 0
    n = len(text)
    while start < n and not ltext[start:].startswith('<a href='):
        start = start + 1
    finish = start+8
    while finish < n and not ltext[finish:].startswith('</a>'):
        finish = finish + 1
    if finish >= n:
        return None
    finish = finish + 4
    return (ltext[start:finish], start, finish)

def getlinkdata(link):
# note: this utility function knows link is delimited by '<a href=' and '</a>'
    url = ''
    text = ''
    urlstart = 8
    n = len(link)
    urlend = urlstart
    while link[urlend+1] != '>':
        urlend = urlend + 1
    url = link[urlstart:urlend].strip('\' "')
    if not url.startswith('http'):
        url = 'local:' + url
    textstart = urlend + 2
    textend = textstart+1
    while not link[textstart:textend].endswith('</a>'):
        textend = textend + 1
    text = link[textstart:textend-4]
    return (url, text)

def main():
    page = input("enter url: ")
    linkdict = getlinks(page)
    if linkdict:
        for link in sorted(linkdict.keys()):
            print('%s:\n    %s' % (link, linkdict[link]) )

main()
