neufelry-twitter-sms 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,32 @@
1
+ twitter-sms: Twitter SMS for the rest of us.
2
+ =======================================
3
+
4
+ Twitter-sms bridges the gap left by Twitter.com when it removed SMS capability for many countries. Twitter-sms runs in the background and periodically checks Twitter for new tweets; When new tweets are found they are forwarded via a gmail account to your mobile phone's email address.
5
+
6
+ All it requires is:
7
+ * A running computer with internet access and Ruby installed. (*nix systems only for the moment.),
8
+ * A google email address (to forward messages from) and,
9
+ * An SMS capable phone with an email-to-sms email address. (i.e. 12345551234@text.provider.net that automatically forwards messages to your phone as SMS)
10
+
11
+ DISCLAIMER: Please bear in mind that it MAY cost you to receive text message on your email address; I am not responsable for any costs incurred to you using this program.
12
+
13
+ Setup
14
+ -----
15
+ To use twitter-sms you will need only to create the config file "~/.twitter-sms.conf" and fill it with the necessary YAML mappings.
16
+
17
+ Here is an example conf:
18
+
19
+ bot:
20
+ email: "twitter.bot@gmail.com"
21
+ password: p0n33zR0oL
22
+ user:
23
+ name: rkneufeld
24
+ password: p0n33zR0oL
25
+ phone: "12045555555@text.provider.net"
26
+ config:
27
+ per_hour: 12
28
+ keep_alive: true
29
+
30
+ This config will cause the script to run forever; sending you the last 5 minutes tweets every 5 minutes. (60 / 5 == 12)
31
+
32
+ One can also run the script as a cron job; instructions to follow soon...
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :minor: 3
3
+ :patch: 1
4
+ :major: 0
@@ -0,0 +1,193 @@
1
+ require 'rubygems'
2
+ require 'twitter'
3
+ require 'tlsmail'
4
+ require 'optparse'
5
+ require 'cgi'
6
+ require 'net/pop'
7
+
8
+ if RUBY_VERSION < "1.9"
9
+ raise "Version too low. Please get Ruby 1.9"
10
+ end
11
+
12
+ SEC_PER_HOUR = 3600 # Seconds per hour (don't like this...)
13
+
14
+ class TwitterSms
15
+
16
+ def initialize(config_file="#{ENV['HOME'] + '/.twitter-sms.conf'}", args=ARGV)
17
+ load_config(config_file)
18
+ load_opts(args) # Loaded options are intended to overide defaults
19
+
20
+ # Required for gmail smtp (and not a part of standalone Net::SMTP)
21
+ Net::SMTP.enable_tls(OpenSSL::SSL::VERIFY_NONE)
22
+ end
23
+
24
+ # Run the twitter-sms bot once or repeatedly, depending on config
25
+ def run
26
+ begin # do-while
27
+ load_config if config_stale? unless @config['dont_refresh']
28
+
29
+ if @config['active']
30
+ tweets = update
31
+ send tweets unless tweets.nil?
32
+ end
33
+
34
+ if @config['keep_alive']
35
+ putd "Waiting for ~#{@config['wait']/60.0} minutes..."
36
+ Kernel.sleep @config['wait']
37
+ end
38
+ end while @config['keep_alive']
39
+ tweets # Return the last set of tweets we get
40
+ end
41
+
42
+ # Collect a list of recent tweets on a user's timeline (that are not their own)
43
+ def update
44
+ twitter = Twitter::Base.new(@user['name'],@user['password'])
45
+
46
+ begin
47
+ if twitter.rate_limit_status.remaining_hits > 0
48
+ now = Time.now
49
+ tweets = twitter.timeline(:friends, :since => @last_check)
50
+ @last_check = now
51
+
52
+ # Block own tweets if specified via settings
53
+ tweets.reject! {|t| t.user.screen_name == @user['name']} unless @config['own_tweets']
54
+ # Don't send messages from users under no_follow
55
+ tweets.reject! {|t| @config['no_follow'].member?(t.user.screen_name) }
56
+ tweets.reverse # reverse-chronological
57
+ else
58
+ putd "Your account has run out of API calls; call not made."
59
+ end
60
+ rescue
61
+ putd "Error occured retreiving timeline. Perhaps Internet is down?"
62
+ end
63
+ end
64
+
65
+ # Email via Gmail SMTP any tweets to the desired cell phone
66
+ def send(tweets)
67
+ putd "Sending received tweets..."
68
+ begin
69
+ # Start smtp connection to provided bot email
70
+ Net::SMTP.start('smtp.gmail.com', 587, 'gmail.com',
71
+ @bot['email'], @bot['password'], :login) do |smtp|
72
+
73
+ tweets.each do |tweet|
74
+ smtp.send_message(content(tweet),@bot['email'],@user['phone']) rescue putd "Error occured sending message:"
75
+ putd "\tSent: #{tweet.user.screen_name}: #{tweet.text[0..20]}..."
76
+ end
77
+
78
+ end
79
+ putd "Messages sent."
80
+ rescue
81
+ putd "Error occured starting smtp. Perhaps account info is incorrect" +
82
+ " or Internet is down?"
83
+ end
84
+ end
85
+
86
+ private
87
+
88
+ # Put Debug (prepend time) if debug printouts turned on
89
+ def putd (message)
90
+ puts "#{Time.now.strftime("(%b %d - %H:%M:%S)")} #{message}" if @config['debug']
91
+ end
92
+
93
+ def collect_pop_messages
94
+ Net::POP3.enable_ssl(OpenSSL::SSL::VERIFY_NONE) # maybe verify...
95
+ Net::POP3.start('pop.gmail.com',995, @bot['email'], @bot['password']) do |pop|
96
+ pop.each_mail do |mail|
97
+ process_pop_message(mail)
98
+ end
99
+ end
100
+ end
101
+
102
+ def process_pop_message(msg)
103
+ p mail.inspect
104
+ end
105
+
106
+ # Parse and store a config file (either as an initial load or as
107
+ # an update)
108
+ def load_config(config_file=@config_file['name'])
109
+ # Load config file -- Add try block here
110
+ loaded_config = YAML.load_file(config_file)
111
+ @config_file = { 'name' => config_file,
112
+ 'modified_at' => File.mtime(config_file) }
113
+
114
+ # Seperate config hashes into easier to use parts
115
+ @user = loaded_config['user']
116
+ @bot = loaded_config['bot']
117
+
118
+ config_defaults = { 'own_tweets' => false,
119
+ 'keep_alive' => true,
120
+ 'per_hour' => 30,
121
+ 'debug' => false,
122
+ 'dont_refresh' => false,
123
+ 'active' => true}
124
+
125
+ # Merge specified config onto defaults
126
+ @config = config_defaults.merge(loaded_config['config'])
127
+
128
+ set_wait
129
+ @last_check = Time.now - @config['wait']
130
+ putd "Loaded config file"
131
+ end
132
+
133
+ # Set wait time based on times per hour
134
+ def set_wait
135
+ @config['wait'] = SEC_PER_HOUR / @config['per_hour']
136
+ end
137
+
138
+ def load_opts(args)
139
+ opts = OptionParser.new do |opts|
140
+ opts.banner = "Twitter-sms bot help menu:\n"
141
+ opts.banner += "==========================\n"
142
+ opts.banner += "Usage #$0 [options]"
143
+
144
+ # The problem with this is if the asked for config file doesn't exist
145
+ opts.on('-c', '--config-file [FILE]',
146
+ 'Location of the config file to be loaded') do |filename|
147
+ load_config(filename)
148
+ end
149
+
150
+ opts.on('-t', '--times-per-hour [TIMES]',
151
+ 'Indicate the amount of times per hour to check (> 0)') do |times|
152
+ times = 1 if times <= 0
153
+ @config['per_hour'] = times
154
+ end
155
+
156
+ opts.on('-o', '--own-tweets',
157
+ "Makes your own tweets send in addition to followed account\'s tweets") do
158
+ @config['own_tweets'] = true
159
+ end
160
+
161
+ opts.on('-s', '--single-check',
162
+ 'Forces the program to only check once, instead of continually') do
163
+ @config['keep_alive'] = false
164
+ end
165
+
166
+ opts.on_tail('-h', '--help', 'display this help and exit') do
167
+ puts opts
168
+ exit
169
+ end
170
+ end
171
+
172
+ opts.parse!(args)
173
+ end
174
+
175
+ def config_stale?
176
+ return File.mtime(@config_file['name']) > @config_file['modified_at']
177
+ end
178
+
179
+ # Produce the content of the SMTP message to be sent
180
+ def content(tweet)
181
+ "From: #{@bot['email']}\n"+
182
+ "To: #{@user['phone']}\n"+
183
+ #On date line 2 '\n's are required for proper message
184
+ "Date: #{Time.parse(tweet.created_at).rfc2822}\n\n"+
185
+ "#{tweet.user.screen_name}: #{CGI.escapeHTML(tweet.text)}"
186
+ end
187
+
188
+ end
189
+
190
+ def filename(path)
191
+ path.split('/')[-1]
192
+ end
193
+
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+ require 'mocha'
5
+
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'twitter_sms'
8
+
9
+ class Test::Unit::TestCase
10
+ end
@@ -0,0 +1,7 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class TwitterSmsTest < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: neufelry-twitter-sms
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Neufeld
@@ -39,7 +39,13 @@ extensions: []
39
39
  extra_rdoc_files: []
40
40
 
41
41
  files:
42
+ - README.md
43
+ - VERSION.yml
42
44
  - bin/twitter-sms
45
+ - lib/twitter-sms
46
+ - lib/twitter-sms/twitter-sms.rb
47
+ - test/test_helper.rb
48
+ - test/twitter_sms_test.rb
43
49
  has_rdoc: true
44
50
  homepage: http://github.com/neufelry/twitter-sms
45
51
  post_install_message: