tweetskim 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/{README.rdoc → README.md} +59 -41
- data/bin/tweetskim +17 -2
- data/lib/tweetskim/core.rb +36 -15
- data/lib/tweetskim/version.rb +1 -1
- data/test/test_helper.rb +2 -0
- data/test/test_tweetskim.rb +75 -14
- data/tweetskim.gemspec +2 -1
- metadata +17 -6
data/{README.rdoc → README.md}
RENAMED
@@ -1,61 +1,79 @@
|
|
1
1
|
|
2
|
-
|
2
|
+
DESCRIPTION:
|
3
|
+
===========
|
3
4
|
|
4
|
-
A stripped down, command line-centered way to read tweets
|
5
|
+
A stripped down, command line-centered way to read tweets
|
6
|
+
efficiently. Combine with unix tools and pipelines - read tweets
|
7
|
+
however you want.
|
5
8
|
|
6
9
|
|
7
|
-
|
10
|
+
USAGE:
|
11
|
+
======
|
8
12
|
|
9
|
-
|
13
|
+
`tweetskim`
|
10
14
|
|
15
|
+
Prints tweets to stdout: one column for your timeline, one for
|
16
|
+
mentions of your account. Use it like any other command line tool -
|
17
|
+
pipe to `less` to page output, concat it to file (`tweetskim >
|
18
|
+
tweets.txt`), and so on.
|
11
19
|
|
12
|
-
== INSTALL:
|
13
20
|
|
14
|
-
|
21
|
+
PREREQUISITES:
|
22
|
+
==============
|
15
23
|
|
24
|
+
You must have some version of Ruby and RubyGems installed. That's it.
|
16
25
|
|
17
|
-
== FEATURES/PROBLEMS:
|
18
26
|
|
19
|
-
|
27
|
+
INSTALL:
|
28
|
+
========
|
20
29
|
|
30
|
+
`gem install tweetskim`
|
21
31
|
|
22
|
-
|
32
|
+
(The program will help you set up OAuth/pin authentication with Twitter
|
33
|
+
the first time you run it.)
|
23
34
|
|
24
|
-
add dependencies to gem spec
|
25
35
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
36
|
+
TODO:
|
37
|
+
=====
|
38
|
+
|
39
|
+
|
40
|
+
options
|
41
|
+
----
|
42
|
+
|
43
|
+
add usage text, handle options
|
44
|
+
|
45
|
+
-h, --help
|
46
|
+
|
30
47
|
-m, --mark-all-read
|
48
|
+
|
49
|
+
-l=N, --last-n-tweets=N
|
50
|
+
|
31
51
|
-a, --show-all
|
32
|
-
|
33
|
-
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
== LICENSE:
|
52
|
+
|
53
|
+
-i, --inverse-order
|
54
|
+
|
55
|
+
-t, --html-output
|
56
|
+
|
57
|
+
-hm, --hide-mentions
|
58
|
+
|
59
|
+
-ht, --hide-timeline
|
60
|
+
|
61
|
+
-x=USER, --exclude=USER
|
62
|
+
|
63
|
+
-o=USER, --only=USER
|
64
|
+
|
65
|
+
|
66
|
+
multiple accounts
|
67
|
+
------
|
68
|
+
handle explicit, different username options
|
69
|
+
|
70
|
+
split out authorization in separate, explicit step- tweetskim authorize USER
|
71
|
+
|
72
|
+
set tokens per account (if username)
|
73
|
+
|
74
|
+
|
75
|
+
LICENSE:
|
76
|
+
========
|
59
77
|
|
60
78
|
(The MIT License)
|
61
79
|
|
data/bin/tweetskim
CHANGED
@@ -2,5 +2,20 @@
|
|
2
2
|
|
3
3
|
require "tweetskim"
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
|
6
|
+
DEFAULT_MAX_TWEETS = 100
|
7
|
+
DEFAULT_COLUMN_WIDTH = 40
|
8
|
+
|
9
|
+
adapter = Tweetskim::TwitterAdapter.new
|
10
|
+
formatter = Tweetskim::Formatter.new
|
11
|
+
|
12
|
+
timeline = adapter.timeline(:count => DEFAULT_MAX_TWEETS)
|
13
|
+
mentions = adapter.mentions(:count => DEFAULT_MAX_TWEETS)
|
14
|
+
|
15
|
+
timeline_col = formatter.column timeline, {:width => DEFAULT_COLUMN_WIDTH}
|
16
|
+
mentions_col = formatter.column mentions, {:width => DEFAULT_COLUMN_WIDTH}
|
17
|
+
|
18
|
+
timeline_padded = formatter.pad timeline_col, DEFAULT_COLUMN_WIDTH
|
19
|
+
mentions_padded = formatter.pad mentions_col, DEFAULT_COLUMN_WIDTH
|
20
|
+
|
21
|
+
puts formatter.pasted_columns([timeline_padded, mentions_padded])
|
data/lib/tweetskim/core.rb
CHANGED
@@ -4,15 +4,43 @@ module Tweetskim
|
|
4
4
|
require 'rubygems'
|
5
5
|
require 'twitter'
|
6
6
|
require 'oauth'
|
7
|
+
|
8
|
+
|
9
|
+
class Formatter
|
7
10
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
11
|
+
def column(tweets, options = {})
|
12
|
+
tweet_texts = tweets.reverse.map {|tweet| "--#{tweet.user.name}-- #{tweet.text}"}
|
13
|
+
reflowed_tweets = tweet_texts.map {|tweet| `echo "#{tweet}" | fmt -w #{options[:width]}` }
|
14
|
+
column = reflowed_tweets.join "\n\n"
|
12
15
|
end
|
13
16
|
|
14
|
-
|
15
|
-
|
17
|
+
def pad(column, width)
|
18
|
+
padded_lines = []
|
19
|
+
column.each_line do |line|
|
20
|
+
chopped_line = line.chop
|
21
|
+
padded_lines.push `printf "%-#{width}s\n" "#{chopped_line}"`
|
22
|
+
end
|
23
|
+
padded_lines.join ""
|
24
|
+
end
|
25
|
+
|
26
|
+
def pasted_columns(columns)
|
27
|
+
col_tmp_files = []
|
28
|
+
|
29
|
+
columns.each_with_index do |col, i|
|
30
|
+
filepath = "/tmp/tweetskim-col#{i}.txt"
|
31
|
+
`rm #{filepath}; echo "#{col}" > #{filepath}`
|
32
|
+
col_tmp_files.push filepath
|
33
|
+
end
|
34
|
+
|
35
|
+
col_tmp_files = col_tmp_files.join " "
|
36
|
+
`paste #{col_tmp_files}`.chomp "\t\n"
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
class TwitterAdapter
|
43
|
+
|
16
44
|
# TODO call for each user in config
|
17
45
|
# implicit for the user authenticated in client. Different user =
|
18
46
|
# different client
|
@@ -25,13 +53,6 @@ module Tweetskim
|
|
25
53
|
client = authenticated_client
|
26
54
|
timeline = client.home_timeline(options)
|
27
55
|
end
|
28
|
-
|
29
|
-
|
30
|
-
def tweet_column(tweets, column_width)
|
31
|
-
tweet_texts = tweets.reverse.map {|tweet| "--#{tweet.user.name}-- #{tweet.text}"}
|
32
|
-
reflowed_tweets = tweet_texts.map {|tweet| `echo "#{tweet}" | fmt -w #{column_width}` }
|
33
|
-
reflowed_tweets.join "\n\n"
|
34
|
-
end
|
35
56
|
|
36
57
|
CONSUMER_KEY = "3oUZhYLZcaqqQePajIjnBg"
|
37
58
|
CONSUMER_SECRET = "mAYecEGPwy7BlkibFGHCACtY5x1Mm0YOvczxsll4OY"
|
@@ -72,7 +93,7 @@ module Tweetskim
|
|
72
93
|
puts "Please authenticate by following this URL:"
|
73
94
|
puts request_token.authorize_url
|
74
95
|
|
75
|
-
print "What was the PIN Twitter gave you? "
|
96
|
+
print "What was the PIN that Twitter gave you? "
|
76
97
|
pin = gets.chomp
|
77
98
|
|
78
99
|
OAuth::RequestToken.new(oauth_consumer, rtoken, rsecret)
|
@@ -82,7 +103,7 @@ module Tweetskim
|
|
82
103
|
end
|
83
104
|
|
84
105
|
#TODO store tokens for each user
|
85
|
-
TOKEN_FILE_PATH = File.expand_path "~/.tweetskim/tokens"
|
106
|
+
TOKEN_FILE_PATH = File.expand_path "~/.tweetskim/default.tokens"
|
86
107
|
|
87
108
|
def user_tokens_stored?
|
88
109
|
File.exists? TOKEN_FILE_PATH
|
data/lib/tweetskim/version.rb
CHANGED
data/test/test_helper.rb
CHANGED
data/test/test_tweetskim.rb
CHANGED
@@ -3,28 +3,89 @@ require File.dirname(__FILE__) + '/test_helper.rb'
|
|
3
3
|
class TestTweetskim < Test::Unit::TestCase
|
4
4
|
|
5
5
|
def setup
|
6
|
-
@
|
7
|
-
end
|
8
|
-
|
9
|
-
def test_something
|
10
|
-
assert_equal 4, @t.trial
|
6
|
+
@f = Tweetskim::Formatter.new
|
11
7
|
end
|
12
8
|
|
13
|
-
def
|
14
|
-
|
9
|
+
def t(text)
|
10
|
+
status = Twitter::Status.new
|
11
|
+
status.stubs(:text).returns text
|
12
|
+
user = Twitter::User.new
|
13
|
+
user.stubs(:name).returns "Mock User"
|
14
|
+
status.stubs(:user).returns user
|
15
|
+
return status
|
15
16
|
end
|
17
|
+
|
18
|
+
def test_column_creation
|
19
|
+
tweets = [t("Ut enimad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."), t("Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. "), t("Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.")]
|
20
|
+
|
21
|
+
expected = <<FORMATTED
|
22
|
+
--Mock User-- Excepteur sint occaecat
|
23
|
+
cupidatat non proident, sunt in culpa
|
24
|
+
qui officia deserunt mollit anim id
|
25
|
+
est laborum.
|
26
|
+
|
27
|
+
|
28
|
+
--Mock User-- Duis aute irure dolor in
|
29
|
+
reprehenderit in voluptate velit esse
|
30
|
+
cillum dolore eu fugiat nulla pariatur.
|
31
|
+
|
32
|
+
|
33
|
+
--Mock User-- Ut enimad minim veniam,
|
34
|
+
quis nostrud exercitation ullamco
|
35
|
+
laboris nisi ut aliquip ex ea commodo
|
36
|
+
consequat.
|
37
|
+
FORMATTED
|
16
38
|
|
17
|
-
|
18
|
-
|
39
|
+
actual = @f.column(tweets, {:width => 40})
|
40
|
+
|
41
|
+
assert_equal expected, actual
|
19
42
|
end
|
20
43
|
|
21
|
-
|
22
|
-
def test_column_creation
|
23
|
-
tweet_str = ["Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ", "Ut enimad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.", "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. ", "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."]
|
44
|
+
def test_whitespace_padding
|
24
45
|
|
25
|
-
|
46
|
+
col = <<COL
|
47
|
+
aaaaaa
|
48
|
+
aaaaa
|
49
|
+
aaaa
|
50
|
+
aaa
|
51
|
+
aa
|
52
|
+
a
|
53
|
+
|
54
|
+
COL
|
26
55
|
|
27
|
-
|
56
|
+
expected = <<COL
|
57
|
+
aaaaaa
|
58
|
+
aaaaa
|
59
|
+
aaaa
|
60
|
+
aaa
|
61
|
+
aa
|
62
|
+
a
|
63
|
+
|
64
|
+
COL
|
65
|
+
|
66
|
+
assert_equal expected, @f.pad(col, 6)
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
def test_column_pasting
|
71
|
+
first_col = <<COL
|
72
|
+
aaa
|
73
|
+
aaa
|
74
|
+
aaa
|
75
|
+
COL
|
76
|
+
second_col = <<COL
|
77
|
+
bbb
|
78
|
+
bbb
|
79
|
+
bbb
|
80
|
+
COL
|
81
|
+
|
82
|
+
expected = <<COL
|
83
|
+
aaa\tbbb
|
84
|
+
aaa\tbbb
|
85
|
+
aaa\tbbb
|
86
|
+
COL
|
87
|
+
|
88
|
+
assert_equal expected, @f.pasted_columns([first_col, second_col])
|
28
89
|
end
|
29
90
|
|
30
91
|
end
|
data/tweetskim.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tweetskim
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2012-03-03 00:00:00.000000000Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: twitter
|
16
|
-
requirement: &
|
16
|
+
requirement: &13731040 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *13731040
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: oauth
|
27
|
-
requirement: &
|
27
|
+
requirement: &13730620 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,7 +32,18 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *13730620
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: mocha
|
38
|
+
requirement: &13730200 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *13730200
|
36
47
|
description: ! 'Usage: tweetskim [username]'
|
37
48
|
email:
|
38
49
|
- thomas@kjeldahlnilsson.net
|
@@ -43,7 +54,7 @@ extra_rdoc_files: []
|
|
43
54
|
files:
|
44
55
|
- .gitignore
|
45
56
|
- Gemfile
|
46
|
-
- README.
|
57
|
+
- README.md
|
47
58
|
- Rakefile
|
48
59
|
- bin/tweetskim
|
49
60
|
- lib/tweetskim.rb
|