Utilisateur:EvHart/aRSS

Un article de Wikipédia, l'encyclopédie libre.

#!/usr/bin/ruby
################################################################################
# Wikitools: make RSS from wikimedian article
# Copyright (C) 2006  EvHart under GPL License
#
# This program is free software; you can redistribute it and/or 
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
# 
# version 26/05/2006
# author EvHart
#
################################################################################
#       Bugs:
#       - Comments links.
#       - Ftp commandline (use static var for publishFTP)
#
#       Todo:
#       - Redesign.
#       - Use scan insted of match.
#       - Ftp commandline
################################################################################
require 'net/http'
require 'tempfile'
require 'net/ftp'
 
require 'timeout'


class WikimediaRSS
        @rss

        @host
        @title

        @desc

        def initialize(host,title,desc=nil)
                @host = host
                @title = title

                if(desc==nil)
                        @desc = "RSS for #{title}"
                else
                        @desc = desc
                end
                @rss = createRSS()
        end

        def publishFTP(host,login=nil,psw=nil,fileDest=nil)
        
                Tempfile.open("w+") do |file|
                        file << @rss 
                        file.seek 0

                        Net::FTP.open(host) do |ftp|
                                
                                if(login != nil && psw != nil)
                                        ftp.login(login,psw)
                                else
                                        ftp.login
                                end

                                if(fileDest == nil)
                                        fileDest = "rss.xml"
                                end
                                        ftp.put(file.path,fileDest)

                
                        end
                end
        
        end

        def save(file="rss.xml")
                File.open(file,"w+") do |file|
                        file << @rss 
                end
        end
        
        private
        # :(
        def createRSS()
                str = getArticle()
                str = "#{/\<ul id="pagehistory">\n*((.+\n)*).*\<\/ul\>\<input id="historysubmit"/.match(str)}"
        
                #Remove <!-- start content --> & <div class="printfooter">
                str.sub!(/\<ul id="pagehistory"\>/,'')
                #Remove footer
                str.sub!(/\<\/ul\>\<input id="historysubmit"/,'')
        
                #Header
                rss = '<?xml version="1.0"?>'
                rss << '<rss version="2.0">'
                rss << '  <channel>'
                rss << '          <title>'+@title+'</title>'
                rss << '          <link>http://'+@host+'/w/index.php?title='+@title+'</link>'
                rss << '          <description>'+@desc+'</description>'
        
                str.each do |rssItem|
        
                        #Remove unusefull things:
                        rssItem.sub!(/\(.*\)\(.*\)(.*)*/,'')
                
        
                        #Create Items
                        rssItem.sub!(/<li>.*name="diff" \/\>/,'<item>')
                        rssItem.sub!(/<\/li>/,'</item>')
                        
                        #Cleanup
                        #autocomment
                        rssItem.sub!(/\<span class="autocomment"\>.*"\>→<\/a\>/,'<i>Dans: </i>')
                        rssItem.sub!(/\s+-\<\/span\>/,'...')
                        
                        #Create Title (date,author)
        
                                #Select date
                                date= "#{/\<item\> \<a href=.*\<span class='history-user'\>/.match(rssItem)}"
                                date.sub!(/<.*"\>/,'')
                                date.sub!(/<.*\>/,'')
        
                                #Select author
                                author = "#{/\<span class='history-user'\>.*\<span class='comment'\>/.match(rssItem)}"
                                author.sub!(/\<span class="minor"\>m\<\/span\>/,'')
                                author.sub!(/<span class='comment'\>/,'')
                                author.sub!(/\<\/a\>\<\/span\>/,'')
                                author.sub!(/\<span.*"\>/,'')
                
        
        
                        rssItem.sub!(/\<span class='history-user'.*\>\<\/span\>/,'')
                
                
        
                        #title
                        rssItem.sub!(/\<item\>/,'<item><title>'+author+' ('+date+')</title>')
                
        
                        #Create link
                        rssItem.sub!(/\<a href="/,'<link>http://'+@host)
                        rssItem.sub!(/" title=.*\<\/a\>/,'</link>')
                
        
                        #Create description (use comments)
                        rssItem.sub!(/\<span class="minor"\>m\<\/span\>/,'<description><b> [m] </b>')
                        rssItem.sub!(/\)\<\/span\>/,'</description>')
                
                        if( nil != /\<description\>/.match(rssItem))
                                rssItem.sub!(/\<span class='comment'\>\(/,'')
                        else
                                rssItem.sub!(/\<span class='comment'\>\(/,'<description>')
                        end
        
        
        
                        #fixing some bugs
                                #Span:
                                rssItem.sub!(/\<span\>/,'')
                                rssItem.sub!(/\<\/span\>/,'')
                
                                #description
                                if( nil == /\<description\>/.match(rssItem))
                                        rssItem.sub!(/\<\/link\>/,'</link>  <description>')
                                end
                                if( nil == /\<\/description\>/.match(rssItem))
                                        rssItem.sub!(/\<description\>/,' <description> none </description>')
                                end
                        
                                #<li>
                                rssItem.sub!(/\<li\>/,'')
                        
                #Add to RSS !
                rss << rssItem
                end     
        
        
        
                #Footer
                rss << '  </channel>'
                rss << '</rss>'
        
                return rss
        end
        
        
        def getArticle()
                Net::HTTP.start( @host, 80 ) do |http|  
                        return ( http.get( '/w/index.php?title='+@title+'&action=history').body )
                end
        end
end




###################
#      Script     #
###################

# /!\ Just some test....
if ARGV.length  < 3 || (ARGV[2] != '-f' && ARGV[2] != '-ftp' && ARGV[2] != '-s')
        puts "Article to RSS ©2006 EvHart under GNU/GPL License\n"
        puts "Usage : ruby ./ArticleRSS.rb host [article] [-f frequency > 0] [-s save] [-ftp [host] [login] [psw]]\n"
        

        exit(0)
else 
        host = ARGV[0]
        article = ARGV[1]
end

#Default values
frequency = 0
fhost = login = psw = save = nil

#################################
#       Set ftp vars here       #
#################################
fhost = ""
login = ""
psw = ""
################################

# /!\ Just some test....
for i in (2..ARGV.length)
        if (ARGV[i] != nil)
                if (ARGV[i] == "-ftp")
                        fhost= ARGV[i+1]
                        if ARGV[i+2]  != ("-f"||"-s")
                                login=ARGV[i+2] 
                                i=i+1
                        end
                        if ARGV[i+2]  != ("-f"||"-s")
                                psw=ARGV[i+3] 
                                i=i+1
                        end
                elsif (ARGV[i] == "-f")
                        frequency = ARGV[i+1].to_i
                elsif (ARGV[i] == "-s")
                        save = ARGV[i+1]
                end
        end
end

puts "Wikitools: RSS for wikipedia (aV0.1)
Copyright (C) 2006  EvHart under GPL License"
puts "---------------------------------------------------------------- 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
---------------------------------------------------------------- "
if frequency > 1
        puts "Updating frequency set to #{frequency} sec... (press Ctrl-C to quit)"
end

i = 0
trap( 'SIGINT' ) do
        puts "---------------------------------------------------------------- "
        puts "RSS updated #{i+1} times"
        exit(0) 
end
begin

        rss = WikimediaRSS.new(host,article)


        if(fhost != nil)
                puts "Updating RSS... ##{i} At #{Time.now}"
                rss.publishFTP(fhost,login,psw,save)
        elsif (save != nil)
                puts "Saving RSS... ##{i} At #{Time.now}"
                rss.save(save)  
        end

        sleep(frequency)
        i=i+1
end until frequency < 1
###################
###################