用Twitter冒泡

家里网通仍然是不能访问appspot,不过好在有些地方还可以访问,这里也来冒个泡吧。由于GFW把google的好些个网站都给封锁了,以至于前几天Google Reader都不能读取几个Google官方Blog的时候总是出错,于是我也用起了Twitter,搜索到了几个Google官方的twitter账号。

另外Intype也开通了他们的官方Twitter,原来村上先生也是用Twitter的啊,不过总是不更新的twitter怕是没啥意思的,更新太多的也觉得烦人。

设计新的BLOG主题

最近一直在设计这个新的TextStyle主题,总想用最简约的外观和KISS原则把这个Blog程序的前台和后台都重新设计一下,这除了是受到国内一些知名博客所使用风格影响可能也是长期使用Google出品的程序所致。此外还仿照http://www.blogger.com的Favicon设计了一个新的Favicon。在这个新的TextStyle主题里,我几乎去掉了所有js代码和图片,少部分必须保留的图片也准备在以后自己动手重新设计。布局方面依然沿用两栏式的Blog典型布局,顶部的Header移动到侧边栏的左上角,标题准备使用图片制作一个类似lxml的这个可爱的大蛇丸Logo。

Keep it simple, stupid!

参考:

Blog 2009

原来的域名到期,碰巧赶上谷歌公布GAE的收费计划,对于免费用户来说CPU Time现在成了每天6.5小时和而Bandwidth则改成每天1GB,再加上GFW不时作恶,tgbus牛博等“低俗”网站被封,本来有用GAE做程序的念头但是想起这些乱七八糟的事情就觉得兴味索然,不过生活还要继续,2009我将依然在深夜咣咣的敲着键盘书写思想。

采用ObjectPaginator分页

以前的分页是从网上搜索的一些代码,居然不知道Django有ObjectPaginator这么个东西。最近看看了Gae Cookbook上的几个关于django分页的处方,其实用ObjectPaginator做分页模板非常简单。

ObjectPaginator的构造函数需要提供query_set和num_per_page这两个参数,也就是你要使用的数据集和每页的文章数。还有一个orphas参数默认为0,用来避免出现最后一页文章过少的情况。

def __init__(self, query_set, num_per_page, orphans=0):
        self.query_set = query_set
        self.num_per_page = num_per_page
        self.orphans = orphans
        self._hits = self._pages = None

这里我只生成了一个文章分页的数量列表和前一页、下一页三个链接,然后用ObjectPaginator类的方法判断这些链接是否显示,也就是用get_page()方法来取得当前请求页面的文章,用has_next_page()方法判断是否存在下一页,用has_previous_page()方法判断是否存在前一页。

paginator = ObjectPaginator(all_posts,10)
	if page >= paginator.pages:
		page = paginator.pages - 1
	posts=paginator.get_page(page)
	pages=range(1,paginator.pages+1)	
	show_prev = paginator.has_previous_page(page)
	show_next = paginator.has_next_page(page)
	page=page+1

参考:

JIEblog几个更新,搜索引擎优化

最近按照谷歌搜索引擎优化提到的几个项目对JIEblog进行一些改动,包括生成动态的description和keywords标签、为每篇日志生成title标签、生成可读的URL、新的站点地图、添加分类和分类页面,另外正在编写的是成就页面Archives Page。以前对分类Catagory和标签Tag的理解有些问题,分类应该是唯一的而标签应该是一种关键词,这样在使用的时候总的标签云正好可以对应站点的meta keywords,而每篇日志所包含的标签也正好对应每篇日志的meta keywords。

为JIEblog生成符合规范的网站供稿

最近着手改进网站的代码,一方面通过memcache降低CPU使用,另一方面想把网站供稿在feedburner上烧制一下,以减少网络程序访问产生的CPU占用。以前的供稿在Google Reader上虽然显示正常,但在Feedburner上烧录后却只有乱码。研究了一下发现是由于feedburner是根据供稿的编码来识别代码,而不是根据实际的编码,因为这个XML模板是用Intype默认的ANIS编码编写的所以造成了这个错误。

另外用http://feedvalidator.org/验证了一下这个供稿,发现还有不少问题。文章内部字符和标记的错误就不计了,剩下的主要是时间格式不符合规范。其实以前这个时间规范的问题一直会影响Google Reader,不过不知道Google什么时候改正了时间显示的方式,用Google Reader抓取的时间代替了供稿生成的时间,所以我的这个问题也一直没有修正。

Atom使用的这个时间格式标准被称为rfc3339 Timestamps,其实编写一个能生成符合这个rfc3339标准的python代码也不算难,而我可能以后会用django生成的供稿,所以为了节约时间还是直接Google了一个rfc3339 for Python,上面还有Pyfeed这种东西,真是遗憾了,以后干什么一定要先Google一下。

在用http://jieblog.appspot.com烧录的时候发现feedburner居然直接识别了appspot的子域名并且返还了这么个地址http://feeds.feedburner.com/appspot/euFN。不过在没有修改完善之前还是不使用这个供稿了,毕竟修改供稿造成阅读器的项目混乱是很麻烦的。

为JIEblog添加Memcache

虽然从控制台上看Application Quotas还都够用,但是Current Load里首页和feeds两个项目平均CPU占用都有警告:

This URL uses a heigh amount of CPU and may soon exceed its quota.

看着总是不太舒服。首页的高CPU自然比较正常,而feeds因为我没有使用feedburner这类的工具烧制RSS现在的确有点后悔了,再加上这个feeds还是Google Webmaster工具的Sitemap所以占用也会很高。而Google Reader甚至有时候在我发布文章后1分钟内就会更新。

Appengine的FAQ里提到衡量CPU使用的两个主要途径是:

  1. Runtime CPU:应用程序本身产生的CPU使用,这显然是和代码的质量有关系
  2. API CPU:用于调用App Engine API产生的CPU使用,例如:datastore API , urlfetch API, image API, 等。

第一条我显然没有太多时间做。。。所以直接转向第二条,使用Memcache进行优化。Appengine文档里有个很简单的例子,目前我只用Memcache尝试提取首页的Post数据,然后看看效果是否明显:

def get_data(the_key, time_exp):
  data = memcache.get("Post")
  if data is not None:
	return data
  else:
	data = query_for_data()
	if not memcache.add(the_key, data, time_exp):
		logging.error("Memcache set failed.")
	return data

通过使用这个函数,首先检查memcache的data是否有the_key这个数据,如果有的话直接返还data,如果没有的话则调用query_for_data()这个函数。然后将query_for_data()的结果加入memcache,而memcahe则是按照设定的time_exp进行更新。

配置YUI的Rich Text Editor不调用cleanHTML方法

从tinyMCE转到YUI的Rich Text Editor以后好长时间我才发现YUI的这个范例配置的Code Editor会自动调用cleanHTML方法格式化代码,于是好多标签比如script这种标签会直接删除掉,这直接导致我以前配置的swf-mp3-player和prettyprint这两端代码不能使用。

要使YUI的Editor不调用cleanHTML首先需要在配置中把handleSubmit的属性改成false,这样在submit的时候Editor就不会调用cleanHTML了;但点击Code View这个button的时候还是会调用this.cleanHTML()这个方法,直接去掉的话Code View这个button基本上就没用保存文字的功能了,于是查了一下YUI的API,果然有this.getEditorHTML()这个方法,用this.cleanHTML()取代this.cleanHTML()就好了。

添加Gravatar支持

Gravatar是一个支持在网络上引用图片的服务器,用户把头像图片上传到Gravatar服务器上,然后支持Gravatar的网站就会根据用户的email找到用户在Gravatar上传的图片。至少我看到wordpress.com和wordpress通过插件支持这个服务,另外最近看到Github也支持。

添加Gravatar只要通过python生成用户图片的地址就可以了:
# 导入用到的lib
import urllib, hashlib

# 设置变量
email = "someone@somewhere.com"
default = "http://www.somewhere.com/homsar.jpg"
size = 40

# 构建url
gravatar_url = "http://www.gravatar.com/avatar.php?"
gravatar_url += urllib.urlencode({'gravatar_id':hashlib.md5(email).hexdigest(),'default':default,'size':str(size)})

gravatar还支持给图片分级,一般网站允许G-rated就好了,貌似允许X-rated级的会有些危险。

JIEblog source code host on Github.com

JIEblog Source Code
以前一直是用Google Code+Subversion管理代码,现在迁移到ubuntu以后决定尝试一下使用Git,服务器端使用了github.com,唯一不太方便的地方就是github.com在国内不能正常访问。
我最早接触到使用Git的项目既不是linux kernel也不是Rails等什么的开源项目,而是从forum.wowace.com上看到的一些WOW插件作者在使用git管理插件代码,这里面最著名的是oUF等插件的作者Haste的git,还有tekkub等人。我想他们选择git大概是因为开发插件这种东西需要不断的快速的提交,git自然是在适合不过了。
1 2 NEXT
Creative Commons 3.0 BY