'Fetch a KML file:
- unzip it if-required
- follow NetworkLinks recursively if-required
Returns a file object
Designed as a helper function for download_kml()'

def fetch_kml(self, url, filepath, session_id_name, session_id):

    from gluon.tools import fetch
    response = current.response
    public_url = current.deployment_settings.get_base_public_url()
    warning = ''
    local = False
    if (not url.startswith('http')):
        local = True
        url = ('%s%s' % (public_url, url))
    elif ((len(url) > len(public_url)) and (url[:len(public_url)] == public_url)):
        local = True
    if local:
        import Cookie
        cookie = Cookie.SimpleCookie()
        cookie[session_id_name] = session_id
        current.session._unlock(response)
        try:
            file = fetch(url, cookie=cookie)
        except urllib2.URLError:
            warning = 'URLError'
            return warning
        except urllib2.HTTPError:
            warning = 'HTTPError'
            return warning
    else:
        try:
            file = fetch(url)
        except urllib2.URLError:
            warning = 'URLError'
            return warning
        except urllib2.HTTPError:
            warning = 'HTTPError'
            return warning
    filenames = []
    if (file[:2] == 'PK'):
        fp = StringIO(file)
        import zipfile
        myfile = zipfile.ZipFile(fp)
        files = myfile.infolist()
        main = None
        candidates = []
        for _file in files:
            filename = _file.filename
            if (filename == 'doc.kml'):
                main = filename
            elif (filename[(-4):] == '.kml'):
                candidates.append(filename)
        if (not main):
            if candidates:
                main = candidates[0]
            else:
                response.error = 'KMZ    contains    no    KML    Files!'
                return ''
        request = current.request
        path = os.path.join(request.folder, 'static', 'cache', 'kml')
        if (not os.path.exists(path)):
            os.makedirs(path)
        for _file in files:
            filename = _file.filename
            if (filename != main):
                if ('/' in filename):
                    _filename = filename.split('/')
                    dir = os.path.join(path, _filename[0])
                    if (not os.path.exists(dir)):
                        os.mkdir(dir)
                    _filepath = os.path.join(path, *_filename)
                else:
                    _filepath = os.path.join(path, filename)
                try:
                    f = open(_filepath, 'wb')
                except:
                    pass
                else:
                    filenames.append(filename)
                    __file = myfile.read(filename)
                    f.write(__file)
                    f.close()
        file = myfile.read(main)
        myfile.close()
    if ('<NetworkLink>' in file):
        try:
            parser = etree.XMLParser(recover=True, remove_blank_text=True)
            tree = etree.XML(file, parser)
            url = ''
            for element in tree.iter():
                if (element.tag == ('{%s}href' % KML_NAMESPACE)):
                    url = element.text
            if url:
                warning2 = self.fetch_kml(url, filepath)
                warning += warning2
        except (etree.XMLSyntaxError,):
            e = sys.exc_info()[1]
            warning += ('<ParseError>%s    %s</ParseError>' % (e.line, e.errormsg))
    if ('<GroundOverlay>' in file):
        warning += 'GroundOverlay'
    if ('<ScreenOverlay>' in file):
        warning += 'ScreenOverlay'
    for filename in filenames:
        replace = ('%s/%s' % (URL(c='static', f='cache', args=['kml']), filename))
        file = file.replace(filename, replace)
    f = open(filepath, 'w')
    f.write(file)
    f.close()
    return warning
