manveru (owner)

Fork Of

gist: 23266 by chneuki... twicl, a twitter command li...

Revisions

gist: 23409 Download_button fork
public
Public Clone URL: git://gist.github.com/23409.git
Embed All Files: show embed
twicl #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#!/usr/bin/env ruby
# -*- ruby -*-
 
# twitter command line client
# That's What I Call Lame
 
# 09nov2008 +chris+
 
require 'json'
require 'open-uri'
require 'pp'
require 'time'
 
begin
  load "~/.twicl"
rescue LoadError
  abort <<ERR
No ~/.twicl found, please create one with these contents:
 
$auth = ["your twitter username", "your twitter password"]
 
ERR
end
 
STDOUT.sync = true
Thread.abort_on_exception = true
 
def fetch(url, last_id, auth, &block)
  url += "?since_id=#{last_id}" if last_id
  begin
    posts = JSON.load(open(url, :http_basic_authentication => auth))
  rescue => e
    if e.message =~ /400 Bad Request/
      abort ">> API limit reached. Exiting, try again next hour..."
    else
      puts "!> #{e.message}"
      return last_id
    end
  rescue Timeout::Error
    # ignore
  end
 
  # On startup, get at most posts of last three days.
  unless last_id
    posts.reject! { |post|
      Time.now - Time.parse(post["created_at"]) > 3*24*60*60
    }
  end
  
  posts.reverse_each { |post|
    post["stamp"] = Time.parse(post["created_at"]).strftime("%m/%d %H:%M")
    yield post
  }
  
  return posts.map { |post| post["id"] }.max || last_id
end
 
def update_friends
  $last_friends = fetch("http://twitter.com/statuses/friends_timeline.json",
                        $last_friends, $auth) { |post|
    puts "\r%s %s: %s" % [post["stamp"],
                          post["user"]["screen_name"],
                          post["text"]]
  }
end
 
def update_replies
  $last_replies = fetch("http://twitter.com/statuses/replies.json",
                        $last_replies, $auth) { |post|
    puts "\r%s >> %s: %s" % [post["stamp"],
                             post["user"]["screen_name"],
                             post["text"]]
  }
end
 
def update_direct
  $last_direct = fetch("http://twitter.com/direct_messages.json",
                       $last_direct, $auth) { |post|
    puts "\r%s <> %s: %s" % [post["stamp"],
                             post["sender"]["screen_name"],
                             post["text"]]
  }
end
 
def post(string, auth)
  res = Net::HTTP.post_form(
    URI.parse("http://#{auth * ":"}@twitter.com/statuses/update.json"),
    "status" => string)
  JSON.parse(res.body)["id"]
end
 
Thread.new {
  loop {
    update_friends; update_replies; update_direct
    sleep 120
  }
}
 
Thread.new {
  loop {
    print "\r> "
    line = gets
    exit if line.nil?
 
    line.chomp!
 
    unless line.strip.empty?
      if line.size > 160
        puts "!> Line to long, #{line[160..-1].dump} would be clipped."
      else
        post line, $auth
        sleep 1 # ensure it will show up on next fetch
      end
    end
    
    update_friends; update_replies; update_direct
  }
}.join