• 昨天在装上了Opera,用起来还算顺手。不过很不适应的一个就是插件比起FireFox来说要差很多。

    在国内访问blogspot.com等网站需要代理的帮助,刚装上Opera后第一件事就是去找这种东西,Opera中叫做Widget,找到了一个下ProxyWidget。

    但是这个东西我怎么弄也不能工作,放弃了。 

    下午上Opera的网站上学习了一会Browser JavaScript。

    做了一个小js,通过这个js把页面中的所有blogspot.com的相关链接用http://anonymouse.org/cgi-bin/anon-www.cgi/ 访问,基本满足了我目前的要求。

    下面是简单的脚本,可以保存在一个js文件中,再通过Tools- >Preferences->Advanced->Content->JavaScript Options->User JavaScript Files 引用它所在的目录就可以了,这个目录下如果还有其它的js,也会被自动加载的。

    opera_proxy.js:


    document.addEventListener('DOMContentLoaded', function(){
    var proxy_url="http://anonymouse.org/cgi-bin/anon-www.cgi/";
    for( var link_count=0,element;element=document.links[ link_count ]; link_count++ ){
    var lhref = element.getAttribute('href');
    if(lhref == null){
    continue;
    }

    var domain = null;
    if(lhref.indexOf("http://")==0){
    domain = lhref.substring("http://".length,lhref.length);
    domain = domain.substring(0,domain.indexOf("/"));
    }
    if(domain!=null && (domain.indexOf("blogspot.com")>=0)){
    element.setAttribute('href',proxy_url+lhref);
    }
    }
    },false);

    现在是一个扩展的时代,呵呵。

     

    昨天用Gant写了一个构建的脚本,比单纯的Ant构建脚本要简单,很适合我这种懒人用。 今天晚饭后准备重构一下,用Gant的最新版本写一下。

    昨天把<修改代码的奥秘>看完了,最大的收获是我平时修改代码的方法在书中也有类似的讲述,以前我觉得自己的改法很有罪恶感,现在看到别人也用了类似的方法,觉得”天下乌鸦一般黑“ :).

     

  • 今天想下载新歌,原来的程序不能用了,检查发现sogou的源代码变了,正则匹配不管用了,faint.

    观察了一下新的源代码格式,发现现在的信息都放在musicInfoList这个变量里了,正好顺便试用jdk6的ScriptEngineManager,呵呵 .

    基本想法是使用ScriptEngine执行一下musicInfoList变量定义,就可以通过得到的对象找到专辑的各种信息,余下的操作以上一版一样,只是代码更简单了.

    import java.io.CharArrayWriter;
    import java.util.regex.Matcher
    import java.util.regex.Pattern
    import javax.script.*;

    def download(address,outer){
      outer << address.toURL().openStream()
      outer.close()
    }

    class FileBinaryCategory
    {
      def static leftShift(File a_file, URL a_url)
      {
        def input
        def output

        try
        {
          input = new BufferedInputStream(a_url.openStream())
          output = new BufferedOutputStream(new FileOutputStream(a_file))
          output << input
        }
        finally
        {
           input?.close()
           output?.close()
        }
      }
    }
    if(args.length<2){
     println "Usage:groovy ${this.class.name}.groovy <store_dir> <url>"
     return;
    }
    def mp3dir = args[0]
    def mp3source = args[1]                
    def mp3source_outer = new CharArrayWriter();
    download(mp3source,mp3source_outer);
    def mp3html=mp3source_outer.toString();
    def mp3 = mp3html =~ /musicInfoList\s*=\s*\[(.+)\];/
    if(mp3.find()){
     def mp3MapStr = "[${mp3.group(1)}]";
     def manager = new ScriptEngineManager();
        def engine= manager.getEngineByName("js");
     def mp3Array = engine.eval(mp3MapStr);//得到一个NativeArray对象
     def itemLen = mp3Array.getLength();
     def i=0;
     while(i<itemLen){
      def mp3Item = mp3Array.get(i,mp3Array);
      def song_name = mp3Item.get("title",mp3Item);
      def song_url = mp3Item.get("url",mp3Item);
      def song_type = mp3Item.get("postfix",mp3Item);
         print "found ${song_name} from ${song_url}...."
         try{
          print "Begin downloading ..."
          def file = new File(mp3dir+File.separator+song_name+"."+song_type)
          def pdir = file.getParentFile()
          if(pdir == null){
           println "Error file path:${file},no parent dir."
           return
          }
          if(!pdir.exists()){
           pdir.mkdirs()
          }
          if(!file.exists()){
              use (FileBinaryCategory)
              {
                file << song_url.toURL()
              }  
          }
      println " end."
         }catch(Throwable te){
          println "Download mp3 ${song_name} error,${te}"; 
         }
      i++;
     }

     

    刚才试着下载了 不能说的秘密 ,使用这个链接 下载正常,sogou音乐盒的专辑功能真是不错,省得一首一首的找了,特别是一些老歌,热心的网友已经找得很全了,我就只能提供个小工具方便大家下载,呵呵.

  • 本周休假回来之后离开了VC,又走近了Java,真亲切,呵呵。

    昨天做公司一个活儿的前端页面的时候根据同事的建议使用了Prototype。

    现在流行Ajax,页面要是不停的刷新,都不好意思给人家看。唉,逼得人没法子了。以前在做幻灯的时候也用了Prototype,不过已经过去半年多了,具体的用法也忘记得差不多了,只记得我当时都返回XML数据,自己写了个简单的XML解析函数,费了好大劲儿。

    这回我决定使用JSON,目的只有一个--偷懒,不用再解析XML才能得到数据。Prototype支持JSON(在http header中增加一个X-JSON就行了,Prototype自动会把json对象返回给调用函数)。当我完成一个实作之后,就是觉得这也太好用了,向作者致敬。开始在项目中实现功能,发现了一个对我们中国人来说致命的问题,对json返回的中文解析时会出错,无法正确的得到一个json对象,甚至还会报出[Object Error]错误。很奇怪Prototype为什么要采用在Header中增加自定义的X-JSON来实现此功能,IE中Header的长度是有限制的,当数据量比较大时,难免会出问题。

    所以,还是把JSON String写到HTTP body中,自己手工再执行一下,以获取json object。

    如果要在Header中实现,为了避免无法解析,必须在增加header之前转码,我试了一下,对IE,直接把String 由GBK编码转成ISO8856-1就可以了,在Prototype中,可以正常解析json,但此时FireFox中却是乱码了,难道要在服务器端根据浏览器的类型进行适配?

    X-JSON Header 是个好想法,不过实现起来比直接在http body中返回json object复杂,简单就是美,呵呵。

    推荐一本讲Groovy的书《Groovy In Action》,为数不多的讲解Groovy的书,正在努力攻读,争取春节后就把它看完。

  • Tapestry4之前在Page类中访问HttpSession或HttpRequest是很方便的,这样子就可以了IRequestCycle.getRequestContext().getSession(),昨天看了一下它的源代码,竟然有这样子的注释“ 

      /**
         * Returns the {@link RequestContext}. This is provided to ease the upgrade from Tapestry 3.0.
         *
         * @deprecated To be removed in 4.1.
         */

    在4.1的时候会被删除,虽然我现在用得还是4.0,考虑到以后的升级还是决定不这样做了。

    那只好这样子用了

    /**注入Request*/

    @InjectObject("infrastructure:request")
     public abstract WebRequest getRequest();

    public void login(IRequestCycle cycle) {
        this.getRequest().getSession(true).setAttribute("user", getName());
    }

    上面的方法能够在session中保存对象,可想删除怎么办呢?    this.getRequest().getSession(true)这样子得到的对象是Tapestry包装的WebSession,当中竟然没有removeAttribute这个方法,郁闷。看看Api中是怎么说的,attribute  the new value for the attribute, or null to delete the attribute entirely.

    找到答案了,把属性设为null就从session中删除这个对象了。

     this.getRequest().getSession(true).setAttribute("user", null);

    用了一段时间Tapestry觉得在开发的时候最好看看它的源代码,有些问题文档上没有,看源代码就很明白了。

    最近在做新的项目,竟然把以前一想就头大的javascript用了不少,第一次发现原来javascript可以这样写,在写之前看了些Prototype的东西,在写我们自己的项目的一些页面功能时,参照着Prototype的方法来做,竟然也有点面向对象编程的感觉。

    刚过完五一,工作起来状态恢复得慢,今天才差不多有些感觉了,继续努力工作,好好学习:)

  • <%@ page contentType="text/html; charset=gb2312" language="java" import="java.sql.*" errorPage="" %>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
    <title>无标题文档</title>
    <STYLE>BODY IMG {
     BORDER-RIGHT: gold 3px ridge; BORDER-TOP: gold 3px ridge; BORDER-LEFT: gold 3px ridge; CURSOR: hand; BORDER-BOTTOM: gold 3px ridge
    }
    </STYLE>
    <SCRIPT language=JavaScript>
    <!--
      ImgName=new Array(10);
      ImgName[0]="0.jpg";
      ImgName[1]="18.jpg";
      ImgName[2]="28.jpg";
        ImgName[3]="3.jpg";
      ImgName[4]="4.jpg";
      ImgName[5]="5.jpg";
        ImgName[6]="6.jpg";
      ImgName[7]="7.jpg";
      ImgName[8]="8.jpg";
        ImgName[9]="9.jpg";
      var t=0;
    function playImg()
      {
          if (t==9)
       {t=0;}
        else
       {t++;}
        img.style.filter="blendTrans(Duration=3)";
      img.filters[0].apply();
       img.src=ImgName[t];
      img.filters[0].play();
      mytimeout=setTimeout("playImg()",5000);
       }
    -->
    </SCRIPT>
    </head>

    <body onLoad="playImg()">
    <table width="357" height="168" cellpadding="0" cellspacing="0" bgcolor="#999999">
      <tr>
        <td width="131" rowspan="2"><div align="center"><img name="img" src="0.jpg" width="96" height="120"></div></td>
        <td width="224" height="140" colspan="4"><div align="center"></div></td>
      </tr>
      <tr>
        <td bgcolor="#CCCCCC">
    <div align="center">1</div></td>
        <td><div align="center">2</div></td>
        <td><div align="center">3</div></td>
        <td><div align="center">4</div></td>
      </tr>
    </table>
    </body>
    </html>

  • <!--StartFragment-->    <style type=text/css>
    td {
        font-size: 12px;
        color: #000000;
        line-height: 150%;
        }
    .sec1 {
        background-color: #EEEEEE;
        cursor: hand;
        color: #000000;
        border-left: 1px solid #FFFFFF;
        border-top: 1px solid #FFFFFF;
        border-right: 1px solid gray;
        border-bottom: 1px solid #FFFFFF
        }
    .sec2 {
        background-color: #D4D0C8;
        cursor: hand;
        color: #000000;
        border-left: 1px solid #FFFFFF;
        border-top: 1px solid #FFFFFF;
        border-right: 1px solid gray;
        font-weight: bold;
        }
    .main_tab {
        background-color: #D4D0C8;
        color: #000000;
        border-left:1px solid #FFFFFF;
        border-right: 1px solid gray;
        border-bottom: 1px solid gray;
        }
    </style>
          <script language=javascript>
    function secBoard(n)
    {
      for(i=0;i<secTable.cells.length;i++)
        secTable.cells[i].className="sec1";
      secTable.cells[n].className="sec2";
      for(i=0;i<mainTable.tBodies.length;i++)
        mainTable.tBodies[i].style.display="none";
      mainTable.tBodies[n].style.display="block";
    }
    </script>
          <table border=0 cellspacing=0 cellpadding=0 width=549 id=secTable>
            <tr height=20 align=center>
              <td class=sec2 width=10% onclick="secBoard(0)">关于TBODY标记</td>
              <td class=sec1 width=10% onclick="secBoard(1)">关于cells集合</td>
              <td class=sec1 width=10% onclick="secBoard(2)">关于tBodies集合</td>
              <td class=sec1 width=10% onclick="secBoard(3)">关于display属性</td>
            </tr>
          </table>
          <table border=0 cellspacing=0 cellpadding=0 width=549 height=240 id=mainTable class=main_tab>
            <tbody style="display:block;">
            <tr>
              <td align=center valign=top> <br>
                <br>
                这里填加内容,略去。1 </td>
            </tr>
            </tbody> <tbody style="display:none;">
            <tr>
              <td align=center valign=top> <br>
                <br>
                这里填加内容,略去。2 </td>
            </tr>
            </tbody> <tbody style="display:none;">
            <tr>
              <td align=center valign=top> <br>
                <br>
                这里填加内容,略去。3 </td>
            </tr>
            </tbody> <tbody style="display:none;">
            <tr>
              <td align=center valign=top> <br>
                <br>
                这里填加内容,略去。4 </td>
            </tr>
            </tbody>
          </table>