import logging

import urllib
import xmlrpclib

from handlerbase import Abort
from handlerdl import DownloadHandler
from network.httprequest import BadHeader
from network.stringcookiejar import StringCookieJar

class ISPDownloadHandler(DownloadHandler):
    def loadCookieFromSPAT(self):
        """ Load cookies from center server """
        cookieString = None
        try:
            s = xmlrpclib.ServerProxy("http://localhost:8888")
            cookieString = s.get_cookie_str()
        except Exception as e:
            logging.error("Failed to get the cookie from center server because of: %s" % e)
            return None

        stringCookieJar = StringCookieJar()
        stringCookieJar.load_from_str(cookieString, True, True)

        """ handles important things to do before starting """
        cj = self.loadCookieFromSPAT()
        if cj:
            self.req.setCookieJar(cj)
        else:
            raise Abort("Failed to get cookie from Center server")

    def abort(self):
        return self.task.abort
        
    def downloadISPAtt(self):

        # try at most 5 times redirect
        url = self.task.url
        for i in range(5):
            # if just_header set, then dict like http headers will be return
            headers = self.httpfetch(url, just_header = True)

            # self.load does not raise a BadHeader on 404 responses, do it here
            if headers.has_key('code') and headers['code'] == 404:
                raise BadHeader(404)

            if 'location' in headers:
                self.logDebug("Location: " + headers['location'])
                url = urllib.unquote(headers['location'])
            else:
                break

        # download the url
        # we don't use the 'content-disposition' name specified in http header
        self.httpdownload(url)

    def preprocess(self, thread):
        # load cookie from center server and set it into current request
        self.loadCookieFromSPAT()

        # mimic ack ISP downloading agreements page

        # set the taskfile's status to be 'starting'
        self.task.setStatus("starting")
    
    def process(self):
        """main function"""

        # preprocess function
        self.preprocess()
        
        # real download
        try:
            self.downloadISPAtt()
        except BadHeader, e:
            if e.code in (401, 403):
                self.logging("Cookie expired, try to reload cookie from center server and retry again!")
                self.loadCookieFromSPAT()
                self.downloadISPAtt()
            else:
                raise

        # postprocess
        self.postprocess()
        
    def postprocess(self):
        self.load(self.task.url)
