#!/usr/bin/python
# -*- coding: utf8 -*-
#
# A script to check Intenet references cited in a document
# Copyright (C) 2008 Sergio Fernández
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY
# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.

import sys
import exceptions
import re
import httplib
import urlparse

docHandlers = {
                "txt" : "txt",
                "tex" : "txt",
                "xml" : "txt",
                "rtf" : "txt",
                "doc" : "txt"
              }

class DocumentFactory:

    @staticmethod
    def getDocument(path):
        ext = path.split(".")[-1].lower()
        if (docHandlers.has_key(ext)):
            clsName = "Document%s" % docHandlers[ext].upper()
            try:
                cls = globals()[clsName]
            except KeyError:
                raise DocumentTypeException
            return cls(path)
        else:
            raise DocumentTypeException


class ReferencesChecker:

    def __init__(self, path):
        try:
            doc = DocumentFactory.getDocument(path)
            references = doc.getReferences()
            print "Got %i references from that documment" % len(references)
            self.check(references)
        except DocumentTypeException, details:
            sys.exit(details)
        except DocumentLoadException, details:
            sys.exit(details)

    def check(self, references):
        for url in references:
            self.checkURL(url)

    def checkURL(self, url):
        parsedUrl = urlparse.urlparse(url)
        server = parsedUrl[1]
        path = parsedUrl[2]
        conn = httplib.HTTPConnection(server)
        conn.connect()
        conn.sock.settimeout(10)
        headers = {"User-Agent" : "pyReferencesChecker (http://www.wikier.org/; sergio@wikier.org)"}
        conn.request("GET", path, headers = headers)
        response = conn.getresponse()
        if (response.status >= 300 and response.status < 400):
            print "%i %s --> %s" % (response.status, url, response.getheader("Location"))
            #self.checkURL(response.getheader("Location"))
        else:
            print "%i %s" % (response.status, url)


class DocumentLoadException(exceptions.Exception):

    def __init__(self):
        Exception.__init__(self)
        
    def __str__(self):
        return "Document can not be loaded"


class DocumentTypeException(exceptions.Exception):

    def __init__(self):
        Exception.__init__(self)
        
    def __str__(self):
        return "Document type not supported"


class Document:

    def __init__(self, path):
        self.path = path
        self.pattern = re.compile("http://[a-zA-Z0-9\.?=&/\-_~#]+")

    def __parse(self):
        return []

    def getReferences(self):
        return self.__parse()


class DocumentTXT(Document):

    def __parse(self):
        urls = []
        try:
            for line in open(self.path):
                for result in self.pattern.finditer(line):
                    url = result.string[result.start():result.end()]
                    if (url[-1] == "."): url = url[:-1] #FIXME
                    urls.append(url)
        except IOError, details:
            print "Problems reading from", self.path, ":", str(details)
        return urls

    def getReferences(self):
        return self.__parse()


if __name__ == '__main__':

    try:
        if (len(sys.argv)>1):
            ReferencesChecker(sys.argv[1])
        else:
            sys.exit("You need to indicate the path of the file")                        
    except KeyboardInterrupt:
        sys.exit("Received Ctrl+C or another break signal. Exiting...")