toozoofoo

域名:note.lianpeng.me

莲蓬网几个月前开始对用户收藏的网页进行截屏,并展示在链接左侧,在底层用得工具是wkhtmltoimage,原理其实就是模拟浏览器行为,渲染出网页后进行截屏。但是现在发现这个工具对于某些网站,截图之后的图片是一片空白,这个实在令人难以忍受。在一番研究之后才了解到,这样的网页一般是有图片的,而这些图片展示有两种情况:使用了一种叫做parallax的技术(例如这个:http://llidesign.co.uk/iconic-furniture/)图片使用了异步加载的方式这两种情况都是需要人用鼠标往下滚动页面时出发了一些js脚本,产生图片显示,我查下了wkhtmltoimag的各种参数,貌似都不支持。而我知道现在的一种叫做headless webkit的实现,它也是一种浏览器,只不过没有界面,暴露一些浏览器的api给开发使用。当然,它的出现得益于nodejs的诞生。这样的js库有很多,这里只列出一个PhantomJS,它的api里就有截屏的接口,网站中甚至提供了一个简单的例子:var page = require('webpage').create(); page.open('http://github.com/', function() { page.render('github.png'); phantom.exit(); });在python里调用PhantomJS的这个api,只需要写个js,然后通过Popen运行。但是问题在于由于网页的下载和渲染,包括截屏都是异步的,python程序里调用后,并没有等待截屏结束。在google之后,得到的解决,借助selenium:driver = webdriver.PhantomJS() # or add to your PATH driver.set_window_size(1024, 796) # optional driver.set_page_load_timeout(20) driver.get(url) driver.save_screenshot(target) # save a screenshot to disk driver.quit() 具体selenium在内部如何实现同步的,有兴趣可以看下源码。

莲蓬一直用第三方网站的favicon服务来显示收藏链接的网站图标(像这样: apiary.io):google:https://s2.googleusercontent.com/s2/favicons?alt=site&domain=lianpeng.meduckduckgo:https://icons.duckduckgo.com/ip2/lianpeng.me.ico开源的实现(GAE上部署的):http://g.etfv.co/http://lianpeng.me?defaulticon=lightpng但是这些无一例外的被Q了,所以现在莲蓬实现了获取网站图标的功能,存储在自己的服务器上。如果你有兴趣,可以直接使用:http://lianpeng.me/service/favicon/?url=http://apiary.io/。

在安德门地铁站附近的路边经常会看到地上铺满很多旧衣服,基本的类型都是那种耐穿,深色的衣服,还有一些皮鞋、户外鞋,一个老人坐在电动车上看着行人,不时的还下来回答路过行人的询价。我想起来在之前我老婆的姑父跟我说过这样的一种生意,他们从各个地方以低价回收旧衣服,但是对收购的衣服是有选择的,必须是名牌,耐克,阿迪,质量必须好,没有破损,这样才能拿到路边高价出售,其实也不算高价,比原价便宜的多了,但是这个低买高卖的价格差是很大的。但我想现在这个年代哪还有人穿二手的旧衣服呢,即便是衣服是名牌,也毫发无损,若是穿起来也会觉得有失体面,大家宁愿去商场买件新的,毕竟大家的生活水平已经比以前提高了很多。可究竟什么人愿意买?没错,是农村人。我在农村的确见到过有年纪大的父母穿着子女的衣服,比如我爸妈,呵呵,他们都节俭惯了,衣服一般不轻易丢掉,我妈就会穿我不再穿的高中时代的西式校服去采茶。尽管如此,安德门毕竟属于市区,哪里来的农村人?可能大家也想到了——农民工,他们对衣服的要求不是很高,但是也不能在雇主面前穿的破破烂烂,耐穿是首要的,因为农民工做的工作都是体力活,在烟尘来回搬运,在水泥墙砖中穿梭,长期在艰苦的环境下劳动,像我们这样坐在计算机前养尊处优的人穿的衣服是很经不起折腾的,牛仔裤除外。农民工基本不会在城市里消费,他们都是挣了钱,带回家消费,可是在长期在城市,基本的衣食住行花费还是有的,但价格绝对要低廉,否则挣的钱不够这些开销,比如吃,可以选择像沙县这样的小吃店,量足也不贵,还可以任意添饭,住的地方可能就是在工地上,行的话,公共交通已经很便宜了,至于穿,就是去摆地摊的那儿买,但是通常地摊上的衣服都不怎么耐穿,虽然廉价但是质量不咋地。这就给我们前面说的这个生意带来机会,但是放在以前不一定有市场,因为相对来说有品牌的二手衣服还是有点贵,但是这几年人口红利已经开始消退,老年化现象严重,农民工变得稀有,随之农民工的身价却开始提升,工资开始变高了,可以说他们的工资并不比我们这些搞IT的工资低多少。这就使得他们可以更多可支配的收入,虽然还保持着节俭的习惯,但是貌似对于面子、形象工程的衣服,他们可以在价格上稍微妥协下,特别是那些包工头们。为何是安德门?安德门是交通枢纽,是两条地铁的交汇处,附近有汽车站和公交车总站,连接市区和偌大的江宁,这里的人流量很大,工程建设也不少,民工都在这聚集,拿着工具蹲在路边,等待雇主的来到,晚间还经常可以看到在地铁站里,一群农民工聚在一个角落打扑克,欢乐不停,甚至于有人直接将安德门地铁站当做安身的家了,直接睡在地铁站里或者地铁附近,这里俨然是民工的集散点。显然在这个地方卖衣服最合适不过了。学到了什么?我们在象牙塔里学到的知识通常在街头是用不到的,在街头需要街头智慧来解决问题,观察身边的每个现象和问题,虽然解决方案可能一样,但是在不同的时机会有不同的结果,就像如果在30年前如果卖给中国人牛奶跟现在比,就完全不同,所以除了观察还需要考虑时机,最后,我想说只要有决心遍地都是机会,留心身边,把握机遇。后记一个同事说以前也做过类似的事情,他将学校里军训的迷彩服低价收购,然后卖给农民工的事情,农民工对这类的衣服喜大普奔。军训的迷彩服应该算是比较耐穿的,虽然穿起来不怎么舒服,但是价格绝对便宜,因为现在的学生军训结束后,绝对不会再留恋它的,抱着直接扔掉的想法后如果有人愿意出一些的钱来买它,他们是乐意的,考虑到农民工的消费能力,回收这些衣服的人,基本上就是很低的成本,也就意味着他们不用出很高的价格,就可以有很高的利润率。

在年少无知的以前,读了圣贤书之后,自身却染上了一些坏毛病,比如脸皮薄,看不惯别人听流行音乐,以为自己文艺了,在技术上被一些Unix哲学之类的思想渗透,有股洁癖骚劲,以前还写下了一篇关于重复造轮子的檄文,现在再读,觉得自己好傻好天真,当然不是说文章里的观点全是错的,而是过于片面和绝对。你可以说现在的我变的圆滑,就好像丢了某种信仰之后的世俗,如果说接触社会的经历让人看到更多,我觉得也未尝不可继续圆滑下去。 就拿重复造轮子来说,现在的我并不那么排斥了,轮子在某一方面来看有它的好处,在中国“墙”和政策的保护下,我们的互联网繁荣了,许多从国外复制模式过来的所谓“山寨网站”也活的很好,而且开始有了他们自己的创新,并且最终赢得了用户认可,人们不再介意山寨不山寨的问题,而是好用不好用的问题,有很多这样的网站微博(Twitter)、美团(Groupon)、SegmentFault(Stackoverflow)、花瓣(Pinterest)等等。在商业里重复造轮子应该说是再正常不过的事情了,你不能说你开了一家餐馆,我就不能在你旁边开另一家餐馆,再看下苹果的iPod,它不是第一个mp3,当然也不是最后的一个,Google不会因为市场上已经有了搜索引擎,就不再研发,虽然不是所有的轮子都有希望比旧的轮子更佳,但如果我们希望新造的轮子会比老的更好,就不应该阻止轮子的重新发明,否则就等于葬送了进步,我们不再有相互竞争的产品,不再有便宜的沃尔玛,不再有创新和好的生活。牛皮是不是吹大了?虽然轮子的含义被我放大了,或许我们一般意义的造轮子仅仅是针对技术上的,但即便如此,轮子也仍然是有他的用处,任何技术上的创新都是从模仿开始的,而且模仿过程也是一个绝佳的学习过程,即便轮子造出来没有人用,社会价值不大,自己也从中得到如何造一个轮子的经验,个人的自信也会由此而产生。我经常看到在Github上看到很多的人代码库里有着一些模仿的项目,例如之前流行的瀑布流形式jquery布局插件,或者是模仿Medium.com的可视化编辑器,光是Markdown编辑器我就见过不少,但是仍然有这么多的人重复性的造轮子,如果是以前,我会想,做同样的事情有一个工具就好了,干嘛还要有其他各种形形色色但功能是一样的东西呢,但是我自己却走上了重复造轮子的道路,莲蓬网自身就是一个轮子,但我并非是像素级别的抄袭(好欣慰),而且我在开发莲蓬网的过程中,学了知识,得了经验,还认识了一些人,或多或少锻炼了我的运营能力,虽然有限,而且我在此基础上,加上满足特殊需求的功能,那么这样的轮子就是有价值的。PS: 虽然我说的造轮子正面意义足够充分,但绝不应当成为恶意抄袭和毫无版权意识的理由,请特别注意。

我的博客几经周转,从最早自己搭建的Wordpress到百度Hi,然后是点点,现在我将所有文件导入到莲蓬笔记里了,虽然不是最好的写博方式,但是自己的狗粮自己吃罢,而且不用担心访问不了或者无法迁移的问题,用着放心。

收藏的列表页面现在除了网页小图之外,全是文字,显得有些单调,现在大家在每次收藏网页后,莲蓬会在后台获取收藏网页的截图,并在列表页面展示,一方面使得页面更加丰富,另一方面我们根据图片可以迅速识别和找到想要找的链接,不需要完全靠网页标题来识别。对于大家以前收藏的网页,没有全部去获取截图,如果有需要可以选择保存某个链接,这样莲蓬就会自动去获取截图。

在这么长的时间里一直忽略了和和大家的沟通,现在希望通过QQ群(251623482)建立和大家的交流的渠道,我知道在莲蓬的用户中很多是做程序开发和设计的“蓬友”,大家可以在这里互相结识,发表自己的见闻和想法。 

这几年微博洗礼了互联网市场,在催生了相关产业链的同时,摧枯拉朽了不少个人博客,却也因此沉淀出了许多坚持原创的独立博客,给我们提供着新鲜的干货:独特的思考方式、创造性的想法、难得的经验,我们从中学习和吸取他们的成功与失败,借着他们的经验解决自己的问题,创造自己的作品,我们以自己的方式表达感谢:一条称赞的评论,一封感谢的邮件,一个鼓励的反馈... 作为博客作者,他们是很乐意看到这些的,但我想,在网络中坚持不懈的写出一篇篇文章,分享着自己的经历、经验、知识、思考、创造,他最希望的是能让更多的人看到自己的文章,帮助更多的人解决他们自己的问题,因为这就是分享的意义。                                        我和大家一样,都从其他的人博客中学到很多,特别是作为一个技术开发人员,更能深深感觉到这些博客的价值,遗憾的是我几乎没有在他们的博客中留下任何评论和反馈,我只是默默的将文章收藏起来,加以标签。过去用的是美味书签、Kippt,而现在我用自己开发的书签网站,不管怎样,我希望有更多的人看到我所收藏的文章和博客网站,也像作者那样,希望对看到的人有所帮助。所以,最近我一直在构思着开发一个收录各个原创独立博客的网站,名字我都想好了,就是文章的的标题:博客英雄谱。这是一个分类目录网站,相对于搜索引擎,我没有试图去爬取网络上的所有网站,而是更加专注于博客网站这个垂直的网站类型,然后分门别类的组织这些博客,贴上标签,大家可以按照自己的兴趣,找到高质量的原创博客,关注或订阅他们的文章,甚而至于结识博主本人。最初可能只是博客的收录,大家也可以提交自己或别人的博客,后面可以加上一些用户打分和博客排名的机制,以及开发一些网站widget之类的小东西,例如一键订阅到各个RSS阅读器。如果你也感兴趣,可以联系我:toozoofoo#gmail.com,也可以加入莲蓬QQ群参与讨论 。

我们发布了一个简单的笔记功能,你可以用它来记录你脑中的想法,也可以像莲蓬志这样当作博客来用。你可以直接前往这里,或者在如下图所示的地方找到入口:

现在可以只订阅某个特定专辑,而不用关注用户的所有专辑

谷歌Chrome浏览器可以为插件设置快捷键,喜欢快捷键的同志有福了,可以为莲蓬设置快捷键,快速收藏网页。下面介绍具体做法:首先找到扩展程序的菜单,“菜单栏->工具->扩展程序”,点击“扩展程序”,在出现的页面里最下方找到“键盘快捷键”的链接。菜单位置:找到“扩展程序”里最下面的“键盘快捷键”:在点击这个链接后出现的对话框里找到“莲蓬”一栏,在右边的输入框里填写需要设置的快捷键(例如:“Ctrl” + “Shift” + “L”),设置完成后即可使用,你可以尝试按住你刚设置的快捷键,收藏当前这篇文章。设置快捷键:

这次的改版没花多少时间来进行,主要变化是布局、配色以及收藏(编辑)网页链接的方式。前一版:新版:布局以前三栏的形式现在改成了两栏,原来的菜单一栏占据了很大的空间,有点浪费,现在去掉了,所有菜单现在全部在新增的导航栏上。颜色颜色上也参考了现在风行的Flat UI的配色,颜色更加鲜亮醒目。站内新加和编辑收藏现在网站里新加和编辑收藏的方式和浏览器插件工具保持一致,统一用弹出对话框的形式。 除此之外,在探索发现里设立了一个精选专辑的页面,这是我对用户公开的专辑筛选出的专辑,并且给这些专辑配上一个漂亮的封面。总的来说,界面更加干净清爽,希望你会喜欢。

参加完杨同学的婚宴,已经是八九点了,准备去KTV再闹一会,路上一起的是丁同学,突然问起我何时结婚,会不会请他参加婚宴。你知道我是老实人,不打诳语的,我跟他的交情一般,虽然大学期间觉得他不怎么出色,是个经常挂科的人物,但是我基本都是一视同仁,不过我结婚是不大会请他的,“老实说,我还真没有打算要请你”,我想继续解释,“我不想那么麻烦,只想请我们宿舍的、玩的来的大学同学,还有高中同学,他们大部分都在南京,其他人太远了,我也不希望他们特地抽时间大老远跑来,太麻烦了”。“我不怕麻烦阿”,丁同学说,“只要你请我,我肯定会去的”。“为什么?结婚叫你上份子,你也乐意?”,我表示不解。“只要有人请我,我都很开心”,“钱不重要,钱花的越多,我越开心。”。“为什么?”。“因为我觉得钱花的越少,你的钱就真的越少,你钱花的越多,你的工资也就越高”。我不由得感慨一番,他说的是对的,虽然这个道理足够简单,但我往往忽略它:没有舍,哪有得。换句话说就是舍不得孩子,套不着狼。我以前开发了一些网站,基本都是自己搞定,哪怕是UI和Logo,虽然很丑,也没有做什么推广,只因为舍不得花钱,拉不下脸去做推广。网站都最终都以失败告终,这倒不是说是因为没有好的logo,网站就不行,而是你如何看待一件事情的,因为仔细想想,其实并非是关乎钱,而是“舍”的问题,因为做成一件事情并非完全是靠钱,你是否舍得厚着脸皮做硬广,是否舍得放弃其他的项目的机会成本。之前看了一篇文章Freelancers: Work for free,作者谈及他在自由职业生涯里,如何达到他今天的成就,就提出一个观念:免费或者以低价为你的客户服务。这并不意味着你永远都要做没有回报或者回报很低的事情,而是在事业起步阶段,或者说人年轻的时候,不应该计较太多得失,你为别人做的越多,迟早人家是要还的,可能并非是那么直接的付你费用,就像作者那样,他得到的可能是一份心意、礼物,名声,机会和以及意想不到的好运。但我也发觉,如果带着功利心去做一件事情,总想着我为别人付出,一定会有回报,那么有可能会大失所望。“一定记得请我阿”,丁同学临走前说。 “好的”。

在早前一个用户报使用google帐号关联到莲蓬网进行登录出现需要经常登录的现象,刚开始以为是用户使用的浏览器问题,但是我自己试着用google帐号登录,的确会出现session过期以致需要重新登录的现象。通过chrome开发者工具找到当前的sessionid,拿去查数据库,djangosession表里记录的expiredate是今天的某个时间,显然不是django默认的session过期时间14天,而使用微博和Github登录则不存在这个问题,而只有google关联登录有问题。莲蓬在第三方社会化登录模块使用的是django-social-auth,根源应是这里,我们知道django session的过期时间是调用Session的set_expiry()函数来设置的,搜索源码发现django-social-auth是根据第三方网站的oauth api返回的expire字段来设置的:而google api的expires值是3600秒:| 99 | 247 | google-oauth2 | xxxx@gmail.com | {"accesstoken": "xxxxxxxxxxxxxxxxxxxxxx", "tokentype": "Bearer", "expires": 3600}所以解决办法目前是设置SOCIALAUTHSESSION_EXPIRATION = False来disable django-social-auth根据第三方网站的expires字段设置session过期时间。经验教训就是要用开源的东西就必须了解研究清楚才能去用。

如果你有遗留数据库,希望从其他语言或者web框架投入到Django的怀抱,几个工作就可以使得你的工作完成了一半,首先通过django-admin创建了一个项目: django-admin.py startproject myproject 并修改settings.py文件中的DATABASES的设置,将数据库设为遗留数据库的ip和port, 然后通过:python manage.py inspectdb,可以看到输出的是django的model定义,可以把输出重定向到文件models.py,这就完成了model定义,当然,inspectdb的输出结果还是需要修改下的。id : 主键id的那个字段可以直接删除db_table可以删除,不能rename外键:需要略微修改的是外键的字段名,例如:user_id = models.IntegerField(null=True, blank=True),最好就是将user_id后面的_id删除,直接是user,这样就是django风格的model定义了,django会帮你在转化为sql时将user变成user_id,同时将IntegerField改成ForeignKey。图片字段,像avatar这样的用于记录图片位置的字段,需要修改成ImageField

午睡的时候想起读小学时的情景,那是夏天(似乎童年的记忆里只有夏日吧),中午回家吃饭,吃罢饭,照例是去小店买一袋水蜜桃,1毛钱,要全冰的,否则撑不到从家到学校的路。马头牌的蛋筒是稀有的美味,需积累几天的冰钱,然而一个孩子是没有积蓄和延迟享受的想法的,得了钱花掉才好,否则哪日翻便裤衣兜,却不见他们时,那才叫一个杀千刀的恨自己。那时没念过李白的“人生得意须尽欢,莫使金樽空对月”,只有“床前明月光”,但这两句都在说他是月光族,我那时是一天光,这样想来李白也该是有颗孩子的心罢。记忆里,这去学校的路是很长的,且是不能够用公里数计的,然而有这冰,却似乎是个愉快的旅途。大且蓝的天空中常常会飘来一堆大且白的云,投下一块大且快意的影子,我便在这大且快意的影子中,满意的吃这冰,一同徘徊,他行的慢时,我便等他,他行的疾时,我便小跑追上他。然而我们究竟不是同路,在短暂的旅途中,我们又告了别,看他随风而去,远远的走了,但我想于他这旅途也是愉快的罢。冰吃罢,学校就也该到了,此时的学校很安静,只有操场上的染着革命烈士鲜血的国旗因为风而发出呼呼的声音。大家在午睡,有的直接伏在课桌上睡的,有的则是和同桌商量好,轮流睡在课桌上的,而条凳太窄,容易掉下来,需借几条并列排在一起才好些,另外一些则是像我这样从抽屉里拿出用作装化肥的袋子,加入午睡阵营,至于是复合化肥还是尿素,已经不记得了,或许都有,袋子和身高差不多,铺在教室的地上,也有在走廊上的,只要是太阳照顾不周的地方:四年级的时候我便在学校里的桃树下睡过,也曾有过些美梦,蓝的天,白的云,以及没有见过的书里说的海,这荫凉虽不大,却和路上同行的大且白的云为我画出的快活圈一般的快意。然而在教室建筑外午睡是不允许的,并且有值日同学的检查,入黑名单是要被老师训的,所以和值日同学建立友好和睦的关系是件十分必要的事情。现在我伏在电脑前开始午睡,想起冰的夏日,然而那路上的冰的甜味似乎随着时代的进步,逐渐淡去了,而那些曾陪伴过我的云如今又去了哪里,我想,美好的夏日总该有这些云才好,但或许现在只能在桃树下的梦中才得见了。

What's is real? 南方公园有一集,关于imaging land,超人,大力水手,不是真实的,但是他们的影响可能比你我任何一个人都要大,即便在我们死后多年,我们的后代,仍然被这些不真实的东西所影响,相比之下,你我同超人,谁更真实?

在扇贝网有很多图片,例如头像、单词书封面、小组徽章等,这些都是存储在mongodb中的,如果每次请求图片都从mongodb读取的话,对mongodb来说压力还是有的,而且每次请求的response status code都是200,浏览器无法对之进行缓存,所以我们在nginx这一层加了一个proxy cache,将从mongodb中的图片缓存到文件系统中,下次请求图片时要么在浏览器缓存中,要么从文件系统中读取,只有当图片在文件系统中无法找到时才会通过mongodb读取数据。nginx配置: nginx.conf:proxy_cache_path /var/www/cache/ levels=1:2 keys_zone=app-cache:8m max_size=1000m inactive=600m; proxy_temp_path /var/www/proxy/; 配置文件: location ^~ /images/ { try_files $uri @proxy; } location @proxy { uwsgi_pass http://proxy_server; include uwsgi_params } 如果所有图片都走一台机器,很容易把带宽用光,所以在带宽不足的情况下,你需要有多台机器来serve,其中一台机器A会跟mongodb或者说应用程序打交道,其他机器B只作为静态代理服务器,对他们的请求都将转发到A,如果本地图片已经存在,则直接从文件系统读取,不再转发到A。 B的配置: location ^~ /images/ { try_files $uri @proxy; } location @proxy { proxy_pass http://ip_of_A; proxy_store on; proxy_store_access user:rw group:rw all:r; proxy_temp_path /var/www/temp; proxy_set_header Host "domain_of_static_server"; proxy_redirect default; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } 假定你会为图片专门设立一个域名,例如static.yourdomain.com,他们同时指向A和B,那么请注意: proxy_pass http://ip_of_A; ... proxy_set_header Host "domain_of_static_server"; ipofA需要是一个ip而不是static.yourdomain.com,think about it.

网站上的静态文件(css,js,img)这次要使用多台服务器serve,而之前模版、css里全部是绝对路径,所以大改了一番,在模版里使用STATIC_URL这个常量代替,开发完成后,需要测试全站是否还有遗漏的地方,如果有的话,一般页面上引用的静态文件会出现404情况,根据这一依据,之需要测试全部url即可。人工在页面上点点固然可靠,事实上在开发过程中也是这么做的,但人总是不可靠的,而且url数量之多,根本没法人来做,所以还得依靠工具,为了测试每个url,第一个想到的就是像爬虫那样,爬去取每个页面的url,然后察看后台是否出现404,所以最简单直接的工具就是wget。通过wget的-m(--mirror) 参数能够像爬虫那样把整个网站全部url对应的网页爬取下来,因为网站需要登录,那么还需要额外的工作,需要你先成功登录: ``` wget --keep-session-cookies --save-cookies cookies.txt --post-data "username=XXX&password=XXX" "http://127.0.0.1:8000/login/"cookie.txt中的内容大致如下: 127.0.0.1:8000 FALSE / FALSE 1348716805 sessionid 837e0ba5f05c932c10683cfc4f292eb9 。这样就可以让wget访问需要登录的url了: wget -m http://127.0.0.1:8000/ --load-cookies cookie.txt -X /accounts/logout/,/admin/logout/,/admin/ -X是需要排除的url目录,比如注销帐户的url。



刚刚