dustin-twitter 0.3.2.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/History.txt +89 -0
- data/License.txt +19 -0
- data/Manifest.txt +66 -0
- data/README.txt +75 -0
- data/Rakefile +4 -0
- data/TODO.txt +2 -0
- data/bin/twitter +15 -0
- data/config/hoe.rb +74 -0
- data/config/requirements.rb +17 -0
- data/examples/blocks.rb +15 -0
- data/examples/direct_messages.rb +26 -0
- data/examples/favorites.rb +20 -0
- data/examples/friends_followers.rb +25 -0
- data/examples/friendships.rb +13 -0
- data/examples/location.rb +8 -0
- data/examples/replies.rb +26 -0
- data/examples/sent_messages.rb +26 -0
- data/examples/timeline.rb +33 -0
- data/examples/twitter.rb +27 -0
- data/examples/verify_credentials.rb +13 -0
- data/lib/twitter/base.rb +248 -0
- data/lib/twitter/cli/config.rb +9 -0
- data/lib/twitter/cli/helpers.rb +97 -0
- data/lib/twitter/cli/migrations/20080722194500_create_accounts.rb +13 -0
- data/lib/twitter/cli/migrations/20080722194508_create_tweets.rb +16 -0
- data/lib/twitter/cli/migrations/20080722214605_add_account_id_to_tweets.rb +9 -0
- data/lib/twitter/cli/migrations/20080722214606_create_configurations.rb +13 -0
- data/lib/twitter/cli/models/account.rb +33 -0
- data/lib/twitter/cli/models/configuration.rb +13 -0
- data/lib/twitter/cli/models/tweet.rb +20 -0
- data/lib/twitter/cli.rb +328 -0
- data/lib/twitter/direct_message.rb +22 -0
- data/lib/twitter/easy_class_maker.rb +43 -0
- data/lib/twitter/rate_limit_status.rb +19 -0
- data/lib/twitter/status.rb +22 -0
- data/lib/twitter/user.rb +37 -0
- data/lib/twitter/version.rb +9 -0
- data/lib/twitter.rb +20 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +74 -0
- data/setup.rb +1585 -0
- data/spec/base_spec.rb +109 -0
- data/spec/cli/helper_spec.rb +35 -0
- data/spec/direct_message_spec.rb +35 -0
- data/spec/fixtures/followers.xml +706 -0
- data/spec/fixtures/friends.xml +609 -0
- data/spec/fixtures/friends_for.xml +584 -0
- data/spec/fixtures/friends_lite.xml +192 -0
- data/spec/fixtures/friends_timeline.xml +66 -0
- data/spec/fixtures/public_timeline.xml +148 -0
- data/spec/fixtures/rate_limit_status.xml +7 -0
- data/spec/fixtures/status.xml +25 -0
- data/spec/fixtures/user.xml +38 -0
- data/spec/fixtures/user_timeline.xml +465 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/status_spec.rb +40 -0
- data/spec/user_spec.rb +42 -0
- data/tasks/deployment.rake +41 -0
- data/tasks/environment.rake +7 -0
- data/tasks/website.rake +17 -0
- data/twitter.gemspec +49 -0
- data/website/css/common.css +47 -0
- data/website/images/terminal_output.png +0 -0
- data/website/index.html +138 -0
- metadata +176 -0
data/lib/twitter/cli.rb
ADDED
@@ -0,0 +1,328 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
gem 'main', '>= 2.8.2'
|
3
|
+
gem 'highline', '>= 1.4.0'
|
4
|
+
gem 'activerecord', '>= 2.1'
|
5
|
+
gem 'sqlite3-ruby', '>= 1.2.2'
|
6
|
+
require 'main'
|
7
|
+
require 'highline/import'
|
8
|
+
require 'activerecord'
|
9
|
+
require 'sqlite3'
|
10
|
+
|
11
|
+
HighLine.track_eof = false
|
12
|
+
CLI_ROOT = File.expand_path(File.join(File.dirname(__FILE__), 'cli'))
|
13
|
+
require CLI_ROOT + '/config'
|
14
|
+
require CLI_ROOT + '/helpers'
|
15
|
+
Dir[CLI_ROOT + '/models/*.rb'].each { |m| require m }
|
16
|
+
|
17
|
+
include Twitter::CLI::Helpers
|
18
|
+
|
19
|
+
Main {
|
20
|
+
def run
|
21
|
+
puts "twitter [command] --help for usage instructions."
|
22
|
+
puts "The available commands are: \n install, uninstall, add, remove, list, change, post, befriend, defriend, follow, leave, d and timeline."
|
23
|
+
end
|
24
|
+
|
25
|
+
mode 'install' do
|
26
|
+
description 'Creates the sqlite3 database and runs the migrations.'
|
27
|
+
def run
|
28
|
+
migrate
|
29
|
+
attempt_import
|
30
|
+
say 'Twitter installed.'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
mode 'uninstall' do
|
35
|
+
description 'Removes the sqlite3 database. There is no undo for this.'
|
36
|
+
def run
|
37
|
+
FileUtils.rm(Twitter::CLI::Config[:database]) if File.exists?(Twitter::CLI::Config[:database])
|
38
|
+
say 'Twitter gem uninstalled.'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
mode 'add' do
|
43
|
+
description 'Adds a new twitter account to the database. Prompts for username and password.'
|
44
|
+
argument('username', 'u') {
|
45
|
+
optional
|
46
|
+
description 'optional username'
|
47
|
+
}
|
48
|
+
argument('password', 'p') {
|
49
|
+
optional
|
50
|
+
description 'optional password'
|
51
|
+
}
|
52
|
+
|
53
|
+
def run
|
54
|
+
account = Hash.new
|
55
|
+
say "Add New Account:"
|
56
|
+
|
57
|
+
# allows optional username arg
|
58
|
+
if params['username'].given?
|
59
|
+
account[:username] = params['username'].value
|
60
|
+
else
|
61
|
+
account[:username] = ask('Username: ') do |q|
|
62
|
+
q.validate = /\S+/
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# allows optional password arg
|
67
|
+
if params['password'].given?
|
68
|
+
account[:password] = params['password'].value
|
69
|
+
else
|
70
|
+
account[:password] = ask("Password (won't be displayed): ") do |q|
|
71
|
+
q.echo = false
|
72
|
+
q.validate = /\S+/
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
do_work do
|
77
|
+
base(account[:username], account[:password]).verify_credentials
|
78
|
+
Account.add(account)
|
79
|
+
say 'Account added.'
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
mode 'remove' do
|
85
|
+
description 'Removes a twitter account from the database. If username provided it removes that username else it prompts with list and asks for which one you would like to remove.'
|
86
|
+
argument( 'username' ) {
|
87
|
+
optional
|
88
|
+
description 'username of account you would like to remove'
|
89
|
+
}
|
90
|
+
|
91
|
+
def run
|
92
|
+
do_work do
|
93
|
+
if params['username'].given?
|
94
|
+
account = Account.find_by_username(params['username'].value)
|
95
|
+
else
|
96
|
+
Account.find(:all, :order => 'username').each do |a|
|
97
|
+
say "#{a.id}. #{a}"
|
98
|
+
end
|
99
|
+
account_id = ask 'Account to remove (enter number): ' do |q|
|
100
|
+
q.validate = /\d+/
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
begin
|
105
|
+
account = account_id ? Account.find(account_id) : account
|
106
|
+
account_name = account.username
|
107
|
+
account.destroy
|
108
|
+
Account.set_current(Account.first) if Account.new_active_needed?
|
109
|
+
say "#{account_name} has been removed.\n"
|
110
|
+
rescue ActiveRecord::RecordNotFound
|
111
|
+
say "ERROR: Account could not be found. Try again. \n"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
mode 'list' do
|
118
|
+
description 'Lists all the accounts that have been added and puts a * by the current one that is used for posting, etc.'
|
119
|
+
def run
|
120
|
+
do_work do
|
121
|
+
if Account.count == 0
|
122
|
+
say 'No accounts have been added.'
|
123
|
+
else
|
124
|
+
say 'Account List'
|
125
|
+
Account.find(:all, :order => 'username').each do |a|
|
126
|
+
say a
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
mode 'change' do
|
134
|
+
description 'Changes the current account being used for posting etc. to the username provided. If no username is provided, a list is presented and you can choose the account from there.'
|
135
|
+
argument( 'username' ) {
|
136
|
+
optional
|
137
|
+
description 'username of account you would like to switched to'
|
138
|
+
}
|
139
|
+
|
140
|
+
def run
|
141
|
+
do_work do
|
142
|
+
if params['username'].given?
|
143
|
+
new_current = Account.find_by_username(params['username'].value)
|
144
|
+
else
|
145
|
+
Account.find(:all, :order => 'username').each do |a|
|
146
|
+
say "#{a.id}. #{a}"
|
147
|
+
end
|
148
|
+
new_current = ask 'Change current account to (enter number): ' do |q|
|
149
|
+
q.validate = /\d+/
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
begin
|
154
|
+
current = Account.set_current(new_current)
|
155
|
+
say "#{current} is now the current account.\n"
|
156
|
+
rescue ActiveRecord::RecordNotFound
|
157
|
+
say "ERROR: Account could not be found. Try again. \n"
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
mode 'post' do
|
164
|
+
description "Posts a message to twitter using the current account. The following are all valid examples from the command line:
|
165
|
+
$ twitter post 'my update'
|
166
|
+
$ twitter post my update with quotes
|
167
|
+
$ echo 'my update from stdin' | twitter post"
|
168
|
+
def run
|
169
|
+
do_work do
|
170
|
+
post = ARGV.size > 1 ? ARGV.join(" ") : ARGV.shift
|
171
|
+
say "Sending twitter update"
|
172
|
+
finished, status = false, nil
|
173
|
+
progress_thread = Thread.new { until finished; print "."; $stdout.flush; sleep 0.5; end; }
|
174
|
+
post_thread = Thread.new(binding()) do |b|
|
175
|
+
status = base.post(post, :source => Twitter::SourceName)
|
176
|
+
finished = true
|
177
|
+
end
|
178
|
+
post_thread.join
|
179
|
+
progress_thread.join
|
180
|
+
say "Got it! New twitter created at: #{status.created_at}\n"
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
mode 'befriend' do
|
186
|
+
description "Allows you to add a user as a friend"
|
187
|
+
argument('username') {
|
188
|
+
required
|
189
|
+
description 'username or id of twitterrer to befriend'
|
190
|
+
}
|
191
|
+
|
192
|
+
def run
|
193
|
+
do_work do
|
194
|
+
username = params['username'].value
|
195
|
+
base.create_friendship(username)
|
196
|
+
say "#{username} has been added as a friend. follow notifications with 'twitter follow #{username}'"
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
mode 'defriend' do
|
202
|
+
description "Allows you to remove a user from being a friend"
|
203
|
+
argument('username') {
|
204
|
+
required
|
205
|
+
description 'username or id of twitterrer to defriend'
|
206
|
+
}
|
207
|
+
|
208
|
+
def run
|
209
|
+
do_work do
|
210
|
+
username = params['username'].value
|
211
|
+
base.destroy_friendship(username)
|
212
|
+
say "#{username} has been removed from your friends"
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
mode 'follow' do
|
218
|
+
description "Allows you to turn on notifications for a user"
|
219
|
+
argument('username') {
|
220
|
+
required
|
221
|
+
description 'username or id of twitterrer to follow'
|
222
|
+
}
|
223
|
+
|
224
|
+
def run
|
225
|
+
do_work do
|
226
|
+
username = params['username'].value
|
227
|
+
base.follow(username)
|
228
|
+
say "You are now following notifications from #{username}"
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
mode 'leave' do
|
234
|
+
description "Allows you to turn off notifications for a user"
|
235
|
+
argument('username') {
|
236
|
+
required
|
237
|
+
description 'username or id of twitterrer to leave'
|
238
|
+
}
|
239
|
+
|
240
|
+
def run
|
241
|
+
do_work do
|
242
|
+
username = params['username'].value
|
243
|
+
base.leave(username)
|
244
|
+
say "You are no longer following notifications from #{username}"
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
mode 'd' do
|
250
|
+
description "Allows you to direct message a user. The following are all valid examples from the command line:
|
251
|
+
$ twitter d jnunemaker 'yo homeboy'
|
252
|
+
$ twitter d jnunemaker yo homeboy
|
253
|
+
$ echo 'yo homeboy' | twitter d jnunemaker"
|
254
|
+
argument('username') {
|
255
|
+
required
|
256
|
+
description 'username or id of twitterrer to direct message'
|
257
|
+
}
|
258
|
+
|
259
|
+
def run
|
260
|
+
do_work do
|
261
|
+
username = params['username'].value
|
262
|
+
post = ARGV.size > 1 ? ARGV.join(" ") : ARGV.shift
|
263
|
+
base.d(username, post)
|
264
|
+
say "Direct message sent to #{username}"
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
mode 'timeline' do
|
270
|
+
description "Allows you to view your timeline, your friends or the public one"
|
271
|
+
argument( 'timeline' ) {
|
272
|
+
description 'the timeline you wish to see (friends, public, me)'
|
273
|
+
default 'friends'
|
274
|
+
}
|
275
|
+
option('force', 'f') {
|
276
|
+
description "Ignore since_id and show first page of results even if there aren't new ones"
|
277
|
+
}
|
278
|
+
|
279
|
+
def run
|
280
|
+
do_work do
|
281
|
+
timeline = params['timeline'].value == 'me' ? 'user' : params['timeline'].value
|
282
|
+
options, since_id = {}, Configuration["#{timeline}_since_id"]
|
283
|
+
options[:since_id] = since_id if !since_id.blank? && !params['force'].given?
|
284
|
+
cache = [:friends, :user].include?(timeline)
|
285
|
+
collection = base.timeline(timeline.to_sym, options)
|
286
|
+
output_tweets(collection, {:cache => cache, :since_prefix => timeline})
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
mode 'replies' do
|
292
|
+
description 'Allows you to view all @replies at you'
|
293
|
+
option('force', 'f') {
|
294
|
+
description "Ignore since_id and show first page of replies even if there aren't new ones"
|
295
|
+
}
|
296
|
+
|
297
|
+
def run
|
298
|
+
do_work do
|
299
|
+
options, since_id = {}, Configuration["replies_since_id"]
|
300
|
+
options[:since_id] = since_id if !since_id.blank? && !params['force'].given?
|
301
|
+
collection = base.replies(options)
|
302
|
+
output_tweets(collection, {:since_prefix => 'replies'})
|
303
|
+
end
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
mode 'clear_config' do
|
308
|
+
def run
|
309
|
+
do_work do
|
310
|
+
count = Configuration.count
|
311
|
+
Configuration.destroy_all
|
312
|
+
say("#{count} configuration entries cleared.")
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
mode 'open' do
|
318
|
+
description 'Opens the given twitter user in a browser window'
|
319
|
+
argument('username') {
|
320
|
+
required
|
321
|
+
description "username or id of twitterrer who's page you would like to see"
|
322
|
+
}
|
323
|
+
|
324
|
+
def run
|
325
|
+
`open http://twitter.com/#{params['username'].value}`
|
326
|
+
end
|
327
|
+
end
|
328
|
+
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Twitter
|
2
|
+
class DirectMessage
|
3
|
+
include EasyClassMaker
|
4
|
+
|
5
|
+
attributes :id, :text, :sender_id, :recipient_id, :created_at, :sender_screen_name, :recipient_screen_name
|
6
|
+
|
7
|
+
class << self
|
8
|
+
# Creates a new status from a piece of xml
|
9
|
+
def new_from_xml(xml)
|
10
|
+
DirectMessage.new do |d|
|
11
|
+
d.id = (xml).at('id').innerHTML
|
12
|
+
d.text = (xml).get_elements_by_tag_name('text').innerHTML
|
13
|
+
d.sender_id = (xml).at('sender_id').innerHTML
|
14
|
+
d.recipient_id = (xml).at('recipient_id').innerHTML
|
15
|
+
d.created_at = (xml).at('created_at').innerHTML
|
16
|
+
d.sender_screen_name = (xml).at('sender_screen_name').innerHTML
|
17
|
+
d.recipient_screen_name = (xml).at('recipient_screen_name').innerHTML
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# This is pretty much just a macro for creating a class that allows
|
2
|
+
# using a block to initialize stuff and to define getters and setters
|
3
|
+
# really quickly.
|
4
|
+
module Twitter
|
5
|
+
module EasyClassMaker
|
6
|
+
|
7
|
+
def self.included(base)
|
8
|
+
base.extend(ClassMethods)
|
9
|
+
end
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
# creates the attributes class variable and creates each attribute's accessor methods
|
13
|
+
def attributes(*attrs)
|
14
|
+
@@attributes = attrs
|
15
|
+
@@attributes.each { |a| attr_accessor a }
|
16
|
+
end
|
17
|
+
|
18
|
+
# read method for attributes class variable
|
19
|
+
def self.attributes; @@attributes end
|
20
|
+
end
|
21
|
+
|
22
|
+
# allows for any class that includes this to use a block to initialize
|
23
|
+
# variables instead of assigning each one seperately
|
24
|
+
#
|
25
|
+
# Example:
|
26
|
+
#
|
27
|
+
# instead of...
|
28
|
+
#
|
29
|
+
# s = Status.new
|
30
|
+
# s.foo = 'thing'
|
31
|
+
# s.bar = 'another thing'
|
32
|
+
#
|
33
|
+
# you can ...
|
34
|
+
#
|
35
|
+
# Status.new do |s|
|
36
|
+
# s.foo = 'thing'
|
37
|
+
# s.bar = 'another thing'
|
38
|
+
# end
|
39
|
+
def initialize
|
40
|
+
yield self if block_given?
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Twitter
|
2
|
+
class RateLimitStatus
|
3
|
+
include EasyClassMaker
|
4
|
+
|
5
|
+
attributes :reset_time_in_seconds, :reset_time, :remaining_hits, :hourly_limit
|
6
|
+
|
7
|
+
class << self
|
8
|
+
# Creates a new rate limi status from a piece of xml
|
9
|
+
def new_from_xml(xml)
|
10
|
+
RateLimitStatus.new do |s|
|
11
|
+
s.reset_time_in_seconds = xml.at('reset-time-in-seconds').inner_html.to_i
|
12
|
+
s.reset_time = Time.parse xml.at('reset-time').inner_html
|
13
|
+
s.remaining_hits = xml.at('remaining-hits').inner_html.to_i
|
14
|
+
s.hourly_limit = xml.at('hourly-limit').inner_html.to_i
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Twitter
|
2
|
+
class Status
|
3
|
+
include EasyClassMaker
|
4
|
+
|
5
|
+
attributes :created_at, :id, :text, :user, :source, :truncated, :in_reply_to_status_id, :in_reply_to_user_id, :favorited
|
6
|
+
|
7
|
+
# Creates a new status from a piece of xml
|
8
|
+
def self.new_from_xml(xml)
|
9
|
+
s = new
|
10
|
+
s.id = (xml).at('id').innerHTML
|
11
|
+
s.created_at = (xml).at('created_at').innerHTML
|
12
|
+
s.text = (xml).get_elements_by_tag_name('text').innerHTML
|
13
|
+
s.source = (xml).at('source').innerHTML
|
14
|
+
s.truncated = (xml).at('truncated').innerHTML == 'false' ? false : true
|
15
|
+
s.favorited = (xml).at('favorited').innerHTML == 'false' ? false : true
|
16
|
+
s.in_reply_to_status_id = (xml).at('in_reply_to_status_id').innerHTML
|
17
|
+
s.in_reply_to_user_id = (xml).at('in_reply_to_user_id').innerHTML
|
18
|
+
s.user = User.new_from_xml(xml.at('user')) if (xml).at('user')
|
19
|
+
s
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/twitter/user.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
module Twitter
|
2
|
+
class User
|
3
|
+
include EasyClassMaker
|
4
|
+
|
5
|
+
attributes :id, :name, :screen_name, :status, :location, :description, :url,
|
6
|
+
:profile_image_url, :profile_background_color, :profile_text_color, :profile_link_color,
|
7
|
+
:profile_sidebar_fill_color, :profile_sidebar_border_color, :friends_count, :followers_count,
|
8
|
+
:favourites_count, :statuses_count, :utc_offset , :protected
|
9
|
+
|
10
|
+
# Creates a new user from a piece of xml
|
11
|
+
def self.new_from_xml(xml)
|
12
|
+
u = new
|
13
|
+
u.id = (xml).at('id').innerHTML
|
14
|
+
u.name = (xml).at('name').innerHTML
|
15
|
+
u.screen_name = (xml).at('screen_name').innerHTML
|
16
|
+
u.location = (xml).at('location').innerHTML
|
17
|
+
u.description = (xml).at('description').innerHTML
|
18
|
+
u.url = (xml).at('url').innerHTML
|
19
|
+
u.profile_image_url = (xml).at('profile_image_url').innerHTML
|
20
|
+
|
21
|
+
# optional, not always present
|
22
|
+
u.profile_background_color = (xml).at('profile_background_color').innerHTML if (xml).at('profile_background_color')
|
23
|
+
u.profile_text_color = (xml).at('profile_text_color').innerHTML if (xml).at('profile_text_color')
|
24
|
+
u.profile_link_color = (xml).at('profile_link_color').innerHTML if (xml).at('profile_link_color')
|
25
|
+
u.profile_sidebar_fill_color = (xml).at('profile_sidebar_fill_color').innerHTML if (xml).at('profile_sidebar_fill_color')
|
26
|
+
u.profile_sidebar_border_color = (xml).at('profile_sidebar_border_color').innerHTML if (xml).at('profile_sidebar_border_color')
|
27
|
+
u.friends_count = (xml).at('friends_count').innerHTML if (xml).at('friends_count')
|
28
|
+
u.followers_count = (xml).at('followers_count').innerHTML if (xml).at('followers_count')
|
29
|
+
u.favourites_count = (xml).at('favourites_count').innerHTML if (xml).at('favourites_count')
|
30
|
+
u.statuses_count = (xml).at('statuses_count').innerHTML if (xml).at('statuses_count')
|
31
|
+
u.utc_offset = (xml).at('utc_offset').innerHTML if (xml).at('utc_offset')
|
32
|
+
u.protected = (xml).at('protected').innerHTML == 'false' ? false : true if (xml).at('protected')
|
33
|
+
u.status = Status.new_from_xml(xml.at('status')) if (xml).at('status')
|
34
|
+
u
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/twitter.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
%w(uri cgi net/http yaml rubygems hpricot active_support).each { |f| require f }
|
2
|
+
|
3
|
+
$:.unshift(File.join(File.dirname(__FILE__)))
|
4
|
+
require 'twitter/version'
|
5
|
+
require 'twitter/easy_class_maker'
|
6
|
+
require 'twitter/base'
|
7
|
+
require 'twitter/user'
|
8
|
+
require 'twitter/status'
|
9
|
+
require 'twitter/direct_message'
|
10
|
+
require 'twitter/rate_limit_status'
|
11
|
+
|
12
|
+
module Twitter
|
13
|
+
class Unavailable < StandardError; end
|
14
|
+
class CantConnect < StandardError; end
|
15
|
+
class BadResponse < StandardError; end
|
16
|
+
class UnknownTimeline < ArgumentError; end
|
17
|
+
class RateExceeded < StandardError; end
|
18
|
+
|
19
|
+
SourceName = 'twittergem'
|
20
|
+
end
|
data/script/destroy
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
APP_ROOT = File.join(File.dirname(__FILE__), '..')
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'rubigen'
|
6
|
+
rescue LoadError
|
7
|
+
require 'rubygems'
|
8
|
+
require 'rubigen'
|
9
|
+
end
|
10
|
+
require 'rubigen/scripts/destroy'
|
11
|
+
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
14
|
+
RubiGen::Scripts::Destroy.new.run(ARGV)
|
data/script/generate
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
APP_ROOT = File.join(File.dirname(__FILE__), '..')
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'rubigen'
|
6
|
+
rescue LoadError
|
7
|
+
require 'rubygems'
|
8
|
+
require 'rubigen'
|
9
|
+
end
|
10
|
+
require 'rubigen/scripts/generate'
|
11
|
+
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
14
|
+
RubiGen::Scripts::Generate.new.run(ARGV)
|
data/script/txt2html
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
begin
|
5
|
+
require 'newgem'
|
6
|
+
rescue LoadError
|
7
|
+
puts "\n\nGenerating the website requires the newgem RubyGem"
|
8
|
+
puts "Install: gem install newgem\n\n"
|
9
|
+
exit(1)
|
10
|
+
end
|
11
|
+
require 'redcloth'
|
12
|
+
require 'syntax/convertors/html'
|
13
|
+
require 'erb'
|
14
|
+
require File.dirname(__FILE__) + '/../lib/twitter/version.rb'
|
15
|
+
|
16
|
+
version = Twitter.git::VERSION::STRING
|
17
|
+
download = 'http://rubyforge.org/projects/twitter'
|
18
|
+
|
19
|
+
class Fixnum
|
20
|
+
def ordinal
|
21
|
+
# teens
|
22
|
+
return 'th' if (10..19).include?(self % 100)
|
23
|
+
# others
|
24
|
+
case self % 10
|
25
|
+
when 1: return 'st'
|
26
|
+
when 2: return 'nd'
|
27
|
+
when 3: return 'rd'
|
28
|
+
else return 'th'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class Time
|
34
|
+
def pretty
|
35
|
+
return "#{mday}#{mday.ordinal} #{strftime('%B')} #{year}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def convert_syntax(syntax, source)
|
40
|
+
return Syntax::Convertors::HTML.for_syntax(syntax).convert(source).gsub(%r!^<pre>|</pre>$!,'')
|
41
|
+
end
|
42
|
+
|
43
|
+
if ARGV.length >= 1
|
44
|
+
src, template = ARGV
|
45
|
+
template ||= File.join(File.dirname(__FILE__), '/../website/template.rhtml')
|
46
|
+
|
47
|
+
else
|
48
|
+
puts("Usage: #{File.split($0).last} source.txt [template.rhtml] > output.html")
|
49
|
+
exit!
|
50
|
+
end
|
51
|
+
|
52
|
+
template = ERB.new(File.open(template).read)
|
53
|
+
|
54
|
+
title = nil
|
55
|
+
body = nil
|
56
|
+
File.open(src) do |fsrc|
|
57
|
+
title_text = fsrc.readline
|
58
|
+
body_text = fsrc.read
|
59
|
+
syntax_items = []
|
60
|
+
body_text.gsub!(%r!<(pre|code)[^>]*?syntax=['"]([^'"]+)[^>]*>(.*?)</\1>!m){
|
61
|
+
ident = syntax_items.length
|
62
|
+
element, syntax, source = $1, $2, $3
|
63
|
+
syntax_items << "<#{element} class='syntax'>#{convert_syntax(syntax, source)}</#{element}>"
|
64
|
+
"syntax-temp-#{ident}"
|
65
|
+
}
|
66
|
+
title = RedCloth.new(title_text).to_html.gsub(%r!<.*?>!,'').strip
|
67
|
+
body = RedCloth.new(body_text).to_html
|
68
|
+
body.gsub!(%r!(?:<pre><code>)?syntax-temp-(\d+)(?:</code></pre>)?!){ syntax_items[$1.to_i] }
|
69
|
+
end
|
70
|
+
stat = File.stat(src)
|
71
|
+
created = stat.ctime
|
72
|
+
modified = stat.mtime
|
73
|
+
|
74
|
+
$stdout << template.result(binding)
|