腾讯微博oauth2的api python实现

最近公司要求 游戏街有新的文章上线的时候都自动发送新浪腾讯微博。

新浪微博没有官方python SDK,不过有官方推荐的 python sdk:http://code.google.com/p/sinaweibopy/
腾讯就比较悲催了。没有官方python sdk也就算了,连官方推荐的sdk也木有。所以我基于廖雪峰 的sina微博python sdk改了一个腾讯微博的sdk出来。发现还挺好用。。

代码可以github 上找到:https://github.com/jinuljt/qqweibov2

1 Comment

ssh public key登录错误一例

今天遇到个怪事,我用rsync了一次服务器文件之后发现我居然不能够用public key登录了。我什么配置也木有修改啊!

看了ssh登录的verbose输出:
debug2: key: /home/user/.ssh/id_rsa (0x2158ae20)
debug2: key: /home/user/.ssh/id_dsa ((nil))
debug1: Authentications that can continue: publickey,password
debug1: Next authentication method: publickey
debug1: Offering public key: /home/user/.ssh/id_rsa
debug2: we sent a publickey packet, wait for reply
debug1: Authentications that can continue: publickey,password
debug1: Trying private key: /home/user/.ssh/id_dsa
debug2: we did not send a packet, disable method
debug1: Next authentication method: password

说明已经发送了publickey。实在想不出有什么原因,一顿google,说是authorized_key 和 .ssh 文件夹的权限问题。我没改过权限啊。而且ls -l后发现权限也是正确的。

突然想到可以看服务器的log嘛。于是
tail -f /var/log/auth.log
然后用ssh登录,发现 Authentication refused: bad ownership or modes for directory /home/user
居然是该用户的home文件夹权限被改掉了!改回来就ok了。

PS:说来说去这种明明陪好了public key 却又不能用public key登录的问题大致都能从文件(夹)权限方面找找问题。。。这次连home文件夹都被改了权限实在是完全没想到。说起来也好避免啊。都是我用root用户搞得。。。

No Comments

使用dropbox api来备份

最近发现越来越多的app集成dropbox来读取和保存文件了。我重新考虑了一下我的备份blog数据库的策略。之前我是直接在服务器上运行一个dropbox客户端来进行备份数据库,这样其实相当的浪费服务器资源。当然直接运行一个dropbox是比较简单,只要把保存到dropbox的文件夹下面即可。

不过为了不浪费服务器资源,我看了一下dropbox的api文档,写了一个简单的脚本来上传文件到dropbox。

#!/usr/bin/env python
#-*- coding:utf-8 -*-
#author: juntao liu
import sys
import json
from dropbox import client, rest, session

#app key and secret
APP_KEY = 'your app key'
APP_SECRET = 'your app secret key'

#access type 'dropbox' or 'app_folder'
ACCESS_TYPE = 'app_folder'

#TOKEN_FILE save token for next time access
TOKEN_FILE = 'your token file path'

class DPClient:
    client = None

    def __init__(self, app_key, app_secret, access_type='app_folder'):
        self.sess = session.DropboxSession(app_key, app_secret, access_type)
        self.request_token = self.sess.obtain_request_token()

    def build_authorize_url(self):
        # Make the user log in and authorize this token
        return self.sess.build_authorize_url(self.request_token)

    def token_from_dropbox(self):
        #This will fail if the user didn't vist the authorize url and hit 'Allow'
        self.access_token = self.sess.obtain_access_token(self.request_token)

        self.key = self.access_token.key
        self.secret = self.access_token.secret

        self.client = client.DropboxClient(self.sess)

    def token_from_file(self, file_path):
        try:
            d = json.loads(file(file_path).read())
            self.sess.set_token(d['key'], d['secret'])
        except:
            return False
        self.client = client.DropboxClient(self.sess)
        return True

    def save_token(self, file_path):
        d = {'key': self.key, 'secret': self.secret}
        file(file_path, 'w+').write(json.dumps(d))

    def upload_file(self, full_path, rename='', overwrite=True):
        from os import path
        if not client:
            print 'dropbox client not exists'
            return

        if not path.exists(full_path):
            print 'file not exists'
            return

        f = open(full_path)
        if not rename:
            filename = path.basename(full_path)
        else:
            filename = rename
        self.client.put_file(filename, f, overwrite)

if __name__ == '__main__':
    if len(sys.argv) != 2:
        print "./upload_dp.py <file>"
        sys.exit(1)

    dp = DPClient(APP_KEY, APP_SECRET)
    if not dp.token_from_file(TOKEN_FILE):
        print "url:", dp.build_authorize_url()
        print "please authorize in the browser. After you're done, press enter"
        raw_input()
        dp.token_from_dropbox()
        dp.save_token(TOKEN_FILE)
    dp.upload_file(sys.argv[1])

很简单的程序,就像我说的很简单的目的只是为了上传文件。
默认DPClient上传文件会覆盖同名文件,并且使用传入的文件名作为上传的文件名。更多的功能请参考Dropbox的开发者网站:https://www.dropbox.com/developers

,

2 Comments

《改变心理学的40项研究》

1 通过对割裂脑病人的研究,左右脑是拥有独立思考的能力的。不过由于左右脑拥有的功能不同,所以我们需要一个联通的大脑。
2 研究发现丰富环境下的老鼠比贫瘠环境下的老鼠拥有更重、更厚的大脑皮层,更大的大脑神经元。
3 具有相同遗传基因的人(同卵双胞胎),即便分开抚养并且生活条件大相径庭,他们长大成人以后不仅在外表上极为相似,而且其基本心理和人格也惊人的相似。
4 感知深度的能力是天生的。
5 知觉恒常性中的大小恒常性(近大远小)是后天经验的。
6 人需要梦。如果做梦被剥夺,那么它会反弹。
7 梦是一种生理需求。
8 催眠让被试产生了一种期望,这种期望促使被试以与期望相一致的方式表现某种行为。
9 经典条件反射(巴甫洛夫条件反射学说)可以解释许多人类行为
10 人类所有的行为起源于学习和条件反射(比如:情绪)
11 迷信行为与其他任何一种行为一样,很容易用操作性条件反射原理解释
12 儿童会模仿作为榜样的成人的行为
13 教师的期望效应对学生的在校表现会产生长期的潜在影响
14 每个人都有他的某个智力技能强项。多元智力理论
15 尽管内部过程无法法直接观察,但我们可以通过分析可观察的行为而客观、科学地将其推断出来
16 记忆是什么时候用,什么时候重组的。相当不可靠。
17 爱除了食物还要接触安慰(拥抱)
18 智力或认知的发展在很大程度上是一个渐进过程,不能跳跃
19 道德价值观是一个渐进过程。
20 当我们拥有控制力时,我们便是更快乐和更有成就的人
21 人类性反应的过程研究
22 人类脸部表情全球通用
23 《社会再适应评定量表》与健康
24 改变自己的原有行为或观点来降低认知失调
25 内控与外控行为。I-E量表
26 双性化与BSRI量表。
27 个体的特殊行为模式与健康有关
28 个人主义与集体注意(文化)对人心理与生理都有影响。
29 做出心理诊断是更具病人所处的环境或场合而不是病人本身所具有的特征。(标签化的人)
30 应对焦虑的防御机制:压抑、退行、投射、反向作用和升华作用
31 习得性抑郁,当你发现你的行动是徒劳的(你没法控制)。
32 高密度环境(拥挤)对人有不良影响。
33 心理学治疗的方法之间没有太过显著的差别(针对个人特征而言可能某类治疗会更有效)。
34 系统脱敏疗法,接近你所恐惧的,你会慢慢适应它,摆脱它的。
35 罗夏墨迹测试,反映了你当前的心理特征,不过他不是也反映了心理治疗师的吗?
36 TAT测试,为画编个故事。貌似比罗夏墨迹测试靠谱点,不过还是存在一样的问题。
37 人的言行是不一的,嘴上说不吃KFC,不喝蒙牛了。当下就忘了。
38 从众。
39 人越多你就会觉得自己的责任越少,做出行动的可能性越低。
40 在情景的压迫下,我们会盲目的听从“权威”做明明自己认为错误的事情。

PS:
LOL,《改变心理学的40项研究》这书绝对推荐每个人都看看。心理学还是比较现实的能够直接改变生活的知识。

No Comments

django有内存泄露?

写了一个抓app store数据的小爬虫。这玩意是为了配合原来的项目使用的,所以我直接用了该项目的django配置,为了使用数据库模块嘛。没想到还没跑多少数据我就发现爬虫的内存居然飙升到900MB+了。难道有什么bug会内存泄露?

我仔细看了一下代码,很简单的东西,多线程使用urllib获取app store数据,然后用django的db models把数据保存到数据库。看不出问题,只好直接动手了,首先把保存数据那块给屏蔽了;然后跑了一遍,完全木有内存泄露,仔细查看了一遍保存数据库的代码,完全木有问题。

没办法了,只好google “django models memory leak”,元凶终于付出水面,原来是我在本地由于开了django的DEBUG模式,所以django会把所有sql查询的数据都缓存起来。去掉debug模式就一切ok。
https://docs.djangoproject.com/en/dev/faq/models/#why-is-django-leaking-memory

No Comments

用iCal的数据填充pomodoro

最近一段时间一直使用wunderlist管理todolist。使用番茄工作法工作。我用的是pomodoro这款番茄工作法软件。

我遇到的一个需求是想让wunderlist和pomodoro可以协同起来。很简单的需求,这都是由于pomodoro上的一个功能勾起来的。pomodoro它可以从thingsomnifocus(这是两款mac上很出名的日程管理软件,价格相当贵)里面获取出当天的日程安排填充到欲执行的工作安排里。

既然pomodoro没有提供这个功能,那么只要自己动手解决了。在applescript editor里面看了一下,pomodoro提供了

start text: Pomodoro name

的接口,可以设定一个pomodoro名字运行。不过天不遂人愿,wunderlist居然没有提供任何applescript可以操作的接口。

等wunderlist改版那要猴年马月。而且最近对于wunderlist提供功能一点小不满意,索性重新转到iCloud的reminder得了。reminder唯一的小遗憾是只能在apple设备上或者pc浏览器上使用。

说了这么多反正就是我从wunderlist转到reminder了。
我还改动了日程安排的方式:
1、任何想到的todo都记录到reminder中。
2、当天需要行动的todo都变成一个allday event放到calender。
3、当天做的事情都变成event写到calendar里面

然后我写了一个applescript脚本。当需要工作(广义的)的时候就是取出当天的allday event让我选择,然后以这个作为pomodoro name开始一个番茄钟。
附上源码:

	tell application "iCal"
		--获取当天的allday events
		set now to (current date)
		set nowTime to time of now
		set nowDate to now - (nowTime)
		set event_lists to (events whose start date = nowDate and allday event = true) of calendars

		set event_list to {}
		repeat with this_list in event_lists
			repeat with this_event in this_list
				set event_list to event_list & summary of this_event
			end repeat
		end repeat

	end tell
	set selected_event to {choose from list event_list}

	tell application "Pomodoro"
		set pomodoro to selected_event
		if selected_event = {false} then
			set pomodoro to ""
		end if
		start pomodoro
	end tell

, ,

No Comments

刚刚读完《谣言》

今天中午加晚上大概花了1个半小时不到的时间看完这本信息量相当之少的书——《谣言》

看完之后比较怀疑自己怎么会选了这本书。在豆瓣搜了一下,原来我买错了,本来是想买《谣言——世界最古老的传媒》。可能是360buy半价买书那会没有注意。(话说还买重了几本书)

不管如何,我看完了它。全书大概就是讲了谣言——其实更贴切的应该换成流言吧——传播过程与如何规避之。我觉得看第一章与最后的结语完全够了。中间的大部分是废话,流程大概是这样的,提出一个问题,然后描述这个问题,最后这章结束了。

总结是:
谣言传播的过程——社会流爆和群体极化
规避谣言的危害——寒蝉效应与去除偏见

我的理解:
社会流爆有点像跟风的意思,大家都相信这个流言,于是你也信了,作者对这个的定义还加了一些从众压力与情感压力。
群体极化大概就是一群想法意见相似的人更容易采信与他们的看法类似的流言。并且这个群体在一起的时候更容易加强。
寒蝉效应其实国人是很明白的,看一下各个网站那阉割自己的行为就是了。
去除偏见就显而易见了。

No Comments

钱松今日喜结良缘

恭喜钱松今天结婚,祝早生贵子、白头携老。(PS:肚子里面已经有了。哈哈)

如今钱松结婚之后我们大学宿舍也就小虎同学没有结婚了。赶紧加油啊。

No Comments

new server, new start

new server, new start 简写成NSNS。嗯哼,我故意的。
之前使用的VPS过期了,又重新租了新的VPS。一年又过去了,与之前没什么变化,还是没有好好些BLOG。

开始总是容易的,可是要完成一件事情是难的。

No Comments

Read《番茄工作法》

最近工作有点昏昏沉沉的,集中不了注意力。昨天上午看到電腦玩物上的Pomodo7o 善用Windows 7工作列進度條特效執行番茄鐘工作法才了解到有这么一种“番茄工作法”。

简单的说,番茄工作法就是把你的时间分成30分钟为一个单位的小块,然后其中25分钟是工作时间,5分钟是休息时间。在这25分钟的工作时间内你需要尽力去完成你预先分配给自己的工作,也就是在这25分钟之内集中你的注意力。你必须要强迫自己集中注意力,不能够去做预先规定的事情以外的事情。
当然事实上我们在这25分钟只能可能会遇到“外部”以及“内部”的打断:当遇到“内部”打断,譬如肚子饿了,渴了之类的你记录下来然后等这一个番茄时间之后再做;当遇到”外部“打断,譬如同事问你问题、来电话之类就诚恳的要求他们等到番茄时间结束。当然如果真的有重要的事情你就放弃当前这个番茄时间,为那件重要的事情重新开始一个番茄。
当番茄时间结束的时候你就必须停掉手下的工作休息5分钟,就算还有几分钟就能做完事情也这样。如果在番茄时间结束之前就完成了工作,那么就复习之前所学或者检查你的工作。

番茄工作法的官方网站是 http://www.pomodorotechnique.com/
它提供了中文的pdf文档。点我下载

番茄工作法的规则:
一个番茄时间共 30 分钟,包括 25 分钟的工作时间和 5 分钟的休息时间。(2.1)
每四个番茄时间过后,停止你的工作,进行一次较长时间的休息,大约 15 到 30 分钟。(2.1.2)
一个番茄时间是不可分割的,不存在半个番茄时间或一刻钟的番茄时间。(2.1.1)
一旦开启番茄计时器,就必须要坚持到底。
如果你当真要打断当前番茄数时间,无论是你挡不住诱惑,还是真的发生了紧急的 事情,你只需要做一件事:把当前的番茄时间作废,就算马上就要响铃了也是一样, 然后在表中对应处标上点号。这时候你不能画“x”。(2.2.2)
如果你在番茄计时器响起前就完成了手头的工作,你可以利用剩余的一部分番茄时 间,复习一遍之前所学的,或检查一下所做的工作,这样可以使你得到一点小小的 提高,记录一下你所做的事情,直到铃声响起。(2.1.3)
“保护你的番茄”,(2.2.3)明确地告知想要打断你的人,并商量推迟他的请求。
如果一项任务的估测值大于 5 到 7 个番茄,那么就打散它。(2.3、3.11、4.2)复杂的工作应该被分割为小的事情。
如果一项任务的估测值小于一个番茄,就把几个小任务组合成一个大任务。(2.3、4.2)
一个番茄一个番茄地连续下去,就会成功。
下一个番茄时间会做得更好。

No Comments

SetTextSize SetPageWidth