tweetskim 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,61 +1,79 @@
1
1
 
2
- == DESCRIPTION:
2
+ DESCRIPTION:
3
+ ===========
3
4
 
4
- A stripped down, command line-centered way to read tweets efficiently.
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
- == USAGE:
10
+ USAGE:
11
+ ======
8
12
 
9
- TODO
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
- gem install tweetskim
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
- TODO
27
+ INSTALL:
28
+ ========
20
29
 
30
+ `gem install tweetskim`
21
31
 
22
- == TODO
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
- two column presentation: add mentions
27
-
28
- usage
29
- tweet-skim [usernames...]
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
- -i --inverse-order
33
- -h --html-output
34
-
35
- configure
36
- dotfile
37
- config accounts, set tokens per account
38
- option: hide timeline, hide mentions
39
-
40
- generate nicely formatted html version in ~/.<APP>/last-generated
41
- point browser to that
42
- "mark all as read, go straight to browser
43
- for multiple accounts: show them tabbed, concated or something else
44
- super readable, greyscale, only gfx=avatars
45
- Links to actual tweets to enable interaction using regular twitter web gui
46
- make the design beautiful
47
- CSS3 workthrough
48
- Design & typography books workthrough
49
-
50
- mobile version
51
- move timeline last read values to central location
52
- mobile app
53
-
54
- web version
55
- figure out way to post "mark as read"
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
- tweet_adapter = Tweetskim::TwitterAdapter.new
6
- puts tweet_adapter.tweet_column(tweet_adapter.timeline(:count => 100), 40)
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])
@@ -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
- class TwitterAdapter
9
-
10
- def trial
11
- 4
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
@@ -1,3 +1,3 @@
1
1
  module Tweetskim
2
- VERSION = "0.0.2"
2
+ VERSION = "0.1.0"
3
3
  end
data/test/test_helper.rb CHANGED
@@ -1,3 +1,5 @@
1
1
  require 'stringio'
2
2
  require 'test/unit'
3
+ require 'mocha'
4
+
3
5
  require File.dirname(__FILE__) + '/../lib/tweetskim'
@@ -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
- @t = Tweetskim::TwitterAdapter.new
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 test_twitter_integration_get_mentions
14
- assert_equal 10, @t.mentions[0...10].count
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
- def test_twitter_integration_get_timeline
18
- assert_equal 10, @t.timeline[0...10].count
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
- # tweets = tweet_str.map { |str| Twitter::Status.new :text => str }
46
+ col = <<COL
47
+ aaaaaa
48
+ aaaaa
49
+ aaaa
50
+ aaa
51
+ aa
52
+ a
53
+
54
+ COL
26
55
 
27
- puts @t.tweet_column( @t.timeline, 40)
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
@@ -22,5 +22,6 @@ Gem::Specification.new do |s|
22
22
  # s.add_development_dependency "rspec"
23
23
  s.add_runtime_dependency "twitter"
24
24
  s.add_runtime_dependency "oauth"
25
-
25
+
26
+ s.add_development_dependency "mocha"
26
27
  end
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.2
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: &18244880 !ruby/object:Gem::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: *18244880
24
+ version_requirements: *13731040
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: oauth
27
- requirement: &18244460 !ruby/object:Gem::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: *18244460
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.rdoc
57
+ - README.md
47
58
  - Rakefile
48
59
  - bin/tweetskim
49
60
  - lib/tweetskim.rb