rjp-twittermoo 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/bin/twittermoo.rb +174 -0
  2. metadata +62 -0
data/bin/twittermoo.rb ADDED
@@ -0,0 +1,174 @@
1
+ require 'rubygems'
2
+ require 'twitter'
3
+ require 'gdbm'
4
+ require 'sha1'
5
+ require 'optparse'
6
+ require 'socket'
7
+
8
+ $options = {
9
+ :host => 'localhost',
10
+ :port => nil,
11
+ :dbfile => ENV['HOME'] + '/.twittermoo.db',
12
+ :config => ENV['HOME'] + '/.twittermoo',
13
+ :verbose => nil,
14
+ :once => nil,
15
+ :wait => 20
16
+ }
17
+
18
+ OptionParser.new do |opts|
19
+ opts.banner = "Usage: twittermoo.rb [-v] [-p port] [-h host] [-d dbfile] [-c config] [-o] [-w N]"
20
+
21
+ opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
22
+ $options[:verbose] = v
23
+ end
24
+
25
+ opts.on("-o", "--once", "Run once and quit") do |p|
26
+ $options[:once] = p
27
+ end
28
+
29
+ opts.on("-w", "--wait N", Integer, "Delay between sending messages") do |p|
30
+ $options[:wait] = p
31
+ end
32
+
33
+ opts.on("-p", "--port N", Integer, "irccat port") do |p|
34
+ $options[:port] = p
35
+ end
36
+
37
+ opts.on("-d", "--dbfile DBFILE", String, "dbfile") do |p|
38
+ $options[:dbfile] = p
39
+ end
40
+
41
+ opts.on("-h", "--host HOST", String, "host") do |p|
42
+ $options[:host] = p
43
+ end
44
+
45
+ opts.on("-c", "--config CONFIG", String, "config file") do |p|
46
+ $options[:config] = p
47
+ end
48
+ end.parse!
49
+
50
+ def send_message(x)
51
+ if $options[:port].nil? then
52
+ puts "! #{x}"
53
+ else
54
+ begin
55
+ # irc_cat doesn't seem to like persistent connections
56
+ $socket = TCPSocket.new($options[:host], $options[:port])
57
+ $socket.puts(x)
58
+ $socket.close
59
+ end
60
+ end
61
+ end
62
+
63
+ # TODO move this to something like log4r if they have it
64
+ def log(x)
65
+ if $options[:verbose] then
66
+ puts *x
67
+ end
68
+ end
69
+
70
+ config = YAML::load(open($options[:config]))
71
+
72
+ # TODO add an option for OAuth
73
+ httpauth = Twitter::HTTPAuth.new(config['email'], config['password'])
74
+ twitter = Twitter::Base.new(httpauth)
75
+
76
+ already_seen = GDBM.new($options[:dbfile])
77
+
78
+ if $options[:once].nil? then
79
+ log "B fetching current timeline and ignoring"
80
+ twitter.friends_timeline().each do |s|
81
+ sha1 = SHA1.hexdigest(s.text + s.user.name)
82
+ xtime = Time.parse(s.created_at)
83
+ threshold = Time.now - 3600
84
+ if xtime < threshold then
85
+ already_seen[sha1] = "s"
86
+ end
87
+ end
88
+ end
89
+
90
+ prev_time = Time.now - 3600
91
+ log "L entering main loop"
92
+ loop {
93
+
94
+ log "T fetching direct messages since #{prev_time}"
95
+
96
+ twitter.direct_messages().each do |s|
97
+ log "D #{s.id} #{s.text}"
98
+ xtime = Time.parse(s.created_at)
99
+ if xtime > prev_time then
100
+ prev_time = xtime # this is kinda lame
101
+ end
102
+ end
103
+
104
+ log "T fetching current timeline"
105
+ tl = []
106
+ attempts = 5
107
+ loop do
108
+ begin
109
+ tl = twitter.friends_timeline()
110
+ log "Y timeline fetched successfully, #{tl.size} items"
111
+ break
112
+ rescue Timeout::Error, Twitter::CantConnect
113
+ log "E $!"
114
+ attempts = attempts - 1
115
+ if attempts == 0 then
116
+ log "too many failures, bailing for 120s"
117
+ sleep 120
118
+ attempts = 5
119
+ else
120
+ log "transient failure, sleeping for 30s"
121
+ sleep 30
122
+ end
123
+ rescue
124
+ raise $!
125
+ sleep 10
126
+ end
127
+ end
128
+
129
+ log "Y timeline fetched successfully, #{tl.size} items"
130
+
131
+ tl.reverse.each do |s|
132
+ sha1 = SHA1.hexdigest(s.text + s.user.name)
133
+ status = already_seen[sha1]
134
+ if status.nil? then
135
+ log "N +/#{sha1} #{s.user.name} #{s.text[0..6]}..."
136
+ ts = Time.parse(s.created_at)
137
+ output = "<#{s.user.screen_name}> #{s.text} (#{ts.strftime('%Y%m%d %H%M%S')})"
138
+ if s.text =~ /^@(\w+)\s/ then
139
+ log "? #{$1}"
140
+ if 1 then # twitter.friends.include?($1) then
141
+ log "+ #{output}"
142
+ if output.length > 250 then
143
+ $stderr.puts "#{output[0..250]}..."
144
+ exit;
145
+ end
146
+ send_message(output)
147
+ else
148
+ log "- #{output}"
149
+ end
150
+ else
151
+ log "+ #{output}"
152
+ if output.length > 250 then
153
+ $stderr.puts "#{output[0..250]}..."
154
+ exit;
155
+ end
156
+ send_message(output)
157
+ end
158
+ already_seen[sha1] = "p"
159
+ sleep $options[:wait]
160
+ else
161
+ if status != 'p' then
162
+ log "O #{status}/#{sha1} #{s.user.name} #{s.text[0..6]}..."
163
+ end
164
+ already_seen[sha1]='p'
165
+ end
166
+ end
167
+
168
+ if $options[:once].nil? then
169
+ log "S #{Time.now}"
170
+ sleep 300
171
+ else
172
+ break
173
+ end
174
+ }
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rjp-twittermoo
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Rob Partington
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-05-16 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: twitter
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0.5"
24
+ version:
25
+ description:
26
+ email: zimpenfish@gmail.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files: []
32
+
33
+ files:
34
+ - bin/twittermoo.rb
35
+ has_rdoc: false
36
+ homepage: http://rjp.github.com/twittermoo
37
+ post_install_message:
38
+ rdoc_options: []
39
+
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: "0"
47
+ version:
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: "0"
53
+ version:
54
+ requirements: []
55
+
56
+ rubyforge_project:
57
+ rubygems_version: 1.2.0
58
+ signing_key:
59
+ specification_version: 2
60
+ summary: Simple Twitter-to-Socket gateway
61
+ test_files: []
62
+