merry xmas

mplayer -loop 0 01-圣诞结.mp3

音频片段:需要 Adobe Flash Player(9 或以上版本)播放音频片段。 点击这里下载最新版本。您需要开启浏览器的 JavaScript 支持。


随机日志:
备份Twitter Friend Timeline到Google Calendar

Twistory是一个不错的服务,但是他不支持Protected User的时间线备份,并且只能进行User Timeline的备份。我的想法是能进行我的Friend Timeline的备份,按照时间进行备份,这样可以在以后方便地管理,并且可以用google进行搜索,不用管twitter search那个烂玩意儿了。

本日志中代码以Creative Attribution-Noncommercial-Share Alike Commons(创作共用 署名-非商业性使用-相同方式共享协议)协议开放。

NND谁知道怎么让wp-syntax自动换行?折腾半天还是不行…

昨天研究了一下Google Calendar API,发现一个问题…Google只给出了用Zend Framework封装好的库函数的调用方法,具体实现没说。本来准备研究一下那几个函数的,结果发现原来里面附带的Calendar.php可以当命令行脚本使用,支持从命令行用参数添加Event。最后的结果就是这个了:

< ?php
        //Licensed Under Creative Commons by-nc-sa
        //Original Author: @yegle ,yegle.net
	$last_id = intval(file_get_contents(".lastbackup"));
	$str = file_get_contents("http://TwitterUserName:TwitterPassword@twitter.com/statuses/friends_timeline.xml?since_id=".$last_id);
	if($str === FALSE ) exit();
	$xml = simplexml_load_string($str);
	$i = 0;
	$return = 0;
	foreach($xml->status as $item){
		$timestamp = strtotime($item->created_at);
		$id = $item->id;
		$date = date("Y-m-d",$timestamp);
		$time = date("H:i",$timestamp);
		$text = $item->text;
		$text = str_replace("\"","\\\"",$text);
		$user = $item->user->screen_name;
		$cmd="/usr/bin/php /home/yegle/Calendar.php createEvent YourGoogleAccountName YourGooglePassword \"FROM:$user $text\" \"$text::$id\" '' '$date' '$time' '$date' '$time' '-07' >>twitterbackup.log";
		system($cmd, &$return );
		if($return !==0 ) exit();
		$i++;
	}
	if($i!==0) file_put_contents(".lastbackup",strval($xml->status[0]->id));
?>

使用说明:
其中用system函数调用PHP执行了Calendar.php,Calendar.php是从ZendFramework里找到的一个Gdata演示程序。

将以上内容保存为一个PHP文件,如backuptwitter.php
下载最新的ZendFramework,使用该地址或自行在ZendFramework下载最新版本
解压缩,将其中的libarary目录复制到合适的位置,例如/home/yegle/library/
将demos/Zend/Gdata/Calendar.php复制到其他地方待用。
修改Calendar.php,在文件第一个

< ?php

之后添加如下代码:

set_include_path("/home/yegle/library/:".get_include_path());

注意修改其中的路径

最后修改backuptwitter.php,将其中的用户名密码全部替换成你的实际用户名密码,其中的cmd变量也做相应的修改以符合你的实际情况。

最终的效果:
每条推的内容将被填入Event的Title
推的时间会被填入Event的起止时间
Description里会填入推的内容以及id,方便以后去twitter.com查看原始推。

//Fixme:

  1. 使用system函数调用脚本进行事件的添加,万一有出错,可能导致部分推没有备份
  2. 使用前,必须往.lastbackup文件里写入一个你当前Friend Timeline里最后一条推的id


随机日志:
笑话——蚊子

蚊子咬了我一口,得意洋洋地飞走了
一边飞一边唱:
我轻轻的尝一口 你说的爱我 还在回味你给过的温柔
我轻轻的尝一口 这香浓的诱惑 我喜欢的样子你都有

神奇的网络啊…

这是个神奇的网络

你要是发出声音呢,有人会说你是想出风头,会说你不给面子,会说你死不放手,死缠烂打

你要是不发出声音呢,有人会说你认怂,会说你这下无话可说了吧,或者反过来说这人装清高,故弄玄虚

有人去ffmpeg issue tracker上丢人,这次是研究我到底是不是windows用户,以及我有qq号码,凭什么说与腾讯无关,还有我的vpn用户不遵守版权,为啥我就能这么义正辞严,还研究了我上次举报暴风之后隔这么久才举报射手,到底安的什么心。

有人邮件问我,为啥darwin是开源的,我不去要求苹果把mac os都开源了

有人或直接或委婉地质问我,为什么我不给射手面子

什么是开源软件?什么是自由软件?什么是GPL?

Tomasen仍然不承认之前有违反GPLv2的行为

这篇日志不开放评论,有意见请上twitter。如果你反感本人,记得千万别用dabr或者twip上twitter

关于射手播放器

真是造孽啊…又举报了一个播放器,谁知道这么多不明真相的人围观…
Continue reading ‘关于射手播放器’

VPN使用的误区

现在选择购买VPN的人越来越多了,但是很多人并不是很了解VPN,以至于很多时候使用上存在误区。
先举个推友的推做例子:

XXVPN确实不错,是我用过的VPN中最好的,无论是稳定性、保密性、速度都比XXXXVPN 要好

分条解释:
1、稳定性:
计算机程序是最讲究逻辑的,对于一个程序来说,除了“能工作”、“不能工作”这两个状态之外,只有一个“在XXXX状态下无法工作”的状态,而不存在所谓的“不稳定”状态。如果一个VPN,A能用而B不能用,那么多半是B的客户端设置问题而不是VPN服务端的问题
2、保密性:
有很多人误会vpn上网就绝对安全了。vpn只是提供一个到国外的加密信道,在没有使用ssl等端对端加密方法时,从加密信道出口到目的网站仍然是不加密的。具体的解释可以参考tor对自己安全性的描述。
3、速度快:
速度的快慢是个主观感受。免费vpn速度达到50k有人就觉得很快了,我用自己的vpn速度不到500k都嫌慢。拿腾讯qq下载测速和拿google chrome测速结果肯定不同。还有要区分是延时和速度,玩游戏追求低延时,搞下载追求高带宽,两者不同

是谁怂恿我写这个日志的…好像说完这三条就没了…orz…

自动解压0day资源脚本

这个脚本是以前在管理学校ftp的时候用的,当然自己在下载学校ftp资源的时候也常用这个脚本。

使用脚本要保证系统内存在rar命令。将脚本保存为dr,加上可执行权限后放到系统路径内可用

脚本能处理以下情况:
1、文件夹内压缩包以r00、r01结尾
2、文件夹内压缩包以part01.rar、part02.rar结尾
3、文件夹内包含多个子文件夹,以CD1、CD2命名

脚本能处理绝大多数0day的电影资源,但是没有经过严格测试。从我的使用来讲,至少90%以上的电影0day资源能顺利解压~
代码以CC by-nc-sa释出

#!/bin/bash
# by yegle@yegle.net
# released under CC by-nc-sa
function unrar(){
if test -e *01.[Rr][Aa][Rr]
then
	rar x *01.[Rr][Aa][Rr] && rm *[0-9][0-9].[Rr][Aa][Rr]
elif test -e *.[Rr]00
then
	rar x *.[Rr]00 && rarname=`basename *.[Rr]00 00` && rm "$rarname"[0-9][0-9] "$rarname"[Aa][Rr]
elif test -e *.000
then
	rar x *.000 && rm *.[0-9][0-9][0-9]
fi
rm -rf *.sfv Thumbs.db *COMPLETE* *.[Dd][Ii][Zz]
}
 
 
 
if test -e [Cc][Dd]1
then
	for dir in ./[Cc][Dd][1-9]
	do
		cd $dir
		unrar
		cd -
	done
else unrar
fi

PHP cURL代码举例

上次贴出来的twitter同步到人人的代码,很多人留言说看不懂。其实这个代码从总体上说还是比较简单的,可能大家对curl相关函数不太了解导致抱怨说看不懂。这里写篇简单的日志介绍一下curl的使用。

注意:如果你需要深入学习,请在线查看php.net的文档,本文仅仅是对不了解PHP curl函数族的用户的入门简介。代码没有经过严格检查,如有错误请留言指出。同样,全文及以下代码以CC by-nc-sa释出,转载请注明出处。

curl是client url library的缩写。使用curl可以完成几乎所有的HTTP交互。我写的PHP代码里,包括本博客上帖出来的例如自动同步twitter到人人,以及twip项目里,大量使用了这个函数族。

PHP中curl库的介绍在这里:http://us3.php.net/manual/en/book.curl.php。如果需要使用PHP做HTTP交互相关的开发,建议仔细阅读这个页面提到的各个函数。

在PHP中使用curl非常简单。典型的使用例子:

$ch = curl_init();//创建一个curl会话,返回一个curl handle.
curl_setopt($ch,CURLOPT_URL,'http://example.com');//设置该会话相关的URL地址
//在这个地方可以调用多次curl_setopt函数,进行更多具体的设置
curl_exec($ch);//执行curl操作
curl_close($ch);//结束该curl会话

各个函数的功能在注释里注明了。对于一般的开发者来说,关键的是掌握curl_setopt函数第二个参数可允许设置的所有内容。选择适当的curl_setopt参数,可以完成诸如用户名密码验证、post数据、保存cookie、使用代理连接、伪装成浏览器访问等等功能。可以说PHP中使用curl函数族的精髓在curl_setopt函数的使用。

举例说明一下几个典型的应用:
发送GET请求:

$url = 'http://example.com';
$ch = curl_init($url);
curl_exec($ch);
curl_close($ch);

访问这个PHP将得到http://example.com/页面的内容。这个代码仅仅是将GET得到的内容简单地“echo”出来,没有进行处理,也没有将网站的cookie以及header信息返回。

发送一个POST请求:

$url = 'http://example.com/index.php';
$ch = curl_init($url);
curl_setopt($ch,CURLOPT_POST,TRUE);
curl_setopt($ch,CURLOPT_POSTFIELDS,'username=test&password=asdf');
curl_exec($ch);
curl_close($ch);

这部分代码post了两个字段,username和password,执行这个脚本之后在index.php中可以通过$_POST['username']和$_POST['password']来访问这两个post字段的值

不直接输出结果,或需要先对结果进行过滤

$url = 'http://example.com';
$ch = curl_init($url);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,TRUE);
$ret = curl_exec($ch);
curl_close($ch);
$ret = str_replace('fuck','XXXX',$ret);
echo $ret;

这部分代码,通过curl_setopt的设置,在执行curl_exec函数时不直接将结果输出,保存在$ret变量中,方便进行其他处理。注意的是:CURLOPT_RETURNTRANSFER的设置只是不让curl_exec不直接输出结果而已,无论有没有设置这个参数,curl_exec返回值里总是包含获得的页面内容。

返回服务端的完整信息:

function echo_header($ch,$str){
header($str);
return strlen($str);
}
$url = 'http://example.com/';
$ch = curl_init($url);
curl_setopt($ch,CURLOPT_HEADERFUNCTION,'echo_header');
curl_exec($ch);
curl_close($ch);

这段代码将服务端的http return header原封不动地返回给客户端。使用CURLOPT_HEADERFUNCTION设置了一个回调函数,在curl_exec时,每从服务端得到一行return header信息,就调用这个函数,将curl handler和该header的内容作为参数调用这个函数。设置的函数*必须*返回header内容的长度。如果你足够敏感的话,你会发现,这个就是Twitter API proxy的简化版本。

使用cookie保持登录:

$login = 'http://example.com/login.php';
$view = 'http://example.com/user.php';
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,$login);
curl_setopt($ch,CURLOPT_COOKIEJAR,'/tmp/cookie');
curl_setopt($ch,CURLOPT_POST,TRUE);
curl_setopt($ch,CURLOPT_POSTFIELDS,'username=test&password=mypass');
curl_setopt($ch,CURLOPT_RETURNTRANSFER,TRUE);
curl_exec($ch);
curl_setopt($ch,CURLOPT_URL,$view);
curl_setopt($ch,CURLOPT_COOKIEFILE,'/tmp/cookie');
$ret = curl_exec($ch);
echo $ret;

这段代码稍微有点复杂。这个代码完成了两次curl_exec,演示了如何使用一个curl handler完成多次http request。绝大多数的网站都通过SESSION COOKIE完成用户的保持登录,也就是说只要cookie在,而且session没过期,就可以用这个cookie保持登录状态。这段代码首先在$login,使用POST完成了登陆,同时将cookie保存在/tmp/cookie里。在第二次curl_exec时,curl使用这个cookie以登录后的状态抓取了user.php的内容,并echo了出来。没错,这个代码就是twitter自动转发人人网站代码的简化版。

test to post from my g2 using wptogo

hey it works!

twitter同步到renren的php脚本

声明:脚本以CC by-nc-sa协议公布,如需转载请给出原文链接并保留脚本头部的版权声明。

声明:本人不对可能发生的您的renren.com好友被刷屏、脚本错误反复刷屏、您的好友解除与你的好友关系、您的renren.com帐号被举报等等任何不良后果负责~

100129:修正脚本的bug

网上已经有一个twitter2renren的同步网站了,地址在这里:http://twitter2renren.appspot.com/
问题有两个,一个是据说现在已经无法同步了,另一个是这个网站需要输入twitter用户名密码,不支持OAuth,这让我很不放心。于是决定自己写个脚本。

自己动手丰衣足食,不过也有问题,一是一般只用于解决自己的问题,其他人可能还需要修改才能用,二是一般都是无比quick and dirty,懒得写注释和注意排版。这次这个代码好像好多人想用,所以已经尽量考虑比较多的特殊情况,排版也稍微好看一点了……

使用说明:
根据代码中的提示,修改几个变量的值
然后尝试运行一遍脚本,如果没有报错的话,你会看到最近的推显示在屏幕上。这是转发twitter到renren.com后根据renren返回的json解码得到的信息。
根据你执行脚本时的速度选择crontab的时间间隔。我这里选的是5分钟。执行crontab -e
添加以下代码:

*/5 * * * * /path/to/twitter2renren.php 2>&1 >>/path/to/logfile

Done!

以下为代码:

< ?php
 
//
//twitter2renren.php
//By @yegle, yegle.net
//Licensed under CC by-nc-sa
//
 
$file = '用于记录你最后一次同步tweet id的文件路径。注意不要删除并让脚本能读取!';
$cookie_file = '保留curl模拟登陆renren.com的cookie文件路径。';
$name_pwd = '你的twitter用户名密码。格式为:yourusername:yourpassword';
$hashtag = '如果你希望在你的推里包含特殊字符串时才转过去,请设置该变量,否则只转发不是以@开头的推';
$renren_username = 'renren.com登录用户名';
$renren_password = 'renren.com登录密码';
 
//配置完毕,请停止编辑文件!
//That's it!Stop editing anything below unless you know what you are doing!
if(file_exists($file)){
    $lastid = intval(file_get_contents($file));
}
else{
    touch($file);
    $lastid = 0;
}
 
 
$timeline_url = 'http://'.$name_pwd.'@twitter.com/statuses/user_timeline.json?count=200';
if($lastid!==0) $timeline_url.='&since_id='.$lastid;
 
 
$timeline = file_get_contents($timeline_url);
$arr = json_decode($timeline,TRUE);
if(empty($arr)) exit();
$new_id = $arr[0]['id'];
if($new_id == '') exit();
file_put_contents($file,$new_id);
$post_arr = array();
foreach($arr as $tweet){
    if(strpos($tweet['text'],'@')!==0){
        if($hashtag!=='' && strpos($tweet['text'],$hashtag)!==FALSE){
            $post_arr[] = $tweet['text'].' [twitter]';
        }
    }
}
 
 
$post_arr = array_reverse($post_arr);
 
$renren_login = 'http://passport.renren.com/PLogin.do';
$ch = curl_init($renren_login);
curl_setopt($ch,CURLOPT_COOKIEJAR,$cookie_file);
curl_setopt($ch,CURLOPT_POST,TRUE);
curl_setopt($ch,CURLOPT_FOLLOWLOCATION,TRUE);
curl_setopt($ch,CURLOPT_POSTFIELDS,'email='.$renren_username.'&password='.$renren_password.'&autoLogin=true&origURL=http://www.renren.com/Home.do&domain=renren.com');
curl_setopt($ch,CURLOPT_RETURNTRANSFER,TRUE);
curl_exec($ch);
curl_close($ch);
 
$renren_status = 'http://status.renren.com/doing/update.do';
foreach($post_arr as $item){
    $post = 'c='.urlencode($item).'&raw='.urlencode($item).'&isAtHome=0';
 
    $ch = curl_init($renren_status);
    curl_setopt($ch,CURLOPT_POST,TRUE);
    curl_setopt($ch,CURLOPT_POSTFIELDS,$post);
    curl_setopt($ch,CURLOPT_RETURNTRANSFER,TRUE);
    curl_setopt($ch,CURLOPT_COOKIEFILE,$cookie_file);
    curl_setopt($ch,CURLOPT_FOLLOWLOCATION,TRUE);
    curl_setopt($ch,CURLOPT_REFERER,'http://status.renren.com/ajaxproxy.htm');
    $ret = curl_exec($ch);
    curl_close($ch);
    $ret = json_decode($ret,TRUE);
    echo $ret['msg']."\n";
}
 
?>

自动获取sentense.me图片做为桌面背景

煎蛋看见这个sentense.me的,图片做得挺好看,遂萌发自动下载后随机替换桌面背景的想法。

稍微写一下正则就可以解决了。以下为代码。请确保系统装有wget、feh,并建立一个wallpapers目录作为存放图片的目录。另外其中的1280×800是适合我屏幕的分辨率,你可以根据你自己屏幕分辨率更改:

#!/bin/sh
 
wget http://sentense.me/  -O - -q |\
sed -n 's/.*"\([^"]*1280x800[^"]*\.png\)".*/http:\/\/sentense.me\1/p'|\
wget -i - -P wallpapers -nc -q 
cd wallpapers
set -- *
length=$#
random_num=$(( $RANDOM % ($length + 1) ))
#echo ${!random_num}
DISPLAY=:0.0 feh --bg-scale ${!random_num}

可以将这个脚本加入crontab,或者在系统每次登录时执行
其中随机取文件那部分是从网上找的sniplet…其实我没看懂…

广告:请关注我的VPN服务~http://yegle.net/openvpn/

使用proxychains防止DNS缓存污染

今天看见@kevinxue在twitter上问,某socks代理,能在浏览器里使用,不能与proxychains搭配使用,我第一反应就猜到是proxyresolv这个脚本里设置的DNS服务器的问题。默认在proxychains.conf里设置了proxy_dns,proxychains会自动调用proxyresolv这个脚本来进行DNS解析。
打开这个proxyresolv就可以知道,其实只是用socks代理服务器,让dig这个命令到特定的DNS上查询而已。其实可以写一个更加简单的脚本,配合一个PHP脚本进行DNS解析。至少在我测试看来,比dig的效率更高。

修改后的proxyresolv:

#!/bin/sh
# This script is called by proxychains to resolve DNS names
 
if [ $# = 0 ] ; then
    echo "  usage:"
    echo "      proxyresolv hostname "
    exit
fi
 
export LD_PRELOAD=""
wget -q http://example.com/dnsquery.php?url=$1 -O -

其中dnsquery.php的内容:

< ?php if(isset($_GET['url'])){
         $url=$_GET['url'];
         $arr=dns_get_record($url,DNS_AAAA);
         if(!empty($arr)){
                 foreach($arr as $item){
                         echo $item['ipv6']."\n";
                 }
         }
         $arr=dns_get_record($url,DNS_A);
         if(!empty($arr)){
                 foreach($arr as $item){
                         echo $item['ip']."\n";
                 }
         }
 }
 ?>

这样通过http请求进行DNS query,就不怕墙在中途进行DNS缓存污染了。
正常的HTTP请求可能会遇到解析敏感词被暂时RST,解决方法也很简单,在proxyresolv里对请求的URL进行加密,dnsquery.php相应进行解密。至于具体的加密解密方法就很随意了,避过关键词即可

现在遇到的问题是:proxychains必须在proxychains.conf里设置一个有效的代理地址,如果代理地址无效,不会自动fallback到直接连接,所以这个防止DNS缓存下毒的方法实用性不是很大,仅仅是一个比原来proxyresolv脚本更快的方法而已…