tweetwine 0.2.11 → 0.2.12
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +7 -0
- data/{MIT-LICENSE.txt → LICENSE.txt} +1 -1
- data/README.md +122 -0
- data/Rakefile +59 -78
- data/bin/tweetwine +1 -0
- data/example/example_helper.rb +3 -1
- data/example/search_statuses_example.rb +2 -0
- data/example/show_followers_example.rb +2 -0
- data/example/show_friends_example.rb +2 -0
- data/example/show_home_example.rb +2 -0
- data/example/show_mentions_example.rb +2 -0
- data/example/show_metadata_example.rb +2 -0
- data/example/show_user_example.rb +2 -0
- data/example/update_status_example.rb +2 -0
- data/example/use_http_proxy_example.rb +2 -0
- data/lib/tweetwine/cli.rb +2 -0
- data/lib/tweetwine/client.rb +2 -0
- data/lib/tweetwine/io.rb +16 -11
- data/lib/tweetwine/meta.rb +3 -1
- data/lib/tweetwine/options.rb +2 -0
- data/lib/tweetwine/retrying_http.rb +2 -0
- data/lib/tweetwine/startup_config.rb +2 -0
- data/lib/tweetwine/url_shortener.rb +2 -0
- data/lib/tweetwine/util.rb +9 -6
- data/lib/tweetwine.rb +2 -0
- data/man/tweetwine.1 +109 -0
- data/man/tweetwine.1.ronn +69 -0
- data/man/tweetwine.7 +216 -0
- data/man/tweetwine.7.ronn +122 -0
- data/test/cli_test.rb +3 -1
- data/test/client_test.rb +3 -1
- data/test/io_test.rb +38 -31
- data/test/options_test.rb +3 -1
- data/test/retrying_http_test.rb +11 -11
- data/test/startup_config_test.rb +4 -2
- data/test/test_helper.rb +57 -47
- data/test/url_shortener_test.rb +3 -1
- data/test/util_test.rb +10 -3
- metadata +145 -20
- data/README.rdoc +0 -117
- /data/example/{fixtures → fixture}/home.json +0 -0
- /data/example/{fixtures → fixture}/mentions.json +0 -0
- /data/example/{fixtures → fixture}/search.json +0 -0
- /data/example/{fixtures → fixture}/update.json +0 -0
- /data/example/{fixtures → fixture}/user.json +0 -0
- /data/example/{fixtures → fixture}/users.json +0 -0
- /data/test/{fixtures → fixture}/test_config.yaml +0 -0
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
=== 0.2.12 released 2010-04-17
|
2
|
+
|
3
|
+
* Since this is a command line application, provide documentation as gem
|
4
|
+
manual
|
5
|
+
* Fix highlighting of URLs when partial URLs match
|
6
|
+
* Improve test code structure
|
7
|
+
|
1
8
|
=== 0.2.11 released 2010-02-28
|
2
9
|
|
3
10
|
* Fix compatibility with rest-client 1.4.0
|
data/README.md
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
tweetwine -- a simple Twitter command line agent
|
2
|
+
================================================
|
3
|
+
|
4
|
+
## DESCRIPTION
|
5
|
+
|
6
|
+
Tweetwine supports showing the home timeline of the authenticated user, the
|
7
|
+
latest statuses of friends and followers, and the latest statuses that mention
|
8
|
+
the user. If that's not enough, statuses can be searched with arbitrary terms.
|
9
|
+
In addition, new statuses can be sent.
|
10
|
+
|
11
|
+
Features:
|
12
|
+
|
13
|
+
* Simple to use command line interface, with Bash completion support
|
14
|
+
* ANSI coloring of statuses, but in discreet manner
|
15
|
+
* Supports shortening URLs in a status update with a configurable shortening
|
16
|
+
service
|
17
|
+
* Configuration file for preferred settings
|
18
|
+
|
19
|
+
## INSTALL
|
20
|
+
|
21
|
+
Install Tweetwine with RubyGems:
|
22
|
+
|
23
|
+
$ gem install tweetwine
|
24
|
+
|
25
|
+
The program is compatible with both Ruby 1.8 and 1.9.
|
26
|
+
|
27
|
+
The program requires [rest-client](http://github.com/archiloque/rest-client)
|
28
|
+
gem to be installed. In addition, the program needs
|
29
|
+
[json](http://json.rubyforge.org/) gem on Ruby 1.8.
|
30
|
+
|
31
|
+
Documentation is provided as gem man pages. Use
|
32
|
+
[gem-man](http://github.com/defunkt/gem-man) to see them:
|
33
|
+
|
34
|
+
$ gem man tweetwine
|
35
|
+
|
36
|
+
## BASIC USAGE AND CONFIGURATION
|
37
|
+
|
38
|
+
In the command line, run the program by entering
|
39
|
+
|
40
|
+
$ tweetwine [ <GLOBAL_OPTIONS> ] [ <COMMAND> ] [ <COMMAND_OPTIONS> ]
|
41
|
+
|
42
|
+
The program needs the user's username and password for authentication. This
|
43
|
+
information can be supplied either via a configuration file or as an option
|
44
|
+
(`-a USERNAME:PASSWORD`) to the program. It is recommended to use the former
|
45
|
+
method over the latter.
|
46
|
+
|
47
|
+
The configuration file, in `~/.tweetwine`, is in YAML syntax. The program
|
48
|
+
recognizes the following basic settings:
|
49
|
+
|
50
|
+
username: <your_username>
|
51
|
+
password: <your_password>
|
52
|
+
colors: true|false
|
53
|
+
|
54
|
+
For all the global options and commands, see:
|
55
|
+
|
56
|
+
$ tweetwine help
|
57
|
+
|
58
|
+
For information about a specific command and its options, enter:
|
59
|
+
|
60
|
+
$ tweetwine help <COMMAND>
|
61
|
+
|
62
|
+
### URL shortening for status update
|
63
|
+
|
64
|
+
Before actually sending a status update, it is possible for the software to
|
65
|
+
shorten the URLs in the update by using an external web service. This can be
|
66
|
+
enabled via the `shorten_urls` key in configuration file; for example:
|
67
|
+
|
68
|
+
username: spoonman
|
69
|
+
password: withyourhands
|
70
|
+
colors: true
|
71
|
+
shorten_urls:
|
72
|
+
enable: true
|
73
|
+
service_url: http://is.gd/create.php
|
74
|
+
method: post
|
75
|
+
url_param_name: URL
|
76
|
+
xpath_selector: //input[@id='short_url']/@value
|
77
|
+
|
78
|
+
The supported methods (in `method`) are `get` and `post`. The method chosen
|
79
|
+
affects whether parameters are passed as URL query parameters or as payload
|
80
|
+
in the HTTP request, respectively. Extra parameters can be given via
|
81
|
+
`extra_params` key, as a hash.
|
82
|
+
|
83
|
+
The `xpath_selector` is needed to extract the shortened URL from the result.
|
84
|
+
|
85
|
+
URL shortening can be disabled by
|
86
|
+
|
87
|
+
* not defining `shorten_urls` key in the configuration file,
|
88
|
+
* setting key `enable` to `false`, or
|
89
|
+
* using the command line option `--no-url-shorten`.
|
90
|
+
|
91
|
+
*NOTE:* The use of the feature requires [nokogiri](http://nokogiri.org/) gem
|
92
|
+
to be installed.
|
93
|
+
|
94
|
+
### HTTP proxy setting
|
95
|
+
|
96
|
+
If `$http_proxy` environment variable is set, Tweetwine attempts to use the
|
97
|
+
URL in the environment variable as HTTP proxy for all its HTTP connections.
|
98
|
+
This setting can be overridden with `--http-proxy` and `--no-http-proxy`
|
99
|
+
command line options.
|
100
|
+
|
101
|
+
### Bash command line completion support
|
102
|
+
|
103
|
+
Bash shell supports command line completion via tab character. If you want to
|
104
|
+
enable Tweetwine specific completion with Bash, source the file
|
105
|
+
`tweetwine-completion.bash`, located in `contrib` directory:
|
106
|
+
|
107
|
+
. contrib/tweetwine-completion.bash
|
108
|
+
|
109
|
+
In order to do this automatically when your shell starts, insert the following
|
110
|
+
snippet to your Bash initialization script (such as `~/.bashrc`):
|
111
|
+
|
112
|
+
if [ -f <path_to_tweetwine>/contrib/tweetwine-completion.bash ]; then
|
113
|
+
. <path_to_tweetwine>/contrib/tweetwine-completion.bash
|
114
|
+
fi
|
115
|
+
|
116
|
+
## COPYRIGHT
|
117
|
+
|
118
|
+
Tweetwine is Copyright (c) 2009-2010 Tuomas Kareinen
|
119
|
+
|
120
|
+
## SEE ALSO
|
121
|
+
|
122
|
+
tweetwine(1), <http://github.com/tuomas/tweetwine>
|
data/Rakefile
CHANGED
@@ -1,94 +1,75 @@
|
|
1
|
-
|
1
|
+
# coding: utf-8
|
2
2
|
|
3
|
-
require "
|
3
|
+
require "rake/clean"
|
4
4
|
|
5
|
+
$LOAD_PATH.unshift(File.expand_path("../lib/", __FILE__))
|
5
6
|
name = "tweetwine"
|
6
|
-
require "#{name}"
|
7
|
+
require "#{name}/meta"
|
7
8
|
version = Tweetwine::VERSION.dup
|
8
9
|
|
9
|
-
|
10
|
+
namespace :gem do
|
11
|
+
CLOBBER.include "#{name}-*.gem"
|
10
12
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
s.version = version
|
15
|
-
s.homepage = "http://github.com/tuomas/tweetwine"
|
16
|
-
s.summary = "A simple Twitter agent for command line use"
|
17
|
-
s.description = "A simple but tasty Twitter agent for command line use, made for fun."
|
18
|
-
|
19
|
-
s.author = "Tuomas Kareinen"
|
20
|
-
s.email = "tkareine@gmail.com"
|
21
|
-
|
22
|
-
s.platform = Gem::Platform::RUBY
|
23
|
-
s.files = FileList[
|
24
|
-
"Rakefile",
|
25
|
-
"MIT-LICENSE.txt",
|
26
|
-
"*.rdoc",
|
27
|
-
"bin/**/*",
|
28
|
-
"contrib/**/*",
|
29
|
-
"example/**/*",
|
30
|
-
"lib/**/*",
|
31
|
-
"test/**/*"].to_a
|
32
|
-
s.executables = ["tweetwine"]
|
33
|
-
|
34
|
-
s.add_dependency("rest-client", ">= 1.0.0")
|
35
|
-
|
36
|
-
s.has_rdoc = true
|
37
|
-
s.extra_rdoc_files = FileList["MIT-LICENSE.txt", "*.rdoc"].to_a
|
38
|
-
s.rdoc_options << "--title" << "#{name} #{version}" \
|
39
|
-
<< "--main" << "README.rdoc" \
|
40
|
-
<< "--exclude" << "test" \
|
41
|
-
<< "--line-numbers"
|
42
|
-
end
|
13
|
+
file "#{name}.gem" => :"man:build" do |f|
|
14
|
+
sh %{gem build #{name}.gemspec}
|
15
|
+
end
|
43
16
|
|
44
|
-
|
45
|
-
|
46
|
-
pkg.need_tar = true
|
47
|
-
end
|
17
|
+
desc "Package the software as a gem"
|
18
|
+
task :build => [:"test:all", "#{name}.gem"]
|
48
19
|
|
49
|
-
desc "
|
50
|
-
task :
|
51
|
-
|
52
|
-
f.write spec.to_ruby
|
20
|
+
desc "Install the software as a gem"
|
21
|
+
task :install => :build do
|
22
|
+
sh %{gem install #{name}-#{version}.gem}
|
53
23
|
end
|
54
|
-
end
|
55
24
|
|
56
|
-
desc "
|
57
|
-
task :
|
58
|
-
|
25
|
+
desc "Uninstall the gem"
|
26
|
+
task :uninstall => :clean do
|
27
|
+
sh %{gem uninstall #{name}}
|
28
|
+
end
|
59
29
|
end
|
60
30
|
|
61
|
-
|
62
|
-
|
63
|
-
sh %{gem uninstall #{name}}
|
64
|
-
end
|
31
|
+
namespace :man do
|
32
|
+
CLOBBER.include "man/#{name}.?", "man/#{name}.?.html"
|
65
33
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
end
|
34
|
+
desc "Build the manual"
|
35
|
+
task :build do
|
36
|
+
sh "ronn -br5 --manual='#{name.capitalize} Manual' --organization='Tuomas Kareinen' man/*.ronn"
|
37
|
+
end
|
38
|
+
|
39
|
+
desc "Show the manual section 1"
|
40
|
+
task :show1 => :build do
|
41
|
+
sh "man man/#{name}.1"
|
42
|
+
end
|
75
43
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
t.verbose = true
|
81
|
-
t.warning = true
|
82
|
-
t.ruby_opts << "-rrubygems"
|
83
|
-
t.libs << "test"
|
44
|
+
desc "Show the manual section 7"
|
45
|
+
task :show7 => :build do
|
46
|
+
sh "man man/#{name}.7"
|
47
|
+
end
|
84
48
|
end
|
85
49
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
50
|
+
namespace :test do
|
51
|
+
require "rake/testtask"
|
52
|
+
|
53
|
+
desc "Run unit tests"
|
54
|
+
Rake::TestTask.new(:unit) do |t|
|
55
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
56
|
+
t.verbose = true
|
57
|
+
t.warning = true
|
58
|
+
t.ruby_opts << "-rrubygems"
|
59
|
+
t.libs << "test"
|
60
|
+
end
|
61
|
+
|
62
|
+
desc "Run integration/example tests"
|
63
|
+
Rake::TestTask.new(:example) do |t|
|
64
|
+
t.test_files = FileList["example/**/*_example.rb"]
|
65
|
+
t.verbose = true
|
66
|
+
t.warning = false
|
67
|
+
t.ruby_opts << "-rrubygems"
|
68
|
+
t.libs << "example"
|
69
|
+
end
|
70
|
+
|
71
|
+
desc "Run all tests"
|
72
|
+
task :all => [:unit, :example]
|
92
73
|
end
|
93
74
|
|
94
75
|
desc "Find code smells"
|
@@ -96,9 +77,9 @@ task :roodi do
|
|
96
77
|
sh %{roodi "**/*.rb"}
|
97
78
|
end
|
98
79
|
|
99
|
-
desc "
|
80
|
+
desc "Show parts of the project tagged as incomplete"
|
100
81
|
task :todo do
|
101
|
-
FileList["
|
82
|
+
FileList["**/*.*"].egrep /(TODO|FIXME)/
|
102
83
|
end
|
103
84
|
|
104
|
-
task :default =>
|
85
|
+
task :default => :"test:all"
|
data/bin/tweetwine
CHANGED
data/example/example_helper.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
1
3
|
%w{
|
2
4
|
coulda
|
3
5
|
matchy
|
@@ -37,7 +39,7 @@ module Tweetwine
|
|
37
39
|
|
38
40
|
def fixture(filename)
|
39
41
|
contents = nil
|
40
|
-
filepath = File.dirname(__FILE__) << "/
|
42
|
+
filepath = File.dirname(__FILE__) << "/fixture/" << filename
|
41
43
|
File.open(filepath) do |f|
|
42
44
|
contents = f.readlines.join("\n")
|
43
45
|
end
|
data/lib/tweetwine/cli.rb
CHANGED
data/lib/tweetwine/client.rb
CHANGED
data/lib/tweetwine/io.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require "strscan"
|
1
4
|
require "uri"
|
2
5
|
|
3
6
|
module Tweetwine
|
@@ -92,11 +95,9 @@ module Tweetwine
|
|
92
95
|
def format_status(status)
|
93
96
|
status = Util.unescape_html(status)
|
94
97
|
if @colors
|
95
|
-
status =
|
96
|
-
status =
|
97
|
-
URI.extract(status, ["http", "https"]).uniq
|
98
|
-
status = colorize_all(:cyan, status, url)
|
99
|
-
end
|
98
|
+
status = colorize_matching(:yellow, status, USERNAME_REGEX)
|
99
|
+
status = colorize_matching(:magenta, status, HASHTAG_REGEX)
|
100
|
+
status = colorize_matching(:cyan, status, URI.extract(status, ["http", "https"]).uniq)
|
100
101
|
end
|
101
102
|
status
|
102
103
|
end
|
@@ -114,12 +115,16 @@ module Tweetwine
|
|
114
115
|
end
|
115
116
|
end
|
116
117
|
|
117
|
-
def
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
118
|
+
def colorize_matching(color, str, pattern)
|
119
|
+
regexp = case pattern
|
120
|
+
when Array
|
121
|
+
Regexp.union(pattern.map { |p| Regexp.new(Regexp.escape(p)) })
|
122
|
+
when Regexp
|
123
|
+
pattern
|
124
|
+
else
|
125
|
+
raise "Unknown kind of pattern"
|
126
|
+
end
|
127
|
+
Util.str_gsub_by_group(str, regexp) { |s| colorize(color, s) }
|
123
128
|
end
|
124
129
|
|
125
130
|
def colorize(color, str)
|
data/lib/tweetwine/meta.rb
CHANGED
data/lib/tweetwine/options.rb
CHANGED
data/lib/tweetwine/util.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
1
3
|
require "cgi"
|
2
4
|
require "time"
|
3
5
|
require "uri"
|
@@ -44,19 +46,20 @@ module Tweetwine
|
|
44
46
|
|
45
47
|
def self.str_gsub_by_group(str, regexp)
|
46
48
|
dup_str = str.dup
|
47
|
-
|
48
|
-
while
|
49
|
+
str_pos, dup_pos = 0, 0
|
50
|
+
while str_pos < str.size && (match_data = regexp.match(str[str_pos..-1]))
|
49
51
|
matching_group_indexes = indexes_of_filled_matches(match_data)
|
50
52
|
|
51
53
|
matching_group_indexes.each do |i|
|
52
54
|
replacement = (yield match_data[i]).to_s
|
53
|
-
dup_str[
|
55
|
+
dup_str[dup_pos + match_data.begin(i), match_data[i].size] = replacement
|
54
56
|
replacement_delta = replacement.size - match_data[i].size
|
55
|
-
|
57
|
+
dup_pos += replacement_delta
|
56
58
|
end
|
59
|
+
|
57
60
|
skip_delta = match_data.end(0)
|
58
|
-
|
59
|
-
|
61
|
+
str_pos += skip_delta
|
62
|
+
dup_pos += skip_delta
|
60
63
|
end
|
61
64
|
dup_str
|
62
65
|
end
|
data/man/tweetwine.1
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
.\" generated with Ronn/v0.5
|
2
|
+
.\" http://github.com/rtomayko/ronn/
|
3
|
+
.
|
4
|
+
.TH "TWEETWINE" "1" "April 2010" "Tuomas Kareinen" "Tweetwine Manual"
|
5
|
+
.
|
6
|
+
.SH "NAME"
|
7
|
+
\fBtweetwine\fR \-\- a simple Twitter command line agent
|
8
|
+
.
|
9
|
+
.SH "SYNOPSIS"
|
10
|
+
.
|
11
|
+
.nf
|
12
|
+
|
13
|
+
tweetwine [ <GLOBAL_OPTIONS> ]
|
14
|
+
tweetwine [ <GLOBAL_OPTIONS> ] <COMMAND> [ <COMMAND_OPTIONS> ]
|
15
|
+
.
|
16
|
+
.fi
|
17
|
+
.
|
18
|
+
.SH "DESCRIPTION"
|
19
|
+
Tweetwine supports showing the home timeline of the authenticated user, the
|
20
|
+
latest statuses of friends and followers, and the latest statuses that mention
|
21
|
+
the user. If that's not enough, statuses can be searched with arbitrary terms.
|
22
|
+
In addition, new statuses can be sent.
|
23
|
+
.
|
24
|
+
.P
|
25
|
+
\fICOMMAND\fR is one of
|
26
|
+
.
|
27
|
+
.IP "\(bu" 4
|
28
|
+
\fBfollowers\fR,
|
29
|
+
.
|
30
|
+
.IP "\(bu" 4
|
31
|
+
\fBfriends\fR,
|
32
|
+
.
|
33
|
+
.IP "\(bu" 4
|
34
|
+
\fBhome\fR,
|
35
|
+
.
|
36
|
+
.IP "\(bu" 4
|
37
|
+
\fBmentions\fR,
|
38
|
+
.
|
39
|
+
.IP "\(bu" 4
|
40
|
+
\fBsearch\fR,
|
41
|
+
.
|
42
|
+
.IP "\(bu" 4
|
43
|
+
\fBupdate\fR, or
|
44
|
+
.
|
45
|
+
.IP "\(bu" 4
|
46
|
+
\fBuser\fR.
|
47
|
+
.
|
48
|
+
.IP "" 0
|
49
|
+
.
|
50
|
+
.P
|
51
|
+
The default is \fBhome\fR.
|
52
|
+
.
|
53
|
+
.SH "OPTIONS"
|
54
|
+
Options given from command line override corresponding settings from
|
55
|
+
configuration (\fB~/.tweetwine\fR).
|
56
|
+
.
|
57
|
+
.P
|
58
|
+
\fIGLOBAL_OPTIONS\fR are:
|
59
|
+
.
|
60
|
+
.TP
|
61
|
+
\fB\-a\fR, \fB\-\-auth USERNAME:PASSWORD\fR
|
62
|
+
Authentication.
|
63
|
+
.
|
64
|
+
.TP
|
65
|
+
\fB\-c\fR, \fB\-\-[no\-]colors\fR
|
66
|
+
Colorize output with ANSI escape codes.
|
67
|
+
.
|
68
|
+
.TP
|
69
|
+
\fB\-n\fR, \fB\-\-num N\fR
|
70
|
+
The number of statuses in page, default 20.
|
71
|
+
.
|
72
|
+
.TP
|
73
|
+
\fB\-\-[no\-]http\-proxy URL\fR
|
74
|
+
Use proxy for HTTP and HTTPS.
|
75
|
+
.
|
76
|
+
.TP
|
77
|
+
\fB\-\-no\-url\-shorten\fR
|
78
|
+
Do not shorten URLs for status update.
|
79
|
+
.
|
80
|
+
.TP
|
81
|
+
\fB\-p\fR, \fB\-\-page N\fR
|
82
|
+
The page number for statuses, default 1.
|
83
|
+
.
|
84
|
+
.TP
|
85
|
+
\fB\-v\fR, \fB\-\-version\fR
|
86
|
+
Show version information and exit.
|
87
|
+
.
|
88
|
+
.TP
|
89
|
+
\fB\-h\fR, \fB\-\-help\fR
|
90
|
+
Show help message and exit.
|
91
|
+
.
|
92
|
+
.P
|
93
|
+
In order to see \fICOMMAND_OPTIONS\fR, enter:
|
94
|
+
.
|
95
|
+
.IP "" 4
|
96
|
+
.
|
97
|
+
.nf
|
98
|
+
|
99
|
+
$ tweetwine help <COMMAND>
|
100
|
+
.
|
101
|
+
.fi
|
102
|
+
.
|
103
|
+
.IP "" 0
|
104
|
+
.
|
105
|
+
.SH "COPYRIGHT"
|
106
|
+
Tweetwine is Copyright (c) 2009\-2010 Tuomas Kareinen
|
107
|
+
.
|
108
|
+
.SH "SEE ALSO"
|
109
|
+
tweetwine(7), \fIhttp://github.com/tuomas/tweetwine\fR
|