Archive for the ‘WEB后端’ Category

最近负责的某项目,提供了文件下载功能。有用户反馈,下载的.lnk文件,后缀名变成了.download。

经查,只有chrome系列浏览器才有这个问题。

抓包看下请求,发现服务端在response的header里给出了正确的文件名,如:

Content-Disposition: attachment; filename="xxx.lnk"

那么,这个重命名肯定是浏览器的默认行为。实际上,lnk类型的文件是一个软链,运行后会执行什么完全取决于不同的系统环境,没办法预期,Chrome认为这比较危险,就在底层强制对其重命名了。所以,这不是web应用所能决定的。

到此,问题就解决了。总共花费1分钟,就把bug resolved掉,还不用改一行代码,happy呀~

本文链接:http://www.imququ.com/post/87.html

--EOF--

上次总结了Django博客系统的开发,这次接着总结程序部署的相关内容。这几天我折腾了个够,尝试各种组合来搭环境,从一开始的Apache + mod_wsgi,之后的Nginx + uWSGI,再后来的Lighttpd + FastCGI,最后采用的是Lighttpd + Apache + FastCGI。

最后还是加上了Apache,是因为我发现Lighttpd自带的mod_compress貌似只对静态文件有用,我的博客动态输出的页面怎么都不会被gzip。

Read the rest of this entry »

上周末新博客上线后,经过观察,还挺稳定,linode的VPS速度也挺快。这几天linode差不多玩熟了,就计划着把老站彻底迁移过来。我这博客荒废这么久没人来看,但迁移网站有一些基本流程还是打算给弄下,当是练习吧。

先迁移数据和文件,这个简单,旧数据用phpmyadmin导出,再导到新库;文件直接scp过来,保持之前的目录不变。先前的代码程序是php的,我给它们单独分了一个qgy18.imququ.com虚拟主机,这个不需要加python模块了。

Read the rest of this entry »

Pingback和Xml-RPC

In: WEB后端  

14 03 2011

WordPress有一个功能:当有人引用本站文章时,会添加一条评论在文后,显示引用页面的信息;发博客时WordPress也会通知文章内每个链接,让它知道自己被引用了。这个功能非常赞,让博客间的互动变得更容易。

改用自己的博客系统后,还想用这么高级的功能,只有靠自己了。搜索得知,这个功能叫Pingback,是基于XML-RPC的一个协议。Pingback功能需要实现一个xmlprc client,在文章更新时ping对方服务;以及一个xmlrpc server,来接受其它服务器发过来的ping。

先研究下XML-RPC协议,走http用xml来交换数据,跟SOAP很像,但比SOAP简单的多。Python里有现成的库可以方便的处理xmlrpc。

来尝试下写个xmlrpc客户端:

from xmlrpclib import ServerProxy
from pprint import pprint

s = ServerProxy('http://www.aoao.org.cn/xmlrpc.php')
pprint(s.system.listMethods())

这段代码运行完,输出了aoao同学提供的好多方法。那些metaWeblog、blogger、wt、wp开头的都是跟博客管理有关的,调用时需要传帐号密码,就先不玩了。试下addTwoNumbers和sayHello,看名字应该可以玩:

>>> s.demo.addTwoNumbers(1, 2)
3
>>> s.system.multicall([{'methodName':'demo.addTwoNumbers','params':[1,2]},{'met
hodName':'demo.sayHello','params':[]}])
[[3], ['Hello!']]

果然成功了。看起来跟本地函数一样的调用形式,xmlrpclib却在后台把输入参数拼装成xml,post给远端服务,再拿到返回的xml数据解析出返回值。也支持多个方法批量调用,真是太赞了~

回过头来看Pingback协议,更新文章时怎么通知他人就有思路了:

  • 先找出文章中所有链接,还要找出链接对应的xmlrpc(pingback) server;
  • 调用该server的pingback.ping方法,把本文链接和对方链接作为参数传过去;
  • 处理返回状态,记录下这次pingback的信息,这是为了避免更新文章时多次ping。

官方文章中提供了两种方案从一个链接找到对应的xmlrpc server:

  • 查找该链接response header里的X-Pingback字段;
  • 查找该链接页面里的<link rel="pingback" href="pingback server">标记。

Read the rest of this entry »

从最开始的ROR,到后来的CICakePHPThinkPHP等各式各样的MVC框架用了不少,还是觉得用来开发QuQuBlogDjango框架最吸引人,玩着玩着就上瘾了。

记录下开发过程中的一些点滴:

Python是之前装的2.6.5,Django用SVN里的1.3RC,IDE用eclipse+Pydev,数据库一开始用sqlite,后来改用到mysql。

开发过程中用Django自带的runserver来启动web服务,用django-debug-toolbar来分析和优化SQL查询语句。服务器上跑的是Apache2+mod_wsgi,之后可能会换成lighttpd+fastcgi。

博客用户系统用的框架自带的django.contrib.auth,Tag系统用的django-tagging,评论系统用的自带的django.contrib.comments。

后台发布博客用的TinyMCE这个优秀的web编辑器,参考了这篇文章给编辑器加上了插入<pre>代码标签功能,前台用SyntaxHighlighter在浏览器端高亮代码,使用AutoLoader动态引入代码高亮文件。

另外还使用django.core.paginator,结合django模板的自定义标签扩展了一个通用的分页组件。

通过django.contrib.syndication.views和django.utils.feedgenerator对博客输出rss和atom订阅,下面是全部代码:

# -*- coding:utf8 -*-
'''
Created on 2011-3-8

@author: Jerry
'''
from django.contrib.syndication.views import Feed
from django.utils.feedgenerator import Atom1Feed
from django.contrib.sites.models import get_current_site

from blogs.models import Post

class PostRssFeed(Feed):
    title = u'Jerry Qu \'s 小站'
    link = 'http://' + get_current_site(None).domain
    description = u'Welcome to Jerry Qu \'s 小站'
    author = 'Jerry Qu'

    def items(self):
        return Post.objects.get_post().order_by('-pub_date')[:10]
    
    def item_title(self, item):
        return item.title

    def item_pubdate(self, item):
        return item.pub_date
    
    def item_description(self, item):
        return item.content

class PostAtomFeed(PostRssFeed):
    feed_type = Atom1Feed
    subtitle = PostRssFeed.description

展示评论时,参考了Gravatar官方文档获取用户头像,跟之前用的wordpress展示上是一样的。

从上面可以看出Django的开发效率是有多么高,基本你能想到的功能都能找到完整的解决方案。但只是使用现成库不见得是一件好事,好在python大部分库都是有源码的,可以通过阅读源码来了解别人的思路,学习别人代码上的优点。

接下来,我还会继续开发这个博客系统,Django和Python好玩的东西还有好多,近期会自己实现以下功能:

  • 媒体中心,主要是图片上传和管理功能;
  • 新的评论系统,使用Akismet Api过滤垃圾评论;以及邮件通知新评论机制;
  • MetaWeblog Api,可以通过Windows Live Writer客户端发表博客。

本文链接:http://www.imququ.com/post/63.html

--EOF--

WebIM

In: WEB后端  

12 03 2011

此项目的开发将无限期终止~原因大家可能也清楚,自己辛辛苦苦原创的东西被人盗用卖钱,心情可想而知。本周抽了点时间修复了遗留的一些bug之后,最终做出了这个决定,这个WebIM的版本将会定格在beta1.5。另外,之前还有不少朋友对它有兴趣,前些时开了一个交流群,不过由于自己忙很少有时间上去 跟大家交流,那个群没有发挥应有的作用被我关了。这里向各位说声抱歉了~

不明真相,或者分不清到底谁是抄袭者的人请移步这里那里,看看08年我在51JS的帖子应该就明白了。至于有些人说什么“这个怎么可能是国人写的,一看就是抄袭”,我只能无语。

一个仿MSN的WEB即时通讯软件,会继续开发下去。它采用xml传输数据,支持多种后台语言,最新版为beta1.3。

  • PHP最终版(beta1.5)的测试地址在这里。>>
  • ASP+ACCESS版本现已开放全部源代码。>>
  • PHP+MYSQL版本同样提供全部源代码下载!>>

update @ 2010.03.05

没错,你看到的“Jerry Qu的小站”确实是我的全新个人博客!有两方面的全新:

首先是程序上的:

  • 现在这个blog程序是我花了大半个星期使用python下的Django框架开发的;
  • 数据库是自己设计,比较简洁,跟wordpress不兼容,迁移数据需要成本;
  • godaddy买了域名ququ4.us,思索再三还是换com的:imququ.com;
  • linode上买了VPS,装的ubuntu,体验了一把自助搭建web服务的全过程;
  • 皮肤直接移植自原wordpress的Compositio Theme,以后有时间再换~

其次会体现在内容上:

  • 之前的博客都长草了那么久,打算借这个更换blog程序的机会重新更新内容;
  • 之前的内容整理后会转移一些过来,但不会太多;
  • 新的内容可能不只包括前端或者技术,但肯定还跟互联网有关~

这次更换博客的想法完全是一时兴起,但执行得超有效率:

  • 过去的大半周天天熬夜来学习Python,熟悉Django框架,编写blog程序;
  • 昨天又花了一晚上,在虚拟机里掌握了linux下Django框架部署的几种方案;
  • 今天花了大半天时间,又搞定了域名和VPS,以及博客程序的部署上线~

更新:下午新博客系统上线后,就开始了数据迁移的工作。到目前为止,旧的博客、图片和一些碎文件都已经迁移完毕,Tag也一并迁移了。评论没有弄,之后可能会升级为Threaded Comment,还要改数据结构,就先不折腾历史数据了@03-13

本文链接:http://www.imququ.com/post/1.html

--EOF--

关于我

JerryQu,当前从事前端开发,@中国北京
这里是我随便记录东西的地方~
需要找我,我的联系方式在这里»
查找QGYWebIM相关信息,请点这里»

  • PPanda sftp如何同步本地文件夹呢?
  • dron 嗯!太有用了,终于完美找回 EditPlus 的感觉了。
  • 袁源 还真的是这样。其实挺佩服微软的呀~就是都太不完善了
  • 三水清 类似功能可以使用fiddler,http://ming.sinaapp.com/?p=218
  • 呆呆 非常感谢~话说我现在想把weinre变成一个服务器,就是我在电脑上修改了,手机上访问可以直接,不知道[...]
  • 困扰了我好几天的问题,不过最后还是让我解决了,要早让我看见这个文章该多好啊,那我也不用烦恼那么久了~[...]
  • hoowolf 非常感谢你的工作!!!
  • welefen 恩,去年我们在新首页导航精准下线的时候也遇到过,当时还做了对用户影响的数据评估和分析。
  • 唠叨下 我们这边测试的时候是在刚做完 preload 后的系统上测试的,就跟刚装完操作系统后一样干净。怎么说[...]
  • gust 我是在ubuntu11.10环境下
  • gust 想用google浏览器的话可以这样 webbrowser.get('/usr/bin/google[...]
  • jin 怎么zenCoding的缩写设置呢,类似editplus下的acp配置
  • Jerry Qu @Feather,确实Shadow是基于Weinre封装的。在我这里也很慢,因为它连的是http:/[...]
  • Feather 谢谢分享,其实Adobe的Shadow产品貌似也是用这个原理来做的,不过shadow封装好,比较方便[...]
  • i am bug 感谢屈屈!