2007年 04月 14日

とちゅうでやめた

#!/usr/bin/ruby -d


require 'rubygems'
require 'twitter'

require 'socket'
require 'rice/irc'
require 'nkf'


class IrcTwitterGateway

	def initialize(host, port)
		@clients = []

		s = TCPServer.new(host, port)
		Thread.start(s) do |s|
			loop do
				@clients << Session.new(s.accept)
			end
		end

		# @pass, @nick, @login, @user

	end


	class Session
		include RICE

		NAME = "twittergw"
		VERSION = -1
		CHANNEL = "#twitter"

		def initialize(socket)
			@s = socket
			begin
				while l = @s.gets
					$stderr.puts 's <- c: ' + l.inspect if $DEBUG
					begin
						m = Message.parse(l)
						p m
						case m
						when Command::PASS
							@pass = m.params[0]

						when Command::NICK
							@nick = m.params[0]

						when Command::USER
							@login, @real = m.params[0], m.params[3]
							@host = @s.peeraddr[2]
							@mask = "#{@nick}!#{@login}@#{@host}"
							p [@nick, @login, @real, @pass]

							on_user(m)

						when Command::PRIVMSG
							on_privmsg(m)

						end
					rescue InvalidMessage, UnknownCommand
						$stderr.puts '- -: ' + l.inspect if $DEBUG
					end
					break if m.kind_of?(Command::QUIT)
				end
			#rescue IOError
			ensure
				@s.close
			end
		end

		def on_user(m)
			@s << Message.new(NAME, "001", [@nick, "Welcome to the Internet Relay Network #{@mask}"])
			@s << Message.new(NAME, "002", [@nick, "Your host is #{NAME}, running version #{VERSION}"])
			@s << Message.new(NAME, "003", [@nick, "This server was created #{Time.now}"])
			@s << Message.new(NAME, "004", [@nick, "#{NAME} `Tynoq` v#{VERSION}"])
			@s << Message.new(@mask, "JOIN", [CHANNEL, ""])
			log "Hello this is Twitter Gateway."


			@twitter = ::Twitter::Base.new(@real, @pass)
			@friends = @twitter.friends
			@s << Message.new(NAME, "353", [@nick, "=", CHANNEL, @friends.map{|i| i.screen_name }.join(" ")])
			@s << Message.new(NAME, "366", [@nick, CHANNEL, "End of NAMES list"])

			@timeline = []
			Thread.start do
				loop do
					check_timeline
					check_friends
					sleep 60
				end
			end
		end

		def on_privmsg(m)
		end

		private
		def check_timeline
			@twitter.timeline.each do |s|
				message(s.user.screen_name, CHANNEL, s.created_at.to_s + s.text)
			end
		end

		def message(sender, target, str)
			str.gsub!(/&#(x)?([0-9a-f]+);/i) do |m|
				[$1 ? $2.hex : $2.to_i].pack("U")
			end
			@s << Message.new(sender, "PRIVMSG", [target, NKF.nkf("-j", str)])
		end

		def log(str)
			@s << Message.new(NAME, "NOTICE", [CHANNEL, str])
		end
	end
end

host, port = nil, 19876
IrcTwitterGateway.new(host, port)
sleep

rubyforge の twitter gem package は依存が微妙にやっかい (外部サイトへの依存がある) なのと、since 指定でとってこれないので、自分でかいたほうがいい。