#!/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
###################
###################