Commits

asypost committed 9df6223

clean up

Comments (0)

Files changed (9)

 #encoding=utf-8
 
-from template import render_to_template
-import os
 import logging
 import functools
 from threading import Thread
 
-def view(template):
-    def dec(func):
-        @functools.wraps(func)
-        def _(*args,**kwargs):
-            data=func(*args,**kwargs)
-            return render_to_template(data,template)
-        return _
-    return dec
 
 def debug(func):
     logger=logging.getLogger("Debugger")

core/http.py

-#encoding=utf-8
-
-#helpers for http calls
-
-import urllib2
-import urllib
-from core.bases import Request
-
-def get(url,params=None,headers={}):
-    params=params if params else dict()
-    url=Request(url,**params).uri
-    request=urllib2.Request(url,headers=headers)
-    return urllib2.urlopen(request).read()
-
-def post(url,data,headers={}):
-    request=urllib2.Request(url,urllib.urlencode(data),headers)
-    return urllib2.urlopen(request).read()

core/template.py

-#encoding=utf-8
-import os
-import re
-import functools
-import sys
-from configuration import config
-
-py = sys.version_info
-py3k = py >= (3,0,0)
-
-if py3k: # pragma: no cover
-    # See Request.POST
-    def touni(x, enc='utf8', err='strict'):
-        """ Convert anything to unicode """
-        return str(x, enc, err) if isinstance(x, bytes) else str(x)
-    if sys.version_info < (3,2,0):
-        from io import TextIOWrapper
-        class NCTextIOWrapper(TextIOWrapper):
-            ''' Garbage collecting an io.TextIOWrapper(buffer) instance closes
-                the wrapped buffer. This subclass keeps it open. '''
-            def close(self): pass
-else:
-    bytes = str
-    def touni(x, enc='utf8', err='strict'):
-        """ Convert anything to unicode """
-        return x if isinstance(x, unicode) else unicode(str(x), enc, err)
-
-def tob(data, enc='utf8'):
-    """ Convert anything to bytes """
-    return data.encode(enc) if isinstance(data, unicode) else bytes(data)
-
-tonat = touni if py3k else tob
-
-class TemplateError(Exception):pass
-
-def html_escape(string):
-    ''' Escape HTML special characters ``&<>`` and quotes ``'"``. '''
-    return string.replace('&','&amp;').replace('<','&lt;').replace('>','&gt;')\
-                 .replace('"','&quot;').replace("'",'&#039;')
-
-class CachedProperty(object):
-    ''' A property that is only computed once per instance and then replaces
-        itself with an ordinary attribute. Deleting the attribute resets the
-        property. '''
-
-    def __init__(self, func):
-        self.func = func
-
-    def __get__(self, obj, cls):
-        if obj is None: return self
-        value = obj.__dict__[self.func.__name__] = self.func(obj)
-        return value
-
-cached_property = CachedProperty
-
-class lazy_attribute(object): # Does not need configuration -> lower-case name
-    ''' A property that caches itself to the class object. '''
-    def __init__(self, func):
-        functools.update_wrapper(self, func, updated=[])
-        self.getter = func
-
-    def __get__(self, obj, cls):
-        value = self.getter(cls)
-        setattr(cls, self.__name__, value)
-        return value
-
-class BaseTemplate(object):
-    """ Base class and minimal API for template adapters """
-    extensions = ['tpl','html','thtml','stpl']
-    settings = {} #used in prepare()
-    defaults = {} #used in render()
-
-    def __init__(self, source=None, name=None, lookup=[], encoding='utf8', **settings):
-        """ Create a new template.
-        If the source parameter (str or buffer) is missing, the name argument
-        is used to guess a template filename. Subclasses can assume that
-        self.source and/or self.filename are set. Both are strings.
-        The lookup, encoding and settings parameters are stored as instance
-        variables.
-        The lookup parameter stores a list containing directory paths.
-        The encoding parameter should be used to decode byte strings or files.
-        The settings parameter contains a dict for engine-specific settings.
-        """
-        self.name = name
-        self.source = source.read() if hasattr(source, 'read') else source
-        self.filename = source.filename if hasattr(source, 'filename') else None
-        self.lookup = map(os.path.abspath, lookup)
-        self.encoding = encoding
-        self.settings = self.settings.copy() # Copy from class variable
-        self.settings.update(settings) # Apply
-        if not self.source and self.name:
-            self.filename = self.search(self.name, self.lookup)
-            if not self.filename:
-                raise TemplateError('Template %s not found.' % repr(name))
-        if not self.source and not self.filename:
-            raise TemplateError('No template specified.')
-        self.prepare(**self.settings)
-
-    @classmethod
-    def search(cls, name, lookup=[]):
-        """ Search name in all directories specified in lookup.
-        First without, then with common extensions. Return first hit. """
-        if os.path.isfile(name): return name
-        for spath in lookup:
-            fname = os.path.join(spath, name)
-            if os.path.isfile(fname):
-                return fname
-            for ext in cls.extensions:
-                if os.path.isfile('%s.%s' % (fname, ext)):
-                    return '%s.%s' % (fname, ext)
-
-    @classmethod
-    def global_config(cls, key, *args):
-        ''' This reads or sets the global settings stored in class.settings. '''
-        if args:
-            cls.settings = cls.settings.copy() # Make settings local to class
-            cls.settings[key] = args[0]
-        else:
-            return cls.settings[key]
-
-    def prepare(self, **options):
-        """ Run preparations (parsing, caching, ...).
-        It should be possible to call this again to refresh a template or to
-        update settings.
-        """
-        raise NotImplementedError
-
-    def render(self, *args, **kwargs):
-        """ Render the template with the specified local variables and return
-        a single byte or unicode string. If it is a byte string, the encoding
-        must match self.encoding. This method must be thread-safe!
-        Local variables may be provided in dictionaries (*args)
-        or directly, as keywords (**kwargs).
-        """
-        raise NotImplementedError
-class SimpleTemplate(BaseTemplate):
-    blocks = ('if', 'elif', 'else', 'try', 'except', 'finally', 'for', 'while',
-              'with', 'def', 'class')
-    dedent_blocks = ('elif', 'else', 'except', 'finally')
-
-    @lazy_attribute
-    def re_pytokens(cls):
-        ''' This matches comments and all kinds of quoted strings but does
-            NOT match comments (#...) within quoted strings. (trust me) '''
-        return re.compile(r'''
-            (''(?!')|""(?!")|'{6}|"{6}    # Empty strings (all 4 types)
-             |'(?:[^\\']|\\.)+?'          # Single quotes (')
-             |"(?:[^\\"]|\\.)+?"          # Double quotes (")
-             |'{3}(?:[^\\]|\\.|\n)+?'{3}  # Triple-quoted strings (')
-             |"{3}(?:[^\\]|\\.|\n)+?"{3}  # Triple-quoted strings (")
-             |\#.*                        # Comments
-            )''', re.VERBOSE)
-
-    def prepare(self, escape_func=html_escape, noescape=False, **kwargs):
-        self.cache = {}
-        enc = self.encoding
-        self._str = lambda x: touni(x, enc)
-        self._escape = lambda x: escape_func(touni(x, enc))
-        if noescape:
-            self._str, self._escape = self._escape, self._str
-
-    @classmethod
-    def split_comment(cls, code):
-        """ Removes comments (#...) from python code. """
-        if '#' not in code: return code
-        #: Remove comments only (leave quoted strings as they are)
-        subf = lambda m: '' if m.group(0)[0]=='#' else m.group(0)
-        return re.sub(cls.re_pytokens, subf, code)
-
-    @cached_property
-    def co(self):
-        return compile(self.code, self.filename or '<string>', 'exec')
-
-    @cached_property
-    def code(self):
-        stack = [] # Current Code indentation
-        lineno = 0 # Current line of code
-        ptrbuffer = [] # Buffer for printable strings and token tuple instances
-        codebuffer = [] # Buffer for generated python code
-        multiline = dedent = oneline = False
-        template = self.source or open(self.filename, 'rb').read()
-
-        def yield_tokens(line):
-            for i, part in enumerate(re.split(r'\{\{(.*?)\}\}', line)):
-                if i % 2:
-                    if part.startswith('!'): yield 'RAW', part[1:]
-                    else: yield 'CMD', part
-                else: yield 'TXT', part
-
-        def flush(): # Flush the ptrbuffer
-            if not ptrbuffer: return
-            cline = ''
-            for line in ptrbuffer:
-                for token, value in line:
-                    if token == 'TXT': cline += repr(value)
-                    elif token == 'RAW': cline += '_str(%s)' % value
-                    elif token == 'CMD': cline += '_escape(%s)' % value
-                    cline +=  ', '
-                cline = cline[:-2] + '\\\n'
-            cline = cline[:-2]
-            if cline[:-1].endswith('\\\\\\\\\\n'):
-                cline = cline[:-7] + cline[-1] # 'nobr\\\\\n' --> 'nobr'
-            cline = '_printlist([' + cline + '])'
-            del ptrbuffer[:] # Do this before calling code() again
-            code(cline)
-
-        def code(stmt):
-            for line in stmt.splitlines():
-                codebuffer.append('  ' * len(stack) + line.strip())
-
-        for line in template.splitlines(True):
-            lineno += 1
-            line = line if isinstance(line, unicode)\
-                        else unicode(line, encoding=self.encoding)
-            sline = line.lstrip()
-            if lineno <= 2:
-                m = re.search(r"%.*coding[:=]\s*([-\w\.]+)", line)
-                if m: self.encoding = m.group(1)
-                if m: line = line.replace('coding','coding (removed)')
-            if sline and sline[0] == '%' and sline[:2] != '%%':
-                line = line.split('%',1)[1].lstrip() # Full line following the %
-                cline = self.split_comment(line).strip()
-                cmd = re.split(r'[^a-zA-Z0-9_]', cline)[0]
-                flush() # You are actually reading this? Good luck, it's a mess :)
-                if cmd in self.blocks or multiline:
-                    cmd = multiline or cmd
-                    dedent = cmd in self.dedent_blocks # "else:"
-                    if dedent and not oneline and not multiline:
-                        cmd = stack.pop()
-                    code(line)
-                    oneline = not cline.endswith(':') # "if 1: pass"
-                    multiline = cmd if cline.endswith('\\') else False
-                    if not oneline and not multiline:
-                        stack.append(cmd)
-                elif cmd == 'end' and stack:
-                    code('#end(%s) %s' % (stack.pop(), line.strip()[3:]))
-                elif cmd == 'include':
-                    p = cline.split(None, 2)[1:]
-                    if len(p) == 2:
-                        code("_=_include(%s, _stdout, %s)" % (repr(p[0]), p[1]))
-                    elif p:
-                        code("_=_include(%s, _stdout)" % repr(p[0]))
-                    else: # Empty %include -> reverse of %rebase
-                        code("_printlist(_base)")
-                elif cmd == 'rebase':
-                    p = cline.split(None, 2)[1:]
-                    if len(p) == 2:
-                        code("globals()['_rebase']=(%s, dict(%s))" % (repr(p[0]), p[1]))
-                    elif p:
-                        code("globals()['_rebase']=(%s, {})" % repr(p[0]))
-                else:
-                    code(line)
-            else: # Line starting with text (not '%') or '%%' (escaped)
-                if line.strip().startswith('%%'):
-                    line = line.replace('%%', '%', 1)
-                ptrbuffer.append(yield_tokens(line))
-        flush()
-        return '\n'.join(codebuffer) + '\n'
-
-    def subtemplate(self, _name, _stdout, *args, **kwargs):
-        for dictarg in args: kwargs.update(dictarg)
-        if _name not in self.cache:
-            self.cache[_name] = self.__class__(name=_name, lookup=self.lookup)
-        return self.cache[_name].execute(_stdout, kwargs)
-
-    def execute(self, _stdout, *args, **kwargs):
-        for dictarg in args: kwargs.update(dictarg)
-        env = self.defaults.copy()
-        env.update({'_stdout': _stdout, '_printlist': _stdout.extend,
-               '_include': self.subtemplate, '_str': self._str,
-               '_escape': self._escape, 'get': env.get,
-               'setdefault': env.setdefault, 'defined': env.__contains__})
-        env.update(kwargs)
-        eval(self.co, env)
-        if '_rebase' in env:
-            subtpl, rargs = env['_rebase']
-            rargs['_base'] = _stdout[:] #copy stdout
-            del _stdout[:] # clear stdout
-            return self.subtemplate(subtpl,_stdout,rargs)
-        return env
-
-    def render(self, *args, **kwargs):
-        """ Render the template using keyword arguments as local variables. """
-        for dictarg in args: kwargs.update(dictarg)
-        stdout = []
-        self.execute(stdout, kwargs)
-        return ''.join(stdout)
-
-def render_to_template(data,template):
-    tmpl=SimpleTemplate(open(os.path.join(config.resources_dir,template)).read())
-    return tmpl.render(data)

core/weibo.py

-#!/usr/bin/env python
-#encoding=utf-8
-import logging
-from bases import URIHandler,Request
-import json
-from decorators import async,debug
-
-logger=logging.getLogger("Weibo")
-
-class WeiboProtocolHandler(URIHandler):
-    """
-    微博协议:weibo://action(.+)?params(.?)
-    示例:weibo://status/update?message=今天天气好热啊
-    """
-    protocol="weibo://"
-    def __init__(self,webview):
-        super(WeiboProtocolHandler,self).__init__(webview)
-        self.__clients={}
-
-    @property
-    def clients(self):
-        return self.__clients.values()
-
-    def register_client(self,client_class):
-        """
-        Register a client,if success return True,else return False
-        """
-        client=client_class(self.webview)
-        if client.name not in self.__clients:
-            self.__clients[client.name]=client
-            return True
-        return False
-
-    def pending_response(self,request_id,data):
-        json_str=json.dumps({"request_id":request_id,"data":data})
-        self.webview.execute_script("weibo.util.pendingResponse({0})".format(json_str))
-
-    def handle_uri(self,uri,*args,**kwargs):
-        if self.is_support(uri):
-            request=Request.from_uri(uri)
-            for client in self.__clients.values():
-                #data=client.do_request(request)
-                #self.pending_response(request.id,data)
-                async(self.pending_response_callback)(self.handle_request_async)(client,request)
-            return True
-        return False
-
-    def handle_request_async(self,client,request):
-        data=client.do_request(request)
-        return request.id,data
-
-    def pending_response_callback(self,response):
-        self.pending_response(*response)
-
-    def is_support(self,uri):
-        ret=uri.lower().startswith(self.protocol)
-        ret or logger.warn("Unsupport URI:{0}".format(uri))
-        return ret
-
-    def __eq__(self,other):
-        request1=self.request if isinstance(self.request,Request) else Request.from_uri(self.request)
-        request2=other.request if isinstance(other.request,Request) else Request.from_uri(other.request)
-        return request1.uri==request2.uri
-
-class Client(object):
-    name=None #Client name:for example sina,it's unique
-
-    def __init__(self,webview):
-        self.webview=webview
-
-    def do_request(self,request):
-        raise NotImplemented
-
     import os
     import gettext
     from argparser import ArgParser
-    import util
-    from core import template
     from gettext import gettext as _
     from core.configuration import config
 
-    #setup template builtin functions
-    template.SimpleTemplate.defaults.update( \
-    {"format_time":util.format_time,
-    "make_url_link":util.make_url_link,
-    "make_all_link":util.make_all_link,
-    "trans":_})
     gettext.bindtextdomain("SinaWeibo",os.path.join(os.path.dirname(__file__),"resources/i18n"))
     gettext.textdomain('SinaWeibo')
 

sina.py

-#encoding=utf-8
-
-from core import weibo
-from core.decorators import debug
-from core.template import render_to_template
-from core.bases import Request
-import urlparse,urllib
-import json
-import time
-from core.bases import JSLikeObject
-import logging
-import os
-import pickle
-from core import http
-from gettext import gettext as _
-from notify import Notification
-
-logger=logging.getLogger("SinaClient")
-
-class SinaAPIException(Exception):
-    def __init__(self,error_code,message,request):
-        super(SinaAPIException,self).__init__(message)
-        self.error_code=error_code
-        self.request=request
-
-    def __unicode__(self):
-        return _("Error{0}:{1}").format(self.error_code,self.message)
-
-class SinaClient(weibo.Client):
-    name="sina"
-    base_api_url="https://api.weibo.com/2/"
-    app_key="2220221549"
-    app_secret="d75ef035dda834cf7a60680388ebbf54"
-    base_authorize_url="https://api.weibo.com/oauth2/authorize"
-    base_token_url="https://api.weibo.com/oauth2/access_token"
-    base_code_url="https://api.weibo.com/oauth2/default.html"
-    session_file="sina_session"
-    variable=JSLikeObject()
-
-    @property
-    def session(self):
-        try:
-            self._session
-        except:
-            self._session=self.load_session()
-        return self._session
-
-    @session.setter
-    def session(self,value):
-        self._session=value
-
-    @property
-    def access_token(self):
-        return self.session.get("access_token",None)
-
-    @access_token.setter
-    def access_token(self,value):
-        self.session["access_token"]=value
-
-    @property
-    def expires(self):
-        return self.session.get("expires_in",0)
-
-    @property
-    def timeline_since_id(self):
-        if not self.variable.has_key("timeline"):
-            self.variable.timeline=JSLikeObject()
-        return self.variable.timeline.get("since_id",0)
-
-    @timeline_since_id.setter
-    def timeline_since_id(self,value):
-        if not self.variable.has_key("timeline"):
-            self.variable.timeline=JSLikeObject()
-        self.variable.timeline.since_id=value
-
-    @property
-    def timeline_max_id(self):
-        if not self.variable.has_key("timeline"):
-            self.variable.timeline=JSLikeObject()
-        return self.variable.timeline.get("max_id",0)
-
-    @timeline_max_id.setter
-    def timeline_max_id(self,value):
-        if not self.variable.has_key("timeline"):
-            self.variable.timeline=JSLikeObject()
-        self.variable.timeline.max_id=value
-
-    def is_expires(self):
-        return not self.access_token or time.time() > self.expires
-
-    @debug
-    def get(self,url,**params):
-        params=params if params else dict()
-        params["access_token"]=self.access_token
-        return json.loads(http.get(url,params))
-
-    @debug
-    def post(self,url,**params):
-        if not self.is_expires():
-            params["access_token"]=self.access_token
-        return json.loads(http.post(url,params))
-
-    @debug
-    def get_url(self,path,base=None):
-        base=base if base else self.base_api_url
-        return urlparse.urljoin(base,path)
-
-    def check_weibo_error(self,data):
-        if data and data.has_key("error"):
-            raise SinaAPIException(data.get("error_code"),data.get("error"),data.get("request"))
-
-    def check_authoriztion(self):
-        if not self.is_expires():
-            return {"result":True}
-        request=Request(self.base_authorize_url,**{"client_id":self.app_key,
-            "redirect_uri":self.base_code_url,"display":"mobile"})
-
-        return {"result":False,"authorize_url":request.uri,"code_url":self.base_code_url}
-
-    def get_access_token(self,code):
-        params={"client_id":self.app_key,
-        "client_secret":self.app_secret,
-        "grant_type":"authorization_code",
-        "code":code,"redirect_uri":self.base_code_url}
-
-        self.session=self.post(self.base_token_url,**params)
-        expires_in=self.session["expires_in"]+time.time()
-        self.session["expires_in"]=expires_in
-        self.save_session()
-
-        self.webview.execute_script("updateTimeline();autoUpdate();")
-
-    def save_session(self):
-        try:
-            path=os.path.abspath(os.path.dirname(__file__))
-            file_path=os.path.join(path,self.session_file)
-            _file=open(file_path,"wb")
-            pickle.dump(self.session,_file)
-            _file.close()
-            logger.info("Session Saved")
-        except:
-            logger.warn("Save Session Failed")
-
-    def load_session(self):
-        result=dict()
-        try:
-            path=os.path.abspath(os.path.dirname(__file__))
-            file_path=os.path.join(path,self.session_file)
-            _file=open(file_path)
-            result= pickle.load(_file)
-            _file.close()
-        except:
-            logger.warn("Load Session Failed")
-        self.session=result
-        return result
-
-    def do_request(self,request):
-        path=request.path[len("weibo://"):]
-        if hasattr(self,path):
-            try:
-                return getattr(self,path)(**request.params)
-            except Exception,e:
-                logger.error(e)
-                notification=self.get_notification()
-                notification.update(_("Error"),_("Error:{0}".format(e)),"error")
-                notification.show()
-                return {"result":False}
-
-    def get_notification(self):
-        return Notification(_("Sina Micorblog"))
-
-    def show_status_notification(self,statuses,template):
-        notification=self.get_notification()
-        if len(statuses)>1:
-            notification.update(_("Statuses"),_(template).\
-                format(len(statuses)),"info")
-            notification.show()
-        elif len(statuses)==1:
-            status=statuses[0]
-            notification.update(status["user"]["screen_name"],status["text"],"info")
-            notification.set_image(status["user"]["profile_image_url"])
-            notification.show()
-
-    def timeline(self,feature=0,count=20,type="new"):
-        """
-        get the user friends timeline,
-        these timeline will be rendered to the model timeline
-        """
-        model="timeline"
-        since_id=self.timeline_since_id
-        max_id=self.timeline_max_id
-        url=self.get_url("statuses/friends_timeline.json")
-        if type=="new":
-            response=self.get(url,since_id=since_id,feature=feature,count=count)
-            self.timeline_since_id=response["statuses"][0]["id"] \
-                    if len(response["statuses"])>0 else self.timeline_since_id
-            if not self.timeline_max_id:
-                self.timeline_max_id=response["statuses"][-1]["id"] \
-                    if len(response["statuses"])>0 else self.timeline_max_id
-        elif type=="old":
-            response=self.get(url,max_id=max_id,feature=feature,count=count)
-            #remove the repeat one
-            response["statuses"]=response["statuses"][1:]
-            self.timeline_max_id=response["statuses"][-1]["id"] \
-                    if len(response["statuses"])>0 else self.timeline_max_id
-
-        #show notification
-        self.show_status_notification(response["statuses"],_("Got {0} statuse(s)"))
-
-        response.update({"model":model})
-        html=render_to_template(response,"sina/timeline.html")
-        return {"result":True,"html":html,"since_id":since_id,"max_id":max_id}
-
-    def mentions(self,count=20,type="new"):
-        """
-        get the statuses which mention me,
-        these statuses will be rendered to the model mentions
-        """
-        model="mentions"
-
-        if not self.variable.has_key("mentions"):
-            self.variable.mentions=JSLikeObject()
-
-        since_id=self.variable.mentions.get("since_id",0)
-        max_id=self.variable.mentions.get("max_id",0)
-        url=self.get_url("statuses/mentions.json")
-        if type=="new":
-            response=self.get(url,since_id=since_id,count=count)
-            self.variable.mentions.since_id=[i for i in response["statuses"] \
-                if i.has_key("id")][0]["id"] \
-                if len(response["statuses"])>0 else self.variable.mentions.since_id
-            if not  max_id:
-                self.variable.mentions.max_id=[i for i in response["statuses"] \
-                    if i.has_key("id")][-1]["id"] \
-                    if len(response["statuses"])>0 else self.variable.mentions.max_id
-        elif type=="old":
-            response=self.get(url,max_id=max_id,count=count)
-            response["statuses"]=response["statuses"][1:]
-            self.variable.mentions.max_id=[i for i in response["statuses"] \
-                    if i.has_key("id")][-1]["id"] \
-                    if len(response["statuses"])>0 else self.variable.mentions.max_id
-
-        self.show_status_notification(response["statuses"],_("Got {0} statuse(s) that mentions you"))
-
-        self.check_weibo_error(response)
-        response.update({"model":model})
-        html=render_to_template(response,"sina/timeline.html")
-        return {"result":True,"html":html,"since_id":since_id,"max_id":max_id}
-
-    def update(self,status):
-        """
-        update your status
-        """
-        status=urllib.unquote_plus(status)
-        url=self.get_url("statuses/update.json");
-        response=self.post(url,status=status)
-        self.check_weibo_error(response)
-        statuses=[response,]
-        data={"statuses":statuses};
-        data.update({"model":"timeline"})
-        self.timeline_since_id=statuses[0]["id"] \
-                    if len(statuses)>0 else self.timeline_since_id
-        html=render_to_template(data,"sina/timeline.html")
-        return {"result":True,"html":html}
-
-    def show_status(self,status_id):
-        """
-        show status detail by id
-        """
-        data={"id":status}
-        url=self.get_url("statuses/show.json")
-        status=self.get(url,**data)
-        self.check_weibo_error(status)
-        html=render_to_template({"status":status},"sina/status.html")
-        return {"result":True,"html":html}
-
-    def comments(self,status_id,model,count=50):
-        """
-        get the comments of a status that specified by status_id
-        and will be rendered to the model specified by argument model
-        """
-        comments=self.get(self.get_url("comments/show.json"),id=status_id,count=count)
-        self.check_weibo_error(comments)
-        comments.update({"model":model})
-        html=render_to_template(comments,"sina/comments.html")
-        return {"result":True,"html":html}
-
-    def create_comment(self,status_id,model,comment,comment_ori=0):
-        """
-        create a new comment for status which will be rendered to the model
-        specified by argument model
-        """
-        comment=urllib.unquote_plus(comment)
-        url=self.get_url("comments/create.json")
-        data={"comment":comment,"id":status_id}
-        response=self.post(url,**data)
-        self.check_weibo_error(response)
-        comments={"comments":[response,],"model":model}
-        return {"result":True,"html":render_to_template(comments,"sina/comments.html")}
-
-    def repost(self,model,status_id,status,is_comment=False):
-        status=urllib.unquote_plus(status)
-        url=self.get_url("statuses/repost.json")
-        post_data={"status":status,"id":status_id,"is_comment":is_comment}
-        response=self.post(url,**post_data)
-        statuses=[response,]
-        data={"statuses":statuses}
-        data.update({"model":model})
-        self.timeline_since_id=statuses[0]["id"] \
-                    if len(statuses)>0 else self.timeline_since_id
-        html=render_to_template(data,"sina/timeline.html")
-        return {"result":True,"html":html}
-
 from gi.repository import GdkPixbuf,Gdk
 from core.bases import URIHandler
 from core.bases import Request
-from core.weibo import WeiboProtocolHandler
 from core.view import WebUIView
-from core import template
 from gi.repository import Gtk
 from gi.repository import WebKit
 import logging
 import urllib2
-from sina import SinaClient
 from core.configuration import config 
-from core.template import render_to_template
 from gettext import gettext as _
 from threading import Thread
 from gi.repository import GLib
         self.weibo_view=WebUIView()
         self.weibo_view.register_uri_handler(self)
 
-        self.weibo_handler=WeiboProtocolHandler(self.weibo_view)
-        self.weibo_handler.register_client(SinaClient)
-        self.weibo_view.register_uri_handler(self.weibo_handler)
-
         self.scrolled_window=Gtk.ScrolledWindow.new(None,None)
         
         self.main_window.add(self.scrolled_window)
         self.scrolled_window.add(self.weibo_view)
 
-        self.weibo_view.load_string(render_to_template({"weibo_handler":self.weibo_handler},\
-            "index.html"),"text/html","UTF-8","file://"+os.path.join(config.resources_dir,"index.html"))
+        template=open(os.path.join(config.resources_dir,"index.html")).read()
+        self.weibo_view.load_string(template,"text/html","UTF-8","file://"+os.path.join(config.resources_dir,"index.html"))
 
         self.main_window.show_all()
 
 import logging
 from core.bases import URIHandler
 from core.bases import Request
-from core.weibo import WeiboProtocolHandler
 from core.view_pywebkit import WebUIView
-from core import template
-from core.template import render_to_template
 from core.configuration import config 
 from gettext import gettext as _
 from threading import Thread
 from core.decorators import debug
-from sina import SinaClient
 import os
 import urllib2
 from notify import Notification
         self.weibo_view=WebUIView()
         self.weibo_view.register_uri_handler(self)
 
-        self.weibo_handler=WeiboProtocolHandler(self.weibo_view)
-        self.weibo_handler.register_client(SinaClient)
-        self.weibo_view.register_uri_handler(self.weibo_handler)
-
         self.scrolled_window=gtk.ScrolledWindow(None,None)
         
         self.main_window.add(self.scrolled_window)
         self.scrolled_window.add(self.weibo_view)
 
-        self.weibo_view.load_string(render_to_template({"weibo_handler":self.weibo_handler},\
-            "index.html"),"text/html","UTF-8","file://"+os.path.join(config.resources_dir,"index.html"))
+        template=open(os.path.join(config.resources_dir,"index.html")).read()
+        self.weibo_view.load_string(template,"text/html","UTF-8","file://"+os.path.join(config.resources_dir,"index.html"))
 
         self.main_window.show_all()
 

util.py

-#encoding=utf-8
-
-import datetime
-import locale
-import re
-
-def parse_datetime(str_datetime):
-    l=locale.getlocale(locale.LC_TIME)
-    locale.setlocale(locale.LC_TIME,(None,None))
-    #Tue Oct 30 19:44:00 +0800 2012
-    cells=str_datetime.split(" ")
-    time_str=" ".join(cells[:4]+cells[5:])
-    time = datetime.datetime.strptime(time_str, "%a %b %d %H:%M:%S %Y")
-    locale.setlocale(locale.LC_TIME,l)
-    return datetime.datetime(time.year,time.month,time.day,time.hour,time.minute,time.second,time.microsecond)
-
-def format_time(str_datetime,more_readable=True):
-    time=parse_datetime(str_datetime)
-    fmt="%Y-%m-%d %H:%M:%S"
-    if more_readable:
-        now=datetime.datetime.now()
-        seconds=(now-time).total_seconds()
-        if abs(seconds)>=365*24*60*60:
-            fmt="%Y-%m-%d %H:%M:%S"
-        else:
-            fmt="%m-%d %H:%M:%S"
-    return time.strftime(fmt)
-
-def make_url_link(string):
-    pattern="(((http)|(ftp)|(https))(://)[0-9A-z]+[0-9A-z\.]*\.[0-9A-z]+(/?[0-9A-z%&=]+)*)"
-    return re.sub(pattern,r"<a target=_blank href='\1'>\1</a>",string)
-
-def make_topic_link(string):
-    pattern="(#(.+)#)"
-    return re.sub(pattern,r"<a target=_blank href='http://huati.weibo.com/k/\2'>\1</a>",string)
-
-def make_user_link(string):
-    pattern=ur"((?P<at_user_name>@(?P<user_name>([a-zA-Z0-9_\-\u4e00-\u9fa5]+)))(?P<tail>\s|\S|$))"
-    return re.sub(pattern,r"<a target=_blank href='http://weibo.com/n/\g<user_name>'>\g<at_user_name></a>\g<tail>",string,re.UNICODE)
-
-def make_all_link(string):
-    return make_topic_link(make_user_link(make_url_link(string)))