tweeter-bachue 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -44,13 +44,13 @@ Then please edit them:
44
44
  1. Edit `config/key.yml`
45
45
  2. Replace with your consumer key/secret, oauth token, oauth token secret (google if you need help)
46
46
  3. Then edit `config/proxies.yml`
47
- 4. Add all your proxies info into this file. in this file, host, port and user are related to the ssh account, and gemset and path is related to `tweet` command
47
+ 4. Add all your proxies info into this file. in this file, host, port and user are related to the ssh account, and gemset and path is related to `tweet` command(To be security, password is totally forbidden)
48
48
  5. Don't forget to install and config `tweeter-bachue` in all your proxies in the same way
49
49
  6. You'd better delete `proxies.yml` if you haven't any proxy
50
50
 
51
51
  After all, try:
52
52
 
53
- $ tweet "This is my 'hello world', sent from `tweet-bachue` gem"
53
+ $ tweet "This is my 'hello world', sent from 'tweet-bachue' gem"
54
54
 
55
55
  `tweeter-bachue` will try to tweet it by itself. if it failed for 3 times, will try the same command on each of your proxies by ssh one by one, until anyone of them puts "Succeed". when the `tweeter-bachue` in your proxies failed for 3 times, it will also do the same thing, try its proxies.
56
56
 
@@ -58,7 +58,7 @@ If all tries are failed, `tweeter-bachue` will write the tweet in a file which i
58
58
 
59
59
  ## Contributing
60
60
 
61
- 1. Fork it from <https://gitcafe.com/bachue/tweeter.git>
61
+ 1. Fork it from `git@gitcafe.com:bachue/tweeter.git`
62
62
  2. Create your feature branch (`git checkout -b my-new-feature`)
63
63
  3. Commit your changes (`git commit -am 'Add some feature'`)
64
64
  4. Push to the branch (`git push origin my-new-feature`)
data/bin/tweet CHANGED
@@ -4,44 +4,127 @@ require 'rubygems'
4
4
  require 'twitter'
5
5
  require 'yaml'
6
6
  require 'socket'
7
+ require 'net/ssh'
7
8
  require 'active_support/all'
8
9
 
9
- def lost_file_name(path)
10
- name = Time.now.to_f.to_s.sub('.', '') + '.tweet'
11
- File.join(path, name)
12
- end
13
-
14
- if ARGV.first.downcase == 'proxy'
15
- is_proxy = true
16
- ARGV.shift
17
- end
18
-
19
- tweet = ARGV.join(' ')
20
-
21
- exit if tweet.blank?
22
-
23
- root_dir = File.expand_path File.join(File.dirname(__FILE__), '..')
24
- config_dir = File.join(root_dir, 'config')
25
- lost_dir = File.join(root_dir, 'lost')
26
- client_info = YAML.load_file(File.join(config_dir, 'key.yml')).symbolize_keys
27
- proxies_info = YAML.load_file(File.join(config_dir, 'proxies.yml')).map(&:symbolize_keys) rescue []
28
-
29
- @client = Twitter::Client.new(client_info)
30
- retry_count = 0
31
- begin
32
- retry_count += 1
33
- @client.update(tweet)
34
- puts 'Succeed'
35
- rescue
36
- retry if retry_count < 3
37
- puts "Failed to tweet by #{Socket.gethostname}, ask the proxies"
38
- proxies_info = proxies_info.map { |proxy| [proxy[:host], proxy[:port], proxy[:user], proxy[:path], proxy[:gemset]] }
39
- catch(:succ) {
40
- proxies_info.each { |host, port, user, path, gemset|
41
- puts input = "ssh #{"#{user}@" if user.present?}#{host} #{"-p #{port}" if port.present?} \"#{"rvm use #{gemset} &&" if gemset.present?} #{path.present? ? path : 'tweet' } proxy '#{tweet}'\""
42
- puts output = system(input) rescue next
43
- throw :succ if output =~ /Succeed/
10
+ URL_REGEX = /((http|https):\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(([0-9]{1,5})?\/.*)?/ix
11
+ TWEET_MAX_LENGTH = 150 # The real value is 140, but set 150 here because the length limitation function is not exact
12
+ SHORT_URL_LENGTH = 23
13
+
14
+ def start!
15
+ exit_if_no_args!
16
+ set_proxy_if_it_is!
17
+ exit_if_invalid!(tweet)
18
+ twitter(tweet)
19
+ end
20
+
21
+ def twitter(tweet)
22
+ retry_count = 0
23
+ begin
24
+ retry_count += 1
25
+ client.update(tweet)
26
+ puts 'Succeed'
27
+ rescue
28
+ return if can_handle?
29
+ retry if retry_count < 3
30
+ puts "Failed to tweet by #{Socket.gethostname}, ask the proxies"
31
+ catch(:succ) {
32
+ proxies_info.each { |proxy|
33
+ remote_twitter proxy[:host], proxy[:port], proxy[:user], proxy[:path], proxy[:gemset]
34
+ }
35
+ File.write(lost_file, tweet) unless $is_proxy # reach here means failed in all proxies
36
+ exit 1
44
37
  }
45
- File.open(lost_file_name(lost_dir), 'w') { |f| f << tweet } unless is_proxy
38
+ end
39
+ end
40
+
41
+ def remote_twitter(host, port, user, path, gemset)
42
+ options = {:keys_only => true, :compression => true} # Password is forbidden here
43
+ options.merge! :port => port if port.present?
44
+ output = Net::SSH.start(host, user, :keys_only => true) { |ssh|
45
+ ssh.exec! <<-SHELL
46
+ #{"rvm use #{gemset} &&" if gemset.present?}
47
+ #{path.present? ? path : 'tweet'} proxy #{tweet.dump}
48
+ SHELL
46
49
  }
50
+ throw :succ if output =~ /Succeed/
51
+ end
52
+
53
+ def can_handle?
54
+ case $!.message
55
+ when /Status is a duplicate/
56
+ puts 'Succeed'
57
+ true
58
+ when /Could not authenticate you/
59
+ puts 'Failed to authenticate'
60
+ exit 4
61
+ when /Status is over \d+ characters/
62
+ puts 'Too long'
63
+ exit 3
64
+ else
65
+ false
66
+ end
67
+ end
68
+
69
+ def exit_if_invalid!(tweet)
70
+ unless valid?(tweet)
71
+ puts 'Too long'
72
+ exit 3
73
+ end
74
+ end
75
+
76
+ def valid?(tweet)
77
+ tweet.gsub(URL_REGEX, '*' * SHORT_URL_LENGTH).size <= TWEET_MAX_LENGTH
78
+ end
79
+
80
+ def exit_if_no_args!
81
+ exit 2 if ARGV.blank?
82
+ end
83
+
84
+ def set_proxy_if_it_is!
85
+ if ARGV.first.downcase == 'proxy'
86
+ $is_proxy = true
87
+ ARGV.shift
88
+ end
89
+ end
90
+
91
+ def tweet
92
+ @tweet ||= ARGV.join(' ')
47
93
  end
94
+
95
+ def lost_file
96
+ name = Time.now.to_f.to_s.sub('.', '') + '.tweet'
97
+ lost_path(name)
98
+ end
99
+
100
+ def root_path(filename = nil)
101
+ file = File.expand_path File.join(File.dirname(__FILE__), '..')
102
+ file = File.join(file, filename) if filename.present?
103
+ file
104
+ end
105
+
106
+ def config_path(filename = nil)
107
+ file = root_path('config')
108
+ file = File.join(file, filename) if filename.present?
109
+ file
110
+ end
111
+
112
+ def lost_path(filename = nil)
113
+ file = root_path('lost')
114
+ file = File.join(file, filename) if filename.present?
115
+ file
116
+ end
117
+
118
+ def client_info
119
+ @client_info ||= YAML.load_file(config_path('key.yml')).symbolize_keys
120
+ end
121
+
122
+ def proxies_info
123
+ @proxies_info ||= YAML.load_file(config_path('proxies.yml')).map(&:symbolize_keys) rescue []
124
+ end
125
+
126
+ def client
127
+ @client ||= Twitter::Client.new(client_info)
128
+ end
129
+
130
+ start!
@@ -1,3 +1,3 @@
1
1
  module Tweeter
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -19,6 +19,7 @@ Gem::Specification.new do |gem|
19
19
  gem.add_dependency 'twitter'
20
20
  gem.add_dependency 'activesupport', '>= 3.0.0'
21
21
  gem.add_dependency 'rake'
22
+ gem.add_dependency 'net-ssh'
22
23
  gem.add_development_dependency 'pry'
23
24
  gem.add_development_dependency 'pry-doc'
24
25
  gem.add_development_dependency 'pry-nav'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tweeter-bachue
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-12 00:00:00.000000000 Z
12
+ date: 2013-01-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: twitter
@@ -59,6 +59,22 @@ dependencies:
59
59
  - - ! '>='
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: net-ssh
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
62
78
  - !ruby/object:Gem::Dependency
63
79
  name: pry
64
80
  requirement: !ruby/object:Gem::Requirement
@@ -157,7 +173,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
157
173
  version: '0'
158
174
  segments:
159
175
  - 0
160
- hash: -2088777374129425809
176
+ hash: 670411791857878890
161
177
  required_rubygems_version: !ruby/object:Gem::Requirement
162
178
  none: false
163
179
  requirements:
@@ -166,7 +182,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
166
182
  version: '0'
167
183
  segments:
168
184
  - 0
169
- hash: -2088777374129425809
185
+ hash: 670411791857878890
170
186
  requirements: []
171
187
  rubyforge_project:
172
188
  rubygems_version: 1.8.24