自己写sublime text插件

起因是,自己写Python基本上使用sublime text 2。但是,文件头部的代码

#! /usr/bin/env python
# -*- coding: utf-8 -*-

如果每次都要敲的话,很麻烦。而如果不敲的化,一旦涉及中文,又会报错,就产生了写了一个插件的想法。。问题好久了,直到今天才动手,惭愧一下。。

思路应该是比较简单,就是判断文件类型,然后在头部插入特定的字符串。于是乎,开始在网上查找sumblime text 2的API还有插件开发教程。这是API文档中文翻译版,看一下Default里面的自带插件,就可以动手了。

最初的代码中,字符串是硬编码的。后来,则是从模板文件中读取字符串。在这一步,遇到了一个很诡异的问题,是这样的:模板文件保存在templates文件夹下面,在HeadTemplate.py中(我的插件的名字是HeadTemplate),

def get_tpl_file(settings, filename):
    template_root = settings.get('template_root')
    path = os.path.join(os.path.dirname(__file__), template_root)
    return os.path.join(path, filename)

但是这个函数的返回的结果是/home/username/templates/filename,而实际上,我认为应该返回的是/home/username/.config/sublime-text-2/Packages/HeadTemplate/templates/filename。打印os.path.abspath(__file__),得到的结果是/home/username也就是我的家目录。开始以为是由于隐藏文件夹的缘故,不过试验之后,发现与之无关。为什么会有这个结果,具体原因到现在我也还弄不清楚。不过,解决方案倒是找到了,感谢SErHo的代码

PACKAGE_NAME = 'HeadTemplate'
PACKAGES_PATH = sublime.packages_path()

def get_tpl_file(settings, filename):
    template_root = os.path.join(
                    PACKAGES_PATH, 
                    PACKAGE_NAME, 
                    settings.get('template_root'))
    return os.path.join(template_root, filename)

在其他就没有什么了,按部就班的写下来就好了。代码放在了github上,https://github.com/iEverX/HeadTemplate

算上空行不到50,却写了一个下午。。

Javascript遍历DOM树

这个博客是利用Jekyll在github pages上搭建的,显示在首页的文章,如果用{{ post.content | truncate: 200 }},原有的格式不能完全保持,且有时在最后会有乱码。而{{ post.content | truncatewords: 50 }}也有不能保持格式的问题,而且对于中文来说,word的概念大概就变成了句子,截取的长度不能确定。本来truncatehtml这个插件可以解决格式保持的问题,但是出于安全的考虑,github pages不允许运行插件,所以。。。

这个问题有很长时间了,今天闲的没事,用js写了一下。就是遍历DOM树,叠加文本节点的长度,当长度达到既定长度时,其后所有的节点修改style为display: none,用jQuery就是hide(),具体到自己的博客,代码如下,

$(function() {
    function traverse($node, len, maxCount) {
      var reachMaxCount = len > maxCount;
      if (reachMaxCount) {
        $node.hide();
      }
      var $contents = $node.contents();
      for (var i = 0; i < $contents.length; ++i) {
        if (reachMaxCount) {
          $contents.eq(i).hide();
          continue;
        }
        if ($contents[i].nodeType == 3) { // TextNode
          var tmp = len;
          var s = $contents[i].nodeValue;
          len += s.length;
          reachMaxCount = len > maxCount;
          if (reachMaxCount) {
            $contents[i].nodeValue = s.substring(0, maxCount - tmp);
          }
        }
        else if ($contents[i].nodeType == 1) { // Element
          len = traverse($contents.eq(i), len, maxCount);
        }
      }
      return len;
    }

    $('.post_at_index').each(function() {
      traverse($(this), 0, {{ site.description_length }});
      var thisUrl = $(this).siblings().first().children().attr('href');
      $(this).after('\n<a href="' + thisUrl + '" rel="nofollow">' + 'Read More ...</a>');
    });
});

对于js,我都会使用jQuery,这个同样如此,需要jQuery的支持。在最后加上了了read more,指向页面。写完之后,发现代码不长,不过却花了我一个下午的时间,主要是对js太不熟悉了,上网各种查,开始是用的children()这个方法,但是这个不能处理很好,后来改成了contents(),不过已经浪费了很长时间了。。

另外吐槽一下Liquid这个模板,规避标签太麻烦了,比如要打一个

{{ some tag }}
{% some tag %}

需要如下这样才行,

{{'{'}}% raw %}{{ some tag }}{{'{'}}% endraw %}
{{'{'}}% raw %}{% some tag %}{{'{'}}% endraw %}
或者
{{'{'}}{ some tag }}
{{'{'}}% some tag %}

其他的模板带语言,要输出自身的控制标签确实都不容易,但是Liquid已经不是不容易,而是复杂了。。我感觉,如果有两个停止解析的标志,比如说

{! here is not parsed !}
{@ here is not parsed @}

那么,如果有如果有显示{! !},只需要{@ {! !} @},目前,Liquid有标签rawliteral可以使用,但是我的试验结果是literalraw似乎不太协调,不知什么原因,渲染结果总是与预想的结果不一致。。看了Liquid的issue,发现有可能是Jekyll的问题,也不清楚到底是怎么回事,不去想了。。

web.py中自定义jinja2模块

web.py是一个轻量级的Python web开发框架,不过自带的模板自己很不习惯,就换成了jinja2。web.py已经封装了jinja2的接口,很简单

from web.contrib.template import render_jinja
render = render_jinja('templates', encoding='utf-8')

之后就和自带模板一样使用了。web.py中使用jinja2的源代码如下

class render_jinja:
    """Rendering interface to Jinja2 Templates

    Example:

        render= render_jinja('templates')
        render.hello(name='jinja2')
    """
    def __init__(self, *a, **kwargs):
        extensions = kwargs.pop('extensions', [])
        globals = kwargs.pop('globals', {})

        from jinja2 import Environment,FileSystemLoader
        self._lookup = Environment(loader=FileSystemLoader(*a, **kwargs), extensions=extensions)
        self._lookup.globals.update(globals)

    def __getattr__(self, name):
        # Assuming all templates end with .html
        path = name + '.html'
        t = self._lookup.get_template(path)
        return t.render

__getattr__函数中,path = name + '.html'使得只能访问同级目录下的模板。同时,还不方便使用自定义函数。在其基础之上,稍作修改即可,如下

class RenderJinja2:

    postfix = ('.html', '', 'htm', 'tpl')

    def __init__(self, *a, **kwargs):
        extensions = kwargs.pop('extensions', [])
        globals = kwargs.pop('globals', {})
        registers = kwargs.pop('registers', {})

        self._lookup = Environment(loader=FileSystemLoader(*a, **kwargs), extensions=extensions)
        self._lookup.globals.update(globals)
        self._lookup.globals.update(registers)

    def render(self, path, **kwargs):
        for fix in self.postfix:
            realpath = path + fix
            try:
                t = self._lookup.get_template(realpath)
                return t.render(**kwargs)
            except:
                pass
        raise TemplateNotFound

    def __getattr__(self, name):
        path = name + '.html'
        t = self._lookup.get_template(path)
        return t.render

现在,自定义的函数、变量可以通过register这个字典传入,渲染时也有两种方式,

# 通过register传入自定义的函数或者变量,这里为了方便,使用了locals()
render = RenderJinja2('path/to/templats', encoding='utf-8', registers=locals())

# 渲染时
render.render('path', **kwargs) # 新加的render
render.post(**kwargs) # 原先的方式,通过 __getattr__

Jekyll中使用google-code-prettify高亮代码

这个博客,到现在换了好几个代码高亮的工具,之前的SyntaxHIghlighter虽然漂亮,无奈加载太慢,只能舍弃了。现在用的这个是google-code-prettfy,效果也相当不错。最重要的是,非常小,加载速度比SyntaxHighlighter快得多,而且,可以直接使用markdown的语法去写代码。

首先需要两个文件,prettify.js和prettify.css,自己去官网去下。把这两个放到模板中,如下

<link href="{{ ASSET_PATH }}/google-code-prettify/desert.css" rel="stylesheet" type="text/css" media="all">
<script type="text/javascript" src="{{ ASSET_PATH }}/google-code-prettify/prettify.js"></script>

考虑到加载速度,最好js写到文档末尾,body闭合标签之前,css写到头部

之后,还需要加上如下代码,用于识别并高亮代码块,这个需要使用jQuery

$(function() {
  window.prettyPrint && prettyPrint();
});

现在,就可以使用<pre></pre>标签进行高亮了,

<pre class="prettyPrint">
// code here
</pre>

但这样会有些问题,就是在书写html代码的时候,html标签会被浏览器认为是标签而不是代码的字符。而markdown的语法写的代码其实已经解决了这个问题,所以,我们可以利用如下的js代码,来避免自己用<pre></pre>写代码所出现的问题,同样需要jQuery支持

$(function() {
  $('pre').addClass('prettyprint linenums').attr('style', 'overflow:auto');
});

这样之后,就没有问题了,可以直接用markdown的前置4空格来写代码了。其中addClass('prettyprint linenums')linenums是添加行号的意思。默认只显示第5、10、15…行,可以在css文件中li的格式添加list-style-type: decimal;,以显示全部行号

另外,如果博客中有用bootstrap,其中对pre有如下几句

white-space:pre;white-space:pre-wrap;word-break:break-all;word-wrap:break-word;

这会使得pre中的代码自动换行,而不是溢出形成滚动条。如果不希望如此,可以注释掉。就看个人的喜好了。如果是滚动条,默认的滚动太难看,可以修改一下样式,看一下这篇文章

在Jekyll中用SyntaxHighlighter高亮代码2

之前有一篇博客是关于在Jekyll中利用SyntaxHighlighter去高亮代码的。不过那篇博客中的方法需要每次都加载所有的js文件,加载速度比较慢。其实,可以利用js动态加载js来实现对于不同的语言加载不同的语法分析文件,从而提高js文件的加载速度。废话不多说了,上代码

<script language='javascript'>
    $(function () {

        var stdname = {
            'bash': 'Bash',
            'sh': 'Bash',
            'c': 'Cpp',
            'cpp': 'Cpp',
            'cs': 'CSharp',
            'css': 'Css',
            'java': 'Java',
            'js': 'JScript',
            'php': 'Php',
            'py': 'Python',
            'python': 'Python',
            'rb': 'Ruby',
            'sql': 'Sql',
            'vb': 'Vb',
            'xml': 'Xml',
            'html': 'Xml',
            'perl': 'Perl'
        };

        var used = {};

        var $t = $('pre[class^=brush]');
        if ($t.length > 0) {
            $('body').append('<script src="/static/js/syntaxhighlighter/shCore.js" type="text/javascript"></script>');
        }
        $t.each(function() {
            var lang = stdname[$.trim($(this).attr('class').substring(6))];
            if (used[lang]) {
                return;
            }
            used[lang] = true;
            $('body').append('<script type="text/javascript" src="/static/js/syntaxhighlighter/shBrush' + lang + '.js"></script>');
        });
        if ($t.length > 0) {
            $('body').append('<script language="javascript">SyntaxHighlighter.all();</script>');
        }
    });
</script>

把以上这段代码放在Jekyll模板页的body的最后面即可。

这段代码需要jQuery,我的是1.8.2,不知道低版本的是否可以。此外,shCore.css,shThemeDefault.css文件不是动态加载,所以,这两个文件仍然需要直接放在模板页的头部。

写在学期末

今天,软工的答辩结束。至此,这个学期的课,除了软工的第二次结对编程还要写代码、编译还要检查之外,这个学期就没有其他的事情了。说现在是放假状态也无不可。

就像10月的那篇博客所说,这个学期事情很多。不过那时候并没有切身感受,所有的多与不多,不过自己推断而已。。现在学期结束,那感受就真实了。

先说软工吧,说实话,软工的团队项目做的就是翔一样,而且还累得要死。。其实,说实话,我们做的功能并不复杂,也不是很难,但是就是做不好。。我们做的是一个大项目中的一小块,是用户管理。。想想,用户管理分为哪几块?先不说涉及到网站具体内容的地方,那就是登录、注册、密码重置、信息修改四个地方吧,但是关键是要做好,用户体验要好。现在做完了,说说自己的理解

  1. 界面简洁大方这个完全是界面设计的事情,就不说了
  2. 错误信息提示足够详细,而且足够及时这一点如果要做到,js和ajax必不可少
  3. 用户操作简单,没有门槛流程简单要,要没有特别注意的地方。这一点也需要js支持
  4. 用户信息保护密码加密
  5. 系统的安全防止脚本攻击、SQL注入。激活邮件、重置密码邮件链接不能被伪造

其次说一下数据库,相比较软工和编译,数据库的大作业真的可以说是So easy!用了三天,当然还是遇到了困难。表前前后后改了好几趟,而且有些地方用的id让事情变得比较复杂。。还有一个困难就是DataGridView这个控件的使用,这个问题困住了我们一个晚上!!然后,然后就没有然后了。。或者是,然后就开始写编译了。。

最好说一下编译,这是我这辈子以来,写得最大的一个工程,也是最难的一个。写完数据库,就开始写编译了,那时候,距离最后期限还有4天,我只写完了词法分析和语法语义分析中的常量说明部分。最重要也最麻烦的四元式生成还没有写,汇编更不知道是什么东西。。但是没有办法,作业还是得交啊。。那就问同学,上网查,自己想。。知道截止日期那一天,自己的数组的汇编还没有搞定,错误处理也没搞定。。庆幸的是,编译的截止日期推迟了32小时,我擦,心情大爽!最后的32个小时,总算是把功能搞定了。。不过优化却是无论如何没时间写了。。为了写出这个编译器,和XYQ一起熬夜,72个小时睡了10小时不到。。着绝对是我这辈子最“光明”的时间。。还想着之后就能好好睡觉了。。结果也确实睡了一个好觉,从早上8点多道下午2点多。。之后是数据库的检查,然后第二天是软工的最终复审。。都赶在这几天了!

XYQ一直再说,如果早写一个星期,也不至于被逼得这么惨。。这话再理,不过这个学期伊始,我就说过,不要把大作业都留到最后,结果说了等于白说。。嗯,其实,有一个大作业说是提前写完的,就是Ruby了。。网站在http://share.evercoding.net,自己感觉交个大作业是没问题了。。

然后。。2012世界未末日,不知道什么时候才是真的世界末日

在Jekyll中用SyntaxHighlighter高亮代码

前几天把博客里的代码高亮改成[SyntaxHighligher][]了,感觉好了很多,看着也舒服,关键是复制代码的时候,行号连着代码在一行复制了。主要参考了官网给的这个链接Adding a Syntax Highlighter to your Blogger blog。Jekyll的灵活性应该比Blogger更大,而且直接贴改代码,所以对于Jekyll这个方法是合适的。下面是具体的过程

在Jekyll的模板页里的head里面,添加如下代码,选自己需要的语言的刷子就好

<link href='/static/css/syntaxhighlighter/shCore.css' rel='stylesheet' type='text/css'/>
<link href='/static/css/syntaxhighlighter/shThemeDefault.css' rel='stylesheet' type='text/css'/>
<script src='/static/js/syntaxhighlighter/shCore.js' type='text/javascript'></script>
<!-- The Following is styles for different language  -->
<script src='/static/js/syntaxhighlighter/shBrushBash.js' type='text/javascript'></script>
<script src='/static/js/syntaxhighlighter/shBrushCpp.js' type='text/javascript'></script>
<script src='/static/js/syntaxhighlighter/shBrushCSharp.js' type='text/javascript'></script>
<script src='/static/js/syntaxhighlighter/shBrushCss.js' type='text/javascript'></script>
<script src='/static/js/syntaxhighlighter/shBrushJava.js' type='text/javascript'></script>
<script src='/static/js/syntaxhighlighter/shBrushJScript.js' type='text/javascript'></script>
<script src='/static/js/syntaxhighlighter/shBrushPhp.js' type='text/javascript'></script>
<script src='/static/js/syntaxhighlighter/shBrushPython.js' type='text/javascript'></script>
<script src='/static/js/syntaxhighlighter/shBrushRuby.js' type='text/javascript'></script>
<script src='/static/js/syntaxhighlighter/shBrushSql.js' type='text/javascript'></script>
<script src='/static/js/syntaxhighlighter/shBrushVb.js' type='text/javascript'></script>
<script src='/static/js/syntaxhighlighter/shBrushXml.js' type='text/javascript'></script>
<script src='/static/js/syntaxhighlighter/shBrushPerl.js' type='text/javascript'></script>
<script language='javascript'>
  SyntaxHighlighter.all();
</script>

其中,src里面是文件的目录,把从官网上下载的对应的js文件和css文件放到对应的目录即可。其实也可以直接引用官网的js文件,比如这样(以下代码来自我参考的网址,去掉了一些不需要的代码)

<link href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' rel='stylesheet' type='text/css'/>
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css' rel='stylesheet' type='text/css'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCpp.js' type='text/javascript'></script>
<script language='javascript'>
    SyntaxHighlighter.all();
</script>

不过,这样会导致没有联网的时候,自己写博客预览的时候看不到代码的高亮效果。

之后,写代码的时候,不要使用markdown的语法,直接用pre抱起来就好了。就比如这样

<pre class="brush: cpp">
</pre>

效果就和以上一样了。这个应该比pygments更好看吧。不过目前加载速度比较慢,以后再改吧

忙&累

上一篇博客已经说了,这个学有, “编程生涯”许多的大作业,代码量不小。到现在过去了一个月,代码量是蹭蹭的往上涨。一个科目一个科目的说吧。

软工是最主要的贡献者,要求每天一次scrum,还要写到博客上。基本上是没空闲。不过从这里,却是学到了许多,比如技术上的、项目上的,现在不细说了。然后,上上个星期吧,编译开始。选了个扩编展C0,要求生成汇编码。虽说不是真生的C编译器,对于我们来说,难度那是相当的不小。如果说软工最主要的实在项目的协调上,那么编译难点就在写,写出真正可用的代码。而接下来要说的数据库,没有难点,纯粹的体力活,只要想好一个点子就行,如果踏踏实实的写,估计两个从早写到晚,两天就搞定了。还有就是,自己选了Ruby课,那就有Ruby大作业要写了,这个到目前为止,倒是写了不少了。不过对于Rails真心不习惯,可能是没有理解其精髓,最主要还是不习惯它自动生成的那么多代码(关键是自己以前从没有用那些自动生成大量代码的东西,VS从来都是空项目,Django也没学)。嗯,除了课内的,还有一个是学院的Win8的App开发比赛,为了这个昨天花了一个小时装了Win8,然后又花了N个小时装了各种软件,囧。。

这一段时间,包括这个学期的后半段,应该会一直处在不断的编码过程之中。也学到了许多新的技术吧。就简单的说一下吧,不涉及具体内容。因为都是项目里要用的东西,临时学的,也讲不出什么有用的东西出来,等这一段过了之后,事情少了,有心情了,再具体的说一些,当然也得自己肚子真有东西才行

  • C#的this扩展,个人感觉类似Ruby的开放类,不过应该是用作用域限制的
  • SQL语句,应该使用参数传递的方式,不要字符串拼接,对于C#,可以看看CSDN上的这个帖子《用存储过程防止SQL注入是笑话吗?》和Stackoverflow上的一个帖子《Different ways of passing sqlCommand parameters》。其他语言,道理应该是一样的
  • jQuery,这个真是个好东西,尤其是做Ajax,实在so easy!不过自己对于js几乎算是完全的新手,完全不了解其道理。不过用这个做一些软工项目的前端,效果应该是不错的
  • Rails,这个现在还说不出什么东西来, 等到课上讲了,对这个框架有了更进一步的理解,估计才能说出一些道道。不过,相对于Ruby,个人感觉还是Python更合自己
  • 编译,到目前,写完了词法分析,开始语法分析。感觉就是,词法分析很简单,不过也会有一些坑。语法分析就困难的多了,尤其是错误处理的时候,跳读多少才能保证一个错误的连锁错误最小?这个愁死了
  • 数据库连接池。开始的时候,在项目里,对于数据库连接,用的是单例。结果可想而知。用单例是因为自己对数据库连接的具体原理不清楚,而且上个学期的OO课的大作业,用的就是单例,OO课不用演示,没有运行过压力测试,所以。。.NET是内置的数据库连接池的,这个以前真是不知道。。
  • Win8开发,这个我们组还没开始。。囧。。

OK,结束。。继续Coding

新学期的第一个月

已经过了午夜,算是19号了。算来,从上个月10好开学,也有一个多月了。正好博客也一个月没更新了,正好写一篇。

这个学期,单从课程的多少来看,应该是相当轻松的。不过,如果从课程的难度以及大作业来看,这个学期绝对不好过。编译、数据库还有软件工程,三个课,哪个大作业都不是那么好相与的。而且,我们班的软工课的老师不是学校的老师,而是微软的邹欣老师,上课和中国的老师的风格不一样,走的是欧美路线。整个课程的代码量相当的不小,而且要求相当的阅读量(按他的意思来说,这个和国外名校还差得远呢)。

先稍稍的说一下开学一个月以来的情况把。可能是刚开学,抑或是别的什么原因,感觉这一个月非常的累,琐事不断。还有就是自己还是浮躁,静不下心来,做事情总是三分热度。

不过现在想想,开学一个月自己到底都干了什么,也说不出自己到底干了什么。只是十一之后的大创(大学生创新创业训练计划)的中期答辩,忙了几天。再之前,也想不出什么事情来了。我以为,一个重要的原因就是那些事情根本不重要,就像我说的,琐事一堆而已。也正是由于是琐事,才会感觉到累吧。

除了这些,自己也是干了些其他的事情,虽然没有成果,或者说也是即兴而起,在这里也说一下。

  1. 学习emacs。现在的博客就是在emacs里敲的。虽然一直用vim,不过我一直想学emacs,对于两者没有偏好。不过由于emacs的上手难度比vim要大,所以想了好长时间也没有真正动手,其间的几次简单尝试亦未有收获。这次终于学起来,其实还是选修了一门课,叫做数据密集型计算导论。老师在课上说了一句话,lisp是一门非常强大的语言,然后就有了学lisp的冲动,而些lisp,最好就是用emacs了。
  2. 学习common lisp。就像上面说的,学习emacs其实还有一些必然,学习lisp就是纯属偶然,虽然自己也有过想要学习一门函数式编程语言的想法。不过,学习一门语言如果不深入研究,终究只能停在表面。目前我对于common lisp的理解就是仅仅停在表面,甚至连表面都还没接触到。
  3. 貌似也没有其他什么了。。。

再说说软工课吧。邹欣老师是程序员的大牛了。他教的课,也有大牛的水准。我们只有两个班大约六十人上他的课,然后自有组合成10个团队。每个人,每个团队,都必须在博客园上开一个博客,项目的进程什么的东西需要发在博客上。这在以前的课上是不会有的,博客是属于分享性质的,不算是课上教学的一部分,只能算是一些人的爱好而已。而且,对于团队博客,博客的积分是会影响道最终的团队的成绩的,我认为,这是一种促使我们写出优质文章的手段。我的团队叫做CodingCook,中文名称是代码厨师(呃,在邹欣老师的博客上,写的是代码厨房)。在编程方面,我们目前已经交了一个个人项目,词频统计。然后我们我们现在在进行结对编程。不过感觉老师想得比较好,实际上,近30个组,又有几个是真正结对编程的呢?

至于其他,只能说,争取好好干吧,好好学一个学期。看看到寒假,自己对自己的评价是怎么样的。是一个”爽“,还是一个”我操“。。

用Tornado连接新浪微博

前几天心血来潮,稍稍看了一下Tornado框架,感觉这个框架和web.py很像(因为本来Tornado就是在web.py的基础上修改而来的)。

微博的API就是微博官网上的那个新的API,可以从这里下载。网上有很多的教程,不过用的都是原来的API,不过也可以参照。不多说了,直接贴代码,不过这是简写的,不过可以连接到微博了。

#! /usr/bin/env python
# -*- coding: utf-8 -*-

import tornado.web
import tornado.ioloop

from weibo import APIClient

APP_KEY = '*****'
APP_SECRET = '******'
CALLBACK_URL = 'http://apps.weibo.com/webotxyz/callback'
# 这是回调地址,必须在微博应用的域名下面,否则报错

class Index(tornado.web.RequestHandler):
    def post(self): # 注意,这里是post
        client = APIClient(app_key=APP_KEY, 
                           app_secret=APP_SECRET,
                           redirect_uri=CALLBACK_URL)
        url = client.get_authorize_url()
        # self.write('<a href="' + url +'">click</a>') 
        # 用户点击链接后跳转到验证界面
        self.redirect(url) # 直接跳转到验证界面

class Callback(tornado.web.RequestHandler):
    def post(self): # 注意,这里也是post
        code = self.get_argument('code')
        client = APIClient(app_key=APP_KEY,
                           app_secret=APP_SECRET,
                           redirect_uri=CALLBACK_URL)
        r = client.request_access_token(code)
        access_token = r.access_token
        expires_in = r.expires_in
        client.set_access_token(access_token, expires_in)
        # res = client.get.statuses__user_timeline(screen_name='iEverX')
        # 这以后就可以自己调用API了,比如上一句就是抓取我的最近的微博

app = tornado.web.Application([
    (r'/', Index),
    ('/callback', Callback),
])

if __name__ == '__main__':
    app.listen(9009)
    tornado.ioloop.IOLoop.instance().start()

我的应用的源码在这里http://github.com/iEverX/webotxyz,不过我的应用不可能上线的了,因为抓取数据存到邮箱了。。

下面是我在里面用到的一段Python发送邮件的代码,比较短,可以充分的看出Python的简洁

#! /usr/bin/env python
# -*- coding: utf-8 -*-

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

def send_mail(mail_from, mail_to_list, subject, content):
    from_format = 'Ever' + '<' + mail_from + '>'
    # 格式应该是这样的 Nickname<username@host.address>,中间无空格
    txt = MIMEText(content, 'html') # 若content中有html编码
    # txt = MIMEText(content) # 若content中没有html编码
    txt.set_charset('utf-8')
    msg = MIMEMultipart()
    msg['Subject'] = subject
    msg['From'] = from_mail
    msg['To'] = ';'.join(mail_to_list)
    msg.attach(txt)
    try:
        s = smtplib.SMTP()
        s.connect(mail_info['host'])
        s.login(mail_info['sender'], mail_info['sender_password'])
        s.sendmail(mail_info['sender_address'], mail_to_list, msg.as_string())
        s.close()
    except:
        return false
    return True

嗯,这篇文章几乎都是代码,就当是自己的备忘录好了。。