oz 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +209 -0
- data/bin/oz +287 -0
- data/test/test_oz.rb +210 -0
- metadata +50 -0
data/README
ADDED
@@ -0,0 +1,209 @@
|
|
1
|
+
#
|
2
|
+
# oz.
|
3
|
+
# a command line t
|
4
|
+
# u
|
5
|
+
# by. m
|
6
|
+
# chris wanstrath b
|
7
|
+
# l
|
8
|
+
# - and - e
|
9
|
+
# r
|
10
|
+
# dayne broderson
|
11
|
+
#
|
12
|
+
|
13
|
+
New to ozimodo 1.2 is oz, the swiss army knife of command line tumbling.
|
14
|
+
Sure, Ajax is great. And you know what? Some HTML is okay, too. But nothing
|
15
|
+
beats the warm glow of a terminal.
|
16
|
+
|
17
|
+
First, let us install oz. It's pretty easy, thanks to Ruby and all the
|
18
|
+
people who make it great:
|
19
|
+
|
20
|
+
$ gem install oz
|
21
|
+
|
22
|
+
(If you already have ozimodo 1.2 you can find oz in ozimodo/bin, but the
|
23
|
+
gem install is recommended.)
|
24
|
+
|
25
|
+
== The Wizard of oz
|
26
|
+
|
27
|
+
Not every tumblelog (or blog) supports oz yet, but they will. In
|
28
|
+
the meantime, let's play some with a tumblelog we know supports oz:
|
29
|
+
ozmm.org.
|
30
|
+
|
31
|
+
$ oz --at ozmm.org commands
|
32
|
+
|
33
|
+
This will give us a list of commands ozmm.org's API supports. I get this
|
34
|
+
list:
|
35
|
+
|
36
|
+
- code
|
37
|
+
- commands
|
38
|
+
- image
|
39
|
+
- link
|
40
|
+
- list
|
41
|
+
- post
|
42
|
+
- posts_with_tag
|
43
|
+
- quip
|
44
|
+
- quote
|
45
|
+
- show
|
46
|
+
- tags
|
47
|
+
- types
|
48
|
+
- version
|
49
|
+
- whoami
|
50
|
+
|
51
|
+
Okay, fair enough. Let's start simple.
|
52
|
+
|
53
|
+
$ oz --at ozmm.org version
|
54
|
+
version: "1.2"
|
55
|
+
|
56
|
+
Nice. Up to date. How about...
|
57
|
+
|
58
|
+
$ oz --at ozmm.org tags
|
59
|
+
- ruby: 158
|
60
|
+
- rails: 62
|
61
|
+
- photos: 53
|
62
|
+
- games: 46
|
63
|
+
- svrc: 43
|
64
|
+
- php: 37
|
65
|
+
- mac: 34
|
66
|
+
- quotes: 33
|
67
|
+
- sanfrancisco: 28
|
68
|
+
- music: 17
|
69
|
+
- javascript: 14
|
70
|
+
- tumblelog: 5
|
71
|
+
- cocoa: 4
|
72
|
+
- rss: 4
|
73
|
+
- subversion: 4
|
74
|
+
- io: 3
|
75
|
+
- mysql: 3
|
76
|
+
- vim: 3
|
77
|
+
|
78
|
+
Whoa! Okay, Mr. Web2.0. Let's see what you have to say about vim...
|
79
|
+
|
80
|
+
$ oz --at ozmm.org posts_with_tag vim
|
81
|
+
- 585:
|
82
|
+
user: admin
|
83
|
+
title: ""
|
84
|
+
tags: vim
|
85
|
+
id: 585
|
86
|
+
content: okay we've got ''pastie for vim'':http://pastie.caboo.se/606 ...
|
87
|
+
post_type: quip
|
88
|
+
user_id: 1
|
89
|
+
created_at: 2006-07-10 13:15:00 -07:00
|
90
|
+
[ ...more posts... ]
|
91
|
+
|
92
|
+
We can, of course, also run commands like posts or show 13 to get
|
93
|
+
information on specific posts. What's this code command, though?
|
94
|
+
I'll try it.
|
95
|
+
|
96
|
+
$ oz --at ozmm.org code
|
97
|
+
error: You need to login to do that
|
98
|
+
|
99
|
+
Ah, so it's something secretive. If only we were let into the club...
|
100
|
+
|
101
|
+
== Posting To Your Tumblelog With oz
|
102
|
+
|
103
|
+
oz is great for querying tumblelogs, but the real magic is its ability to
|
104
|
+
post to your tumblelog.
|
105
|
+
|
106
|
+
=== Loggin' In
|
107
|
+
|
108
|
+
The first thing we need to do is login. Since
|
109
|
+
ozimodo 1.2 uses cookies for authentication, this is cake. We'll be doing all
|
110
|
+
of this on our local build of ozimodo, running at http://localhost:3000.
|
111
|
+
|
112
|
+
My username is monet and my password is goodart. Here is how I login:
|
113
|
+
|
114
|
+
$ oz --site monet:goodartlocalhost:3000
|
115
|
+
=> Login successful, you don't have to use --site anymore.
|
116
|
+
=> No URL to hit.
|
117
|
+
|
118
|
+
Ah, great! But what did that do? Well, it created a ~/.ozcache file
|
119
|
+
and stored some information in it.
|
120
|
+
|
121
|
+
$ cat ~/.ozcache
|
122
|
+
cookie: ozimodo=1%26admin%269ce07a6fe388c0ceac0bd5b041757f1b
|
123
|
+
port: 3000
|
124
|
+
host: localhost
|
125
|
+
|
126
|
+
This file contains the host and port of the tumblelog we want to work on as
|
127
|
+
well as our login cookie, which will keep us from sending our password on
|
128
|
+
every request.
|
129
|
+
|
130
|
+
If you don't want the cache file to be ~/.ozcache you can set the OZCACHE
|
131
|
+
environment variable and oz will use that instead.
|
132
|
+
|
133
|
+
=== Posting
|
134
|
+
|
135
|
+
Posting is the easiest part. Since "you know":configure.html a tumblelog
|
136
|
+
consists of multiple post types, let's see what post types we have available.
|
137
|
+
|
138
|
+
$ oz types
|
139
|
+
- code: content
|
140
|
+
- quip: content
|
141
|
+
- post: content
|
142
|
+
- quote:
|
143
|
+
- author
|
144
|
+
- quote
|
145
|
+
- link: content
|
146
|
+
- image:
|
147
|
+
- src
|
148
|
+
- alt
|
149
|
+
- blurb
|
150
|
+
|
151
|
+
We're given a simple list (somewhat YAML-like) which lists each of our
|
152
|
+
available post types and the fields they accept. code consists of
|
153
|
+
simple content while quote consists of author and quote, right?
|
154
|
+
|
155
|
+
Let's post a quip, which Webster defines as a "clever, witty remark often
|
156
|
+
prompted by the occasion."
|
157
|
+
|
158
|
+
$ oz quip --content 'This command line stuff is so 1970.'
|
159
|
+
success: Post saved with id of 22
|
160
|
+
|
161
|
+
Wow, it really worked. If we were to open up our tumblelog at
|
162
|
+
http://localhost:3000 we'd see a new quip with our content.
|
163
|
+
|
164
|
+
How about posting an image?
|
165
|
+
|
166
|
+
$ oz image --src http://facebook.railsconf.org/portraits/139/snap.png \
|
167
|
+
--tags 'rails dhh' --alt 'dhh is hot'
|
168
|
+
success: Post saved with id of 23
|
169
|
+
|
170
|
+
Even though --tags isn't listed in the types info, it's of course a valid
|
171
|
+
switch. You can also use the --title switch with any post.
|
172
|
+
|
173
|
+
Personally, I post a lot of links. It would suck to have to format them in
|
174
|
+
textile from the command line each time. Lots of terminating slashes.
|
175
|
+
|
176
|
+
$ oz link --url http://www.pjhyett.com/ --text 'PJ is a hack.' --tags link
|
177
|
+
success: Post saved with id of 24
|
178
|
+
|
179
|
+
The link post type is special; our above input will be roughly translated
|
180
|
+
to:
|
181
|
+
|
182
|
+
''PJ is a hack.'':http://www.pjhyett.com" before posting.
|
183
|
+
|
184
|
+
It's a nice shortcut.
|
185
|
+
|
186
|
+
== Tips and Tricks
|
187
|
+
|
188
|
+
You can use oz --help for a refresher course at any time. That'll tell you
|
189
|
+
some helpful information, like that you can use --debug or --clear-cache
|
190
|
+
when you're really getting into it.
|
191
|
+
|
192
|
+
If your login has expired you can simply rock the --login switch without having
|
193
|
+
to re-enter your host and port, ala:
|
194
|
+
|
195
|
+
$ oz --login monet:goodart
|
196
|
+
=> Login successful, you don't have to use --site anymore.
|
197
|
+
|
198
|
+
You can mostly ignore the No URL to hit messages as they're just letting you
|
199
|
+
know that while you may have asked something of oz, it's not going to request
|
200
|
+
anything of the remote server.
|
201
|
+
|
202
|
+
If you're interested in how the oz API works, writing your own tumbler, or
|
203
|
+
implementing an API which oz can interact with (%(aside)it's quite versatile%),
|
204
|
+
check out our "API":api.html docs.
|
205
|
+
|
206
|
+
== It Broke!
|
207
|
+
|
208
|
+
As always, check the "install":install.html page for the best ways to report
|
209
|
+
a bug. We thank ya.
|
data/bin/oz
ADDED
@@ -0,0 +1,287 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#
|
4
|
+
# oz.
|
5
|
+
# a command line t
|
6
|
+
# u
|
7
|
+
# by. m
|
8
|
+
# chris wanstrath b
|
9
|
+
# l
|
10
|
+
# - and - e
|
11
|
+
# r
|
12
|
+
# dayne broderson
|
13
|
+
#
|
14
|
+
|
15
|
+
require 'net/http'
|
16
|
+
require 'open-uri'
|
17
|
+
require 'uri'
|
18
|
+
require 'yaml'
|
19
|
+
|
20
|
+
OZ_VERSION = '0.1'
|
21
|
+
USER_AGENT = "oz/#{OZ_VERSION}"
|
22
|
+
|
23
|
+
class OzException < Exception; end
|
24
|
+
class BadFormatOfSiteSwitch < OzException; end
|
25
|
+
class BadFormatOfLoginSwitch < OzException; end
|
26
|
+
class ConfigFileDoesntExist < OzException; end
|
27
|
+
class ConfigFileNeedsHost < OzException; end
|
28
|
+
class CantLoginWithoutHost < OzException; end
|
29
|
+
class LoginFailed < OzException; end
|
30
|
+
class HostNeeded < OzException; end
|
31
|
+
|
32
|
+
class Oz
|
33
|
+
class << self
|
34
|
+
@@debug = false
|
35
|
+
|
36
|
+
def tumble(args)
|
37
|
+
check_oz_switches(args)
|
38
|
+
|
39
|
+
if args.include?('--at')
|
40
|
+
host, port = parse_at_switch(args)
|
41
|
+
else
|
42
|
+
host, port, cookie = load_cache_or_login(args)
|
43
|
+
end
|
44
|
+
|
45
|
+
error "No cache file or host info found. Please run the script with --site user:pass@host:port." unless host
|
46
|
+
|
47
|
+
url = build_url(host, port, args)
|
48
|
+
headers = build_headers(cookie)
|
49
|
+
|
50
|
+
error "No URL to hit." unless url
|
51
|
+
|
52
|
+
debug "Hitting #{url} with headers #{headers.inspect}."
|
53
|
+
|
54
|
+
begin
|
55
|
+
open(url, headers) do |body|
|
56
|
+
puts body.read
|
57
|
+
end
|
58
|
+
rescue => e
|
59
|
+
error "There was an error connecting to http://#{host}:#{port}:\n #{e}"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def do_login(host, port, user, pass)
|
64
|
+
uri = URI.parse("http://#{host}")
|
65
|
+
uri.send(:set_port, port)
|
66
|
+
debug "Tried to login to #{uri.host}:#{port}#{uri.path} as #{user}/#{pass}."
|
67
|
+
begin
|
68
|
+
site = Net::HTTP.new(uri.host, uri.port)
|
69
|
+
res = site.post2("#{uri.path}/api/login", "username=#{user}&password=#{pass}", build_headers)
|
70
|
+
rescue Errno::ECONNREFUSED
|
71
|
+
error "Couldn't connect to http://#{host}:#{port} to login."
|
72
|
+
end
|
73
|
+
(res.header['set-cookie'] =~ /(.+); path(.+)$/) ? $1 : false
|
74
|
+
end
|
75
|
+
|
76
|
+
def parse_site_switch(site)
|
77
|
+
raise BadFormatOfSiteSwitch unless site =~ /^(http:\/\/)?(.+):(.+)@([^:]+):?(\d*)$/
|
78
|
+
[$4, $2, $3, ($5.empty? ? 80 : $5)]
|
79
|
+
end
|
80
|
+
|
81
|
+
def parse_at_switch(args)
|
82
|
+
if i = args.index('--at')
|
83
|
+
info = args[i+1]
|
84
|
+
args.delete_at(i+1)
|
85
|
+
args.delete_at(i)
|
86
|
+
else
|
87
|
+
return false
|
88
|
+
end
|
89
|
+
|
90
|
+
raise BadFormatOfAtSwitch unless info =~ /^(http:\/\/)?([^:!]+):?(\d*)$/
|
91
|
+
[$2, ($3.empty? ? 80 : $3).to_i]
|
92
|
+
end
|
93
|
+
|
94
|
+
def parse_login_switch(login)
|
95
|
+
raise BadFormatOfLoginSwitch unless login =~ /^(.+):(.+)$/
|
96
|
+
[$1, $2]
|
97
|
+
end
|
98
|
+
|
99
|
+
def write_to_cache(options)
|
100
|
+
cache_file = ENV['OZCACHE'] || (File.expand_path('~') + '/.ozcache')
|
101
|
+
options.stringify_keys!
|
102
|
+
cache = if File.exists? cache_file
|
103
|
+
YAML.load(File.read(cache_file)).merge(options)
|
104
|
+
else
|
105
|
+
options
|
106
|
+
end
|
107
|
+
file = File.new(cache_file, 'w')
|
108
|
+
file.write(YAML.dump(cache))
|
109
|
+
file.close_write
|
110
|
+
debug "Wrote #{cache.inspect} to cache file #{cache_file}."
|
111
|
+
end
|
112
|
+
|
113
|
+
def clear_cache
|
114
|
+
files = [ENV['OZCACHE'], File.expand_path('~') + '/.ozcache'].compact
|
115
|
+
|
116
|
+
return info("No cache exists.") unless files.any? { |f| File.exists?(f) }
|
117
|
+
|
118
|
+
while file = files.shift
|
119
|
+
next unless File.exists? file
|
120
|
+
File.unlink file
|
121
|
+
info "Deleted cache file #{file}"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def load_cache_or_login(args)
|
126
|
+
host, port, cookie = load_cache
|
127
|
+
host, port, cookie = cache_info_from_switch(host, port, args) if args.any? { |a| a =~ /site|login/ }
|
128
|
+
[host, port, cookie]
|
129
|
+
end
|
130
|
+
|
131
|
+
def load_cache
|
132
|
+
if (file = ENV['OZCACHE']) && File.exists?(file)
|
133
|
+
elsif (file = File.expand_path('~') + '/.ozcache') && File.exists?(file)
|
134
|
+
else return false
|
135
|
+
end
|
136
|
+
yaml = YAML.load(File.read(file))
|
137
|
+
debug "Loaded cache file #{file}"
|
138
|
+
yaml['host'] ? [yaml['host'], yaml['port'], yaml['cookie']] : false
|
139
|
+
end
|
140
|
+
|
141
|
+
def cache_info_from_switch(host, port, args)
|
142
|
+
if ((i = args.index('--login')) || (i = args.index('--site')))
|
143
|
+
switch_type, info = args[i], args[i+1]
|
144
|
+
args.delete_at(i+1)
|
145
|
+
args.delete_at(i)
|
146
|
+
else
|
147
|
+
return false
|
148
|
+
end
|
149
|
+
|
150
|
+
case switch_type
|
151
|
+
when '--login'
|
152
|
+
raise CantLoginWithoutHost unless host
|
153
|
+
user, pass = parse_login_switch(info)
|
154
|
+
when '--site'
|
155
|
+
host, user, pass, port = parse_site_switch(info)
|
156
|
+
end
|
157
|
+
|
158
|
+
raise LoginFailed unless cookie = do_login(host, port, user, pass)
|
159
|
+
|
160
|
+
info "Login successful, you don't have to use --site anymore."
|
161
|
+
write_to_cache(:host => host, :port => port.to_i, :cookie => cookie)
|
162
|
+
|
163
|
+
[host, port, cookie]
|
164
|
+
end
|
165
|
+
|
166
|
+
def build_url(host, port, args)
|
167
|
+
return unless args.size.nonzero?
|
168
|
+
port = (port == 80) ? '' : ":#{port}"
|
169
|
+
domain = host =~ /([^\/]+)\/(.+)/ ? "#{$1}#{port}/#{$2}" : "#{host}#{port}"
|
170
|
+
url = "http://#{domain}/api/"
|
171
|
+
url << args.shift # something like 'list' or 'show' -- the page you want to hit
|
172
|
+
url << "/#{args.shift}" if args.size.nonzero? unless args.first =~ /^--/ # the '33' part of /api/show/33
|
173
|
+
|
174
|
+
# turns --link http://ozmm.org into &post[link]=http://ozmm.org
|
175
|
+
sep = '?'
|
176
|
+
while arg = args.shift
|
177
|
+
next unless arg =~ /^--(\w+)/
|
178
|
+
url << "#{sep}post[#{$1}]=#{args.shift}"
|
179
|
+
sep = '&'
|
180
|
+
end if args.size.nonzero?
|
181
|
+
|
182
|
+
url = URI.escape(url)
|
183
|
+
debug "Built url #{url}"
|
184
|
+
url
|
185
|
+
end
|
186
|
+
|
187
|
+
def build_headers(cookie = nil)
|
188
|
+
headers = { 'User-Agent' => USER_AGENT, 'Accept' => 'text/plain' }
|
189
|
+
cookie ? headers.merge('Cookie' => cookie) : headers
|
190
|
+
end
|
191
|
+
|
192
|
+
def error(msg)
|
193
|
+
puts "=> #{msg}"
|
194
|
+
exit
|
195
|
+
end
|
196
|
+
|
197
|
+
def info(msg)
|
198
|
+
puts "=> #{msg}"
|
199
|
+
end
|
200
|
+
|
201
|
+
def debug(msg)
|
202
|
+
info msg if @@debug
|
203
|
+
end
|
204
|
+
|
205
|
+
def check_oz_switches(args)
|
206
|
+
if args.index('--clear-cache')
|
207
|
+
clear_cache
|
208
|
+
exit
|
209
|
+
end
|
210
|
+
|
211
|
+
if args.index('--help')
|
212
|
+
show_help
|
213
|
+
exit
|
214
|
+
end
|
215
|
+
|
216
|
+
if i = args.index('--debug')
|
217
|
+
args.delete_at(i)
|
218
|
+
@@debug = true
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
def show_help
|
223
|
+
break_length = 29
|
224
|
+
puts "Usage: oz [command] [arguments] <switch>"
|
225
|
+
|
226
|
+
show_switch = proc { |s| (' ' * 4) + sprintf("%-#{break_length}s", s) }
|
227
|
+
|
228
|
+
print show_switch.call('--site user:pass@host:port')
|
229
|
+
puts "Login. Once you do this, your login cookie and server will be cached"
|
230
|
+
|
231
|
+
print show_switch.call('--at host:port')
|
232
|
+
puts "Hit a specific host once. Use this for hitting APIs you don't want to login to."
|
233
|
+
|
234
|
+
print show_switch.call('--debug')
|
235
|
+
puts "Print debug information"
|
236
|
+
|
237
|
+
print show_switch.call('--clear-cache')
|
238
|
+
puts "Clear your local login/site cache"
|
239
|
+
|
240
|
+
print show_switch.call('--help')
|
241
|
+
puts "This message"
|
242
|
+
|
243
|
+
puts
|
244
|
+
puts "Remote Commands:"
|
245
|
+
|
246
|
+
print show_switch.call('commands')
|
247
|
+
puts "Get a list of valid commands from the server"
|
248
|
+
|
249
|
+
print show_switch.call('types')
|
250
|
+
puts "Get a list of valid type commands and their arguments from the server"
|
251
|
+
|
252
|
+
print show_switch.call('list')
|
253
|
+
puts "See a list of recent posts"
|
254
|
+
|
255
|
+
print show_switch.call('show #')
|
256
|
+
puts "Examine post number #"
|
257
|
+
|
258
|
+
puts
|
259
|
+
puts "Example usage:"
|
260
|
+
puts " $ ./oz --site mark:love@ozmm.org list"
|
261
|
+
puts " => Login successful, you don't have to use --site anymore."
|
262
|
+
puts " <list of recent posts>"
|
263
|
+
puts " $ ./oz show 12"
|
264
|
+
puts " <YAML description of post 12>"
|
265
|
+
puts " $ ./oz image --src http://ozmm.org/images/smiley_face.jpg --alt 'smile!' --tags 'photos faces'"
|
266
|
+
puts " success: Post saved with id of 13"
|
267
|
+
|
268
|
+
puts
|
269
|
+
puts " See http://ozimodo.rubyforge.org/oz.html for a more in-depth tutorial."
|
270
|
+
end
|
271
|
+
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
class Hash
|
276
|
+
def stringify_keys!
|
277
|
+
keys.each do |key|
|
278
|
+
unless key.class.to_s == "String"
|
279
|
+
self[key.to_s] = self[key]
|
280
|
+
delete(key)
|
281
|
+
end
|
282
|
+
end
|
283
|
+
self
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
Oz.tumble(ARGV.dup) unless $DONT_RUN
|
data/test/test_oz.rb
ADDED
@@ -0,0 +1,210 @@
|
|
1
|
+
$:.unshift Dir.pwd
|
2
|
+
require 'test/unit'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'tempfile'
|
5
|
+
$DONT_RUN = true
|
6
|
+
load 'bin/oz'
|
7
|
+
|
8
|
+
# don't let oz exit when it wants to
|
9
|
+
Kernel.send(:define_method, :exit, proc {})
|
10
|
+
|
11
|
+
class OzTest < Test::Unit::TestCase
|
12
|
+
|
13
|
+
def test_load_cache_from_env
|
14
|
+
ENV['OZCACHE'] = 'ozimondo'
|
15
|
+
file = File.new('ozimondo', 'w')
|
16
|
+
file.write <<-MONDO
|
17
|
+
---
|
18
|
+
host: ozmm.org
|
19
|
+
port: 80
|
20
|
+
cookie: crazy#RJrj3rhQ#ROHr3$TOhy4--
|
21
|
+
MONDO
|
22
|
+
file.close_write
|
23
|
+
assert_equal ['ozmm.org', 80, 'crazy#RJrj3rhQ#ROHr3$TOhy4--'], Oz.load_cache
|
24
|
+
FileUtils.rm 'ozimondo'
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_write_host_to_cache
|
28
|
+
ENV['OZCACHE'] = 'ozicachedo'
|
29
|
+
Oz.write_to_cache(:host => 'ozmm.org')
|
30
|
+
assert_equal 'ozmm.org', YAML.load(File.read('ozicachedo'))['host']
|
31
|
+
FileUtils.rm 'ozicachedo'
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_write_host_and_port_to_cache
|
35
|
+
ENV['OZCACHE'] = 'ozidom'
|
36
|
+
Oz.write_to_cache(:host => '127.0.0.1', :port => 3000)
|
37
|
+
assert_equal '127.0.0.1', YAML.load(File.read('ozidom'))['host']
|
38
|
+
assert_equal 3000, YAML.load(File.read('ozidom'))['port']
|
39
|
+
FileUtils.rm 'ozidom'
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_load_cache_or_login
|
43
|
+
assert false
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_cache_info_from_switch
|
47
|
+
assert false
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_do_login_good
|
51
|
+
assert_equal 'ozimodo=cookiecookie', Oz.do_login('ozmm.org', 80, 'cookie', 'monster')
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_parse_site_switch_good
|
55
|
+
args = %w[--site chris:jimmy@ozmm.org]
|
56
|
+
assert_equal %w[ozmm.org chris jimmy] + [80], Oz.parse_site_switch(args.last)
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_parse_site_switch_with_http
|
60
|
+
args = %w[--site http://jimmy:chris@ozmm.org]
|
61
|
+
assert_equal %w[ozmm.org jimmy chris] + [80], Oz.parse_site_switch(args.last)
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_parse_site_switch_with_port
|
65
|
+
args = %w[--site http://local:host@ozmm.org:3000]
|
66
|
+
assert_equal %w[ozmm.org local host 3000], Oz.parse_site_switch(args.last)
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_parse_site_switch_no_auth
|
70
|
+
args = %w[--site http://ozmm.org]
|
71
|
+
assert_raises(BadFormatOfSiteSwitch) do
|
72
|
+
Oz.parse_site_switch(args.last)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_parse_site_switch_bad
|
77
|
+
args = %w[--site chris!@ozmm.org]
|
78
|
+
assert_raises(BadFormatOfSiteSwitch) do
|
79
|
+
Oz.parse_site_switch(args.last)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_parse_login_switch
|
84
|
+
args = %w[--login chris:jimmy]
|
85
|
+
assert_equal %w[chris jimmy], Oz.parse_login_switch(args.last)
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_parse_login_switch_bad
|
89
|
+
args = %w[--login chris!jimmy]
|
90
|
+
assert_raises(BadFormatOfLoginSwitch) do
|
91
|
+
Oz.parse_login_switch(args.last)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_parse_at_switch
|
96
|
+
args = %w[--at http://ozmm.org]
|
97
|
+
assert_equal ['ozmm.org', 80], Oz.parse_at_switch(args)
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_parse_at_switch_with_port
|
101
|
+
args = %w[--at http://onepointzero.com:4000]
|
102
|
+
assert_equal ['onepointzero.com', 4000], Oz.parse_at_switch(args)
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_build_url_no_params
|
106
|
+
host = 'ozmm.org'
|
107
|
+
port = 80
|
108
|
+
args = %w[list]
|
109
|
+
assert_equal 'http://ozmm.org/api/list', Oz.build_url(host, port, args)
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_build_url_in_subdirectory
|
113
|
+
host = 'modzer0.cs.uaf.edu/hank-log'
|
114
|
+
port = 3001
|
115
|
+
args = %w[list]
|
116
|
+
assert_equal 'http://modzer0.cs.uaf.edu:3001/hank-log/api/list', Oz.build_url(host, port, args)
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_build_url_one_param
|
120
|
+
host = 'ozimodo.net'
|
121
|
+
port = 3000
|
122
|
+
args = %w[show 55]
|
123
|
+
assert_equal 'http://ozimodo.net:3000/api/show/55', Oz.build_url(host, port, args)
|
124
|
+
end
|
125
|
+
|
126
|
+
def test_build_url_to_post
|
127
|
+
host = 'ozmm.org'
|
128
|
+
port = 80
|
129
|
+
args = %w[image --src http://ozmm.org/puppy.jpg --alt aww --tags photo]
|
130
|
+
assert_equal 'http://ozmm.org/api/image?post[src]=http://ozmm.org/puppy.jpg&post[alt]=aww&post[tags]=photo',
|
131
|
+
Oz.build_url(host, port, args)
|
132
|
+
end
|
133
|
+
|
134
|
+
def test_build_url_to_post_again
|
135
|
+
host = 'ozmm.org'
|
136
|
+
port = 80
|
137
|
+
args = %w[link --link http://hotchicks.com --quip babybaby!]
|
138
|
+
assert_equal 'http://ozmm.org/api/link?post[link]=http://hotchicks.com&post[quip]=babybaby!',
|
139
|
+
Oz.build_url(host, port, args)
|
140
|
+
end
|
141
|
+
|
142
|
+
def test_build_url_to_post_is_escape
|
143
|
+
host = 'ozmm.org'
|
144
|
+
port = 80
|
145
|
+
args = %w[link --link http://hotchicks.com --quip] + ['baby baby!']
|
146
|
+
assert_equal 'http://ozmm.org/api/link?post[link]=http://hotchicks.com&post[quip]=baby%20baby!',
|
147
|
+
Oz.build_url(host, port, args)
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_build_headers
|
151
|
+
expected = { 'User-Agent' => USER_AGENT, 'Accept' => 'text/plain' }
|
152
|
+
assert_equal expected, Oz.build_headers
|
153
|
+
end
|
154
|
+
|
155
|
+
def test_stringify_keys_bang
|
156
|
+
hash = { :make => 'Apple', :model => 'Powerbook' }
|
157
|
+
hash.stringify_keys!
|
158
|
+
assert_equal %w[make model], hash.keys.sort
|
159
|
+
end
|
160
|
+
|
161
|
+
def test_clear_cache
|
162
|
+
$stdout = Tempfile.new('tmp')
|
163
|
+
ENV['OZCACHE'] = 'clearme'
|
164
|
+
FileUtils.touch 'clearme'
|
165
|
+
assert_equal true, File.exists?('clearme')
|
166
|
+
Oz.clear_cache
|
167
|
+
assert_equal false, File.exists?('clearme')
|
168
|
+
end
|
169
|
+
|
170
|
+
def test_check_switches_clear_cache
|
171
|
+
$stdout = StringIO.new
|
172
|
+
ENV['OZCACHE'] = 'clearme'
|
173
|
+
FileUtils.touch 'clearme'
|
174
|
+
assert_equal true, File.exists?('clearme')
|
175
|
+
Oz.check_oz_switches(%w[nothing new --clear-cache something else])
|
176
|
+
assert_equal false, File.exists?('clearme')
|
177
|
+
$stdout = STDOUT
|
178
|
+
end
|
179
|
+
|
180
|
+
def test_check_switches_debug_is_on
|
181
|
+
Oz.check_oz_switches(%w[list --debug leet haxor])
|
182
|
+
assert Oz.send(:class_variable_get, :@@debug)
|
183
|
+
end
|
184
|
+
|
185
|
+
def test_check_switches_help_prints_something
|
186
|
+
$tmpout, $stdout = '', StringIO.new
|
187
|
+
Kernel.send(:alias_method, :real_print, :print)
|
188
|
+
Kernel.send(:define_method, :print, proc { |s| $tmpout << s.to_s })
|
189
|
+
Oz.check_oz_switches(%w[idont commands --help])
|
190
|
+
assert /--site/ =~ $tmpout
|
191
|
+
assert /--debug/ =~ $tmpout
|
192
|
+
Kernel.send(:alias_method, :print, :real_print)
|
193
|
+
$stdout = STDOUT
|
194
|
+
end
|
195
|
+
|
196
|
+
end
|
197
|
+
|
198
|
+
module Net
|
199
|
+
class FakeResponse
|
200
|
+
attr_reader :header
|
201
|
+
def initialize(params, headers)
|
202
|
+
@header = { 'set-cookie' => 'ozimodo=cookiecookie; path=/' }
|
203
|
+
end
|
204
|
+
end
|
205
|
+
class HTTP
|
206
|
+
def post2(uri, params, headers)
|
207
|
+
FakeResponse.new(params, headers)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
metadata
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.0
|
3
|
+
specification_version: 1
|
4
|
+
name: oz
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: "0.1"
|
7
|
+
date: 2006-07-11 00:00:00 -07:00
|
8
|
+
summary: oz is a command line tumbler for ozimodo tumblelogs
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: chris@ozmm.org
|
12
|
+
homepage:
|
13
|
+
- http://ozimodo.rubyforge.org
|
14
|
+
- http://rubyforge.org/projects/ozimodo
|
15
|
+
rubyforge_project:
|
16
|
+
description: oz is a command line tumbler for ozimodo tumblelogs. Use it to query tumblelogs or post to your tumblelog from the command line.
|
17
|
+
autorequire:
|
18
|
+
default_executable: oz
|
19
|
+
bindir: bin
|
20
|
+
has_rdoc: false
|
21
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
22
|
+
requirements:
|
23
|
+
- - ">"
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: 0.0.0
|
26
|
+
version:
|
27
|
+
platform: ruby
|
28
|
+
signing_key:
|
29
|
+
cert_chain:
|
30
|
+
post_install_message:
|
31
|
+
authors:
|
32
|
+
- Chris Wanstrath and Dayne Broderson
|
33
|
+
files:
|
34
|
+
- README
|
35
|
+
- bin/oz
|
36
|
+
- test/test_oz.rb
|
37
|
+
test_files: []
|
38
|
+
|
39
|
+
rdoc_options: []
|
40
|
+
|
41
|
+
extra_rdoc_files: []
|
42
|
+
|
43
|
+
executables:
|
44
|
+
- oz
|
45
|
+
extensions: []
|
46
|
+
|
47
|
+
requirements: []
|
48
|
+
|
49
|
+
dependencies: []
|
50
|
+
|