LunaRss v0.5 – modificat0 da Chiaroscuro
Codice LunaRss 0_6 – refactored by Chiaroscuro
Commenti
- messo proxy come opzionalità (non vado tramite proxy e il codice dava problemi)
- aggiunta un pò di cerimonia per settare o non settare il proxy. un flag NEED_PROXY server per abilitare/disabilitare il proxy. la variabile proxy_url contiene l’eventuale indirizzo del proxy. ho mantenuto la forma estesa if-then con due modi per definire il parser volutamente per il momento, per maggiore chiarezza.
- ho ritagliato una zona configuration prima dell’applicazione
- elimino ‘dati = {}’ – ridondante
- semplifico extract_data – rimuovo l’indice e vado direttamente in push sull’array
- creo un metodo align che mi permette di scrivere l’HTML meglio indentato. Ispirato da del codice di Brian Marick.
- tolgo l’escaping degli apici nell’html usando ’\’ perchè non più necessario entro un blocco di testo HEREDOC
- rss_da_parsare diventa ‘parser’. parse di cosa è chiaro dal contesto
- elenco_rss diventa feeds
- rss_file diventa feed
- trasformo la hash che contiene i dati in una struttura dati FeedData, per renderne più chiaro l’uso applicativo
- trasformo la variabile ‘data’ in un attributo @data
- ‘data = get_raw_data’ svanisce. quando voglio usare i dati chiamo rss_data.
def rss_data @data ||= get_raw_data end
- rss_data funziona come un ‘memorizzatore’: la prima volta che viene chiamato esegue get_raw_data. le volte seguenti ritorna i dati scaricati.
- extract_data diventa ‘parse’. parse cosa si capisce dall’argomento.
require 'net/http'
FeedData = Struct.new :channel, :titles, :descriptions, :links
class Rss_parser
def initialize(url, proxy=nil)
@url_completo = url
@url_no_http = @url_completo.gsub(/http\:\/\//,'')
@url_http = @url_no_http.gsub(/\/.*/,'')
@url_pagina = "/" + @url_completo.gsub(%r{http:\/\/.*?\/},'')
@http_proxy = proxy
end
def esegui_parsing
return FeedData.new(
parse( channel_title_pattern ),
parse( item_title_pattern ),
parse( item_description_pattern ),
parse( item_links_pattern )
)
end
private
def get_raw_data()
if @http_proxy.nil?
h = Net::HTTP.new(@url_http)
else
proxy_uri = URI.parse(@http_proxy)
h = Net::HTTP::Proxy(proxy_uri.host, proxy_uri.port).new(@url_http)
end
resp,data = h.get(@url_pagina,nil)
data.gsub!(/\0/,'')
return data
end
def rss_data
@data ||= get_raw_data
end
def parse pattern
output_data = []
rss_data.scan pattern do |x|
output_data << x
end
return output_data
end
def channel_title_pattern
%r{<channel(?!s).*?>.*?(?:<title>(?:<!\[CDATA\[)*(.*?)(?:\]\]>)*</title>.*?)?</channel>}m
end
def item_title_pattern
%r{<item(?!s).*?>.*?(?:<title>(?:<!\[CDATA\[)*(.*?)(?:\]\]>)*</title>.*?)?</item>}m
end
def item_links_pattern
%r{<item(?!s).*?>.*?(?:<link>(?:<!\[CDATA\[)*(.*?)(?:\]\]>)*</link>.*?)?</item>}m
end
def item_description_pattern
%r{<item(?!s).*?>.*?(?:<description>(?:<!\[CDATA\[)*(.*?)(?:\]\]>)*</description>.*?)?</item>}m
end
end
##############################
def align text
text.gsub(/^\s*\./m, '')
end
##############################
class RssMaker
def header
align <<-HTML
.Content-type: text/html\r\n\r\n
.<html>
.<body>
HTML
end
def footer
align <<-HTML
.</body>
.</html>
HTML
end
def channel name
align <<-HTML
.<h3>#{name}</h3>
HTML
end
def entry titolo, descrizione, link
align <<-HTML
.<strong>
. <a href="#{link}"> #{titolo} </a>
.</strong><br/>
.
.<font size="-1"> #{descrizione} </font>
.<p/>
HTML
end
end
##############################
# Configurations
feeds=[
'http://www.repubblica.it/rss/scienza_e_tecnologia/rss2.0.xml',
'http://programmazione.it/rss.xml',
'http://www.hwupgrade.it/rss_news.xml',
'http://www.hwupgrade.it/rss_articoli.xml',
'http://www.beppegrillo.it/index.xml'
]
NEED_PROXY = false #switch this if you have a proxy
proxy_url = "http://10.0.0.2:8080" #put here your proxy, if you have one
##############################
rss_make = RssMaker.new
puts rss_make.header
feeds.each do |feed|
if NEED_PROXY
parser = Rss_parser.new feed, proxy_url
else
parser = Rss_parser.new feed
end
data = parser.esegui_parsing
puts rss_make.channel( data.channel )
0.upto data.titles.length do|i|
puts rss_make.entry(
data.titles[i],
data.descriptions[i],
data.links[i]
)
end
end
puts rss_make.footer