Category: 未分类

  • Gravity 在 E71 上怎么用 GPS

    有了个新手机 (E71) 之后就比较喜欢折腾,尤其对基于位置的应用非常感兴趣,比如在 google maps 中打开 latitude 图层,分享自己的位置,以及查看朋友们都在什么地方,可惜 google buzz 的图层在国内无法使用。

    foursquare 是目前最流行的一个基于位置的服务了,另外 twitter 也开始支持 geotagging,尽管 s60 的应用跟 iPhone 比起来太少,有人还是做出了一个出众的软件 Gravity. 它最先只支持 twitter,现在最新的测试版不仅支持 twitter 自定义 API proxy,还支持了 foursquare, facebook, google reader, 新浪微博等一堆 web 服务。提一下,用 Gravity 看 Google reader 非常舒服。

    几天前在机场比较无聊,又急着想方便地使用手机的 GPS 功能在 twitter, foursquare 上面分享位置,于是买了个 Gravity 的 license,这玩意的 UI 在 symbian 上确实是算好的,可惜的是文档太少,很多只能自己摸索,或者看山寨文档。比如一开始我用试用版就以为试用版限制了不能发布信息呢,后来才知道直接输入文字即可。

    最郁闷的是我连续折腾了好多天,都没有在 E71 上让 Gravity 成功使用 GPS. 本来想着在机场买了就可以用的,结果回来之后才搞明白,现在真相大白,不得不把 E71 上 Gravity 的用法分享出来,以造福广大劳苦人民。

    其实很简单——安装 FP2 版本!janole (Gravity 作者,此为其 twitter 用户名) 每次发布新版,总是有两个版本,比如最近发布了 6375 测试版,就给了两个短链接 bit.ly/6375ALL 和 bit.ly/6375FP2 (此域名被封,无需尝试)。我们普遍都认为 E71 是 FP1,于是就安装 6375ALL,这样无论如何都不能使用 GPS 的(我用尽了各种招数,包括打电话给朋友抱怨这软件垃圾……)。 在写 tweet 的界面使用上方向键,只能让 GPS icon 消失或者显示灰色;点击菜单 “options – tools – gps to clipboard”, 没有任何反应。foursquare 也找不到 checkin 的地方。

    Gravity 6375 FP2 下载 – Gravity 更新频繁,请 follow @janole 以获取最新信息。

    安装了 FP2 版本,发现 E71 也是支持的,一切都变得很容易。foursquare 多了一行 “Places nearby”,进去以后可能右下角会显示个气泡说 “waiting for GPS”,然后就搜到附近的地点了。twitter 发布信息的时候,按上方向键可以使 GPS icon 变成橘黄色,同时显示个省略号表示正在锁定位置,省略号消失时图标变成绿色就表示锁定成功了,否则使用上一次位置(我猜的)。其实在安装的过程中,在程序接入提醒那一步我就惊喜地发现多了一条:接入定位数据。

    当然了,想要在 twitter 使用 geotagging,你必须登录 twitter 账户并打开该设置。因为 twitter 不会默认给你打开这个特性,以避免意料不到的隐私泄露。

    似乎有消息称 Gravity 还要支持 google buzz,如果真这样就无敌了。

  • 世界很小

    半个月前,美国那边过来一个同事,聊天时我第一次从他那儿知道百姓网的渊源(以前没怎么关注过),于是就查了一下相关的新闻,当时就看到了王建硕的主页,但是没太在意,只粗略浏览了一篇访问 Facebook 的记录。

    恰好几天后,有好友发给我一个链接,是王建硕的最新一篇 blog post,上面竟然有我主页的链接(Nice Technical Blogs)。

    这事一方面在时间上很巧,另一方面也说明技术圈挺小的,我不太记得那个美国同事是不是跟王建硕也见面过了。后来我猜测,应该是 Robert Mao 推荐了我大学同学兼室友 xlvector郑昀,他们都在研究推荐系统相关课题,正好 xlvector blog 有我的一个链接,我就被不小心发现了。包括我在内的三个人都是来自中国科学技术大学,这也算是个巧合……

    被点名了,流量有小幅跳跃,google reader 增加了几个 subscriber, 给我加了点动力(压力),得提高文章质量。

  • dabr 架设与修改

    我的 Nokia 3100 已经用了大约有四五年了,最近很有冲动要买个 iPhone,不过某人却给我买了个 E71,粉碎了我的梦想。在 Nokia 3100 退休之际,看一下它的丰功伟绩:发出的信息 10243,收到的信息 11431.

    其实 E71 我也比较满意,不买 iPhone 也省下一笔钱。先配置了一下 Share Online,让它可以把照片上传到 flickr,然后就开始整 twitter. 先试了一下 Gravity,界面挺不错的,就是不是免费软件,最关键的是听说流量耗费比较大,我试用了一会确实如此,实在想不到为什么它会用那么多。

    我一直在想自己做一个 twitter 客户端,只需要能够发布和查看与自己相关的信息(我发布的或者提到我的),几个月前曾经用 Adobe AIR 尝试过,后来因为时间问题搁浅了,也许以后有空了还会拣起来。我关心的信息就这么多,但是 Gravity 不管这些,它会定时更新默认的 timeline,一方面耗费流量,另一方面信息过载让我比较头疼。

    dabr 是个非常好的选择,后来我使用也非常喜欢,虽然它只是个 mobile web interface. 第一,它可以让我访问到 twitter; 第二,只有在你操作的情况下它才会刷新页面,产生数据流量,且流量相当小; 第三,它是开源软件,可以非常方便地修改来适应自己的需求。其实它的安装就是比普通的 PHP 程序多了个 rewrite rule,很简单。不过我的配置比较特殊,也作了些修改,所以记下来,就当是个另类的 dabr 教程。

    我的服务器上有两个 web server,lighttpd 运行着包括 qingbo.net 在内的一些 PHP 或者 python 程序,监听 80 端口,apache 监听 443 端口,是我的私人 svn repository 和 trac 的前端,只能 https 访问。由于还没有为 apache 配置 PHP 环境,所以我仍然把 dabr 的程序分配给 lighttpd 运行,但是给它单独开了一个新端口(比如 3000),且只能本机访问(请求目标地址为 127.0.0.1)。又因为 lighttpd 没有配置 ssl,就用 apache 做个 ProxyPass,指向 127.0.0.1:3000,这样外部还是只能通过 https 来访问 dabr,避免某些安全隐患。

    dabr 的 SetupGuide 没有给 lighttpd 的 rewrite 写法,其实基本上跟 Apache 是一样的。我的规则如下:

    url.rewrite-once = (
      "^/images/.*$" => "$0",
      "^/(.*)\?(.*)$" => "/index.php?q=$1&$2",
      "^/(.*)$" => "/index.php?q=$1"
    )
    

    之后是 dabr 程序的调整 (Update – 我流量包月以后,发现根本无需改这些设置,默认的也没多少流量,呵呵):

    限制 twitter 用户

    默认情况下架设一个 dabr 程序是任何人可以访问的,如果知道的人太多,可能给服务器造成比较大的负担。

    避免这个情况的方法在 dabr 的 SetupGuide 里就介绍了,把一段代码放在 config.php 里就可以。

    去除不需要的菜单项

    dabr 默认在页面顶部和底部都有一长串的链接,但是很多可能是我们不需要的。它们是使用函数 menu_register 添加的,在源代码目录执行命令 “grep -r menu_register *” (Linux 系统) 即可找到所有调用了该函数的文件,然后进去找到你不想要的菜单项,注释掉即可。

    例如 index.php 一开始就调用了这个函数,”about” 一般来说没用,把它注释了。需要注意,common/twitter.php 里调用 menu_register 时的参数数组有非常多的条目,其中许多包含一行 'hidden' => true,,这种并不是显示出来的菜单项。

    修改每页展示的 tweets 条数

    我修改了 twitter_user_page, twitter_home_page, twitter_replies_page 几个函数,给它们定义的 $request 变量 url 中增加了 count=5 这个参数

    强制 text only 模式

    主要是为减少不必要流量,另外我屏幕也比较小。打开 common/settings.php, 改一下 setting_fetch 函数,当获取 ‘browser’ 配置值时,总是返回 ‘text’:

    function setting_fetch($setting, $default = NULL) {
      $settings = (array) unserialize(base64_decode($_COOKIE['settings']));
      if (array_key_exists($setting, $settings)) {
        return $settings[$setting];
      } else {
        if ($setting == 'browser') {
          return 'text';
        }
        return $default;
      }
    }
    
  • 粗读了 Web 信息架构

    前段时间买了一本“Web 信息架构”,英文名是 Information Architecture for the World Wide Web – Designing Large-Scale Web Sites. 网上还是有一些好评的,不过我却感觉有点无聊。

    我这人本来就不是特别喜欢读书,遇到这种比较无聊的就更觉得没劲了。我只认真地看了一小半,然后用刚才的十几分钟粗略浏览了剩余的内容。这本书给我的感觉就是总结了一些 common sense,或者说是汇编了所谓信息架构所涉及到的一些学科的知识。

    我很难想象这样一个会干涉到产品用户体验、数据库设计等的角色如何在公司的夹缝中生存,看来目前专注于这个的话,也只能给别人做咨询了。不过,产品设计人员在无聊的时候可以打发一下时间。

    书中提到的“搜索日志分析”我还是有点兴趣的,该书在109页的脚注里推荐了一本书 “Search Analysis for Your Site: Conversations with Your Customers”,2007年出版。但是我在网上搜寻许久都没找到,到脚注给出的链接看,发现该书名字跟脚注有些出入,并且状态是 “in progress” ——并没有出版。该未出版的书和这本信息架构的作者中都有 Louis Rosenfeld 这个人,我不知道他们出于什么目的以这样的方式利用这个广告位。我很害怕这本书也是由废话堆积而成。

    该书引用的一段话我倒是很喜欢(115页):

    等一下,葛瑞蒂,月亮还没升上来。

    等到月亮升上来,才能看见我洒的面包屑。

    面包屑会告诉我们回家的路。

    ——《韩森与葛瑞蒂》

    这就是“面包屑”导航 (breadcrumb navigation)名字的由来。我没有找到完全对应的英文原文,但是这一段很相似:

    “Wait, when the moon comes up I will be able to see the crumbs of bread that I scattered, and they will show us the way back home.”

  • .NET 还是 Java?

    今天跟一个计算机专业上大二的小兄弟聊了一会,期间他问:”你们公司招 Java 程序员?是不是基本大公司都不用 .NET?“

    他在自学 C#,这让我隐约回想起我学习计算机的过程。我基本是上大学才开始接触计算机,之前也就去过几次网吧,去校长办公室里打过几次抢滩登陆战。大学的一个寒假,我带回家一大堆计算机方面的书要自学,印象比较深的是还有一本讲 3ds Max 的书,当时什么都不知道,什么都想学……但是当时没有任何人给我指路,一直感觉很迷茫。就像这位小兄弟一样,经常担心,我学了这个技术将来有没有饭吃?

    其实大学跟培训学校的区别就是,培训学校主要传授你一门吃饭的技艺,而大学要教会你如何自己探索吃饭的本事。很不幸的是许多大学已经沦落成为培训学校了。上完大学之后别人问你在大学学到了什么,你如果说我学会了 Java 或者学会了 .NET,岂不让人耻笑?如果大学的目的就在于此,那么大学早就应该开设 Java 系、.NET 系了,学制最多一年。

    问这样的问题,就像要去种地,问别人我是该学锄头呢?还是该学犁呢?好吧,你学犁吧,你就永远是一头牛。你只管闷头拖着犁往前走,撒下的是别人的种子,结出的是别人的果实。

    对于计算机系的人来说,数据结构、算法、编译原理、操作系统原理、计算机体系结构等这些还是必须要学好的。Java 也好,.NET 也好,编程语言只是工具。打好了基础,学什么语言都很容易,可以融会贯通,可以用它们来实现自己的想法。否则,就很容易沦为可怜的流水线工人,帮别人实现那可恶的 CMM…

  • 物流也有技术含量

    今天又看到了一篇分析物流的文章 – “亚马逊“乱”改卓越”,我感觉写得还是挺不错的。想起来几个月前看到的类似主题的文章“为什么都要自建物流”,该文对自建物流的好处也分析得很详细。再到网上搜“自建物流”,发现漫山遍野都是这个话题。

    如果我没记错的话,我只在当当网买过一本书(当当买书经历),恰好就遭遇了一次不愉快,此后就尽量避免在当当买书了。每次都是在豆瓣、当当看书评,然后到卓越下单买书。

    说实话,卓越的网站做得挺烂的,但是吸引我的就是它的物流。买的东西能够准确及时地送达,这才是最重要的。自建物流毫无疑问可以更好地跟自己的电子商务系统对接,提供更好更便捷的送货服务,展现更好的品牌形象。

    物流方面我肯定是外行,不敢多说免得遭人耻笑。不过做互联网多多少少也跟电子商务有点关系,而上面提到的都是电子商务网站的物流。我很欣喜的看到,物流也可以很有技术含量。

    看到用户行为分析在物流系统决策中的应用,感觉数据分析、数据挖掘还是大有前途的,尤其是在中国,大部分的企业这一块还是空白,但是大家都开始认识到它的重要性了。

  • 第二次滑雪

    去年春天我平生第一次去滑雪,没有经过人指导,头回上道之后都不知道怎么下来。不过后来知道点基本的东西了,看看下面人少的时候就冲下去了……

    前天公司组织大家一起去滑雪泡温泉,还很贴心地找教练教我们,总算知道了一些要领,在初级道上可以很自如地滑了。后来上了两次中级道,不过那段又陡又窄的路很让我发怵,速度一快了就忘记怎么控制了。但是再回来初级道,就感觉速度太慢,想快都快不起来。最后我忽悠部门所有同事包括第一次来滑雪的也都上中级道玩了一把……

    比较好的是我在中级道上虽然有时候歪歪斜斜,但最终没有倒,整天下来一个跟头都没摔。

    晚上抽奖还抽到了一瓶 Johnnie Walker, 立即就贡献出来给大家过了酒瘾。有同事后来甚至喝得不省人事。总体来说这次玩得挺愉快的,只是我们在温都水城住,却没有机会去水世界玩点刺激的项目。

  • 不能取得类 WorkBook 的 SaveAs 属性

    同事(非编程出身)用 Ruby 写了个程序,生成一个 Excel 文件,把它作为附件发邮件给某些人。Excel 文件中是昨日数据的报告,他让我帮他每天让该程序自动运行一次。因为程序生成 Excel 文件调用的是 win32 OLE,所以是不能在 Linux 里用 cron 定期运行的,只好在一台 Windows 机器上用“任务计划程序”来实现。

    奇怪的是到了预定的时间,我们并没有收到电子邮件。到任务计划程序中看,果然任务执行失败了,但是没有更详细的信息,这符合微软的风格──用户不需要知道太多。于是在程序中加入 exception handling,将异常信息写入文件,执行任务后,看到异常是:

    OLE error 0x800a03ec: 不能取得类 WorkBook 的 SaveAs 属性

    得说明一下,这个 Ruby 程序如果是双击或者在命令行执行,会正常运行。因为指定了 DisplayAlerts = false, 保存文件的时候也不会有提示(假如有提示,就不好自动运行了)。但是在任务计划程序中就出现了这样的错误,我猜想是环境的问题,就像 Linux cron 里的环境变量跟正常登录的 shell 不完全一致一样。

    该错误的英文版本是 “Unable to get the SaveAs property of the Workbook class”. 很多时候因为中文的有价值信息太少,我们需要猜测出错信息的英文版本,去搜索英文的资料。不过这次英文资料并没有帮上忙,最后试了一下 SaveCopyAs 这个方法,成功!既然用的是微软的东西,咱也不刨根问底地研究为什么这个方法就可以了──你可能会成为人人景仰的佛,但更可能成为唾弃的疯子。

    把 SaveAs 换成 SaveCopyAs 之后,任务计划程序中可以正常运行了,但是在命令行执行时,却会弹出一个需要确认的对话框……同理,不考虑为什么了,直接以暴制暴,用最简单的方式来解决掉它:

    begin
      workbook.saveas(filename)
    rescue Exception => e
      workbook.savecopyas(filename)
    end
    

    这样,手动执行时使用 SaveAs, 任务计划程序中 SaveAs 会抛出异常,就会使用 SaveCopyAs.

  • 用 CSS3 @font-face 嵌入字体

    今天刚发现牛人 Mark Pilgrim 正在写的 Dive Into HTML5,对网站上标题的字体很感兴趣,查了一下,是 Essays 1743.

    这个字体以 LGPL 协议发布,并没有普及到大部分计算机上,所以需要用到 CSS3 的字体嵌入技术,Cross Browser Font Embedding with the CSS3 @font-face selector 一文详细讲解了跨浏览器的解决办法。

    我已经把本站的头部标题改成使用这个字体,如果你没有看到可能是因为缓存的问题,请刷新一下浏览器。(update: 看久了感觉不太舒服,于是已经换掉了).

    上面提到的教程其实挺麻烦的,主要是 IE 仅支持 eot 格式字体文件。由于我是复制 Dive Into HTML5 的样式,于是直接从那儿把字体文件下载到我服务器上,再把 CSS 代码搬过来就可以了。

    @font-face 定义:

    @font-face {
      font-family: "Essays 1743";
      src: url("/static/font/essays1743-min.eot");
      src: local("Essays 1743"), url("/static/font/essays1743-min.ttf")
    }
    

    在标题应用该样式:

    #header-title {
      font-family: "Essays 1743";
      ...
    }
    

    当然了,嵌入字体的做法对中文来说不大适用,因为一个中文字体文件少说几个到十几个 MB, 用户不能忍受,我们的服务器也不一定能够忍受。所以对中文来说,如果只是想标题使用特殊字体,最好做成图片。而这个英文字体文件只有 30 多 KB,和一张图片的大小差不多,如果有大量的文字需要使用该字体,存储、带宽这方面就划算得多了。

  • 外链点击没有 referrer 信息?!

    最近经常盯着访问日志,有一次一边 “tail -f” 日志,一边在 Google Reader 中点击了一下自己的一个日志(此处“日志”指 blog post)链接,发现新增的一行日志竟然没有 referrer 信息!

    我的浏览器并没有做任何隐藏 referrer 的特殊配置,所以这事儿我纳闷了好多天—— Google 是怎么做到的?即使可以做到,有什么必要隐藏 referrer 呢?

    今天晚上动用了一大堆工具——Firebug, Fiddler, Eventbug, 研究了半天,我想 Google 一定是在用 JavaScript 完成这样的 trick.

    后来突然想明白了,我的 Google Reader 一直是使用 https 连接的(避免意想不到的 connection reset),这不是 Google 做的,而是浏览器的默认行为。这么做很有必要,保护用户的隐私。把 https 换成 http 再点击,发现请求头中确实加入了 referrer 字段。据我所知,SearchStatus 这个扩展在遇到 https 页面的时候也是不会向外作任何查询的。

    根据我做的山寨测试,IE, Firefox, Opera 都是这么做的,很好。微软还有一篇 support article 说这个事,里面提到:

    many secure (HTTPS) Web servers store secure information such as credit-card data in the URL

    我想现在应该很少有网站这么做了,不过 url 里面还是很容易找到涉及隐私的信息。隐藏 referrer 虽然给做 web analytics 的人带来了干扰,仍然是非常必要的。

    在解除这个困惑的过程中,看到几年前就有人发现在 AdWords 中点击广告链接测试的时候,没有 referrer header,很奇怪,这几年内也没有人给他正确的答案。我刚刚给了他一个 comment,希望可以解惑……

    这大概也可以解释为什么我们看到自己网站统计中没多少从 Google Reader 过来的流量吧(至少我的是这样)——因为大家都得 “s”.