#!/usr/bin/env ruby require 'socket' require 'net/http' require 'uri' require 'rss' module PhidgetApplication class PhidgetBiff def initialize(ip = "127.0.0.1", port = 4321, interval = 10, url_file = "url.txt") main(ip, port, interval, url_file) end def main(ip, port, interval, url_file) uris = load_uri(url_file) modified_times = init_modified_time(uris) socket = TCPSocket.new(ip, port) init_pin(socket) biff_loop(socket, uris, modified_times, interval) while line = socket.gets pin, data = parse(line) if data != nil && data == 1 set_pin(socket, pin, 0) open_url(uris[pin]) end end socket.close end ########################################################## def load_uri(url_file) uris = Array.new File.open(url_file) do |f| f.each do |line| if(line !~ /^#/) line.chomp! puts line uris.push(URI.parse(line)) break if uris.length > 8 end end end uris end def init_pin(socket) for i in 0..8 set_pin(socket, i, 0) end end def init_modified_time(uris) modified_times = Hash.new uris.each do |uri| time = get_modified_time(uri) modified_times[uri] = time end modified_times end def parse(line) args = line.split(",") if args[0] == "In" and args[1] == "InterfaceKit" and args[2] == "Digital" port = args[3].to_i data = args[4].to_i end return port, data end def open_url(uri) url = uri.to_s if(uri.path =~ /[.]rdf$/) url = parse_rss(uri) end system "cygstart #{url}" end def parse_rss(uri) url = nil Net::HTTP.start(uri.host) do |http| begin response = http.get(uri.path) rss = RSS::Parser.parse(response.body) url = rss.channel.link.to_s rescue end end url end ########################################################## def biff_loop(socket, uris, modified_times, sleep_time = 10) Thread.start do while true uris.each do |uri| time = get_modified_time(uri) puts uri.to_s puts " " + time.to_s if(time != nil && modified_times[uri] < time) set_pin(socket, uris.index(uri), 1) modified_times[uri] = time end end sleep(sleep_time) end end end def get_modified_time (uri, timeout = 2) return nil unless /^http/ =~ uri.to_s time = nil dead = Time.at(0) begin uri_const = URI.parse(uri.to_s) http = http_connect(uri_const, timeout) response = http.head(uri.to_s) if response.code.to_i != 200 time = dead elsif response['last-modified'] time = Time.httpdate(response['last-modified']) else time = Time.now end rescue Net::ProtoFatalError => e # 404 time = dead rescue time = dead # timeout? end time end def http_connect(uri, timeout) http = Net::HTTP.new(uri.host, uri.port) http.open_timeout = timeout http.read_timeout = timeout http end def set_pin(socket, pin, state = 0, delimiter = "\r\n") str = "Out,InterfaceKit,#{pin},#{state}" + delimiter socket.print str end def PhidgetBiff.print_usage puts "Usage:" puts " % PhidgetBiff [ip] [port] [interval] [url_file]" puts " % PhidgetBiff [ip] [port] [interval]" puts " % PhidgetBiff [interval]" puts " % PhidgetBiff " end end ############################################# #プログラム開始 ############################################# case ARGV.length when 0: PhidgetBiff.print_usage PhidgetBiff.new() when 1: PhidgetBiff.new("127.0.0.1", 4321, ARGV[0].to_i) when 2: PhidgetBiff.new(ARGV[0], ARGV[1].to_i) when 3: PhidgetBiff.new(ARGV[0], ARGV[1].to_i, ARGV[2].to_i) when 4: PhidgetBiff.new(ARGV[0], ARGV[1].to_i, ARGV[2].to_i, ARGV[3]) else PhidgetBiff.print_usage exit(0) end end