莊周夢蝶

          生活、程序、未來
             :: 首頁 ::  ::  :: 聚合  :: 管理

          讓ruby簡化你的工作之blog閱讀器

          Posted on 2007-07-09 15:14 dennis 閱讀(1426) 評論(3)  編輯  收藏 所屬分類: 動態語言my open-source
              閱讀專家和牛人的blog已經是我學習的一種主要方法之一,我每天的必做的就是關注下dreamhead、gigix、江南白衣、robbin、李錕等牛人的blog是不是有什么新文章。不過我非常討厭安裝商業公司的rss閱讀器,我害怕他們是流氓軟件!而且很多閱讀器的文章格式與原文有較大差異從而導致重要信息的丟失,我還是喜歡用firefox暢游網絡,這導致我不得不一次一次地在各個blog間跳轉,打開n個網頁查找我關注的信息,一次兩次也就罷了,天天這樣實在是太麻煩了,那么,有沒有什么工具來簡化我的工作,他能自動每天把我關注的所有blog的文章放在一個頁面里,我每天早上需要做的只是運行下這個工具,然后打開生成的網頁就可以看到牛人們的blog。甚至,我可以在windows下做個計劃任務或者linux下使用cron讓這個工具每天在夜深人靜的時候自動運行下,那我每天早上就可以看到牛人們新鮮出爐的好文章了。這個工具生成的網頁應該類似下面這樣:

          然后,當我點擊某個blog標題的時候會自動展開文章列表:

             
              點擊文章標題就會跳轉到相應的文章網頁。OK,想好了需求,怎么做?寫這樣的東西當然是腳本語言最快了,我們用ruby來完成這個工具腳本。稍微思考下就可以知道大概的思路,應該是通過某個方法連接到各個blog站點,然后抓取我們需要的信息集中顯示在這個頁面里。也許你還想到要用正則表達式去解析網頁內容等等,可想象一下這個工作量將多大,再說現在的blog都有替換模板功能,如果哪天換了模板,正則匹配就失效了,還得重新再來,這也太麻煩了。幸好,blog都有提供RSS啊,我們根本沒必要那么麻煩,直接讀RSS不就可以了?那么ruby有沒有提供讀rss的API?還是要我們自己去解析xml?這件事問下《ruby cookbook》就OK。ruby有提供一個解析rss的庫,支持rss0.9,1.0和2.0標準,權衡之下,我使用了rss2.0,后來發現也可以正常讀取rss1.0的blog。開始寫我們的腳本,先建立一個Blog類用于存放信息:
          class Blog
            attr_accessor
          :title,:url,:items
            def initialize(title
          ,url,items=[])
              
          @title=title
              
          @url=url
              
          @items=items
            end
          end
              title、url和items分別是blog的標題、地址和文章列表,我們將文章存儲在一個數組里,默認是空的。然后再定義一個解析blog信息的方法blog_info,根據地址連接rss源并返回一個Blog對象:
          def blog_info(url)
            feed 
          = RSS::Parser.parse(open(url).read, false) 
            blog
          =Blog.new(feed.channel.title,url,feed.items)
          end
              注意,ruby方法默認返回的最后一行的運行結果,這里就是new的Blog對象,我們通過open-uri庫的open方法連接地址并讀取內容,然后使用RSS模塊的Parser類解析信息,最后將這些信息組織成一個Blog對象并返回。我同時關注好幾個blog,那么將這些blog的rss地址放在一個數組里,然后遍歷數組分別調用blog_info得到Blog對象,最后需要考慮的就是怎么將Blog對象顯示在網頁里。
          def rss_read
            urls
          =['http://www.aygfsteel.com/canonical/rss','http://dreamhead.blogbus.com/index.rdf',
                  
          'http://michael.nona.name/rss','http://blog.csdn.net/mozilla/Rss.aspx','http://blog.csdn.net/g9yuayon/Rss.aspx']
            urls.collect do |blog_url|
              blogs
          <<blog_info(blog_url)
            end  
          end
              rss_read方法最后返回Blog對象組成的數組,剩下的任務就是將這個數組里信息顯示在生成的網頁里。這個問題很類似生成靜態html文件的需求,那么ruby是否有類似freemark的模板語言?答案當然是yes,ruby on rails使用了ERb將ruby代碼嵌入模板當中,我們當然也可以這樣做。ERb類似jsp的語法,<%=name%>就是輸出變量name,<% %>中的代碼就是一般的ruby代碼,因此,首先定義我們的模板文件blogs.html

          <html>
              
          <head>
                  
          <title>simple rss reader</title>
                      
          <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
                  
          <style rel="stylesheet" type="text/css" media="all" />body {
              margin
          : 80px;
              text
          -align:left;
              font
          :normal 12px Verdana, Arial;
              background
          :#FFF
            }
            a
          :link,a:visited{
              text
          -decoration:none;
              color
          :#333333;
            }
            a
          :hover{
              text
          -decoration:none;
              color
          :#FF6600
            }
            
          .dotline {
              BORDER
          -BOTTOM-STYLE: dotted; BORDER-LEFT-STYLE: dotted; BORDER-RIGHT-STYLE: dotted; BORDER-TOP-STYLE: dotted
            }
                  
          </style>
            
          <script language="javascript">
                     function change(name){
                        var div
          =eval("document.all."+name);
                        div
          .style.display=="none"?(div.style.display=""):(div.style.display="none");
                     }
            
          </script>
            
          </head>
                  
          <body>
                      
          <p align="center"><strong>您關注的blog列表:</strong></p>
                              
          <% num=1 %>
                              
          <% for blog in blogs %>
                                
          <% begin %>
                                  
          <div>
                                      
          <a href="#" onclick="change('blog<%=num%>');"><%= blog.title %></a>
                                      
          <div id="blog<%=num%>" style="display:none">
                                          
          <% for item in blog.items %>
                                              
          &nbsp;&nbsp;&nbsp;&nbsp;
                                              
          <a href="<%=item.link%>" target="_blank"><%= item.title %></a>
                                              
          <br>
                                          
          <% end %>
                                      
          </div>
                                  
          </div>
                                  
          <hr class=dotline color=#000000 size=1>
                                  <% num=num+1 %>
                                
          <% 
                                rescue StandardError
          =>e
                                   puts 
          "錯誤信息"+e
                                end 
          %>  
                            
          <% end %>
                  
          </body>
          </html>
              遍歷blogs數組,然后將blog的title輸出到網頁,接著就是blog.items文章列表循環輸出,將文章列表放在一個div層中以便隱藏,javascript函數change用于隱藏或者顯示文章列表。模板文件有了,現在需要的是讀取模板文件并render,輸出到結果文件:
            blogs=rss_read()
            
          #讀取模板文件
            template=IO.read(File.dirname(__FILE__)+"/blogs.html")
            message
          =ERB.new(template)
            
          #輸出結果文件
            File.open("today.html","w+"){|file| file.puts message.result}
          最后,我們生成的是一個today.html文件,這個網頁就是我們就是我們在文章開頭處展示的。message.result就是經過render后,將blogs變量傳入模板文件后得到結果,我們將它寫入today.html。
              完整的rss-reader.rb如下:
          require 'rss/2.0'
          require 'open-uri'
          require 'erb'
          # author dennis
          # email killme2008@gmail.com


          class Blog
            attr_accessor
          :title,:url,:items
            def initialize(title
          ,url,items=[])
              
          @title=title
              
          @url=url
              
          @items=items
            end
          end
          def blog_info(url)
            feed 
          = RSS::Parser.parse(open(url).read, false) 
            blog
          =Blog.new(feed.channel.title,url,feed.items)
          end
          def rss_read
            urls
          =['http://www.aygfsteel.com/canonical/rss','http://dreamhead.blogbus.com/index.rdf',
                  
          'http://michael.nona.name/rss','http://blog.csdn.net/mozilla/Rss.aspx','http://blog.csdn.net/g9yuayon/Rss.aspx']
            blogs
          =[]
            urls
          .each do |blog_url|
              blogs
          <<blog_info(blog_url)
            end  
            blogs
          end
          if $0==__FILE__
            blogs
          =rss_read()
            
          #讀取模板文件
            template=IO.read(File.dirname(__FILE__)+"/blogs.html")
            message
          =ERB.new(template)
            
          #輸出結果文件
            File.open("today.html","w+"){|file| file.puts message.result}
          end
              使用小竅門:最好將today.html加入FireFox的標簽或者IE的收藏夾,windows下建立一個計劃任務每天凌晨自動運行rss-reader.rb生成toady.html(linux可以使用cron),那么你每天早上打開瀏覽器就可以看到牛人們的新鮮文章了^_^

          評論

          # re: 讓ruby簡化你的工作之blog閱讀器  回復  更多評論   

          2007-07-09 21:11 by pass86
          推薦你一個FIREFOX插件GOOGLE READER NOTIFIER,very good。

          # re: 讓ruby簡化你的工作之blog閱讀器  回復  更多評論   

          2007-07-10 08:12 by dennis
          @pass86
          thx,我確實不知道這個東西,汗,一直都用這個小工具

          # re: 讓ruby簡化你的工作之blog閱讀器  回復  更多評論   

          2007-07-11 15:33 by hanson
          firefox rss插件 wizz RSS也不錯。
          主站蜘蛛池模板: 垫江县| 长沙市| 高安市| 额济纳旗| 双桥区| 堆龙德庆县| 进贤县| 新宾| 高要市| 宁都县| 敦煌市| 北流市| 班戈县| 酉阳| 运城市| 滦南县| 丰镇市| 惠州市| 临沂市| 孝昌县| 汶上县| 灵璧县| 镇赉县| 徐水县| 阳江市| 通化市| 和林格尔县| 衡东县| 和顺县| 兴义市| 邯郸市| 莱芜市| 大竹县| 东乌珠穆沁旗| 南皮县| 永康市| 西畴县| 安康市| 任丘市| 高邑县| 保德县|