PODNOVA_XMLRPC_URL = 'http://www.podnova.com/xmlrpc.srf'
PODNOVA_USERFEED_URL = 'http://www.podnova.com/index_podcatcher_opml.srf'
PODNOVA_PROXYTEST_URL = 'http://www.podnova.com/podnova_client_proxy_test.html'

import threading
import StringIO
from urllibtransport import *
from ipodder import grabbers
import logging

log = logging.getLogger('PodNova')

class ProxyConfiguration:    
    def __init__(self, server, port, username, password, use_proxy=True):             
        self.http_proxy_server = server;
        self.http_proxy_port = port;
        self.http_proxy_auth_username = username;
        self.http_proxy_auth_password = password;
        self.use_proxy = use_proxy;
        self.last_exception = None;
        
        if self.http_proxy_server == None:
            self.http_proxy_server = "";
        if self.http_proxy_port == None:
            self.http_proxy_port = "";
        if self.http_proxy_auth_username == None:
            self.http_proxy_auth_username = "";
        if self.http_proxy_auth_password == None:
            self.http_proxy_auth_password = "";
        
        if use_proxy == True:
            if len(self.http_proxy_auth_username) > 0 and len(self.http_proxy_auth_password) > 0:
              self.proxies = {'http':'http://%s:%s@%s:%s'%(self.http_proxy_auth_username, self.http_proxy_auth_password, self.http_proxy_server, self.http_proxy_port)}
            else:
              self.proxies = {'http':"http://%s:%s" % (self.http_proxy_server,self.http_proxy_port)}
        
            log.info("Proxy set too: " + str(self.proxies))
        else:
            log.info("No proxy is set")
            
    
    def TestProxy(self):
        try:
           import urllib2
    
           proxy_support = urllib2.ProxyHandler(self.proxies)
           authinfo = urllib2.HTTPBasicAuthHandler()
           opener = urllib2.build_opener(proxy_support, authinfo, urllib2.HTTPHandler)
           opener.addheaders = [('User-agent', 'PodNova')]
           urllib2.install_opener(opener)
    
           f = urllib2.urlopen(PODNOVA_PROXYTEST_URL)
           return True
        except Exception, e:
           log.error("Using proxy " + str(self.proxies) + " generated exception " + str(e));
           self.last_exception = e;
           return False    
    
    def GetLastError(self):
        return self.last_exception;
    
    def GetUseProxy(self):
        return self.use_proxy;
    
    def GetProxy(self):
        return self.proxies;

class FeedManagerConnector:
    def __init__(self):        
        self.podnova_url = PODNOVA_XMLRPC_URL;
        
    def GetServer(self, proxy_config):                
        import xmlrpclib
        podnovasrv = None;
        #Connect too the podnova site in order too get the user-guid.    
        if proxy_config.GetUseProxy() == True:            
            if False == proxy_config.TestProxy():
                raise Exception("Can't use proxy " + str(proxy_config.GetProxy()));
            
            podnovasrv = xmlrpclib.Server(self.podnova_url, transport=UrllibTransport(proxy_config.GetProxy()))
        else:
            podnovasrv = xmlrpclib.Server(self.podnova_url)
            
        return podnovasrv
        

class FeedManagerUserId(threading.Thread):
    def __init__(self, username, password_hash, password_salt, proxy_config):
        threading.Thread.__init__(self)
        self.setDaemon(True)
        self.username = username
        self.password_hash = password_hash
        self.password_salt = password_salt
        
        self.proxy_config = proxy_config;
                   
        self.user_guid = ""
        
    def GetUserGuid(self):
        return self.user_guid;
        
    def run(self):
        if len(self.username) == 0 or len(self.password_hash) == 0:
            log.warning("No username and password_hash are specified, can't login too the PodNova.com account")
            self.user_guid = ""
            return;
            
        fmr = FeedManagerConnector();
        srv = fmr.GetServer(self.proxy_config);
        
        try:
            if 'get_user_guid' in srv.system.listMethods():               
                user_guid = srv.get_user_guid(self.username, self.password_hash, self.password_salt);
                if user_guid == 0:
                    log.error("PodNova.com does not know the user " + str(self.username))
                    self.user_guid = "";
                else:                
                    self.user_guid = user_guid;
            else:
                log.error("The method 'get_user_guid' is not supported by the PodNova.com xml-rpc interface");
                self.user_guid = ""
        except Exception, e:
            log.error("While Retrieving the user-id exception '" + str(e) + "' occurred");
            self.user_guid = "";
                
class FeedManagerOpmlFetcher(threading.Thread):
    def __init__(self, gui):
        threading.Thread.__init__(self)
        self.setDaemon(True)
        self.url = PODNOVA_USERFEED_URL;
        self.userguid = gui.m_user_guid;
        self.gui = gui
                        
    def run(self):
        sio = StringIO.StringIO()
        
        if len(self.userguid) == 0:
            log.info("The userguid is not known, going to request the userguid ");
            
            proxy_config = ProxyConfiguration(self.gui.ipodder.config.http_proxy_server, self.gui.ipodder.config.http_proxy_port, self.gui.ipodder.config.http_proxy_username, self.gui.ipodder.config.http_proxy_password, self.gui.ipodder.config.use_proxy_server);            
            fmu = FeedManagerUserId(self.gui.ipodder.config.user_account_name, self.gui.ipodder.config.user_account_password_hash, self.gui.ipodder.config.user_account_password_salt, proxy_config);
            
            fmu.start();
            fmu.join();
            self.gui.m_user_guid = fmu.GetUserGuid();
            self.userguid = self.gui.m_user_guid
                                
            if len(self.userguid) == 0:
                log.error("Unable to retrieve the user-id");
                return
        
        import urllib
        param = {"userguid": self.userguid};                        
        self.url = self.url + "?" + urllib.urlencode(param);
        
        log.info("Going to grab %s", self.url);
        grabber = grabbers.BasicGrabber(self.url, sio, politeness=0)
        try: 
            grabber()
        except grabbers.GrabError, ex: 
            log.error("Can't grab %s: %s", self.url, ex.message)
            return
        self.gui.ThreadSafeDispatch(self.gui.ReplaceFromManagerOpmlEnsuringPopulate, self.url, sio.getvalue())
