吉米·威尔士关于维基百科诞生的演讲
再一次被开源的力量所震撼
我觉得, 我应该也去搞一个NB的开源项目
因为发现很多初学者用python写网站没经验, 写出来的网站比较卡, 让我很痛心
于是这一次, 我又开始了一个坑
打算基于Python的Tornado, 打造一套可以抗千万PV的SNS/微博/轻博客的开源基础框架
让以后Python程序员写SNS, 省去很重复开发的工作 - 比如登录, 比如头像, 比如相册, 比如日记, 比如等等等...
现在项目从零开始, 欢迎参与, 前端, 美工, 程序员, 都可以
项目的 google group , 欢迎加入
https://groups.google.com/group/kanrss_pyer
希望大家来不断督促我, 每天都填一点儿坑
===================================
更多项目详情见这里
使用hg update -r可以变更到指定版本, 方便参看实现
1. hg update -r4; #最基本的hello word
ctrl/index.py 写法如下
import tornado.web
from _urlmap import urlmap
@urlmap("/")
class IndexHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello, world")
2.
hg update -r9; #完成开发服务器, 并实现开发服务器的自动重启
当修改 ctrl/index.py 时候, 开发服务器会自动重启
配置mako模板, 并完成错误提示
render('模板名称', **参数)
dev服务器的错误可以点+号在网页上直接调试, 非常方便
刚刚完成输入@ 出现在@字符旁边出现的div
http://42qu.com/misc/test/at_autocomplete/index.htm
以前一直不知道怎么在textarea中拿到当前光标的坐标
今天研究了一遍豆瓣说的js源代码 http://www.douban.com/note/148320974/
发现原来是用了一个隐藏的pre同步内容 做的定位模拟
太hack了
On 4月30日, 下午9时55分, 张沈鹏 <zsp...@gmail.com> wrote:
> 因为项目可以肯定有@xxx的功能
> 就先写了一下js
>
> 刚刚完成输入@ 出现在@字符旁边出现的divhttp://42qu.com/misc/test/at_autocomplete/index.htm
>
> 以前一直不知道怎么在textarea中拿到当前光标的坐标
>
> 今天研究了一遍豆瓣说的js源代码http://www.douban.com/note/148320974/
>
> 发现原来是用了一个隐藏的pre同步内容 做的定位模拟
> 太hack了
先大概规划一下一期的要做的事情, 明天来出具体的表方案
然后开始先做后台, 然后写页面
一期工程 如下
------------------------------------------------------------------------
先来一个
技术备忘 : 学习quora, 时间一律用int类型(找不到出处了, 但是记得是这样的)
//方便marshal+memcache
------------------------------------------------------------------------
一期工程概要
用户可以登录, 可以写个人资料, 可以写日记, 可以看和编辑日记
------------------------------------------------------------------------
用户注册系统:
页面层面:
1. 顶部开始使用
页面顶部
邮箱 [ ] 密码 [ ] 开始使用
-----------------------------------
2. 单独的注册页面
邮箱 [ ]
错误提示
密码 [ ]
错误提示, 找回密码
开始使用
3. 登录后的顶部激活邮箱提醒
[ 你还没有激活邮箱!!! 点此重发激活邮件 ]
程序层面:
0. 用户系统
1. 找回密码的邮件
2. 激活邮件
...
有一个ID表,只有一个id字段
用来保证 用户 可以有一个和他自己UserId一样的 PageId
------------------------------------------------------------------------
用户个人资料系统/Page系统
页面层面:
1. 填写个人资料页面
头像
名称
自我介绍
绑定域名(可以绑定多个域名)
比如
zuroc.xxx.com
www.zuroc.com
2. 上传头像页面
上传新头像
截取小头像
程序层面:
或者叫做Page系统, 从底层数据上说每个用户本身也是一个Page
但是, 还是有一个用户个人资料设置的页面
------------------------------------------------------------------------
录入日记的系统:
标题[ ]
文本[ ]
[删除] [保存]
程序层面:
仿"轻博客"的概念, 日记有类型, 一开始
note
id cid man_id
不同类型的日记对于不同的表, 默认是纯文本类型
为了可以保持版本, 采用下面的设计
note_default
id
title
rid
state
update_time
把大字段的文本单独建表
note_default_txt
id
txt
日记默认绑定当前用户的Page
note_page
id
page
state
将来可以选择多个Page
------------------------------------------------------------------------
Page的页面:
这个Page的所有日记标题
------------------------------------------------------------------------
日记的展示页面
标题
文本
编辑
------------------------------------------------------------------------
用户个人主页:
简单的各个页面的导航
zpage的id表:
CREATE TABLE `zpage`.`zpage` (
`id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL,
`cid` SMALLINT UNSIGNED NOT NULL DEFAULT 1,
`state` TINYINT UNSIGNED NOT NULL,
PRIMARY KEY (`id`)
)
ENGINE = MyISAM;
当cid为1 , 表示为user
state有
账号被停用
注册, 但是未验证邮箱
注册, 已经验证邮箱, 但是未验证身份
已经验证身份
用户密码表
CREATE TABLE `zpage`.`user_password` (
`id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
`password` BINARY(64) NOT NULL,
PRIMARY KEY (`id`)
)
ENGINE = InnoDB;
注:
用id做salt
len(sha512("1").digest())
Out[11]: 64
用户邮箱表
CREATE TABLE `zpage`.`user_mail` (
`id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` INTEGER UNSIGNED NOT NULL,
`mail` VARCHAR(255) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX `Index_2`(`user_id`, `mail`)
)
ENGINE = MyISAM
CHARACTER SET utf8 COLLATE utf8_bin;
用户任务表(用途, 提醒激活邮箱, 设置用户名, 用户有新私信,等等)
CREATE TABLE `zpage`.`user_task` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(10) unsigned NOT NULL,
`cid` int(10) unsigned NOT NULL,
`rid` int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `Index_2` (`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
用户session表, 用来效验用户的登录状态
CREATE TABLE `zpage`.`user_session` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`value` binary(12) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=binary;
邮件效验表
CREATE TABLE `zpage`.`user_verify` (
`id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` INTEGER UNSIGNED NOT NULL,
`value` BINARY(16) NOT NULL,
`create_time` INTEGER UNSIGNED NOT NULL,
`cid` INTEGER UNSIGNED NOT NULL,
PRIMARY KEY (`id`),
INDEX `Index_2`(`user_id`),
INDEX `Index_3`(`create_time`, `cid`)
)
ENGINE = MyISAM;
注:
value = uuid.bytes
用户登录时间表(方便日后的数据分析)
CREATE TABLE `zpage`.`user_login_time` (
`id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` INTEGER UNSIGNED NOT NULL,
`create_time` INTEGER UNSIGNED NOT NULL,
PRIMARY KEY (`id`)
)
ENGINE = InnoDB;
用户创建时间表(方便日后的数据分析)
CREATE TABLE `zpage`.`user_create_time` (
`id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
`create_time` INTEGER UNSIGNED NOT NULL,
PRIMARY KEY (`id`)
)
ENGINE = InnoDB;
@辰光 我给header加了一个背景, 你看如何?
@辰光
chorme下面自动补全(输入, 关闭页面再开)有问题, 有空你可以先修一下, 没空我来修
你在dropbox中修好即可
bug见图
http://zpage.001er.com/bug/chorme.png
我觉得大致思路是这样
$(function(){
setTimeout(function(){
//判断是不是有内容
},0)
}
function title_value_tip(oo){
oo = $(oo)
var o = oo[0];
if(!o)return;
if(!o.value||o.value=='')o.value = o.title;
var t = function (){
if(!o.value || o.value=='' || o.value == o.title){
$(o).css("color","#ccc");
o.value = o.title;
}
}
$(o).focus(function(){
var v=o.value;
oo.css("color",'');
if(v == o.title)o.value = "";
});
$(o).blur(t);
t()
}
-----------------------------------------------
备注:
移植静态文件到框架成为动态的模板, 并配置nginx (nginx配置参见
https://bitbucket.org/zuroc/zpage/wiki/1day )
技术亮点:
1. js和css的自动压缩
压缩前
http://s.42qu.info/js/z.js
压缩后
http://s.42qu.info/js/~63JAQ~z.js
2. html的空白压缩(见页面源代码)
-----------------------------------------------
@all
谁有兴趣可以帮忙来补充文档
-----------------------------------------------
@辰光
bug:
ie下有bug, 见dropbox内截图
Logo可以短一点, 或者就叫项目的名字 zpage ?
这样EMAIL和Password的输入框可以长一点儿
现在EMAIL输入框太短了
另外"开始使用"的文字貌似有些下沉
因为我对css做了一些小调整,
建议你用firefox插件scrapbook抓取一个新的html
然后定义一个覆盖的样式就可以, 到时候我就可以直接覆盖现有的css
查找抓取文件的步骤是
scrapbook -> 在侧栏显示 -> 抓取的文件 -> 右键 -> 工具 -> 查看文件
弄好放在dropbox中就可以了
此外代码是上的小建议
0.
css没有必要写在一行, 我可以自动压缩的
随便缩进
1.
0pt 干脆直接写 0
2.
background:url('/img/bkg_header.gif')
->
background:url(/img/bkg_header.gif)
3.
既然id应该是唯一的
那么就没有必要写
#header #nav
而直接写
#nav
就可以了
4.
$(".register .input-wrapper").focusin(function() {
$(this).removeClass("blurred");
$(this).removeClass("filled");
$(this).addClass("focused");
});
->
var self=$(this), value=self.find("input").val();
if(!value||value=="")
{
self.removeClass("focused")
.removeClass("filled")
.addClass("blurred");
}else{
self.removeClass("focused")
.addClass("filled");
}
这里jquery可以连着.... , 不需要多次$(this)
其次如果有多个
$(this).xxx
可以
用 var self=$(this);
self.xxx
替代
首先$(this) 有函数调用开销, 多次调用不是一个好习惯
其次这样压缩后, self会被压缩成为b. , 会比多次用$(this).更加省字节
var b=$(this),c=b.find("input").val();if(!c||c==""){b.removeClass("focused").removeClass("filled").addClass("blurred")}
logo可以考虑gif
png在ie6下透明度有问题
有时间的再设计一个这个页面吧
当用户输入密码错误/邮箱格式不对的时候会跳到这个页面
提示他邮箱格式不对
或者
提示他密码错误, 并提示他找回密码
参考示意图
1.
http://i.imgur.com/rFfsU.png
2.
http://i.imgur.com/mFZB6.png
不着急
我先继续写用户系统
完成用户的登录(含注册)与退出
完成留言板(并提供悄悄话功能)
http://2.42qu.info/
完成留言板(并提供悄悄话功能)
--
来自: python-cn`CPyUG`华蟒用户组(中文Python技术邮件列表)
发言: pyth...@googlegroups.com
退订: python-cn+...@googlegroups.com (向此发空信即退!)
详情: http://code.google.com/p/cpyug/wiki/PythonCn
严正: 理解列表! 智慧提问! http://wiki.woodpecker.org.cn/moin/AskForHelp
强烈: 建议使用技巧: 如何有效地报告Bug
http://www.chiark.greenend.org.uk/%7Esgtatham/bugs-cn.html
为了方便围观 , 给一个文件的地址
https://bitbucket.org/zuroc/zpage/src/10d5e2e95ab9/model/feed.py
恩 就是这个文件
--
有Python的技术问题, 欢迎到42区咨询我
配置文件也很nb的实现了根据不同用户不同机器加载不同的配置
对于在上线代码与同一台服务器上进行团队开发方便
感谢张近东( http://42qu.com/zjd ) 同学的代码
当然我也用到了消息队列啊
这个就是beanstalk与python整合的代码
发邮件
https://bitbucket.org/zuroc/zpage/src/801f22f905b8/model/mail.py
这里就用到了( mq_client )
当然feed里面也用了的
根目录下的mq_server.py是启动消息队列的服务
唉 写代码好寂寞的啊啊啊啊啊啊啊啊啊啊 .........
还有
https://bitbucket.org/zuroc/zpage/src/10d5e2e95ab9/model/feed.py
里面有一个
#TODO : 消息流的合并, feed_entry_id_iter 函数可以考虑用天涯的内存数据库来优化
#http://code.google.com/p/memlink/
恩 feed_entry 表等以后大了可以用这个
feed_entry设计的也很简单 就是 feed_id -> id list
不过现在先不管了, 就一台机器, 不需要搞得太复杂
On 5月23日, 下午12时01分, 张沈鹏 <zsp...@gmail.com> wrote:
> 在 2011年5月23日 上午9:08,马一哥 <ppmsn2...@gmail.com> 写道:
>
> > 你为什么认为你的SNS 可以抗千万PV?
>
> 感觉
是可以这样
不过那个一般是上亿日pv才需要做的事情
千万还是比较小的care
不需要这么麻烦
2011/5/24 张沈鹏 <zsp...@gmail.com>:
--
A decathlon Developer & programmer
http://blog.eood.cn/
千万的
mysql
memcache
beanstalk
加上一些crontab就可以了
就可以了
上亿的没有经历过,所以不敢发言, 那个只是猜想 -- 因为看到facebook用thirft
主站服务的
api服务的
后台管理员管理的
恩
不过这样只是为了代码上的逻辑清晰和物理隔离
沈鹏,这真是个大坑呀,不过“抗千万PV”不应该是框架的功能吧。
代码上的框架,最多只能规定应用在代码层次的架构、一些实用方便可复用的类库(像你说的省去很多重复工作),
但解决不了“网站比较卡”的问题。比如分布式、高可用等等这些都需要用很多第三方工具才行,除非你的千万pv的站点就架在一台机器上,
但现在又没有那么NB的机器呵呵。
前两天看了
http://42qu.com/video/play/1
吉米·威尔士关于维基百科诞生的演讲
再一次被开源的力量所震撼
我觉得, 我应该也去搞一个NB的开源项目
因为发现很多初学者用python写网站没经验, 写出来的网站比较卡, 让我很痛心
于是这一次, 我又开始了一个坑
打算基于Python的Tornado, 打造一套可以抗千万PV的SNS/微博/轻博客的开源基础框架
让以后Python程序员写SNS, 省去很重复开发的工作 - 比如登录, 比如头像, 比如相册, 比如日记, 比如等等等...
现在项目从零开始, 欢迎参与, 前端, 美工, 程序员, 都可以
项目的 google group , 欢迎加入
https://groups.google.com/group/kanrss_pyer
希望大家来不断督促我, 每天都填一点儿坑
===================================
更多项目详情见这里
https://bitbucket.org/zuroc/zpage/wiki/Home
--
---------------------------------------------------------------------
您收到此信息是由于您订阅42qu论坛。
发帖,请发邮件到 42...@googlegroups.com
退订,请发邮件到 42qu+uns...@googlegroups.com
设置,请通过 http://goo.gl/jKcEX 访问该论坛
关于hmako 见
42qu.com原来是基于mypy
去年重写了 , 基于tornado了
不过很多东西还是复用的
比如profile和orm
最近对技术没有追求 , 精力放到产品上去了
因为我发现技术很难构成瓶颈
最近喜欢上的redis
发现是神器
要是我重新来写
会把很多mysql的东西转移到redis上
这样orm也就不重要了
用了redis
memcahe也可以少用了
orm只是很轻量级的方便操作
不做太多magic的神奇
在 2012年3月11日 下午4:18,刘鑫 <marc...@gmail.com> 写道:
> 现在的问题不是控制权,是mypy的数据库访问组件频繁造成死锁,这也太不靠谱了,数据库访问工具的主要目的是减少重复劳动,保证安全性,用sqlalchemy可以让开发人员自由的选择封装层的厚度,从connection层到带连接池和反射的engine层再到带线程安全的session层再到sql
> expression,再往上才是orm,任选自己需要的程度就可以了。不能说稳定性做不出来就推给程序员说这是程序员的控制权。
> dbapi层面直接访问也行啊,会写sql是起码的节操问题吧。对于一个长期运维的项目我认为到这一步,形成自己的数据库访问架构是迟早的事。
>
> 在 2012年3月11日 下午1:17,张沈鹏 <zsp...@gmail.com>写道:
>>
>> 我还是喜欢把控制权交给程序员
>>
>> orm只是很轻量级的方便操作
>>
>> 不做太多magic的神奇
>>
>> --
>> 来自: python-cn`CPyUG`华蟒用户组(中文Python技术邮件列表)
>> 规则: http://code.google.com/p/cpyug/wiki/PythonCn
>> 发言: pyth...@googlegroups.com
>> 退订: python-cn+...@googlegroups.com (向此发空信即退!)
>> 详情: http://code.google.com/p/cpyug/wiki/PythonCn
>> 严正: 理解列表! 智慧提问! http://wiki.woodpecker.org.cn/moin/AskForHelp
>> 强烈: 建议使用技巧: 如何有效地报告Bug
>> http://www.chiark.greenend.org.uk/%7Esgtatham/bugs-cn.html
>
>
>
>
> --
> 玄德忠而似伪,以泪博人心尔。孔明智而近妖,信与不信孰知?
> 智拙实验室: http://zerolabrary.appspot.com/
> ......
>
> 劉鑫
> March.Liu
>
> --
> ---------------------------------------------------------------------
> 您收到此信息是由于您订阅42qu论坛。
> 发帖,请发邮件到 42...@googlegroups.com
> 退订,请发邮件到 42qu+uns...@googlegroups.com
> 设置,请通过 http://goo.gl/jKcEX 访问该论坛
--
关于我 : http://zuroc.42qu.com
https://github.com/luckythetourist/autumn
sqlbean是在这个的代码基础上整合memcache和profile和sqlstore而成
Autumn exists as a super-lightweight Object-relational mapper (ORM)
for Python. It's an alternative to SQLObject, SQLAlchemy, Storm, etc.
Perhaps the biggest difference is the automatic population of fields
as attributes
它本身就是一个super-lightweight的东西 :)
--
关于我 : http://zuroc.42qu.com