好久没有更新了
前一段时间是毕业前的疯玩,这一段时间是工作后的疯忙。
不仅要忙快速进入测试人员这个新角色,而且还要认识一大堆的同事,还要填一大堆的表格,装一大堆的软件,同时还要背一大堆的单词来提高的英语水平。
而且门卡没有办下来,进出好麻烦啊,每天都要被保安盘问半天。枉我长得这么帅,保安怎么就记不住呢?
前一段时间是毕业前的疯玩,这一段时间是工作后的疯忙。
不仅要忙快速进入测试人员这个新角色,而且还要认识一大堆的同事,还要填一大堆的表格,装一大堆的软件,同时还要背一大堆的单词来提高的英语水平。
而且门卡没有办下来,进出好麻烦啊,每天都要被保安盘问半天。枉我长得这么帅,保安怎么就记不住呢?

function toggleOneCol() {
var va = $("one_col")
var wrap = $("wrap")
if (va.innerHTML == "Page without sidebar"){
va.title="Page with sidebar";
va.innerHTML="Page with sidebar";
wrap.className="one-column";
} else {
va.title="Page without sidebar";
va.innerHTML="Page without sidebar";
wrap.className = "";
}
}
哈哈,好简单啊Netscape's original proposal defined an Expires header that took a date value in a fixed-length variant format in place of Max-Age:他们就为了长度一定就使用那么负责的日期字符串,然后在处理的时候还要再转化为秒,他们完全不知道我使用了如下变态的方法构造出了这个GMT的expires时间:
##########写Cookie ############
cookies = Cookie.SimpleCookie()
cookies['comm_name'] = comment.author
cookies['comm_name']['path'] = '/'
cookies['comm_name']['max-age'] = 3600*24*365
cookies['comm_email'] = comment.authorEmail
cookies['comm_email']['path'] = '/'
cookies['comm_email']['max-age'] = 3600*24*365
cookies['comm_url'] = comment.authorWebsite
cookies['comm_url']['path'] = '/'
cookies['comm_url']['max-age'] = 3600*24*365
output_headers = []
output_headers.append('%s\r\n' % cookies)
for header in output_headers:
sys.stdout.write(header)
##########读Cookie ############
cookies = os.environ.get('HTTP_COOKIE', None)
if cookies is not None:
user_cookie = Cookie.SimpleCookie()
user_cookie.load(cookies)
try:
comm_name = user_cookie['comm_name'].value
comm_email = user_cookie['comm_email'].value
comm_url = user_cookie['comm_url'].value
except KeyError:
pass
Over,大功告成!
try:
email = request_.get('email')
except ValueError:
return response_.out.write("email is invalid")
gravatar_url = util.getGravatarUrl(email)
result = urlfetch.fetch(gravatar_url)
if result.status_code == 200:
response_.headers['Content-Type'] = "image/png"
response_.out.write(result.content)
else:
response_.out.write("No Image")
哈哈,非常简单啊。archives = Archive.all().order("-date")
memcache.add(key_, archives, 3600)
修正的方法也很简单,把结果读取出来,放到一个list里即可。
archives_ = Archive.all().order("-date")
archives = [x for x in archives_]
memcache.add(key_, archives, 3600)
接下来要做的事情:def counter(handler_method):该装饰函数实现的功能也非常简单:在数据库中有一个表为Counter,其中只包含一条数据,这条数据只包含一个字段count,代表本blog某些页面被访问的次数总和。设计的这么简单是为了提高效率(感觉上字段越少速度越快,不知道是不是真的)。每次访问的时候,如果不是admin的话,那么就让记录加一。
def wrapper(self, *args, **kwargs):
counter = Counter.all().get()
if counter is None:
counter = Counter()
counter.put()
if not users.is_current_user_admin():
counter.count += 1
counter.put()
return handler_method(self, *args, **kwargs)
return wrapper
class MainPage(BaseRequestHandler):那么就给主页添加了计数功能,另外我给单篇文章文章展示和主页的paginator部分加上了计数,其他部分,比如category,tag,archieve等,我觉得没有必要就没有加。 另外还用装饰函数实现了记录visitor的功能,还有用普通方法实现了文章hit计数,呵呵,这个更简单了。 P.S visitor记录了USER_EMAIL(if login), REMOTE_ADDR, HTTP_USER_AGENT, HTTP_REFERER, URL.
@log.counter
def get(self):


之前一直以为这是个不错的想法,直接从url就可以看出文章的年月河标题,可能是有利于搜索引擎或者是对用户友好?但是后来查询代码才发现在每次显示文章的时候,都会进行一次数据库关于permalink比较的查询:youdomain.com/2009/5/your-english-title
然后,我就想为啥不对文章id使用更加高效的get_by_id的方法产生,对于我立马重构了url,现在时通过post = db.Query(Post).filter('permalink =',perm_stem).get()
这样的url来访问实际的地址的。而查询blog的语句也变得更加的高效:youdomain.com/post/post_id
同时由于原来的permalink没用了,所以在博客创建的时候也省掉了复杂的把文章标题转化为英语的过程。之前转化的过程为:先对文章标题进行trim,然后调用tranlaite.google.com,再用BeautifulSoap得到结果页面中ID为result_box的div的内容,并且用‘-’代替其中的空格。整个过程非常的麻烦,还容易出错。我之前就一直想怎么解决这个问题,现在好了。问题根本就不存在了,哈哈。post_id_ = int(post_id)
post = Post.get_by_id(post_id_)
在这个博客网站网站的制作过程中,用户所见页我都使用了XHTML 1.0 Strict和CSS3标准验证。
其中css部分由Inove模板的作者完成,XHTML部分则有我自己写好。
写的过程中遇到很多问题,主要是原来没有写过XHTML代码,甚至连HTML都没怎么写过。所以很多尝试都不知道,哈哈。
下面介绍一些我这个新手在这段时间取得的心得:

然后在实现如下的js代码即可<a href="javascript:rteAction('bold')">B</a>
哈哈,超级简单啊,如果要实现斜体,只需要把bold换为italic即可。对于execCommand能够接受的参数,请参见这里,不同浏览器对于execCommand的兼容性请参见这里,对于超链接的实现超微复杂一点,但是也是超级简单。function rteAction(param) {
document.execCommand(param, false, null);
};
如上语句里面的fielname_or_handle,人家说是一个A file-like object or file name where the image/video will be read from。可惜我不太会python,所以不知道是个啥玩意。后来发现,这个东东可以使本地文件的绝对路径,哈哈。太nb了,至今我还不能获得用户选择的文件的绝对路径。。def InsertPhotoSimple(self, album_or_uri, title, summary, filename_or_handle,
content_type='image/jpeg', keywords=None)
import gdata.urlfetch*另外注意密码保护,由于本程序可以在google code上下载到,所以密码我保存到本机的bbpsw类中,然后定义一个方法getpassword得到密码,或许由更好的方法,但是我不想在每次上传图片的时候跳转到别的页面,所以还是采用这种方法了。 还遇到一个问题:就是图片上传完毕之后,服务器端不好触发客户端的javascript程序,所以我直接产生一个use it的超链接,触发javascript函数,把图片的地址做成img标签,然后加入到编辑页面中。如果不这么做,或许我需要ajax?我不想学那么多新东西啊。。。
gdata.service.http_request_handler = gdata.urlfetch
#override original http handler
...
filename = self.request.get('imgfile')
filetitle = self.request.get('imgtitle')
file_handle = StringIO.StringIO(filename)#convert string to file-like object
gd_client = gdata.photos.service.PhotosService()
gd_client.email = 'gzguoer@gmail.com'
gd_client.password = bbpsw.getpassword()
gd_client.source = 'blowblood-upload-image'
gd_client.ProgrammaticLogin()
album_url = '/data/feed/api/user/gzguoer/albumid/5334765855583692065'
try:
photo = gd_client.InsertPhotoSimple(album_url, 'blogimg',filetitle,
file_handle,content_type='image/jpeg')
template_values = {
'imgtitle':'title',
'img_url':photo.GetMediaURL(),
'response':'upload_complelted,<a href="javascript:getimgurl()">use it</a>',
}
path = os.path.join(os.path.dirname(__file__), '../templates/upload.html')
self.response.out.write(template.render(path, template_values))
except gdata.service.RequestError:
self.response.out.write(GooglePhotosException)
在google上找了半天,终于发现几个非常不错的XHTML的网页编辑器。
功能强大,稳定,而且历史悠久,兼容性等非常好,但是客户端非常大,而且免费的lite版本用起来限制很多。同时每次在新的机器上使用的时候,都需要安装一下程序。。。
非 常好用的编辑器,baidu空间使用的就是这个,支持多国语言,使用方便,去它的网站http://www.fckeditor.net/ 上看的时候发现Oracle和Adobe都是用了该编辑器,呵呵,看来用户还是很多的。但是许可协议比较猛:GPL,LGPL,MPL,三个 Copyleft协议都有,所以我退却了。
以LGPL发布,功能非常的强大。网址为:http://tinymce.moxiecode.com/ 而且还可以搭配文件管理和图片管理插件,估计是用起来非常爽。
支持xhtml输出,支持code/edit/preview三种模式之间切换,支持插入图片,支持各种浏览器,估计我将使用这个nb的XHTML的编辑器作为我这个系统的输入工具。。不过发现一个小问题
我记得原来订阅的RSS,怎么现在都交ATOM了呢?到网上查了一下,才发现ATOM是RSS的升级版。。。比RSS简单,而且可以同时支持摘要和全文,虽然我只想要全文。
要支持ATOM的Feed也很简单,首先在首页的head里面加上如下的语句,这样可以让Firefox等浏览器检测到该页含有Feed链接,从而在地址栏或者其他的地方出现一个Feed标志的小图标:
<link rel="alternate" type="application/atom+xml" title="BlowBlood" href="http://www.blowblood.com/atom">
然后制作/atom页面即可。首先在main.py里面添加url的控制语句,使得/atom页面被blog类的相应方法:FeedHandler所控制,然后在FeedHandler方法中构建atom页面需要的内容,主要是每个post的内容,和该次更新的时间,时间可以取最新一篇post的时间(如果没有的话,则取当前时间),然后把这些数据输出到文件atom.xml中即可。atom.xml的内容如下:
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title><![CDATA[BlowBlood]]></title>
<id>http://www.blowblood.com-by-gzguoer</id>
<subtitle>BlowBlood@WestGate</subtitle>
<link href="http://www.blowblood.com" />
<link href="http://www.blowblood.com/atom" rel="self" />
<updated>{{last_updated}}</updated>
<author>
<name>blowblood</name>
</author>
{%for post in posts%}
<entry>
<link href="{{post.full_permalink}}"/>
<id>{{post.full_permalink}}</id>
<title><![CDATA[ {{post.title}} ]]></title>
<content type="html"><![CDATA[ {{post.content}} ]]></content>
<author>
<name>{{post.author}}</name>
</author>
<updated>{{post.formatted_date}}</updated>
</entry>
{%endfor%}
</feed>
然后就行了,哈哈,是不是非常简单呢?
不过有个很普遍的问题,msIE6出生的时候,还没有RSS这玩意,或者没有引起关注,总之IE6还不支持atom,应该有办法可以解决。。
恩,这个编辑器真的不太好用,非常郁闷,在Code和View之间切换的时候,<br />会变成<br>,而且光标所在也不对。。。难道逼我改进吗?或者我直接换一个nb的richtexteditor?
接下来的任务:
这周总的来说没有什么事情,所以抓紧时间把这个blog系统搞起来,之前采用cpedia做的那个各种不爽,索性自己从头来做一遍。
之前已经建立好了关于blog的文章的数据库,具体的model描述如下所示:
class Post(db.Model):
permalink = db.StringProperty()
title = db.StringProperty()
content = db.TextProperty()
date = db.DateTimeProperty(auto_now_add=True)
author = db.UserProperty()
catalog = db.StringProperty()
private = db.BooleanProperty()
hitcount = db.IntegerProperty(default=0)
commentcount = db.IntegerProperty(default=0)
lastModifiedDate = db.DateTimeProperty()
lastModifiedBy = db.UserProperty()
tags = db.ListProperty(db.Category)
monthyear = db.StringProperty(multiline=False)
由于没有评论的数据库,所以不能评论,今天完成的任务如下:
恩,干的不错,加油!马上就要写答辩ppt了,所以时间无多啊。。。
Recent Comments