irccat 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ gem 'rack'
2
+ gem 'json'
3
+
4
+ group :test do
5
+ gem 'rake', :group => :test
6
+ end
data/README.txt ADDED
@@ -0,0 +1,33 @@
1
+ irc_cat
2
+ ---------
3
+
4
+ = Introduction
5
+
6
+ Irc_Cat is a Ruby IRC bot, inspired by irccat from Last.FM.
7
+
8
+ You can send messages to IRC from a TCP socket or from HTTP.
9
+
10
+ = Configuration
11
+
12
+ http://irccat.rubyforge.org/install.html
13
+
14
+ = How-to use
15
+
16
+ http://irccat.rubyforge.org/use.html
17
+
18
+ = Authentication
19
+
20
+ = Extend
21
+
22
+ = Links
23
+
24
+ * Website: http://irccat.rubyforge.org/
25
+ * Project: http://rubyforge.org/projects/irccat
26
+ * Downloads: http://rubyforge.org/frs/?group_id=5423
27
+ * Bugs: http://webs.lighthouseapp.com/projects/14710-irccat
28
+ * Repository: http://github.com/webs/irccat
29
+
30
+ ----
31
+ Copyright (c) 2007-2008 Jordan Bracco <jordan@lifeisdead.net>
32
+ Inspired by the irccat bot of Last.FM.
33
+ Released under the MIT licence :)
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
data/bin/icat ADDED
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # `cat` for irccat :)
4
+ #
5
+ # Created on 2008-2-17.
6
+ # Copyright (c) 2008. All rights reserved.
7
+
8
+ require 'optparse'
9
+ require 'yaml'
10
+
11
+ OPTIONS = {
12
+ :profile => 'default'
13
+ }
14
+ MANDATORY_OPTIONS = %w( )
15
+
16
+ parser = OptionParser.new do |opts|
17
+ opts.banner = <<BANNER
18
+ icat - just like cat but for irccat
19
+
20
+ Usage: #{File.basename($0)} [options] <files or STDIN>
21
+
22
+ Options are:
23
+ BANNER
24
+ opts.separator ""
25
+ opts.on("-p", "--profile=PROFILE", String,
26
+ "Profile to use (in ~/.irccat.yml).",
27
+ "Default: 'default'") { |OPTIONS[:profile]| }
28
+ opts.on("-h", "--help",
29
+ "Show this help message.") { puts opts; exit }
30
+ opts.parse!(ARGV)
31
+
32
+ if MANDATORY_OPTIONS && MANDATORY_OPTIONS.find { |option| OPTIONS[option.to_sym].nil? }
33
+ puts opts; exit
34
+ end
35
+ end
36
+
37
+ raise "Can't read configuration file (~/.irccat.yml)" unless File.exists?(File.expand_path("~/.irccat.yml"))
38
+ @config = YAML.load_file(File.expand_path("~/.irccat.yml"))
39
+
40
+ @profile = @config["#{OPTIONS[:profile]}"]
41
+ raise "Can't find profile #{OPTIONS[:profile]} in ~/.irccat.yml" if @profile.nil?
42
+
43
+ require File.dirname(__FILE__) + '/../lib/irc_cat/tcp_client'
44
+
45
+ if ARGV.empty?
46
+ puts "has stdin"
47
+ message = STDIN.read
48
+ IrcCat::TcpClient.notify(@profile['host'], @profile['port'], message)
49
+ else
50
+ ARGV.each do |file|
51
+ raise "Can't read #{file}" unless File.exists?(File.expand_path(file))
52
+ IrcCat::TcpClient.notify(@profile['host'], @profile['port'], File.read(File.expand_path(file)))
53
+ end
54
+ end
data/bin/iecho ADDED
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # `echo` for irccat :)
4
+ #
5
+ # Created on 2008-2-17.
6
+ # Copyright (c) 2008. All rights reserved.
7
+
8
+ require 'optparse'
9
+ require 'yaml'
10
+
11
+ OPTIONS = {
12
+ :profile => 'default'
13
+ }
14
+ MANDATORY_OPTIONS = %w( )
15
+
16
+ parser = OptionParser.new do |opts|
17
+ opts.banner = <<BANNER
18
+ iecho - just like echo but for irccat
19
+
20
+ Usage: #{File.basename($0)} [options] text
21
+
22
+ Options are:
23
+ BANNER
24
+ opts.separator ""
25
+ opts.on("-p", "--profile=PROFILE", String,
26
+ "Profile to use (in ~/.irccat.yml).",
27
+ "Default: 'default'") { |OPTIONS[:profile]| }
28
+ opts.on("-h", "--help",
29
+ "Show this help message.") { puts opts; exit }
30
+ opts.parse!(ARGV)
31
+
32
+ if MANDATORY_OPTIONS && MANDATORY_OPTIONS.find { |option| OPTIONS[option.to_sym].nil? }
33
+ puts opts; exit
34
+ end
35
+ end
36
+
37
+ raise "Can't read configuration file (~/.irccat.yml)" unless File.exists?(File.expand_path("~/.irccat.yml"))
38
+ @config = YAML.load_file(File.expand_path("~/.irccat.yml"))
39
+
40
+ @profile = @config["#{OPTIONS[:profile]}"]
41
+ raise "Can't find profile #{OPTIONS[:profile]} in ~/.irccat.yml" if @profile.nil?
42
+
43
+ raise "Nothing to send" if ARGV.empty?
44
+
45
+ require File.dirname(__FILE__) + '/../lib/irc_cat/tcp_client'
46
+
47
+ message = ARGV.join(' ')
48
+
49
+ IrcCat::TcpClient.notify(@profile['host'], @profile['port'], message)
data/bin/irccat ADDED
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Created on 2008-2-17.
4
+ # Copyright (c) 2008. All rights reserved.
5
+
6
+ require 'optparse'
7
+ require 'yaml'
8
+
9
+ options = {
10
+ :config_filename => './config.yml'
11
+ }
12
+
13
+ parser = OptionParser.new do |opts|
14
+ opts.banner = <<BANNER
15
+ irc_cat - stdout for irc
16
+
17
+ Usage: #{File.basename($0)} [options]
18
+
19
+ Options are:
20
+ BANNER
21
+
22
+ opts.separator ""
23
+
24
+ opts.on("-c", "--config=CONFIG", String, "Path to the config file.", "Default: ./config.yml") do |filename|
25
+ options[:config_filename] = filename
26
+ end
27
+
28
+ opts.on("-h", "--help", "Show this help message.") {
29
+ puts opts
30
+ exit
31
+ }
32
+ end
33
+
34
+ parser.parse!(ARGV)
35
+
36
+ raise "Can't read configuration file (#{options[:config_filename]})" unless File.exists?(options[:config_filename])
37
+ config = YAML.load_file(options[:config_filename])
38
+
39
+ lib_dir = File.dirname(__FILE__) + '/../lib/'
40
+ require lib_dir + '/irccat'
41
+
42
+ threads = []
43
+ puts "irccat #{IrcCat::VERSION} (http://irccat.rubyforge.org/)"
44
+
45
+ Thread.abort_on_exception = true
46
+
47
+ irc_config = config['irc']
48
+ IrcCat::Bot.run(irc_config['host'], irc_config['port'], irc_config['nick'], irc_config['pass']) do |bot|
49
+ puts "Connecting..."
50
+ irc_config['channels'].each do |channel|
51
+ name, pass = channel.split(" ")
52
+ bot.join_channel(name, pass)
53
+ end
54
+
55
+ tcp_config = config['tcp']
56
+ if tcp_config['enabled']
57
+ require lib_dir + 'irccat/tcp_server'
58
+ IrcCat::TcpServer.run(bot, tcp_config)
59
+ end
60
+
61
+ http_config = config['http']
62
+ http_config['channels'] = config['irc']['channels']
63
+ if http_config['enabled']
64
+ require lib_dir + 'irccat/http_server'
65
+ IrcCat::HttpServer.run(bot, http_config)
66
+ end
67
+ end
data/bin/irccat-config ADDED
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Configuration generator for irccat
4
+ #
5
+ # Created on 2008-2-17.
6
+ # Copyright (c) 2008. All rights reserved.
7
+
8
+ require 'rubygems'
9
+ require 'optparse'
10
+ require 'yaml'
11
+ require 'highline/import'
12
+
13
+ def irccat_config
14
+ config = Hash.new
15
+ puts "== IRC Configuration"
16
+ config['irc'] = Hash.new
17
+ config['irc']['host'] = ask("Hostname: ") { |q| q.default = "irc.freenode.net" }
18
+ config['irc']['port'] = ask("Port: ") { |q| q.default = "6667" }
19
+ config['irc']['nick'] = ask("Nickname: ") { |q| q.default = "irc_cat" }
20
+ config['irc']['channel'] = ask("Channel: ") { |q| q.default = "#irc_cat" }
21
+ puts "\n== HTTP Configuration"
22
+ config['http'] = Hash.new
23
+ if agree("Enable HTTP? ", true); config['http']['enabled'] = true; else; config['http']['enabled'] = false; end
24
+ if config['http']['enabled']
25
+ config['http']['host'] = ask("Hostname: ") { |q| q.default = "0.0.0.0" }
26
+ config['http']['port'] = ask("Port: ") { |q| q.default = "3489" }
27
+ if agree("Enable Basic HTTP send? ", true); config['http']['send'] = true; else; config['http']['send'] = false; end
28
+ if agree("Enable Github? ", true); config['http']['github'] = true; else; config['http']['github'] = false; end
29
+ end
30
+ puts "\n== TCP Configuration"
31
+ config['tcp'] = Hash.new
32
+ if agree("Enable TCP? ", true); config['tcp']['enabled'] = true; else; config['tcp']['enabled'] = false; end
33
+ if config['tcp']['enabled']
34
+ config['tcp']['host'] = ask("Hostname: ") { |q| q.default = "0.0.0.0" }
35
+ config['tcp']['port'] = ask("Port: ") { |q| q.default = "5678" }
36
+ config['tcp']['size'] = ask("Socket size: ") { |q| q.default = "400" }
37
+ end
38
+ puts "\n== Final steps"
39
+ file = ask("Configuration filename: ") { |q| q.default = "config.yml" }
40
+ puts "Warning: File exists! If you choose yes now the file will be overwritten" if File.exists?(File.expand_path(file))
41
+ if agree("Write configuration file? ", true)
42
+ File.open(File.expand_path(file), "w") { |yfile| YAML.dump(config, yfile) }
43
+ else
44
+ exit
45
+ end
46
+ end
47
+
48
+ def help
49
+ puts "irccat-config - configuration generator for irccat\n"
50
+ puts "Usage: #{File.basename($0)} irccat|client > configfile.yml"
51
+ exit 0
52
+ end
53
+
54
+ if ARGV[0].nil?
55
+ help
56
+ else
57
+ case ARGV[0]
58
+ when 'irccat'
59
+ irccat_config
60
+ when 'client'
61
+ #client_config
62
+ # TODO: todo :D
63
+ help
64
+ else
65
+ help
66
+ end
67
+ end
@@ -0,0 +1,4 @@
1
+ # Configuration file for irccat clients (icat, iecho)
2
+ default:
3
+ host: 127.0.0.1
4
+ port: 5678
@@ -0,0 +1,29 @@
1
+ # IRC connection
2
+ irc:
3
+ host: 'irc.freenode.net'
4
+ port: '6667'
5
+ nick: irc_cat
6
+ channels:
7
+ - "#austinhackerspace"
8
+ # This is a channel with a key
9
+ #- "#secret password"
10
+
11
+ # HTTP Server
12
+ http:
13
+ enabled: true
14
+ # user: http_user
15
+ # pass: http_pass
16
+ host: 0.0.0.0
17
+ port: '3489'
18
+ # Enable post-receive stuff from Github
19
+ github: true
20
+ # Allow send with http
21
+ send: true
22
+ message_param: Message
23
+
24
+ # TCP Server
25
+ tcp:
26
+ enabled: true
27
+ host: 0.0.0.0
28
+ port: '5678'
29
+ size: 400
data/irccat.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "irccat/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "irccat"
7
+ s.version = IrcCat::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["people"]
10
+ s.email = ["folks"]
11
+ s.homepage = ""
12
+ s.summary = %q{Write a gem summary}
13
+ s.description = %q{Write a gem description}
14
+
15
+ s.rubyforge_project = "irccat"
16
+
17
+ s.add_dependency 'rack'
18
+ s.add_dependency 'json'
19
+ s.add_dependency 'mongrel'
20
+
21
+ s.files = `git ls-files`.split("\n")
22
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
23
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
24
+ s.require_paths = ["lib"]
25
+ end
data/lib/irccat/bot.rb ADDED
@@ -0,0 +1,148 @@
1
+ # This is the bot.
2
+ # Original code by Madx (yapok.org)
3
+
4
+ module IrcCat
5
+ class Bot
6
+ def self.run(host, port, nick, nick_pass = nil, &block)
7
+ new(host, port, nick, nick_pass, &block).run
8
+ end
9
+
10
+ def initialize(host, port, nick, nick_pass, &block)
11
+ @host, @port, @nick, @nick_pass = host, port, nick, nick_pass
12
+ @online, @connect_block = false, block
13
+
14
+ @realname = "irccat v#{VERSION}"
15
+ @refresh_rate = 10
16
+ @channels = {}
17
+
18
+ puts "Connecting to IRC #{@host}:#{@port}"
19
+ end
20
+
21
+ def online?
22
+ @online
23
+ end
24
+
25
+ def run(&block)
26
+ @socket = TCPSocket.open(@host, @port)
27
+ login
28
+
29
+ trap(:INT) {
30
+ puts "Bye bye."
31
+ sexit('God^WConsole killed me')
32
+ sleep 1
33
+ @socket.close
34
+ exit
35
+ }
36
+
37
+ threads = []
38
+
39
+ threads << Thread.new {
40
+ begin
41
+ while line = @socket.gets do
42
+ # Remove all formatting
43
+ line.gsub!(/[\x02\x1f\x16\x0f]/,'')
44
+ # Remove CTCP ASCII
45
+ line.gsub!(/\001/,'')
46
+ # Send to event handler
47
+ handle line
48
+ # Handle Pings from Server
49
+ sendln "PONG #{$1}" if /^PING\s(.*)/ =~ line
50
+ end
51
+ rescue EOFError
52
+ err 'Server Reset Connection'
53
+ rescue Exception => e
54
+ err e
55
+ end
56
+ }
57
+ threads << Thread.new {
58
+ }
59
+ threads.each { |th| th.join }
60
+ end
61
+
62
+ # Announces states
63
+ def announce(msg)
64
+ @channels.each do |channel,key|
65
+ say(channel, msg)
66
+ end
67
+ end
68
+
69
+ # Say something funkeh
70
+ def say(chan, msg)
71
+ sendln "PRIVMSG #{chan} :#{msg}"
72
+ end
73
+
74
+ def topic(chan, msg)
75
+ sendln "TOPIC #{chan} :#{msg}"
76
+ end
77
+
78
+ # Send EXIT
79
+ def sexit(message = 'quit')
80
+ sendln "QUIT :#{message}"
81
+ end
82
+
83
+ # Sends a message to the server
84
+
85
+ def sendln(cmd)
86
+ puts "Send: #{cmd}"
87
+ if cmd.size <= 510
88
+ @socket.write("#{cmd}\r\n")
89
+ STDOUT.flush
90
+ else
91
+ end
92
+ end
93
+
94
+ # Handle a received message
95
+
96
+ def handle(line)
97
+ puts "Got: #{line}"
98
+ case line
99
+ when /^:.+\s376/
100
+ puts "We're online"
101
+ @online = true
102
+ @connect_block.call(self) if @connect_block
103
+ when /^:.+KICK (#[^\s]+)/
104
+ auto_rejoin($1)
105
+ end
106
+ end
107
+
108
+ # Automatic events
109
+
110
+ def join_channel(channel, key)
111
+ @channels[channel] = key
112
+ $stdout.flush
113
+ if key
114
+ sendln "JOIN #{channel} #{key}"
115
+ else
116
+ sendln "JOIN #{channel}"
117
+ end
118
+ end
119
+
120
+ def auto_rejoin(channel)
121
+ join_channel(channel, @channels[channel])
122
+ end
123
+
124
+ def login
125
+ begin
126
+ sendln "NICK #{@nick}"
127
+ sendln "USER irc_cat . . :#{@realname}"
128
+ if @nick_pass
129
+ puts "logging in to NickServ"
130
+ sendln "PRIVMSG NICKSERV :identify #{@nick_pass}"
131
+ end
132
+ rescue Exception => e
133
+ err e
134
+ end
135
+ end
136
+
137
+ # Logging methods
138
+
139
+ def log(str)
140
+ $stdout.puts "DEBUG: #{str}"
141
+ end
142
+
143
+ def err(exception)
144
+ $stderr.puts "ERROR: #{exception}"
145
+ $stderr.puts "TRACE: #{exception.backtrace}"
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,134 @@
1
+ module IrcCat
2
+ class HttpServer
3
+ class Unauthorized < StandardError; end
4
+ class BadRequest < StandardError; end
5
+
6
+ def self.run(bot, config)
7
+ new(bot, config).run
8
+ end
9
+
10
+ def initialize(bot, config)
11
+ @bot, @config = bot, config
12
+ end
13
+
14
+ def run
15
+ host, port = @config['host'], @config['port']
16
+ if handler = Rack::Handler.get(handler_name)
17
+ Thread.new {
18
+ handler.run(app, :Host => host, :Port => port)
19
+ }
20
+ else
21
+ raise "Could not find a valid Rack handler for #{handler_name.inspect}"
22
+ end
23
+ end
24
+
25
+ def handler_name
26
+ @config["server"] || "mongrel"
27
+ end
28
+
29
+ def app
30
+ endpoint = self
31
+ builder = Rack::Builder.new
32
+ if requires_auth?
33
+ builder.use Rack::Auth::Basic, "irccat" do |user,pass|
34
+ auth_user == user && auth_pass == pass
35
+ end
36
+ end
37
+ if prefix = @config["prefix"]
38
+ builder.map prefix do
39
+ run endpoint
40
+ end
41
+ else
42
+ builder.run endpoint
43
+ end
44
+ builder
45
+ end
46
+
47
+ def auth_user
48
+ @config["user"]
49
+ end
50
+
51
+ def auth_pass
52
+ @config["pass"]
53
+ end
54
+
55
+ def requires_auth?
56
+ if auth_user
57
+ if auth_pass
58
+ if auth_pass.empty?
59
+ raise "Empty HTTP password in config"
60
+ end
61
+ true
62
+ end
63
+ end
64
+ end
65
+
66
+ def call(env)
67
+ request = Rack::Request.new(env)
68
+
69
+ case request.path_info
70
+ when "/"
71
+ [200, {"Content-Type" => "text/plain"}, "OK"]
72
+ when "/topic"
73
+ message = request.params["message"]
74
+ if channel = request.params["channel"]
75
+ @bot.join_channel("##{channel}", request.params["key"])
76
+ @bot.topic("##{channel}", message)
77
+ else
78
+ raise "Need a channel"
79
+ end
80
+
81
+ [200, {"Content-Type" => "text/plain"}, "OK"]
82
+ when "/send"
83
+ raise "Send support is not enabled" unless @config["send"]
84
+
85
+ if @config['message_param']
86
+ message = request.params[@config['message_param']]
87
+ else
88
+ message = request.params["message"]
89
+ end
90
+
91
+ if channel = request.params["channel"]
92
+ @bot.join_channel("##{channel}", request.params["key"])
93
+ @bot.say("##{channel}", message)
94
+ elsif nick = request.params["nick"]
95
+ @bot.say(nick, message)
96
+ elsif channels = @config['channels']
97
+ channels.each do |channel|
98
+ @bot.say(channel, message)
99
+ end
100
+ else
101
+ raise "Unkown action"
102
+ end
103
+
104
+ [200, {"Content-Type" => "text/plain"}, "OK"]
105
+ when "/github"
106
+ raise "GitHub support is not enabled" unless @config["github"]
107
+
108
+ data = JSON.parse(request.POST['payload'])
109
+
110
+ repository = data['repository']['name']
111
+ data['commits'].each do |commit|
112
+ topic = commit['message'].split("\n").first
113
+ ref = commit['id'][0,7]
114
+ author = commit['author']['name']
115
+ @bot.announce "#{topic} - #{ref} - #{author}"
116
+ end
117
+
118
+ [200, {"Content-Type" => "text/plain"}, "OK"]
119
+ else
120
+ [404, {}, ""]
121
+ end
122
+ rescue Unauthorized
123
+ [401, {'WWW-Authenticate' => %(Basic realm="IrcCat")}, 'Authorization Required']
124
+ rescue BadRequest
125
+ [400, {}, 'Bad Request']
126
+ rescue Exception => e
127
+ puts "Got an error: #{e.class}, #{e.message}"
128
+ e.backtrace.each do |b|
129
+ puts "- #{b}"
130
+ end
131
+ [503, {}, "ERR"]
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,75 @@
1
+ # this class has dubious semantics and we only have it so that
2
+ # people can write params[:key] instead of params['key']
3
+
4
+ class HashWithIndifferentAccess < Hash
5
+ def initialize(constructor = {})
6
+ if constructor.is_a?(Hash)
7
+ super()
8
+ update(constructor)
9
+ else
10
+ super(constructor)
11
+ end
12
+ end
13
+
14
+ def default(key = nil)
15
+ if key.is_a?(Symbol) && include?(key = key.to_s)
16
+ self[key]
17
+ else
18
+ super
19
+ end
20
+ end
21
+
22
+ alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
23
+ alias_method :regular_update, :update unless method_defined?(:regular_update)
24
+
25
+ def []=(key, value)
26
+ regular_writer(convert_key(key), convert_value(value))
27
+ end
28
+
29
+ def update(other_hash)
30
+ other_hash.each_pair { |key, value| regular_writer(convert_key(key), convert_value(value)) }
31
+ self
32
+ end
33
+
34
+ alias_method :merge!, :update
35
+
36
+ def key?(key)
37
+ super(convert_key(key))
38
+ end
39
+
40
+ alias_method :include?, :key?
41
+ alias_method :has_key?, :key?
42
+ alias_method :member?, :key?
43
+
44
+ def fetch(key, *extras)
45
+ super(convert_key(key), *extras)
46
+ end
47
+
48
+ def values_at(*indices)
49
+ indices.collect {|key| self[convert_key(key)]}
50
+ end
51
+
52
+ def dup
53
+ HashWithIndifferentAccess.new(self)
54
+ end
55
+
56
+ def merge(hash)
57
+ self.dup.update(hash)
58
+ end
59
+
60
+ def delete(key)
61
+ super(convert_key(key))
62
+ end
63
+
64
+ def stringify_keys!; self end
65
+ def symbolize_keys!; self end
66
+
67
+ protected
68
+ def convert_key(key)
69
+ key.kind_of?(Symbol) ? key.to_s : key
70
+ end
71
+ def convert_value(value)
72
+ value.is_a?(Hash) ? value.with_indifferent_access : value
73
+ end
74
+ end
75
+
@@ -0,0 +1,9 @@
1
+ require 'socket'
2
+ module IrcCat
3
+ class TcpClient
4
+ def self.notify(ip,port,message)
5
+ socket = TCPSocket.open(ip,port)
6
+ socket.write(message + "\r\n")
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,38 @@
1
+ # The TCP Server
2
+ module IrcCat
3
+ class TcpServer
4
+ def self.run(bot, config)
5
+ new(bot, config).run
6
+ end
7
+
8
+ def initialize(bot, config)
9
+ @bot, @config = bot, config
10
+ end
11
+
12
+ def run
13
+ Thread.new do
14
+ socket = TCPserver.new(ip, port)
15
+ puts "Starting TCP (#{ip}:#{port})"
16
+
17
+ loop do
18
+ Thread.start(socket.accept) do |s|
19
+ str = s.recv(@config['size'])
20
+ sstr = str.split(/\n/)
21
+ sstr.each do |l|
22
+ @bot.announce("#{l}")
23
+ end
24
+ s.close
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ def ip
31
+ @config["ip"] || '127.0.0.1'
32
+ end
33
+
34
+ def port
35
+ @config["port"] || '8080'
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,3 @@
1
+ module IrcCat #:nodoc:
2
+ VERSION = '0.4.0'
3
+ end
data/lib/irccat.rb ADDED
@@ -0,0 +1,13 @@
1
+ require 'socket'
2
+ require 'rack'
3
+ require 'json'
4
+
5
+ current_dir = File.dirname(__FILE__)
6
+
7
+ require current_dir + '/irccat/version'
8
+ require current_dir + '/irccat/indifferent_access'
9
+ require current_dir + '/irccat/bot'
10
+
11
+ module Irccat
12
+ # Your code goes here...
13
+ end
metadata ADDED
@@ -0,0 +1,129 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: irccat
3
+ version: !ruby/object:Gem::Version
4
+ hash: 15
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 4
9
+ - 0
10
+ version: 0.4.0
11
+ platform: ruby
12
+ authors:
13
+ - people
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-03-24 00:00:00 -05:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rack
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: json
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :runtime
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ name: mongrel
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ type: :runtime
62
+ version_requirements: *id003
63
+ description: Write a gem description
64
+ email:
65
+ - folks
66
+ executables:
67
+ - icat
68
+ - iecho
69
+ - irccat
70
+ - irccat-config
71
+ extensions: []
72
+
73
+ extra_rdoc_files: []
74
+
75
+ files:
76
+ - .gitignore
77
+ - Gemfile
78
+ - README.txt
79
+ - Rakefile
80
+ - bin/icat
81
+ - bin/iecho
82
+ - bin/irccat
83
+ - bin/irccat-config
84
+ - examples/client.yml
85
+ - examples/server.yml
86
+ - irccat.gemspec
87
+ - lib/irccat.rb
88
+ - lib/irccat/bot.rb
89
+ - lib/irccat/http_server.rb
90
+ - lib/irccat/indifferent_access.rb
91
+ - lib/irccat/tcp_client.rb
92
+ - lib/irccat/tcp_server.rb
93
+ - lib/irccat/version.rb
94
+ has_rdoc: true
95
+ homepage: ""
96
+ licenses: []
97
+
98
+ post_install_message:
99
+ rdoc_options: []
100
+
101
+ require_paths:
102
+ - lib
103
+ required_ruby_version: !ruby/object:Gem::Requirement
104
+ none: false
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ hash: 3
109
+ segments:
110
+ - 0
111
+ version: "0"
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ hash: 3
118
+ segments:
119
+ - 0
120
+ version: "0"
121
+ requirements: []
122
+
123
+ rubyforge_project: irccat
124
+ rubygems_version: 1.6.0
125
+ signing_key:
126
+ specification_version: 3
127
+ summary: Write a gem summary
128
+ test_files: []
129
+