oz 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/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
|
+
|