twail 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/MIT-LICENSE.txt +21 -0
- data/README.markdown +50 -0
- data/Rakefile +7 -0
- data/bin/twail +2 -0
- data/lib/twail.rb +119 -0
- data/notes.txt +9 -0
- data/twail.gemspec +23 -0
- metadata +73 -0
data/MIT-LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Copyright (c) 2010 Daniel Choi, http://danielchoi.com/software/
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
data/README.markdown
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# twail
|
2
|
+
|
3
|
+
`twail` is inspired by the venerable Unix `tail` program. `twail` tails
|
4
|
+
your Twitter timelines.
|
5
|
+
|
6
|
+
Before using twail, you must first get a Twitter API key and authorize the twurl
|
7
|
+
command to access your Twitter account. Type
|
8
|
+
|
9
|
+
twurl -T
|
10
|
+
|
11
|
+
for instructions.
|
12
|
+
|
13
|
+
Assuming you've done that, read on.
|
14
|
+
|
15
|
+
Usage: twail [timeline]
|
16
|
+
|
17
|
+
[timeline] can be any of these:
|
18
|
+
|
19
|
+
public
|
20
|
+
home
|
21
|
+
friends
|
22
|
+
user
|
23
|
+
mentions
|
24
|
+
retweeted_by_me
|
25
|
+
retweeted_to_me
|
26
|
+
retweets_of_me
|
27
|
+
|
28
|
+
"home" is the default.
|
29
|
+
|
30
|
+
You can use these abbreviations:
|
31
|
+
|
32
|
+
p h f u m by to of
|
33
|
+
|
34
|
+
|
35
|
+
`twail` works like `tail -f`. It will print tweets out as they appear
|
36
|
+
in the specified timeline. You can redirect the output however you
|
37
|
+
want. One pipeline I like to use is
|
38
|
+
|
39
|
+
twail home | tee -a twitter.home.log
|
40
|
+
|
41
|
+
Lots of other pipelines are possible. Knock yourself out.
|
42
|
+
|
43
|
+
`twail` was created by Daniel Choi. It's really just a convenience
|
44
|
+
wrapper around the awesome [twurl][twurl] program.
|
45
|
+
|
46
|
+
[twurl]:https://github.com/marcel/twurl
|
47
|
+
|
48
|
+
You can follow me on Twitter at <http://twitter.com/danchoi>.
|
49
|
+
|
50
|
+
|
data/Rakefile
ADDED
data/bin/twail
ADDED
data/lib/twail.rb
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
require 'json'
|
4
|
+
require 'yaml'
|
5
|
+
require 'twurl'
|
6
|
+
|
7
|
+
TIMELINES = %w( public home friends user)
|
8
|
+
SPECIAL = %w(mentions retweeted_by_me retweeted_to_me retweets_of_me)
|
9
|
+
|
10
|
+
if %w(-h --help).include?(ARGV.first)
|
11
|
+
puts <<END
|
12
|
+
|
13
|
+
Before using twail, you must first get a Twitter API key and authorize the twurl
|
14
|
+
command to access your Twitter account. Type
|
15
|
+
|
16
|
+
twurl -T
|
17
|
+
|
18
|
+
for instructions.
|
19
|
+
|
20
|
+
Assuming you've done that, read on.
|
21
|
+
|
22
|
+
Usage: twail [timeline]
|
23
|
+
|
24
|
+
[timeline] can be any of these:
|
25
|
+
|
26
|
+
public
|
27
|
+
home
|
28
|
+
friends
|
29
|
+
user
|
30
|
+
mentions
|
31
|
+
retweeted_by_me
|
32
|
+
retweeted_to_me
|
33
|
+
retweets_of_me
|
34
|
+
|
35
|
+
"home" is the default.
|
36
|
+
|
37
|
+
You can use these abbreviations:
|
38
|
+
|
39
|
+
p h f u m by to of
|
40
|
+
|
41
|
+
END
|
42
|
+
exit
|
43
|
+
end
|
44
|
+
|
45
|
+
class String
|
46
|
+
def wrap(len=65)
|
47
|
+
gsub(/\n/, " ").gsub(/.{1,#{len}}(?:\s|\Z)/){$&+"\n"}
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
timeline = if ARGV.first
|
52
|
+
(TIMELINES + SPECIAL).detect {|t|
|
53
|
+
t =~ /^#{ARGV.first}/ || ((t =~ /_/) && (t.split('_')[1] =~ /^#{ARGV.first}/))
|
54
|
+
}
|
55
|
+
else
|
56
|
+
'home'
|
57
|
+
end
|
58
|
+
puts "Logging #{timeline} timeline at #{Time.now}"
|
59
|
+
url = case timeline
|
60
|
+
when 'retweets_of_me'
|
61
|
+
# This doesn't seem to do anything different; figure out later
|
62
|
+
"/1/statuses/#{timeline}.json?include_entities=true"
|
63
|
+
when *SPECIAL
|
64
|
+
"/1/statuses/#{timeline}.json"
|
65
|
+
else
|
66
|
+
"/1/statuses/#{timeline}_timeline.json"
|
67
|
+
end
|
68
|
+
|
69
|
+
trap("INT") {
|
70
|
+
xs = ['Goodbye.', 'Farewell.', 'Have a nice day.',
|
71
|
+
'Now go enjoy the weather!', 'Live long and prosper.',
|
72
|
+
'May the force be with you.']
|
73
|
+
$stderr.puts xs[rand(xs.size)]
|
74
|
+
exit
|
75
|
+
}
|
76
|
+
|
77
|
+
seen = []
|
78
|
+
network = true
|
79
|
+
|
80
|
+
loop do
|
81
|
+
raw = begin
|
82
|
+
Twurl::CLI.output = StringIO.new
|
83
|
+
Twurl::CLI.run([url])
|
84
|
+
if network == false
|
85
|
+
network = true
|
86
|
+
$stderr.print(" The network is back up!\n")
|
87
|
+
end
|
88
|
+
Twurl::CLI.output.read
|
89
|
+
Twurl::CLI.output.rewind
|
90
|
+
Twurl::CLI.output.read
|
91
|
+
rescue SocketError
|
92
|
+
if network
|
93
|
+
$stderr.print("The network seems to be down.")
|
94
|
+
else
|
95
|
+
$stderr.print('.')
|
96
|
+
end
|
97
|
+
network = false
|
98
|
+
sleep 20
|
99
|
+
next
|
100
|
+
end
|
101
|
+
res = JSON.parse(raw).reverse
|
102
|
+
res.each do |x|
|
103
|
+
next if seen.include?(x['id'])
|
104
|
+
seen << x['id']
|
105
|
+
text = x['text'].gsub(/\n/, ' ')
|
106
|
+
user_width = 18
|
107
|
+
from = x['user']['screen_name'][0,user_width]
|
108
|
+
total_width = `tput cols`.to_i
|
109
|
+
text_width = (total_width - user_width) - 3
|
110
|
+
textlines = text.wrap(text_width).split(/\n/)
|
111
|
+
|
112
|
+
puts("%s| %s" % [from.rjust(user_width), textlines.shift])
|
113
|
+
textlines.each do |line|
|
114
|
+
puts("%s| %s" % [''.rjust(user_width), line])
|
115
|
+
end
|
116
|
+
end
|
117
|
+
sleep 30
|
118
|
+
end
|
119
|
+
|
data/notes.txt
ADDED
data/twail.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = "twail"
|
5
|
+
s.version = '0.0.1'
|
6
|
+
s.platform = Gem::Platform::RUBY
|
7
|
+
s.required_ruby_version = '>= 1.9.0'
|
8
|
+
|
9
|
+
s.authors = ["Daniel Choi"]
|
10
|
+
s.email = ["dhchoi@gmail.com"]
|
11
|
+
s.homepage = "http://danielchoi.com/software/twail.html"
|
12
|
+
s.summary = %q{tail your Twitter timeslines}
|
13
|
+
s.description = %q{tail your Twitter timeslines}
|
14
|
+
|
15
|
+
s.rubyforge_project = "twail"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_dependency 'twurl', '>= 0.6.3'
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: twail
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Daniel Choi
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-04-21 00:00:00 -04:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: twurl
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 0.6.3
|
25
|
+
type: :runtime
|
26
|
+
version_requirements: *id001
|
27
|
+
description: tail your Twitter timeslines
|
28
|
+
email:
|
29
|
+
- dhchoi@gmail.com
|
30
|
+
executables:
|
31
|
+
- twail
|
32
|
+
extensions: []
|
33
|
+
|
34
|
+
extra_rdoc_files: []
|
35
|
+
|
36
|
+
files:
|
37
|
+
- MIT-LICENSE.txt
|
38
|
+
- README.markdown
|
39
|
+
- Rakefile
|
40
|
+
- bin/twail
|
41
|
+
- lib/twail.rb
|
42
|
+
- notes.txt
|
43
|
+
- twail.gemspec
|
44
|
+
has_rdoc: true
|
45
|
+
homepage: http://danielchoi.com/software/twail.html
|
46
|
+
licenses: []
|
47
|
+
|
48
|
+
post_install_message:
|
49
|
+
rdoc_options: []
|
50
|
+
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: 1.9.0
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: "0"
|
65
|
+
requirements: []
|
66
|
+
|
67
|
+
rubyforge_project: twail
|
68
|
+
rubygems_version: 1.6.1
|
69
|
+
signing_key:
|
70
|
+
specification_version: 3
|
71
|
+
summary: tail your Twitter timeslines
|
72
|
+
test_files: []
|
73
|
+
|