Skip to content

Instantly share code, notes, and snippets.

@NeoCat
Last active August 29, 2015 14:05
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NeoCat/e704e427b60112617b87 to your computer and use it in GitHub Desktop.
Save NeoCat/e704e427b60112617b87 to your computer and use it in GitHub Desktop.
Monitor your GMail mail box and tweet the damage report.
#!/usr/bin/ruby
require 'net/imap'
require 'nokogiri'
require 'twitter'
require 'cgi'
require 'open-uri'
mail_user = '***@gmail.com'
mail_password = '***'
mail_label = 'Ingress'
$tw_id = '***<Your Twitter ID>***'
$tw_client = Twitter::REST::Client.new do |config|
config.consumer_key = 'cAgdRnwNRPjf8vAXMCf6Zs87Z'
config.consumer_secret = 'ZtSABAdg6oBqNnKB5NWY098JV969iyj0dcdYvW1wSheJVpmMBa'
config.access_token = '***<Your Twitter Access Token>***'
config.access_token_secret = '***<Your Twitter Access Token Secret>***'
end
STDOUT.sync = true
def tweet(msg)
begin
puts "#{Time.now} #{msg}"
$tw_client.update(msg + " @" + $tw_id)
rescue => e
puts "#{Time.now} tweet failed: #{e}"
end
end
def process_body(body)
doc = Nokogiri::HTML(body)
link = doc.xpath("//table//table//tr[5]")[0].content == "LINK DESTROYED"
msg = link ? "LINK DAMAGE: " : "DAMAGE: "
damage_reports = doc.xpath("//table//table//tr[3]//div")
msg += damage_reports[0].content + "\n"
link_url = damage_reports[1].xpath("a/@href").to_s
msg += link_url + "\n"
geo = {}
if link_url.match /ll=([-0-9.]+),([-0-9.]+)/
geo = {:lat => $1.to_f, :long => $2.to_f}
end
damage_img = doc.xpath("//table//table//tr[4]//img[1]/@src")[0].to_s
damage_imgs = doc.xpath("//table//table//td/table/div/div[1]/img").map {|x| x["src"].to_s}.uniq[0,4]
puts "image: #{link ? damage_imgs.join(" ") : damage_img}"
damage_reports = doc.xpath("//table//table//tr[last()]//div[1]").first.inner_html
msg2 = msg + damage_reports.gsub(/.*<br>/, '').split[0,3].join(" ").gsub(/[Rr]esonators/,'res').gsub(/remaining/, 'rem')
puts "#{Time.now}: #{msg2}"
Thread.new do
begin
if link
ids = damage_imgs.map{|url| $tw_client.upload(open(url))}
p $tw_client.update(msg2 + " @" + $tw_id, geo.merge({:media_ids => ids.join(",")}))
else
$tw_client.update_with_media(msg2 + " @" + $tw_id, open(damage_img), geo)
end
rescue
begin
$tw_client.update_with_media(msg + " @" + $tw_id, open(damage_img), geo)
rescue => e
puts "tweet with photo failed: #{e}"
tweet msg
end
end
end
end
def process_mail(mail)
uid = mail.attr["UID"]
seen = mail.attr["FLAGS"].include? :Seen
body = mail.attr["BODY[1]"]
if mail.attr["BODY"].multipart?
n = mail.attr["BODY"].parts.map.with_index{|part,idx|
idx if part.media_type == "TEXT" and part.subtype == "HTML"
}.select{|x| x}[0]
if not n
raise "***NO HTML PART***"
end
if n != 0
body = $imap.uid_fetch(uid, "BODY[#{n+1}]")[0].attr["BODY[#{n+1}]"]
end
if mail.attr["BODY"].parts[n].encoding == "QUOTED-PRINTABLE"
body = body.unpack('M')[0]
end
end
process_body(body)
end
def fetch_mail(range)
begin
mail = $imap.fetch(range, ["UID","BODY","BODY[1]","FLAGS"])
begin
mail.each {|m| process_mail(m)}
rescue
puts "failed to process mail: #$! at #$@"
tweet "failed to process mail /"
end
rescue
puts "failed to fetch mail: #$! at #$@"
tweet "failed to fetch mail /"
end
end
$imap = nil
first_connect = true
while true
$last_id = -1
begin
unless $imap
sleep 5 unless first_connect
$imap = Net::IMAP.new('imap.gmail.com', 993, true)
$imap.login(mail_user, mail_password)
$imap.select(mail_label)
puts "#{Time.now} connected to IMAP server"
fetch_mail -1 if first_connect
first_connect = false
end
th = Thread.new do
sleep 600
$imap.idle_done
end
# puts "#{Time.now} entring IDLE ..."
$imap.idle do |resp|
if resp.name == "EXISTS"
p $last_id = resp.data
$imap.idle_done
else
p resp
end
end
# puts "#{Time.now} exit from IDLE ..."
th.kill
rescue Net::IMAP::Error => e
p e.inspect
if e.inspect.include? "connection closed"
puts "#{Time.now} connection closed: reconecting..."
$imap = nil
else
tweet "unknown mail server error /"
raise
end
end
next unless $imap
fetch_mail $last_id..-1 if $last_id != -1
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment