view pyikriam/ikariam.py @ 170:7df753a99926

merged
author "Rex Tsai <chihchun@kalug.linux.org.tw>"
date Sun, 02 Nov 2008 02:23:13 +0800
parents 8f699a9da6c0
children 9f248c8460ce
line wrap: on
line source

from lazy.www import c
from lconf import LoadConfigfile
import cookielib
import os
import urllib2
import urllib
from utils import dyna_prog, decorator
from lxml import etree
from StringIO import StringIO

class fake_moz(object):
    __metaclass__ = decorator

    def __init__(self):
        super(fake_moz, self).__init__()
        cookie_jar = cookielib.LWPCookieJar()
        cookie_proc = urllib2.HTTPCookieProcessor(cookie_jar)
        opener = urllib2.build_opener(cookie_proc)
        opener.addheaders = [('User-agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW; rv:1.8.1.12pre) Gecko/20071220 BonEcho/2.0.0.12pre')]
        fake_moz.set_backend(self, opener)
        self.cookie_jar = cookie_jar
        pass
    pass


class Ikariam:

    cities = {}
    COOKIEFILE = '/tmp/ikariam.lwp'

    def __init__(self):
        browser = fake_moz()
        self.browser = browser
        self._cookie_jar = browser.cookie_jar

        if os.path.isfile(self.COOKIEFILE):
            self._cookie_jar.load(self.COOKIEFILE)
            pass
 
        urllib2.install_opener(browser)

	self.confdata=LoadConfigfile().cd
        self.baseurl='http://'+self.confdata['server']

        self.login()
        pass

    def login(self):     
	print "login to %s...." % self.confdata['server']
        params = {"universe":self.confdata['server'], \
        "name":self.confdata['user'], \
        "password":self.confdata['pass']}
        ret = c(self.baseurl+'/index.php?action=loginAvatar&function=login').get(params).get_content()
        self._cookie_jar.save(self.COOKIEFILE)
        pass

    def logout(self):
	print "logut from %s...." % self.confdata['server']
        c(self.baseurl+'/index.php?action=loginAvatar&function=logout')
        os.remove(self.COOKIEFILE)
        pass
    
    ##
    # \note We can cache data with decorator 'dynamic programming'.
    #
    @dyna_prog
    def city(self, id):
        return IkariamCity(id=id, core=self)
    pass

class IkariamCity:
    data_patterns = {
        'gold': '/div[@id=\'globalResources\']/ul/li/a/span[@id=\'value_gold\']/text()',
        'inhabitants': '/div[@id=\'cityResources\']/ul/li/span[@id=\'value_inhabitants\']/text()',
        'wood': '/div[@id=\'cityResources\']/ul/li/span[@id=\'value_wood\']/text()',
        'wine': '/div[@id=\'cityResources\']/ul/li/span[@id=\'value_wine\']/text()',
        'marble': '/div[@id=\'cityResources\']/ul/li/span[@id=\'value_marble\']/text()',
        'crystal': '/div[@id=\'cityResources\']/ul/li/span[@id=\'value_crystal\']/text()',
        'sulfur': '/div[@id=\'cityResources\']/ul/li/span[@id=\'value_sulfur\']/text()'
        }
    def __init__(self, id, core ):
        self.core = core
        self.id = id
        self.params = {'view':'city','id':id}
        
    def sync(self):
        page = c(self.core.baseurl).get(self.params).get_content()
        parser = etree.HTMLParser(encoding='utf8')
        page_dom = etree.parse(StringIO(page), parser)

        xpath_globalinfo = "/html/body[@id='city']/div[@id='container']/div[@id='container2']"
        for name, path in self.data_patterns.items():
            xpath = xpath_globalinfo + path
            value = page_dom.xpath(xpath)[0]
            setattr(self, name, value)
            pass
        
        xpath_mainview = '/html/body/div/div/div[@id=\'mainview\']/ul/li'
        pos_doms = page_dom.xpath(xpath_mainview)
        positions = [self._mk_position(pos_dom, idx)
                     for idx, pos_dom in enumerate(pos_doms)]
        self.positions = positions
        pass

    def _mk_position(self, pos_dom, idx):
        import buildings

        build_type = pos_dom.get('class').split()[-1].lower()
        if hasattr(buildings, build_type):
            clz = getattr(buildings, build_type)
            if issubclass(clz, buildings.position):
                building = clz(self.id, idx, self.core.baseurl)
                return building
            pass
        return build_type
    pass