使用Python模拟登录QQ邮箱获取QQ好友列表

2010年7月14日 没有评论

      最近因开发项目的需要,有一个需求,就是很多SNS网站都有的通过Email地址导入好友列表,不过这次要导入的不是Email列表,而是QQ的好友列表。
      实现方式:
      通过google一搜,实现的方式大概有下面这篇文章提到的几种方法:
最后我选择了通过模拟登录QQ邮箱的方式来实现,该实现方式在海内网上的好友查找功能也可以看到。
      QQ邮箱的官方登陆地址是与其他大部分邮箱不同的是,如果使用纯数字的QQ号登录的话,除了密码,还需要输入验证码。
      看到海内上的QQ好友导入功能也是需要输入验证码的,而且验证码的样子和QQ邮箱的很像。由于这是需要在用户手动输入密码的情况下才能实现的功能,因此输入验证码的工作也可以让用户手动来完成。
      验证码处理:
        通过对页面的分析,QQ邮箱的验证码方式实现原理其实是很简单,当需要一张验证码图片或看不清而需要换一张时,它都是向地址发出请求,(页面上该地址是通过js生成的,为了防止浏览器缓存,地址末尾还会带有随机一个随机数),而该链接不但返回一张图片,还在http头部带有设置cookie的一段header。这样当用户提交表单的时候,浏览器就会把该cookie发送回服务器,服务器通过比较该cookie值和经过某种运算后的表单中的验证码值就可以判断验证码是否填写正确。
        现在的问题是由于cookie的安全机制,验证码图片不能直接从腾讯的服务器上去取,那样用户在将QQ和密码发送到我们的服务器时,验证码的cookie不会一起发过来。
      解决方式其实也很简单,将验证码的获取地址改为我们自己的服务器,我们的服务器作为简单的代理,从腾讯的服务器上去获取真正的验证码,再将图片内容和那段cookie发送回用户浏览器。那样用户提交表单的时候,那段cookie就又会发送回我们的服务器了。
      绕过其他验证安全机制:
      一般上有了账号,密码,验证码这3样东西就可以实现模拟登录很多网站了,但是QQ邮箱还有其他的安全机制,在QQ邮箱登陆的表单中还有一个像这样input type="hidden"name="ts"value="1234672721"/的hidden域,该value每次刷新页面都会改变,同时在表单提交的时候,还会通过js将该值与其他hidden域的值进行某些计算才正式提交表单。
      通过多次模拟登录,估计该值是用来判断登录session超时的,同时也参与其他的一些干扰加密的计算。而且该值与验证码是完全无关的,因此在显示我们表单时,只要先去抓取一下页面,从里面提取出ts值,连同其他所有hidden域和相关计算的js代码放入我们的表单中就可以了。
        因此,实际上我们的表单只需要稍微修改一下页面的内容就可以作为显示给用户的表单。主要包括以下几个方面,这里我使用的django,所以使用django的模板语法:
1、input type="hidden"name="ts"value="1234672721"/改为input type="hidden"name="ts"value="{{ts}}"/
2、表单的action地址改为我们自己这里假设为/friends/因此
form name="form1"method="post"action="onSubmit="return checkInput();"
改为
form name="form1"method="post"action="/friends/"onSubmit="return checkInput();"
3、图片验证码地址,有两个地方要改:
document.write("img id=’vfcode’src=’style=’cursor:pointer;border:1px solid#e4eef9’onclick=’changeimg()’");
改为
document.write("img id=’vfcode’src=’/qq-captcha/?aid=23000101&",Math.random(),"’style=’cursor:pointer;border:1px solid#e4eef9’onclick=’changeimg()’");
      另外一个changeimg函数内,也将相应的地址改为我们自己的服务器即可。
      改了这些,页面看上去和原来几乎一样,只是所有交互都改到了我们的服务器上,出于版权和页面统一的需要,在使用到自己的网站上时,可以使用自己设计的页面,只要表单的初始化和提交与原来一样就可以了,甚至也可以通过阅读js部分的源代码,把ts部分的计算移到服务器端进行。
示例代码:
      以下是整个views.py的代码,包括后面会讲到模拟登录部分,login和qq_captcha分别用来初始化登陆页和获取图片验证码:
      拟登录部分都在view qq_friends里面进行,基本上就像前面说得,获取图片验证码的cookie,将表单提交的值原样发送post到腾讯的服务器,如果都正确的话就可以登录了。
        发送的结果大概分为3种,验证码错误,账号或密码错误,登陆成功。不管在哪种情况下,腾讯的服务器都是返回一段js代码,通过那段代码重定向到错误页或邮箱登陆后的首页。
其中验证码错误像是下面这样:
script var urlHead="var targetUrl="";var mailto="";targetUrl=urlHead+"loginpage?"+"errtype=2"+"&verify=true"+"&clientuin=12345678"+"&t="+"&alias="+"&regalias="+"&delegate_url="+"&title="+"&url=%2Fcgi-bin%2Flogin%3Fsid%3D0%2C2%2Czh_CN"+"&org_fun="+"&aliastype=@qq.com"+"&ss="+"&from="+"&autologin=n"if(targetUrl==""){targetUrl="";}document.write("META http-equiv=Refresh content=\’0;url=\""+targetUrl+"\"\’/");/script script type="text/j***ascript"location.href=targetUrl/script
账号或密码错误是这样:
script var urlHead="var targetUrl="";var mailto="";targetUrl=urlHead+"loginpage?"+"errtype=1"+"&verify=false"+"&clientuin=1725*** 012"+"&t="+"&alias="+"&regalias="+"&delegate_url="+"&title="+"&url=%2Fcgi-bin%2Flogin%3Fsid%3D0%2C2%2Czh_CN"+"&org_fun="+"&aliastype=@qq.com"+"&ss="+"&from="+"&autologin=n"if(targetUrl==""){targetUrl="";}document.write("META http-equiv=Refresh content=\’0;url=\""+targetUrl+"\"\’/");/script script type="text/j***ascript"location.href=targetUrl/script
登录成功是这样:
script var urlHead="var targetUrl="";var mailto="";targetUrl=urlHead+"frame_html?sid=UJh1e2XMWhOEbWcu";if(targetUrl==""){targetUrl="";}document.write("META http-equiv=Refresh content=\’0;url=\""+targetUrl+"\"\’/");/script script type="text/j***ascript"location.href=targetUrl/script
其中登录成功后的反馈不但是上面的js代码,还包括一大堆cookie,与邮箱服务器的后续交互都需要用到这些cookie。
      另外上面js代码中frame_html?sid=UJh1e2XMWhOEbWcu的sid部分需要多次用到在后面抓取好友列表页面的url中,所以也需要提取出来。
登录邮箱后,就可以抓取好友列表了,可以通过先访问页面
该页面的ul class="grouplist"/ul部分可以获取好友分组名称和相应的url地址。
然后在相应的访问各个好友分组的页面的就可以获取好友列表了。
      这里由于我自己的QQ号限制,不知道如果没有好友没有分组页面会是什么情况,以及如果某个分组的好友很多的话,该好友列表页面是否会有分页(目前是没有见到分页)。有什么错误的话可以留言给我。
其他说明:
1、由于有些QQ用户给自己取火星文昵称,导致抓取的页面上很容易出现字符编码错误及HTML转义问题。
2、不知道是故意为了防止抓取还是设计不规范,好多页面用BeautifulSoup直接实例化,会导致大量信息的丢失,所以上面的代码都是尽可能先用正则表达式提取必须部分的信息。
3、由于QQ邮箱服务器的代码也在升级(事实上,我前几天刚写的代码就刚失效了,马上做了一些修改,昨天海内上的那个功能也出现了问题,看来他们也是通过QQ邮箱方式来实现的),所以并不能保证你在看到本文章时,上面的代码依然使用有效。但是总体上的思路依然可以提供参考。

分类: 其他 标签:

MySQL时间函数用法代码举例

2010年7月1日 没有评论

      今天同事临时提出一个小需求,因为后台不是很完善,这样功能只能到数据库里面直接运行SQL语句了,发现几个函数还是挺好用的。。。

       select count(*) from user where create_time >= UNIX_TIMESTAMP(‘2010-05-13’) and create_time <= UNIX_TIMESTAMP(‘2010-07-01’);

对于每个类型拥有的值范围以及并且指定日期何时间值的有效格式的描述见7.3.6 日期和时间类型。

这里是一个使用日期函数的例子。下面的查询选择了所有记录,其date_col的值是在最后30天以内:

mysql> SELECT something FROM table
WHERE TO_DAYS(NOW()) – TO_DAYS(date_col) <= 30;

DAYOFWEEK(date)
返回日期date的星期索引(1=星期天,2=星期一, ……7=星期六)。这些索引值对应于ODBC标准。
mysql> select DAYOFWEEK(‘1998-02-03’);
-> 3

WEEKDAY(date)
返回date的星期索引(0=星期一,1=星期二, ……6= 星期天)。
mysql> select WEEKDAY(‘1997-10-04 22:23:00’);
-> 5
mysql> select WEEKDAY(‘1997-11-05’);
-> 2

DAYOFMONTH(date)
返回date的月份中日期,在1到31范围内。
mysql> select DAYOFMONTH(‘1998-02-03’);
-> 3

DAYOFYEAR(date)
返回date在一年中的日数, 在1到366范围内。
mysql> select DAYOFYEAR(‘1998-02-03’);
-> 34

MONTH(date)
返回date的月份,范围1到12。
mysql> select MONTH(‘1998-02-03’);
-> 2

DAYNAME(date)
返回date的星期名字。
mysql> select DAYNAME("1998-02-05");
-> ‘Thursday’

MONTHNAME(date)
返回date的月份名字。
mysql> select MONTHNAME("1998-02-05");
-> ‘February’

QUARTER(date)
返回date一年中的季度,范围1到4。
mysql> select QUARTER(’98-04-01′);
-> 2

WEEK(date)
 
WEEK(date,first)
对于星期天是一周的第一天的地方,有一个单个参数,返回date的周数,范围在0到52。2个参数形式WEEK()允许你指定星期是否开始于星期天或星期一。如果第二个参数是0,星期从星期天开始,如果第二个参数是1,从星期一开始。
mysql> select WEEK(‘1998-02-20’);
-> 7
mysql> select WEEK(‘1998-02-20’,0);
-> 7
mysql> select WEEK(‘1998-02-20’,1);
-> 8

YEAR(date)
返回date的年份,范围在1000到9999。
mysql> select YEAR(’98-02-03′);
-> 1998

HOUR(time)
返回time的小时,范围是0到23。
mysql> select HOUR(’10:05:03′);
-> 10

MINUTE(time)
返回time的分钟,范围是0到59。
mysql> select MINUTE(’98-02-03 10:05:03′);
-> 5

SECOND(time)
回来time的秒数,范围是0到59。
mysql> select SECOND(’10:05:03′);
-> 3

PERIOD_ADD(P,N)
增加N个月到阶段P(以格式YYMM或YYYYMM)。以格式YYYYMM返回值。注意阶段参数P不是日期值。
mysql> select PERIOD_ADD(9801,2);
-> 199803

PERIOD_DIFF(P1,P2)
返回在时期P1和P2之间月数,P1和P2应该以格式YYMM或YYYYMM。注意,时期参数P1和P2不是日期值。
mysql> select PERIOD_DIFF(9802,199703);
-> 11

DATE_ADD(date,INTERVAL expr type)
 
DATE_SUB(date,INTERVAL expr type)
 
ADDDATE(date,INTERVAL expr type)
 
SUBDATE(date,INTERVAL expr type)
这些功能执行日期运算。对于MySQL 3.22,他们是新的。ADDDATE()和SUBDATE()是DATE_ADD()和DATE_SUB()的同义词。
在MySQL 3.23中,你可以使用+和-而不是DATE_ADD()和DATE_SUB()。(见例子)date是一个指定开始日期的
DATETIME或DATE值,expr是指定加到开始日期或从开始日期减去的间隔值一个表达式,expr是一个字符串;它可以以
一个“-”开始表示负间隔。type是一个关键词,指明表达式应该如何被解释。EXTRACT(type FROM date)函数从日期
中返回“type”间隔。下表显示了type和expr参数怎样被关联: type值 含义 期望的expr格式
SECOND 秒 SECONDS
MINUTE 分钟 MINUTES
HOUR 时间 HOURS
DAY 天 DAYS
MONTH 月 MONTHS
YEAR 年 YEARS
MINUTE_SECOND 分钟和秒 "MINUTES:SECONDS"
HOUR_MINUTE 小时和分钟 "HOURS:MINUTES"
DAY_HOUR 天和小时 "DAYS HOURS"
YEAR_MONTH 年和月 "YEARS-MONTHS"
HOUR_SECOND 小时, 分钟, "HOURS:MINUTES:SECONDS"
DAY_MINUTE 天, 小时, 分钟 "DAYS HOURS:MINUTES"
DAY_SECOND 天, 小时, 分钟, 秒 "DAYS HOURS:MINUTES:SECONDS"

MySQL在expr格式中允许任何标点分隔符。表示显示的是建议的分隔符。如果date参数是一个DATE值并且你的计算仅仅包含YEAR、MONTH 和DAY部分(即,没有时间部分),结果是一个DATE值。否则结果是一个DATETIME值。

mysql> SELECT "1997-12-31 23:59:59" + INTERVAL 1 SECOND;
-> 1998-01-01 00:00:00
mysql> SELECT INTERVAL 1 DAY + "1997-12-31";
-> 1998-01-01
mysql> SELECT "1998-01-01" – INTERVAL 1 SECOND;
-> 1997-12-31 23:59:59
mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
INTERVAL 1 SECOND);
-> 1998-01-01 00:00:00
mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
INTERVAL 1 DAY);
-> 1998-01-01 23:59:59
mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
INTERVAL "1:1" MINUTE_SECOND);
-> 1998-01-01 00:01:00
mysql> SELECT DATE_SUB("1998-01-01 00:00:00",
INTERVAL "1 1:1:1" DAY_SECOND);
-> 1997-12-30 22:58:59
mysql> SELECT DATE_ADD("1998-01-01 00:00:00",
INTERVAL "-1 10" DAY_HOUR);
-> 1997-12-30 14:00:00
mysql> SELECT DATE_SUB("1998-01-02", INTERVAL 31 DAY);
-> 1997-12-02
mysql> SELECT EXTRACT(YEAR FROM "1999-07-02");
-> 1999
mysql> SELECT EXTRACT(YEAR_MONTH FROM "1999-07-02 01:02:03");
-> 199907
mysql> SELECT EXTRACT(DAY_MINUTE FROM "1999-07-02 01:02:03");
-> 20102

如果你指定太短的间隔值(不包括type关键词期望的间隔部分),MySQL假设你省掉了间隔值的最左面部分。例如,如果你指定一个type是 DAY_SECOND,值expr被希望有天、小时、分钟和秒部分。如果你象"1:10"这样指定值,MySQL假设日子和小时部分是丢失的并且值代表分钟和秒。换句话说,"1:10" DAY_SECOND以它等价于"1:10" MINUTE_SECOND的方式解释,这对那MySQL解释TIME值表示经过的时间而非作为一天的时间的方式有二义性。如果你使用确实不正确的日期,结果是NULL。如果你增加MONTH、YEAR_MONTH或YEAR并且结果日期大于新月份的最大值天数,日子在新月用最大的天调整。

mysql> select DATE_ADD(‘1998-01-30’, Interval 1 month);
-> 1998-02-28

注意,从前面的例子中词INTERVAL和type关键词不是区分大小写的。

TO_DAYS(date)
给出一个日期date,返回一个天数(从0年的天数)。
mysql> select TO_DAYS(950501);
-> 728779
mysql> select TO_DAYS(‘1997-10-07’);
-> 729669

TO_DAYS()
不打算用于使用格列高里历(1582)出现前的值。

FROM_DAYS(N)
给出一个天数N,返回一个DATE值。
mysql> select FROM_DAYS(729669);
-> ‘1997-10-07’

DATE_FORMAT(date,format)
根据format字符串格式化date值。下列修饰符可以被用在format字符串中: %M 月名字(January……December)
%W 星期名字(Sunday……Saturday)
%D 有英语前缀的月份的日期(1st, 2nd, 3rd, 等等。)
%Y 年, 数字, 4 位
%y 年, 数字, 2 位
%a 缩写的星期名字(Sun……Sat)
%d 月份中的天数, 数字(00……31)
%e 月份中的天数, 数字(0……31)
%m 月, 数字(01……12)
%c 月, 数字(1……12)
%b 缩写的月份名字(Jan……Dec)
%j 一年中的天数(001……366)
%H 小时(00……23)
%k 小时(0……23)
%h 小时(01……12)
%I 小时(01……12)
%l 小时(1……12)
%i 分钟, 数字(00……59)
%r 时间,12 小时(hh:mm:ss [AP]M)
%T 时间,24 小时(hh:mm:ss)
%S 秒(00……59)
%s 秒(00……59)
%p AM或PM
%w 一个星期中的天数(0=Sunday ……6=Saturday )
%U 星期(0……52), 这里星期天是星期的第一天
%u 星期(0……52), 这里星期一是星期的第一天
%% 一个文字“%”。

所有的其他字符不做解释被复制到结果中。

mysql> select DATE_FORMAT(‘1997-10-04 22:23:00’, ‘%W %M %Y’);
-> ‘Saturday October 1997’
mysql> select DATE_FORMAT(‘1997-10-04 22:23:00’, ‘%H:%i:%s’);
-> ’22:23:00′
mysql> select DATE_FORMAT(‘1997-10-04 22:23:00’,
‘%D %y %a %d %m %b %j’);
-> ‘4th 97 Sat 04 10 Oct 277’
mysql> select DATE_FORMAT(‘1997-10-04 22:23:00’,
‘%H %k %I %r %T %S %w’);
-> ’22 22 10 10:23:00 PM 22:23:00 00 6′
MySQL3.23中,在格式修饰符字符前需要%。在MySQL更早的版本中,%是可选的。

TIME_FORMAT(time,format)
这象上面的DATE_FORMAT()函数一样使用,但是format字符串只能包含处理小时、分钟和秒的那些格式修饰符。其他修饰符产生一个NULL值或0。

CURDATE()
 
CURRENT_DATE
以’YYYY-MM-DD’或YYYYMMDD格式返回今天日期值,取决于函数是在一个字符串还是数字上下文被使用。
mysql> select CURDATE();
-> ‘1997-12-15’
mysql> select CURDATE() + 0;
-> 19971215

CURTIME()
 
CURRENT_TIME
以’HH:MM:SS’或HHMMSS格式返回当前时间值,取决于函数是在一个字符串还是在数字的上下文被使用。
mysql> select CURTIME();
-> ’23:50:26′
mysql> select CURTIME() + 0;
-> 235026

NOW()
 
SYSDATE()
 
CURRENT_TIMESTAMP
以’YYYY-MM-DD HH:MM:SS’或YYYYMMDDHHMMSS格式返回当前的日期和时间,取决于函数是在一个字符串还是在数字的上下文被使用。
mysql> select NOW();
-> ‘1997-12-15 23:50:26’
mysql> select NOW() + 0;
-> 19971215235026

UNIX_TIMESTAMP()
 
UNIX_TIMESTAMP(date)
如果没有参数调用,返回一个Unix时间戳记(从’1970-01-01 00:00:00’GMT开始的秒数)。如果UNIX_TIMESTAMP()用一个date参数被调用,它返回从’1970-01-01 00:00:00′ GMT开始的秒数值。date可以是一个DATE字符串、一个DATETIME字符串、一个TIMESTAMP或以YYMMDD或YYYYMMDD格式的本地时间的一个数字。
mysql> select UNIX_TIMESTAMP();
-> 882226357
mysql> select UNIX_TIMESTAMP(‘1997-10-04 22:23:00’);
-> 875996580
当UNIX_TIMESTAMP被用于一个TIMESTAMP列,函数将直接接受值,没有隐含的“string-to-unix-timestamp”变换。

FROM_UNIXTIME(unix_timestamp)
以’YYYY-MM-DD HH:MM:SS’或YYYYMMDDHHMMSS格式返回unix_timestamp参数所表示的值,取决于函数是在一个字符串还是或数字上下文中被使用。
mysql> select FROM_UNIXTIME(875996580);
-> ‘1997-10-04 22:23:00’
mysql> select FROM_UNIXTIME(875996580) + 0;
-> 19971004222300

FROM_UNIXTIME(unix_timestamp,format)
返回表示 Unix 时间标记的一个字符串,根据format字符串格式化。format可以包含与DATE_FORMAT()函数列出的条目同样的修饰符。
mysql> select FROM_UNIXTIME(UNIX_TIMESTAMP(),
‘%Y %D %M %h:%i:%s %x’);
-> ‘1997 23rd December 03:43:30 x’

SEC_TO_TIME(seconds)
返回seconds参数,变换成小时、分钟和秒,值以’HH:MM:SS’或HHMMSS格式化,取决于函数是在一个字符串还是在数字上下文中被使用。
mysql> select SEC_TO_TIME(2378);
-> ’00:39:38′
mysql> select SEC_TO_TIME(2378) + 0;
-> 3938

TIME_TO_SEC(time)
返回time参数,转换成秒。
mysql> select TIME_TO_SEC(’22:23:00′);
-> 80580
mysql> select TIME_TO_SEC(’00:39:38′);
-> 2378

分类: MySQL 标签:

国内SNS平台 开放的API

2010年6月24日 1 条评论

       国外的Facebook开放API已经很久了,Facebook之所以很风靡,多半归功于F8平台。简单地说,F8就是Facebook和第三方应用中间的桥梁,用户可以在不离开Facebook的情况下,使用第三方网站的功能。比如说,现在Facebook的用户可以看 到自己的好友在看什么书、听什么歌等,而这一切都不用Facebook自己来开发。

今天发现校内网的APP开放平台可以用了,也就是说每个像我一样的大学生每天都必登的校 内网开始正式开放了API。校内网(xiaonei.com)成立于2005年12月,是中国最早的校园SNS社区。2006年10月,千橡公司收购校内 网,同年底,完成了千橡公司 5Q校园网与校内网的合并,并正式命名为校内网,域名为:http://www.xiaonei.com。 校内网成为中国大学生市场具有垄断地位的校园网站,每天活跃人数众多。现在校内网正式开放了API,又一次走在了所有中国SNS的前列!

校 内网已经敞开大门,欢迎所有对校内网平台感兴趣的第三方公司与应用开发爱好者个人前来参加。有兴趣的开发应用同学可以加入校内网上的以下2个群:校内 API开放论坛以及xCube。新入门的同学需要首先添加"开发者"这个APP应用。然后你的页面左边便会多出个”开发者"的应用:具体信息详见校内网开 发中心,或校内目前开放的API的文档。

如果说,校内网是靠模仿Facebook起家的话,那么现在才是真正走出了一条自己的路。随着应 用数量的逐渐增加,我想校内网会不断做出自己的特色。千橡CEO陈一舟称,“API平台也将给用户带来无穷的网络乐趣,有效增加用户粘着度。我们欢迎更多 第三方公司加入到校内网的开放平台中来,实现创业梦想、实现共赢。”  

2008年上半年,中国互联网的发展有几件事值得关注:一、视频 行业的牌照问题;二、各大主要互联网公司相续推出开放平台;三、口啤与炒作的融合性。Facebook应该说是开放平台的先行者了,Facebook的成 功就是得益于开放平台及API应用。对于已经在中国推出中文的Facebook,我们不应该把它给忘记。网址:http://developers.facebook.com/

国内几个已经推出相关开放平台的公司及产品:

1、搜狐博客・开放平台
以博客作为个人应用平台,由开发者及搜狐 爱好者开发相关博客应用小程序;由搜狐推出相关文档说明及参数。
网址:http://ow.blog.sohu.com/

2、谷歌 OpenSocial
通用 API 意味着,您仅需较少的学习,便可为多个网站进行构建。目前,OpenSocial由网络社区的广大成员联合开发。最终目标是,对于所有社交网站都能够执行 API并托管第三方社交应用程序。许多网站在执行OpenSocial,包括Engage.com、Friendster、hi5、Hyves、imeem、 LinkedIn、MySpace、Ning、Oracle、 orkut、Plaxo、Salesforce.com、SixApart、Tianji、Viadeo 和 XING、天涯。
网址:http://code.google.com/apis/opensocial/

3、淘宝开放 平台
淘宝开放平台项目(TOP: taobao open platform)是淘宝(中国)软件公司面向3rdapp开发者,提供API接口和相关开发环境的平台。包括:
API接口规范和定义及其规范
API sandbox 在线开发测试环境
网 址:http://www.taobao.com/theme/tao_source/

4、天涯开放 平台
由Google Opensocial提供技术服务的天涯开放平台,主要整合商家;如:7天酒店。
网址:http://my.tianya.cn

5、 校内网开放平台

校内网将于7月8日正式启动校内开放平台插件功能大赛。现邀请三方公司及个人开发爱好者一起加入校内开放平台插件开发,共同探索平 台开放之路。
网址:http://www.xiaonei.com/developerIndex.jsp

6、 聚友(Myspace)开放平台
MySpace聚友开发者平台(MySpace Developer Platform简称MDP)是一个面向开发者的开放平台,开发者可以在上面开发并且发布符合OpenSocial规范的应用程序,比如Widget、Gadget。
网 址:http://developer.myspace.cn/community/

7、 51.com开放平台

51开放平台API是采用REST基础的接口规范。所有的51开放平台API都是通过HTTP的GET或者POST请求来实 现调用的。有了这些API,你就可以通过你的应用程序获得51.com社交网络的用户资料、好友关系、照片等几乎所有可开放的数据。
网址:http://sandbox.developers.51.com/index.php

8、康 盛uchome “我的空间”
UCenterHome使用网站的开放平台应用开发标准(API),Manyou将有机会帮助您与数万网站之间建立合作的纽带,为这些网站上的网民提供个性化的互联网应 用。
网址:http://uchome.developer.manyou.com/uchome/

9、 雅虎开发者社区
NCP是中国雅虎针对站长天下等产品推出的开放式的web应用/模块开发平台。
开发者可以在该平台开发基于Web的模块, 即NCP扩展应用。
网址:http://dev.cn.yahoo.com/

10、豆瓣API

豆瓣API是豆瓣为 第三方开发人员提供的编程接口。利用豆瓣API,你可以在你的网站或程序中使用豆瓣的数据和功能。

11、新浪魔方
新浪魔方通过组 件化的功能组合,灵活方便地满足不同用户的个性需求
网址:http://mofun.sina.com.cn/

一项新技 术的发展,需要更多的参与者,而不是服务的提供者。以免出现,供大于求的局面;反尔会把这些新的应用推向无价值的边缘。“开放”是目前整个互联网都关注的 一个发展趋势,“开放”不仅意谓着“分享”,更将意谓着“共赢”。

分类: 其他 标签:

VSFtp虚拟账号配置与维护

2010年6月8日 没有评论

安装vsftp时没有db_load这个命令
该命令需要 db4-utils 的包
正常情况下,执行

即可安装
其它服务器上,则要到安装光盘上找,或者去网上下载

  为vsftp建立虚拟用户

在RedHat AS里,是自带了vsftpd为系统提供了一个ftp服务,但在实际应用中根据自己的需要还是要做不少的配置。
  我们知道,在建立vsftpd用户时,我们一般是在linux下建立用户useradd的方式来访问ftp,但有时我们只想提供ftp服务,而避免用户用ftp的帐号去登录linux,采用一般的方式只能是限制该用户的访问权限,但还是避免不了用户登录进linux系统,所以比较好的方法是用vsftpd的虚拟用户(virtual users)。
配置的步骤如下
  1) Create the virtual users database.(建立虚拟用户数据库)
  大家看一下logins.txt文件的格式,它的内容是:
  tom
  foo
  fred
  bar
  意思是说用户tom的密码是foo,用户fred的密码是bar,这就是虚拟用户的信息,大家可以按
  <用户名>
  <密 码>
  的格式来建立自己的虚拟用户群。
  然后以root用户登录系统,建立用户数据库:
  db_load -T -t hash -f logins.txt /etc/vsftpd_login.db
  该命令会建立一个文件 /etc/vsftpd_login.db ,同时改变它的文件属性:
  chmod 600 /etc/vsftpd_login.db
  2) Create a PAM file which uses your new database.(建立PAM文件,告诉系统你要使用自己的数据库了)
  看看另一个文件vsftpd.pam,它有两行内容:
  auth required /lib/security/pam_userdb.so db=/etc/vsftpd_login
  account required /lib/security/pam_userdb.so db=/etc/vsftpd_login
  这是告诉系统,我将用新的用户授权库了。ok,把这个文件copy到/etc/pam.d/ftp:
  cp vsftpd.pam /etc/pam.d/ftp
  3) Set up the location of the files for the virtual users(为虚拟用户建立文件夹)
  useradd -d /home/ftpsite virtual
  ls -ld /home/ftpsite
  (会得到以下输出):
  drwx—— 3 virtual virtual 4096 Jul 30 00:39 /home/ftpsite
然后:
  cp /etc/hosts /home/ftpsite
  chown virtual.virtual /home/ftpsite/hosts
  4)修改vsftpd.conf文件
  文件在/etc/vsftpd/vsftpd.conf,在后面加上:
  anonymous_enable=NO
  local_enable=YES
  write_enable=NO (注:这里可按需求设置)
  anon_upload_enable=NO
  anon_mkdir_write_enable=NO
  anon_other_write_enable=NO
  chroot_local_user=YES
  guest_enable=YES
  guest_username=virtual
  user_config_dir=/etc/vsftpd_user_conf

  5)建立用户的权限
  先mkdir /etc/vsftpd_user_conf
  //开放tom和fred的读权限
  #echo "anon_world_readable_only=NO">/etc/vsftpd_user_conf/tom
  #echo "anon_world_readable_only=NO">/etc/vsftpd_user_conf/fred
这样就可以用读权限了,能看到目录和文件。
  6)重启vsftpd
  service vsftpd restart
  ok,用tom用户登录ftp看看,是不是已经可以了

特别注意
1。如果要删除掉一个虚拟用户,先在logins.txt中删除用户对应的用户名和密码,然后删除vsftpd_login.db,重新运行db_load -T -t hash -f logins.txt /etc/vsftpd_login.db
2。如果只是要修改用户的密码,只需重新运行db_load就可以
3。如果要改变用户的其它配置,只需修改用户的配置文件

原文:http://tristan1.javaeye.com/blog/372377

引用
rpm -qa|grep db4

会有3个包

引用
db4-devel-4.3.29-9.fc6
db4-utils-4.3.29-9.fc6
db4-4.3.29-9.fc6

如果缺少,则安装相应的包,rpm安装即可

centos上可以通过

引用
yum install db4-utils
分类: Linux 标签:

mysql中GROUP BY结合GROUP_CONCAT的使用

2010年6月1日 没有评论

我们知道,group by可以将sql查询结果按照group by后面列进行分类显示。比如:

  1. select columnA,columnB from table group by columnA,columnB  

      则查询结果将按照columnA和columnB分类显示。没有显示在group by中的列不能直接作为返回列放在sql语句中,比如如下sql就是不正确的

  1. select columnA,columnC from table group by columnA  

     由于columnC不在group by的范围之类,所以这样写是不对的,所幸的是,group by支持一些sql 函数的使用,比如SUM,AVG,COUNT等等。这些都比较常用,今天我要记录下的是这个不常用的GROUP_CONCAT。

       有一个需求,需要用到group by 才能实现,可是,我同是还需要返回某列的所有结果,(注意,不是做avg,sum等操作,我要枚举这列的所有结果),那么就可以用到 GROUP_CONCAT。

举个例子:

我有一张数据库表结构如下:

列名 含义
year 年份
month 月份
volumn 期数

该表存储了某杂志的年份,月份和期数。如果需求对该表内容作如下显示:

2010年12月 第1期第2期第3期 第4期
2010年11月 第1期第2期第3期 第4期第5期
2010年10月 第1期第2期第3期 第4期
2010年9月 第1期第2期第3期 第4期第5期
2010年8月 第1期第2期第3期 第4期

sql该怎么写呢?按照年份和月份做group by?然后按照年份和月份做倒叙排列?

  1. select year,month from magazine group by year,month order by year desc,month desc  

   那具体的期数信息就丢了?能不能做group by的时候,还能返回在某个年份year和月份month分组下的所有期数volumn信息?(某个年份+月份下的期数信息是不固定的,只能通过数据库查询才能获得)

该是GROUP_CONCAT上阵的时候了。

  1. select year,month GROUP_CONCAT(volumn) from magazine group by year,month order by year desc, month desc  

这样,查询的返回结果类似于:

year month GROUP_CONCAT(volumn)
2010 12 1,2,3,4
2010 11 1,2,3,4,5

不错吧?

      还有点问题需要补充下,就是作为GROUP_CONCAT函数参数的字段,如过返回值为string,则上面的sql语句已经没有问题,但是如果是 number,则返回的GROUP_CONCAT(volumn)值为BLOB类型(其实上面例子返回的就是一个blob类型,我只是为了演示的方便),需要做一下转化。

  1. select year,month GROUP_CONCAT(conv( oct( volumn ) , 8, 10 )) from magazine group by year,month order by year desc, month desc  

      上面的sql对volumn做了一个从8进制到10进制的转换,这样返回的就是一个字符串了。

mysql默认会以‘,’来分隔多的值,如果想用其他的分隔符来分隔返回结果,比如期望返回值是这样的:1|2|3|4

这可以用SEPARATOR来搞定。

  1. select year,month GROUP_CONCAT(conv( oct( volumn ) , 8, 10 ) SEPARATOR ‘|’) from magazine group by year,month order by year desc, month desc   

更牛的是,你甚至可以对返回的volumn进行排序!!

  1. select year,month GROUP_CONCAT(conv( oct( volumn ) , 8, 10 ) order by volumn desc SEPARATOR ‘|’) from magazine group by year,month order by year desc, month desc  

这个不常用的东东,还是比较好用的。

引用:http://javeye.javaeye.com/blog/558093

分类: MySQL 标签:

WEB3D 技术

2010年5月31日 没有评论

        3D技术的魅力实在是太有诱惑力了,目前提供在线3D技术的因为带宽限制还不是很普及,不过目前市面上还是出现了部分3D技术实现产品,一些是通过3D引擎实现,还有部分是通过“伪”3D技术,比如像新浪乐居的3D看房,就是采用“鱼眼”技术进行图片拼接实现伪3D效果。

        以下是本人找到的一个3D实现效果,感觉成熟度还不错。


       在线演示地址:http://www.planedit.com/planedit_dark.php?casename=demo&level=0

  那么,什么是Wed3D?它是如何发展起来的?它的最新发展怎样?用于哪些应用?还存在哪些问题?下面我们一一道来。

  VRML——互联网3D图形的开放标准

  VRML是3D图形和多媒体技术通用交换的文件格式,它基于建模技术,描述交互式的3D对象和场景,不仅应用在互联网上,也可以用在本地客户系统中,应用范围极广。由于网上传输的是模型文件,故其传输量大大小于视频图像。VRML97使任何一个3D图形爱好者能制作可在互联网上实时渲染的3D场景模型。

  形形色色的互联网3D图形软件

  制作互联网3D图形的软件并没有完全遵循VRML97标准,许多公司推出了它们自己的制作工具,使用专用的文件格式和浏览器插件,类似的软件大约有三十几种之多。这些软件各有特色,都比VRML有了进步,在渲染速度,图像质量,造型技术,交互性以及数据的压缩与优化上有都胜过VRML之处。

  互联网3D图形的关键技术——实时渲染引擎

  实时渲染引擎的作用是解释并翻译实施场景模型文件的语法,实时渲染从服务器端传来的场景模型文件,在网页访问者的客户端逐帧、实时地显示3D图形。互联网3D图形软件厂商目前通常把实时渲染引擎做成一个插件,在观看前需要先下载并安装在IE浏览器上。显然,实时渲染引擎是实施互联网3D图形的关键技术,它的文件大小、图形渲染质量、渲染速度、以及它能提供的交互性都直接反映其解决方案的优劣。

  新一代互联网3D图形的标准——X3D

  X3D标准的发布,为互联网3D图形的发展提供了广阔的前景,无论是小型的具有3D功能的web客户端应用,还是高性能的广播级应用,X3D都应该是大家共同遵守的标准,从而结束当前互联网3D图形的这种混乱局面。在统一的X3D基本框架下保证不同软件厂家开发软件具有互操作性。

  三维建模与Wed3D图形的制作工具

  手工编写VRML的场景模型文件.wrl文件是非常繁琐而复杂的工作,对于大型场景模型几乎是不可能的。近几年,许多软件厂商都使用3DS max建立场景模型,安装相应的输出插件,再直接建立场景模型文件。现在最有名的Wed3D图形软件公司,如cult3D 和viwepoint都可以在3DS max中直接输出它们的专用文件格式的场景模型文件。

  JAVA在互联网上的3D图形的成功

  Java在互联网上几乎随处可见,而它在3D图形上正在显示出更大的威力。使用Java 的重要理由之一是它的平台无关性。因此,只要支持JVM,就能运行JAVA小程序。两种最有名的浏览器Netscape 和 IE 3都支持JVM(Java 1.0.2)。因此用Java制作的3D图形几乎都可以在互联网的浏览器上显示。

  互联网3D图形技术的应用

  当前,互联网上的图形仍以2D图像为主流,但是,3D图形必将在互联网上占有重要地位。互联网上的交互式3D图形技术Wed3D正在取得新的进展,正在脱离本地主机的3D图形,形成自己独立的框架。最具魅力的Wed3D图形将在互联网上有广泛应用,如电子商务、联机娱乐休闲与游戏、科技与工程的可视化、教育、医学、地理信息、虚拟社区

  Wed3D技术发展前景

  虽然,Wed3D技术将有好的发展前景,但仍然不可盲目乐观,它还面临着很多问题,如带宽、处理器速度等。现在的Wed3D图形是有几十种可供选择的技术和解决方案,多种文件格式和渲染引擎的存在是Wed3D图形在互联网上应用的最大障碍,而这种局面还将长时间存在。

VRML—互联网3D图形的开放标准

  VRML是3D图形和多媒体技术通用交换的文件格式,它描述交互式的3D对象和场景。它不仅应用在互联网上,也可以用在本地客户系统中。其应用范围极广:工程和科学可视化,多媒体,娱乐游戏,互联网3D图形,教育,虚拟社区等。在1996年发布VRML1.0。VRML97是最新的国际标准。VRML97的制定促进互联网上的3D图形技术的开发。由于网上传输的是模型文件,故其传输量大大小于视频图像。VRML97使任何一个3D图形爱好者能制作可在互联网上实时渲染的3D场景模型。VRML是基于建模技术的,它描述3D场景中的几何对象的尺寸和形状,色彩,材质,灯光,动画及其交互性。

  然而,在97年之后,VRML3D图形进展缓慢,远远没有达到期望值。究其原因主要有以下几点:

  1 互联网对3D图形的需求并不急切,到目前为止2D图像仍在HTML文件中站主导。
  2 网络带宽仍然是制约网上的3D图形主要瓶颈。
  3 VRML97过于庞大,它包罗万象:3D几何对象,色彩,材质,灯光,相机,动画以及提供交互性的传感器等等。
  4 网站的访问者必须先花费10-15分钟的时间下载插件,然后再像安装软件那样安装这个插件,才能观看一个十分粗糙3D图形。

  图1用VRML制作的法国虚拟巴黎3D场景(可用鼠标实时3D漫游)

形形色色的互联网3D图形软件

  国际上有一个VRML(VRML Consortium)协会,这是一个非赢利组织,主要任务是制定互联网上的3D图形标准与规范。VRML97发布后, 互联网上的3D图形几乎都使用VRML 。VRML协会没有及时推出VRML97的下一代标准。

  最近几年内互联网又有了长足的进展,互联网对图形、图像、视频技术的发展显然有了新的需求,特别是电子商务。互联网上的竞争十分激烈,只要有需求,有利润,就会推进新技术。制作互联网3D图形的软件并没有完全遵循VRML97标准,许多公司推出了它们自己的制作工具,使用专用的文件格式和浏览器插件,类似的软件大约有三十几种之多。这些软件各有特色,都比VRML有了进步,在渲染速度,图像质量,造型技术,交互性以及数据的压缩与优化上有都胜过VRML之处。它们显然都瞄准了电子商务,为网上的电子商品或电子商场提供3D展示。

  这里我们举出一些软件的英文简称:Cult3D,Viewpoint,GL4Java,Flatland,Fluid3D,Janet3D,Java3D,Pulse3D,Shout3D,Sumea,Superscape,Vecta3D,blaxunn3D ,OpenWorlds。所有的公司都希望自己的解决方案能成为"事实上的国际标准"。

  图2 Wed3D的商品展示(商品可用鼠标作3D旋转和细部观看)

  现在的问题是:要在互联网上观看它们的3D图形,先要下载1MB-7MB的插件,然后安装在网页浏览器上(如IE)。这是一件十分烦人的事,插件的种类之多,使人无所适从。要观看十个不同网站,您就要下载并安装十个不同厂家的插件。

互联网3D图形的关键技术——实时渲染引擎

  这些插件就是实时渲染引擎,其作用是:解释并翻译实施场景模型文件的语法,实时渲染从服务器端传来的场景模型文件,在网页访问者的客户端逐帧、实时地显示3D图形。把实时渲染引擎做成一个插件,在观看前先要下载并安装在IE浏览器上,这是互联网3D图形软件厂商目前的通常做法。显然,实时渲染引擎是实施互联网3D图形的关键技术,它的文件大小、图形渲染质量、渲染速度、以及它能提供的交互性都直接反映其解决方案的优劣。

  文件的大小:目前大多数1MB左右,如微软的VRML渲染引擎是1.2M、blaxxun公司的Contact是4.2M、而最小的基于JAVA技术的只有58k。当然,渲染引擎越大,渲染的图像质量就越好,功能就越强大。但下载一个4.2M的插件才能在网上观看3D图形,在目前的网络速度下,仍然是不现实的。

  图形渲染质量: 目前图形质量较好的渲染引擎应该属于cult3D和viewpoint ( 它们的文件尺寸分别是1.4M 和7.9M ) ,使用专用的文件格式。即有较好的图形质量而下载文件尺寸也不大的应该是Parallelgraphics公司的CortonaVRML(1.33M)。

  渲染速度: 支持openGL 或微软的Direct3D 是提高渲染速度和图形质量的关键,在这一点上互联网3D图形与本地3D图形没有区别。

  交互性:交互性是互联网3D图形的最大特色,只有实时渲染才能提供这种交互性,本地3D图形的预渲染不能提供这种至关重要的灵活性。交互性是指3D图形的观看者控制和操纵虚拟场景及其中3D对象的能力,比如:你可以随时改变在虚拟场景中漫游的方向和速度,你可以打开虚拟场景中的门等等。

  研制更好的实时渲染引擎是各软件厂商竞争的焦点,于是就产生了五花八门的3D图形文件格式与相应的浏览器插件。然而VRML毕竟是交互式3D图形开放式国际标准,仍然有很多软件提供对VRML的兼容性。

  结束这种混乱局面的最好办法是微软在它的IE浏览器中预装一个或几个实时渲染插件,以至于互联网3D图形的观看者不必花费10分钟的时间去下载插件。然而,微软并未选中任何一家公司作为其合作伙伴,也许在某一天微软会推出它自己的一整套解决方案,从而保持它在互联网3D图形领域中的霸权地位。

新一代互联网3D图形的标准——X3D

  VRML(VRML Consortium)协会在1997年将它的名字改为Wed3D(Web 3D Consortium)协会,并制定了VRML97新的国际标准。此后Wed3D这一专用缩写开始在互联网上出现。然而,1997年后的几年,该协会并没有什么大的动作。直到去年(2001年)8月Wed3D协会发布新一代国际标准—- X3D (X3D的含义是可扩展的 3D)。

  X3D是Wed3D协会(Wed3D Consortium)制定的下一代VRML97标准。X3D是在重要软件厂商的支持下提出的,如3Dlabs, ATI Technologies, Blaxxun, Nexternet, OpenWorlds, ParallelGraphics, Sony Electronics, US Army STRICOM, and SGDL Systems 。X3D与MPEG-4和 XML兼容。X3D将集成到MPEG-4的3D内容之中,使用XML语法。它与VRML 97向后兼容,即X3D能提供标准VRML 97 browser的全部功能。X3D的主要任务是把VRML的功能封装到一个轻型的,可扩展的核心之中。由于X3D是可扩展的,任何开发者可以根据自己需求,扩展其功能。X3D 渲染引擎的商业版本也在去年的SIGGRAPH 2001的年会上推出,ParallelGraphics(Wed3D技术的领先软件公司)将联合几个公司开发X3D 新技术。X3D标准的发布,为互联网3D图形的发展提供了广阔的前景,无论是小型的具有3D功能的web客户端应用,还是高性能的广播级应用,X3D都应该是大家共同遵守的标准,从而结束当前互联网3D图形的这种混乱局面。在统一的X3D基本框架下保证不同软件厂家开发软件具有互操作性。

  在SIGGRAPH 2002会议上Wed3D Consortium发布X3D最终工作草案。Wed3D Consortium希望Wed3D软件公司使用X3D规范开发相应的产品评估规范的可行性。Wed3D Consortium准备将该规范递交给国际标准化组织ISO。

三维建模与Wed3D图形的制作工具

  VRML是一种标记语言,任何文字编辑程序都可以编辑VRML的场景模型文件(其扩展名是.wrl)。手工书写.wrl文件是非常繁琐而复杂的工作,对于大型场景模型几乎是不可能的。为了制作Wed3D图形的场景模型文件必需使用传统的三维建模软件。近几年,许多软件厂商都把3Dmax作为三维建模与场景的制作工具。使用3Dmax建立场景模型,安装相应的输出插件,即可以直接建立场景模型文件。现在最有名的Wed3D图形软件公司,如cult3D 和viwepoint都可以在3Dmax中直接输出它们的专用文件格式的场景模型文件。如前述,每个公司都有自己的文件格式和相应的实时渲染插件,同样,也有它们自己的制作工具。

  Wed3D图形的制作工具及实用程序五花八门难以详述,但是它们的功能一般都包括:

  1 建立或编辑三维场景模型
  2 增加或改进Wed3D图形的图像质量
  3 增加Wed3D图形交互性
  4 压缩或优化场景模型文件的大小
  5 文件加密

  三维建模是Wed3D图形制作的关键,而所用的成本是比较高的,例如:如果您要制作一个较高质量的3D手表模型,专业人员要花费40小时建模,价值几万元。大型建筑场景则需要更多的工作量。为解决这个问题,近几年国外出现一种新的建模技术:照片建模技术。对建模对象实地拍摄两张以上的照片,根据透视学和摄影测量学原理,标志和定位对象上的关键控制点,建立三维网格模型。近年已有商品化软件推出,如Canoma,Photo3D,PhotoModeler,ImageModeler等。此类软件的技术要点如下:

  1 寻找和标识建模对象关键点:复杂曲面则需要数量较多的关键点。
  2 拍摄1—4张以上的照片:相机的位置不限,但关键点要拍摄清晰。
  3 把拍摄的照片输入到软件中,使用软件提供的手段定位关键点,构建三维网格模型。
  4 把照片上拍下的2D图像作为材质贴图贴在模型的表面
  5 把已建好的模型输出成相应的文件格式,如VRML

  MetaCreations公司的Canoma是比较早推出的软件,适用于由直线构成的建筑物。
  REALVIZ公司的ImageModeler(价格5000$)是第二代产品,可以制作复杂曲面物体。

  与大型3D扫描仪比较,这类软件有很大的优势:使用简单,节省人力,降低成本。ImageModeler已经被Cult3D用于建模工具。

  最近,3D studio max软件的制作厂家Discreet推出了一款直接面向Wed3D的制作软件—-Plasma,Discreet看到了Wed3D市场的巨大商机,凭借3D studio max的市场优势,相信: Plasma市场前景看好。

JAVA在互联网上的3D图形的成功

  Java在互联网上几乎随处可见,而它在3D图形上正在显示出更大的威力。使用Java 的重要理由之一是它的平台无关性。它的平台无关性来自于Java只需部分编译,负责编译Java程序的叫做Java Virtual Machine (JVM),不同的平台有它自己JVM,处理与平台相关的功能。因此,只要支持JVM,就能运行JAVA小程序。两种最有名的浏览器Netscape 和 IE 3都支持JVM(Java 1.0.2)。因此用Java制作的3D图形几乎都可以在互联网的浏览器上显示。

  令人遗憾的是:微软在它的未来极具发展前景的Window XP中不再预装JVM,由此引起的麻烦是巨大的:要运行基于JAVA的应用,就必须安装JVM,这显然比安装一个插件更麻烦。

  由于全世界有90%的人上网使用微软不要钱的浏览器IE,而Wed3D的渲染引擎插件又必须安装在IE上。面对Wed3D技术未来的发展潜力,软件巨人微软作何打算我们不得而知。

  Shout Interactive and Blaxxun两个公司使用纯Java技术开发了实时渲染引擎(大小只有50K),这个小小的JAVA小程序,不仅在网上自动下载,而且可以在客户端实时渲染3D场景,逐帧显示动态的3D图像。Shout Interactive and Blaxxun为用户扩充自己的3D图形功能预留了极大的空间。两个公司并没有抛弃VRML,Shout Interactive公司可以接受VRML文件,并把它变成自己的文件格式,Blaxxun公司的软件可以直接运行VRML。当然,Shout 3D的小巧灵活并不是没有代价的:它简化了VRML的功能,VRML的一些功能不能用小小50K的Java来实现。可以说这两个公司最先在它们的产品中实现了核心的X3D技术。

  使用这种"无插件技术"(plug-in)的Shout公司为Macy’s and Excite web portal网站制作了栩栩如生如生的3D虚拟时装模特展示,观看者用菜单可以选择:展示的服装,模特的肤色,发型,步型,甚至于灯光都可以用菜单即刻更换。观看者可以用鼠标变换视角,远近,从各个角度观看动态展示。而所有的展示文件只有1M-2M,不需下载插件。图像的质量较好,人物动画的动作流畅自然。

  图3 用shout3D 的java技术制作的3D服装展示

互联网3D图形技术的应用

  当前,互联网上的图形仍以2D图像为主流。但是,3D图形必将在互联网上占有重要地位。互联网上的交互式3D图形技术— Wed3D正在取得新的进展,正在脱离本地主机的3D图形,而形成自己独立的框架。互联网的需求是它发展的动力。互联网的内容提供商和商业网站不断使用新的工具与技术使网站更具吸引力,Wed3D图形是最新的和最具魅力的技术。Wed3D图形将在互联网上有广泛应用,从目前的趋势来看主要有:

  1 电子商务:用3D图形展示商品,更能吸引客户。虚拟商场是人们热中的话题。客户可以在虚拟商场中漫游,挑选商品。许多Wed3D图形技术的软件厂商是瞄准了电子商务的,如cult3D和viewpoint,其图形技术主要是用于商品的3D展示,您甚至于可以在网上操作或使用要购买的商品。然而,Wed3D图形的商业利益究竟有多大,网上的商品销售商只有在能增加销售额的情况下,才肯出资制作Wed3D图形。

  2 联机娱乐休闲与游戏:多用户联机3D游戏将搬上互联网,现在您已经可以在网上经历简单的赛车或空中射击游戏,下载文件不超过2M。当然,如果您想运行大的联机游戏仍然需要CD-ROM的支持。娱乐休闲网站对Wed3D图形有更多的需求,如:城市景观或风景点的虚拟旅游,虚拟博物馆,展览会,艺术画廊等等。

  3 科技与工程的可视化:科普,工程演示,城市建设,建筑装修。

  4 教育:学校,培训,军事训练,可视化仿真。

  5 医学:医疗培训,医疗商业的B2B和B2,许多医学图像的处理将使用Wed3D图形技术。

  6 地理信息系统的数据可视化:将GIS与Wed3D结合起来,可以在互联网上建立许多应用系统,如地图,导游,城市建设,交通运输等等。

  7 多用户虚拟社区(virtual-community):虚拟社区是建立一个大型的虚拟场景,每个虚拟场景的访问者都可以指定一个"替身", "替身"在场景中可以漫游。当几个远程访问者同时访问虚拟社区时,它们可以用语音或文字通讯。虚拟社区可以是一个会场,教室,俱乐部,展览会,画廊等。它真正实现了虚拟现实,在互联网上仿真虚拟社会的各种活动,分布在世界各地的人可以借助互联网开展各种文化科技,娱乐活动。而此时虚拟场景就是他们的三维环境。虚拟社区很可能是Wed3D图形在互联网上的一种主要应用形式。

  现在,已有几家公司推出了自己虚拟社区及全套的解决方案,如Blaxxun, Adobe Atmosphere. Geometrek ,Cybertown, OuterWorlds, berkom ,ActiveWorlds,iCity,pointworlds等。它们除了提供虚拟场景制作以外,还提供:服务器管理,通讯管理,用户管理等功能。Blaxxun公司Virtual Worlds Platform 5.1服务器已经有许多网站用它建立虚拟社区。

  图4 Cybertown虚拟社会首页

  Cybertown是目前世界上规模最大的虚拟社区,它有近200个虚拟场景,几百万人在这个虚拟社会中居住,安家。它有完整的社会管理体系,各类公用设施:商店,俱乐部,职业介绍所,体育馆,公园,跳蚤市场,市政大厅,咖啡厅,画廊等等。您可以在这个虚拟城市中购置房地产,寻找工作,娱乐,学习。您可以结交世界各个角落不同国籍的朋友,与他们会见,谈话(语音或文字),交流各种信息。Wed3D技术将把虚拟社会变成现实,借助于互联网,居住在地球上人们的距离一下子拉近了。

Wed3D技术发展前景

  虽然,Wed3D技术将有好的发展前景,但仍然不可乐观,它面临下述问题:

  网络带宽仍然是Wed3D主要瓶颈:当前处理器的速度与网络的带宽只能初步满足Wed3D图形联机操作的要求,随着 Cable modems 和 DSL 连接的应用,网络带宽将有更大的改进,当一个10MB左右的Wed3D模型文件只需要几秒钟下载时,Wed3D图形的质量将有很大的改善,而现在的带宽还不能满足要求。

  Flash作为2D动画在互联网上的成功的关键是只有唯一的技术和标准。现在的Wed3D图形是有几十种可供选择的技术和解决方案,多种文件格式和渲染引擎的存在是Wed3D图形在互联网上应用的最大障碍,而这种局面在今后若干年还将存在。

  从现在的发展态势来看,有几种技术可能在未来有一定的优势:

  X3D:由Web 3D Consortium制定,得到大学,政府机构及一些Wed3D图形公司的支持,由于它是VRML97下一代新的国际标准,有比较广泛的社会基础。
  Pulse3D:在游戏娱乐领域内领先,使用它的技术的游戏网站有100多个,它得到Discreet 和Entertaindom公司的资金支持,现在它正在把游戏领域的技术优势应用到e-commerce。它的插件支持QuickTime 5 and RealPlayer。
  Viewpoint:前身是MetaCreations(3D图形应用软件开发商),它卖掉了所有的其他软件产品,改名为Viewpoint,专们从事Wed3D图形技术。其渲染引擎的模块化结构极易扩充,并且能与QTVR-, iPix-, and XML-等标准集成。它的目标是e-commerce。它的技术的最大特色是与XML集成。
  Cult3D:开发了e-commerce的全套解决方案,已经有450 e-commerce网站使用了 Cult3D技术,近10000个商业模型,它也在向娱乐领域扩充,提供全面解决方案,提供最稳定可靠的渲染引擎
  Shockwave3D: 这是Macromedia公司Flash插件,有着极为广大的用户群(据说世界上有1亿3千万人安装),更引人注目的是Intel把它的Wed3D 图形集成到Shockwave。IntelWed3D图形极具特色:动态调节3D内容的分辨率,曲面光滑技术,照片级逼真材质及各种特色效应。

  在今年的SIGGRAPH 2002世界计算机图形会议上,Intel宣布建立Wed3D/CAD工作组, 其主要目标是:建立一个统一的,开放的文件格式,用于在Web上显示实时的3D图形。与此同时Wed3D Consortium在SIGGRAPH 2002会议上了发布X3D最终工作草案。X3D是一个成熟的标准,是VRML的下一代标准,但是Intel完全没有提到它,如果Intel重新制定另外一个新标准,X3D的将面临尴尬,就Intel公司的实力和威望,X3D很难成为真正的国际标准。Intel公司很可能将左右新标准的制定与推行。

  预测未来谁是最后的胜利者是困难的,也许很长一段时间内将是多种技术同时共存而又相互竞争。而Intel和微软都具有左右Wed3D发展前景的实力。

  现在我们应该思考一下,我们国内应该如何发展我们自己的Wed3D图形技术?

分类: 其他 标签:

HTML5 Web SQL Database 对象本地持久化

2010年5月30日 没有评论

       HTML 5标准并不只局限于传统的标记语言,它还拥有很多让人期待的API接口,利用这些接口,开发者可以创建更加丰富、更加引人注目的应用程序。之前我们介绍过支持文件拖放上传功能的HTML 5 File API,今天,我们一起来了解HTML 5的Web SQL Database API,使用本地和会话存储实现简单的对象持久化。

  对于HTML 5,也许最为有用的就是它新推出的“Web Storage”(Web 存储)API。对简单的关键值对(比如应用程序设置)或简单对象(如应用程序状态)进行存储,使用本地和会话存储能够很好地完成,但是在对琐碎的关系数据进行处理之外,它就力所不及了。而这正是 HTML 5 的“Web SQL Database”API 接口的应用所在。

      近日Google宣布将支持HTML 5 Web SQL Database API,其他浏览器厂商也表示将紧随其后提供该支持,有的甚至已经开始支持该API了;但同时,HTML 5规范的制订却遇到了阻碍,因为所有的参与者都已选择了SQLite作为底层数据库,要想实现标准化还得考虑多个不同的实现。

      作为HTML 5的一部分,W3C组织正在制订Web SQL Database API草案,该规范主要用于解决如何通过SQL存储及访问数据的问题。文档中所使用的SQL语言是SQLite 3.6.19。网页可以使用这个API与嵌入式的客户端数据库进行交互,这对于那些想要在本地存储数据或是离线浏览的应用来说价值非常大。

      Google已经在其最新的浏览器Chrome 4中通过SQLite提供对Web SQL Database的支持了,这个举动可以看作是向标准化迈进的一大步,因为Google Gears中已经拥有了一个Database API,也是基于SQLite。Gears API为所有主流浏览器提供了结构化的数据存储功能,包括IE、Firefox以及Safari,但现在Google已经停止Gears的开发工作了。

      Firefox 3拥有一个嵌入式SQLite数据库,目前主要用于存储书签和历史记录,但可能不久后就将支持Web SQL Database API。当前的开发工作正在WebKit(Safari所用的渲染引擎)上进行以向Web开发者提供Web Database API。现在谁也不知道微软对于IE和HTML 5 Database API的计划到底是什么。

  先提个醒,该文下面的内容需要读者对 JavaScript 和面对对象编程(尤其是匿名内的内部函数)以及SQL具有很好的理解。

  打开链接

  为了打开一个连接,我们执行以下代码:
db = openDatabase("ToDo", "0.1", "A list of to do items.", 200000);

  以上代码创建了一个数据库对象 db,名称是 Todo,版本编号为0.1。db 还带有描述信息和大概的大小值。用户代理(user agent)可使用这个描述与用户进行交流,说明数据库是用来做什么的。利用代码中提供的大小值,用户代理可以为内容留出足够的存储。如果需要,这个大小是可以改变的,所以没有必要预先假设允许用户使用多少空间。

  为了检测之前创建的连接是否成功,你可以检查那个数据库对象是否为null:
if(!db) alert("Failed to connect to database.");

  绝不可以假设该连接已经成功建立,即使过去对于某个用户它是成功的。为什么一个连接会失败,存在多个原因。也许用户代理出于安全原因拒绝你的访问,也许设备存储有限。面对活跃而快速进化的潜在用户代理,对用户的机器、软件及其能力作出假设是非常不明智的行为。比如,当用户使用手持设备时,他们可自由处置的数据可能只有几兆字节。

  执行查询

  执行一个查询,你可以使用database.transaction()函数。该函数具有单一参数,负责查询实际执行的函数。

  该函数(通常是匿名的)具有一个类型事务的参数。

  db.transaction( function(tx) { 该事务具有一个函数:executeSql。这个函数使用四个参数:表示查询的字符串,插入到查询中问号所在处的字符串数据(很像 Java 的预先准备好的语句),一个成功时执行的函数和一个失败时执行的函数。
tx.executeSql("SELECT COUNT(*) FROM ToDo", [], function(result){}, function(tx, error){});

  查询成功时

  当查询成功执行时,应用程序跳转至一个具有一对参数的查询,一个是 transaction,另一个是它搜集的 results。对于实际上将你的数据传递至用户,这是非常完美的,比如显示 ToDo 列表。有关这个话题后面再讲。

  查询失败失败时

  当查询没能执行时执行。由于你将 transaction 对象作为函数的第一个参数进行传递,当出现错误时你可以继续执行查询。例如,如果是因为缺少表格(table)而查询无法运行,这是创建一个表格并在此执行该语句的绝佳时机。从该函数的第二个参数,你可以获得有关该错误的信息(包括描述)。

  示例

  假设我们想要使用上面的例子,想要查询数据库中的某个表格,如果该表格不存在,我们就创建一个表格。

  在这个示例中,我们将调用具有一个函数参数的 db.transaction()。这个参数中,我们调用 tx.executeSql()。如果这个步骤成功,我们不做任何操作(因此是一个null参数)。或者我们将该事务和执行失败的函数一起传递,并再次调用 tx.executeSql()。这一次使用创建查询。
db.transaction( function(tx) { tx.executeSql("SELECT COUNT(*) FROM ToDo", [], null, function(tx, error) { tx.executeSql("CREATE TABLE ToDo (id REAL UNIQUE, label TEXT, timestamp REAL)", [], null, null); } ); } );

  使用所有这些内部方法,可能有点麻烦,所以你也许想在外部创建一个调用 db.transaction() 的函数。比如,我们可以让错误函数是自包含的,并将其命名为“createToDoTable()”。

  插入

  为了让代码更加简洁和安全,Web SQL Database API 允许你为 transaction.executeSql() 函数提供字符串数据,用以表示调用的 SQL 语句中的变量。我们使用以下的代码进行演示:
db.transaction( function(tx) { tx.executeSql("INSERT INTO ToDo (label, timestamp) values(?, ?)", [label, new Date().getTime()], null, null); } );

   在这个示例中,第一个参数中的两个问号将被后面数组中对应的项替代。第一个是为该任务设置的标签(也许是我们之前在代码中定义的一个变量),以及调用函数生成的时间戳。

  执行该查询,其结果与下面语句类似:
INSERT INTO ToDo (label, timestamp) values ("Test", 1265925077487)

  对结果进行处理

  成功执行的函数对结果对象包含集合或行。每一列表示一个结果。该结果包含分配给它的一组值,表示该特定结果的数据库中的每一列的值。通过调用 result.rows.item(i) 可以访问一个行,其中 i 是你想要查询的行的指针。想要从一行中选择一个值,你可以传递给该行一个数组格式的字符串指针,它表示你需要查询的列。例如,如果想要标签(label)列,我们可以调用 row[‘label’]。

  以下代码使用结果对象来输出一个查询的结果:
db.transaction( function(tx) { tx.executeSql("SELECT * FROM ToDo", [], function(tx, result) { for(var i = 0; i < result.rows.length; i++) { document.write(” + result.rows.item(i)[‘label’] + ‘
‘); } }, null); } );

  结论

  需要注意的是,如果不是绝对需要的情况,不要使用 Web SQL Database。这不是因为它们的技术高高在上,而是因为它们会让你的代码更加复杂。对于大多数情况,本地存储或会话存储就能够完成相应的任务,尤其是你能够保持对象状态持久化的情况。

  正如前面所说,通过这些HTML 5 Web SQL Database API 接口,你可以获取许多功能。我相信,几年以后会出现一些非常优秀的、建立在这些 API 之上的应用程序。

分类: 其他 标签:

MusicAPI & Music MashUp-音乐API 和音乐应用聚合

2010年5月27日 没有评论

无论你是一个歌手或是一个音乐爱好者,现在有许多音乐应用程序接口可以为你所用。Last.fm 是网络中最流行的一个。他的API提供了Last.fm中会员、艺术家、专辑、音轨等诸多数据。目前已经发布了超过36个 Last.fm应用聚合 ,并且这一列表仍在不断增长中。随着最近新增的LyricsFly API和它的拥有314000首歌的歌词数据库,目前已经有25个 音乐APIs 在ProgrammableWeb目录中(还有135 个已发布的聚合应用

Last.fm不过是其中的一个例子。这些应用程序接口(API)帮助你发现那些你喜欢的音乐,提供给你与音乐相关的,包含所有细节的原始数据,还可以让你在线保存和管理你的音乐。另外一些API提供在线的广播和音乐订阅服务。这些API可用来定制音乐播放器,寻找现场的音乐,甚至帮你销售你的音乐作品。许多已经在ProgrammableWeb中增加的专门的栏目去跟踪他们:Music API and Mashup Dashboard

Managing Your Music管理你的音乐

管理你的音乐收藏不再只是意味着将你的CD按照一定循序进行排列。今天,我们可以在不同的地方使用不同的设备来欣赏音乐,这也使我们很容易忘记把喜欢的音乐放在了什么地方。另外,音乐可以无处不在,但是你怎么才能按照你喜欢的方式找到他们呢?

这是开发人员尝试用音乐API来解决的一个关键问题。

Music Discovery 音乐发现

如何能够找到你喜欢的新的音乐作品?如何把它放入到我的收藏,并进行合理的管理归类以便我以后还能找到它?除了我们已经探讨过 Last.fm,当然还有许多别的也不错的解决方案。

类似 Last.fm,OpenStrandsAPI 提供一套Web2.0的方式来发现音乐:API提供一种可编程的方式来访问MyStrands.com社区的推荐、标签和播放列表服务。另外音乐搜索工具中包括了一个数字播客 API-可以让你通过 关键字来查找音乐 , SeeqPod API(多媒体搜索)-可以输入你喜欢的歌曲名字,API将返回一个歌曲列表,Yahoo Audio Search API-通过结构化和非结构化的查询音频文件和相关的音乐数据。

特别值得一提的是 MusicDNS API:它能自动用一些运算法则将你的音乐与它数据库中的音乐进行比较,从而识别那些艺术家的风格与你的相近。

About the Music (Music Metadata) 音乐信息(音乐原始数据)

如果你找到的一些你喜欢的音乐,你可能希望了解更多的关于歌曲或、作者和歌手的相关信息。一些API是提供音乐相关信息的原始数据。Freedb / CDDB提供音乐CD的相关信息:表演者、CD标题、音轨清单和其他信息。最有趣的是你想找的信息可能就在你计算机的CD驱动器中那张CD上,或者其他Freedb 兼容的设备上。

MusicBrainz API, Tunelog APIDiscogs API都提供一些 Web2.0的方式,提供对大型音乐原始信息数据库访问,这些数据库都依赖于或基于 MusicBrainz, Tunelog和Discogs 社区的集体维护。

Media Management and Online Broadcasting 媒体管理和在线广播

一些帮助你管理音乐的API。 Faces.com APIIpernity API 让你可以和朋友以及网站上其他会员分享音乐、照片和视频。

今天我们可以与通过广播完全不同的方式,分享你的媒体资料。但是许多网站更喜欢广播的方式,这意味着内容更专业一些。Orb API允许你广播你的音乐、视频和照片,等等。 RadioTime API能够让你找到并欣赏全球超过60,000 个广播站。

Rhapsody API和音乐订阅服务让你可以管理你的狂想曲列表,搜索音乐和访问你的狂想曲RSS聚合。

Music Players 音乐播放器

Yahoo Music Engine API, Winamp API, 和 MP3Tunes API 都提供通过代码定制他们的音乐播放器的功能。

Music Events 音乐大事件

当听完一个新人的旋律,你可能想要看他们的表演。Eventful API, JamBase APIGruvr API可以让你搜索到演唱会和其他相关事件。Eventful 更进一步满足的你需求,可以让你了解到哪个艺人在你所在的地区露过面,Gruvr的API让你可以整合现场音乐地图和演唱会日历在你自己的网站上。

APIs For Performers 为表演者提供的API

如果你是一个表演者,那么你一定对下面的API看兴趣。你可能希望你的作品让所有人听到和搜索到。你希望把你的歌提交到MusicDNS.org,以便那些喜欢你这种音乐风格的人更容易地发现你的新作。你可以用 Eventful, JamBaseGruvr提供的API来作为你宣传推广的表演日历。最后如果你打算销售你的录音带,研究一下SNOCAP API,可以帮助你建立你自己的音乐商店。

Music Mashups 音乐应用聚合

音乐 API提供了多种多样的音乐应用聚合的可能。其中在我们的音乐应用聚合名单中比较早表较流行的就是MusicPortl,一个通过网络收集某些演艺人士的信息,为包括传记、照片、相册、视频和Blog等内容建立一个页面。MusicPortl通过7个不同的API来提供这些信息,包括Amazon eCommerce API, Flickr API, Last.fm API, MusicBrainz API, Ontok API, Technorati APIYouTube API

许多音乐应用聚合了互联网上演艺人员的数据到一个统一的搜索接口,其中有FoxyTunes。这个月的早些时候你可以在这了列表里看到。

这里有135 个已发布的音乐应用聚合名单,其中表较流行的有:TuneGlue, ZonTube, KEXPlorer.com, MusicTonic, One Hit Wonders Map, JukeboxTube, Indie Tube, NPR Station Map 和音用聚合竞赛优胜者PodBopthe Hype Machine

摘要

现在,有相当多的多种多样音乐API已经发布,这一数量还在不断增长中。点击这里更新当下可用的音乐API列表

分类: 其他 标签:

百度MP3音乐API接口及应用

2010年5月27日 没有评论

      当你在百度去搜索一首歌时,你会发现有种更简单的方法,嘿嘿,安宁ヤ太天真告诉你个秘密,百度有个不公开的API

http://box.zhangmen.baidu.com/x?op=12&count=1&title=大约在冬季$$齐秦$$$$
用上面的地址,红色部分改成歌名与作者名,然后百度就会给你一个XML:
<?xml version="1.0" encoding="gb2312" ?>
<result>
  <count>1</count>
<data>
<encode>http://song.feifa-radio.com/Q/20050701/jingxuan/YjI$.Wma</encode>
<decode>1.Wma</decode>
<type>2</type>
<lrcid>49684</lrcid>
   </data>
</result>

其中的count 值为1是说返回的是一个,这个没什么用,接下来的东西就有用了,encode里的值是歌曲加密后的地址,加密只是对文件名加密的,我们需要的只是前面的路径,也就是 http://song.feifa-radio.com/Q/20050701/jingxuan/ 这部分,然后复制decode 的值: 1.Wma 与前面的相拼就是正确的下载地址:
http://song.feifa-radio.com/Q/20050701/jingxuan/1.Wma
后面的type的值为2表示此歌曲文件类型是wma的,其它的:1表示rm,0表示MP3,通常我们下的类型都是MP3或WMA的,所以只要有2或0的
lrcid这个的值是百度服务器上这首歌的歌词文件的文件名,这个文件的路径是:http://box.zhangmen.baidu.com/bdlrc/496/49684.lrc  

这个地址解析下:
http://box.zhangmen.baidu.com/bdlrc/ 这个是百度lrc歌词存放地址,后面的496是一个的不定的,民就是说歌曲不同那个目录名也不同,它的算法是拿歌词文件名(也就是上面说的 49684) 除以一百,然后取小于等于其结果的最大整数,如上面的:49684/100 =496.84 小于等于496.84 的最大整数就是496,于是这首歌完整的歌词地址就出来了:http://box.zhangmen.baidu.com/bdlrc/496/49684.lrc

安宁ヤ太天真似乎说得复杂了了,呵呵,希望对大家有用

作者: 安宁ヤ太天真
网址: http://hi.baidu.com/kiss3344
版权所有。转载时必须以链接形式注明作者和原始出处及本声明。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Xml;
using System.Windows.Forms;

namespace BaiDuAPI
{
   public partial class Form1 : Form
   {
       public Form1()
       {
           InitializeComponent();

           this.skinEngine1.SkinFile = "vista1_green.ssk";
       }

       private void button1_Click(object sender, EventArgs e)
       {
           System.Media.SoundPlayer sp = new System.Media.SoundPlayer();

           

           try
           {
               string strEncode = "";

               string strDecode = "";

               string strLrc = "";

               string strExt = "";

               string strPath = "";

               string[] AppString;

               string AppAPI = GetMP3URL(textBox4.Text);

               if (AppAPI == "nothing")
               {
                   MessageBox.Show("找不到音乐 " + textBox4.Text + " 请更换查询名称");

                   return;
               }
               else
               {
                   AppString = AppAPI.Split(" ".ToCharArray());

                   strEncode = AppString[0].ToString();           //编码

                   strDecode = AppString[1].ToString();           //解码

                   strExt = AppString[2].ToString();              //扩展名

                   strLrc = AppString[3].ToString();              //歌词URL

                   strPath = AppString[4].ToString();             //歌曲URL

                   textBox1.Text = strEncode;

                   textBox2.Text = strDecode;

                   textBox3.Text = strPath;

                   textBox5.Text = strExt;

                   textBox6.Text = strLrc;
               }
           }
           catch
           {
               MessageBox.Show("找不到音乐 " + textBox4.Text + " 请更换查询名称");
           }

       }

       public string GetMP3URL(string fString)
       {
           try
           {
               string strAPI = "http://box.zhangmen.baidu.com/x?op=12&count=1&title=";

               strAPI = strAPI + fString;

               XmlTextReader hfXMLReader = new XmlTextReader(strAPI);

               DataSet ds = new DataSet();

               ds.ReadXml(hfXMLReader);

               string strDecode = ds.Tables["data"].Rows[0]["decode"].ToString().Replace("\n", "");         //读取歌曲名称

               string strEncode = ds.Tables["data"].Rows[0]["encode"].ToString().Replace("\n", "");       //读取歌曲编码

               string strLrc = ds.Tables["data"].Rows[0]["lrcid"].ToString().Replace("<br />", "");             //读取歌词ID

               string strPath = "";

               string strExt = "";

               string[] strPre = strEncode.Split("/".ToCharArray());

               strPath = strEncode.Replace(strPre[strPre.Length – 1], strDecode);         //赋值MP3真正地址

               string strLrcPath = "http://box.zhangmen.baidu.com/bdlrc/";                //歌词基本地址

               if (strLrc == "0")
               {
                   strLrc = "暂无歌词";
               }
               else
               {
                   strLrc = strLrcPath + (Int32.Parse(strLrc) / 100).ToString() + "/" + strLrc + ".lrc";
               }

               switch (ds.Tables["data"].Rows[0]["type"].ToString())
               {
                   case "1":
                       strExt = "rm";
                       break;
                   case "0":
                       strExt = "mp3";
                       break;
                   case "2":
                       strExt = "wma";
                       break;
               }

               if (strEncode == "nothing")
               {
                   return "nothing";
               }

               return strEncode + " " + strDecode + " " + strExt + " " + strLrc + " " + strPath;
           }
           catch
           {
               return GetMP3URL(fString);
           }
       }

       private void button2_Click(object sender, EventArgs e)
       {
           string tempstr = "";

           for (int i = 1; i < 11; i++)
           {
               tempstr += "1<<" + i.ToString() + ": " + (1 << i).ToString() + "\r\n";
           }

           MessageBox.Show(tempstr);
       }

       private void button2_Click_1(object sender, EventArgs e)
       {
           this.axWindowsMediaPlayer1.URL = textBox3.Text;
       }
   }

原文:http://shuhejiang.blog.163.com/blog/static/117667532009111533750457/

分类: 其他 标签:

同时使用svn+git进行版本管理

2010年5月26日 没有评论

项目环境说明

项目使用svn进行代码版本管理。

使用场景

修改了某些文件后,在修改成另外的实现方法前先备份当前已经实现的方案(git commit临时文件)

在不能连接svn服务器的机器上修改svn版本管理的代码,且需要进行版本管理

前期准备

安装git(MSsyGit,TortoiseGit)

安装svn(TortoiseSVN)

测试步骤

本地新建目录 welkinvcproject.svngit,svn checkout file:///E:/Code/svnRepository/welkinvcproject/trunk

在svn Settings的Global ignore pattern增加*.git,例如我的设置是*.git *.obj *.manifest *.manifest.res *.ilk *.idb *.dep *.user *.exe *.pdb

在 welkinvcproject.svngit目录鼠标右键点击Git Init Here

在welkinvcproject.svngit目录下建立.gitignore文件,把不需要git管理的文件加入此表,例如.svn. 或者编辑.git/info/exclude文件,我设置的是

*.svn

*.obj

*.manifest

*.manifest.res

*.ilk

*.idb

*.dep

*.user

*.exe

*.pdb

在welkinvcproject.svngit目录鼠标右键点击Git Commit -> "master"…,提交所有svn版本控制的文件

在本地随便修改几个文件,但由于还不能确定是最后的代码,所以不能提交到svn,采取临时提交到git的办法来管理。在welkinvcproject.svngit 目录鼠标右键点击Git Commit -> "master"…,提交变更的文件

重复循环执行上一步

最后再提交到svn,再提交到git,这是svn 的代码和git的代码是一致的。(稍后如果发现之前提交到git的某个版本的代码更合适,可以使用git revert到相应的版本,再提交到svn和git)

原文: http://wengshanjin2001.blog.163.com/blog/static/376284582010018101535344/

分类: 其他 标签: