davetron5000-gliffy 0.1.7 → 0.2.0
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.rdoc +175 -48
- data/bin/gliffy +298 -22
- data/lib/gliffy.rb +4 -0
- data/lib/gliffy/credentials.rb +78 -0
- data/lib/gliffy/handle.rb +269 -290
- data/lib/gliffy/request.rb +101 -0
- data/lib/gliffy/response.rb +248 -91
- data/lib/gliffy/url.rb +133 -36
- metadata +21 -21
- data/lib/gliffy/account.rb +0 -55
- data/lib/gliffy/cli.rb +0 -144
- data/lib/gliffy/commands.rb +0 -6
- data/lib/gliffy/commands/delete.rb +0 -10
- data/lib/gliffy/commands/edit.rb +0 -19
- data/lib/gliffy/commands/get.rb +0 -46
- data/lib/gliffy/commands/list.rb +0 -27
- data/lib/gliffy/commands/new.rb +0 -25
- data/lib/gliffy/commands/url.rb +0 -21
- data/lib/gliffy/config.rb +0 -55
- data/lib/gliffy/diagram.rb +0 -100
- data/lib/gliffy/folder.rb +0 -63
- data/lib/gliffy/rest.rb +0 -110
- data/lib/gliffy/user.rb +0 -72
data/lib/gliffy/url.rb
CHANGED
@@ -1,67 +1,164 @@
|
|
1
|
-
require '
|
1
|
+
require 'rubygems'
|
2
|
+
require 'hmac-sha1'
|
3
|
+
require 'base64'
|
2
4
|
|
3
5
|
module Gliffy
|
6
|
+
|
4
7
|
# Handles signing and assembling the URL
|
5
8
|
class SignedURL
|
6
9
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
10
|
+
READ_ONLY_PARAMS = {
|
11
|
+
'oauth_consumer_key' => true,
|
12
|
+
'oauth_token' => true,
|
13
|
+
'oauth_signature_method' => true,
|
14
|
+
'oauth_version' => true,
|
15
|
+
'oauth_nonce' => true,
|
16
|
+
'oauth_timestamp' => true,
|
17
|
+
}
|
18
|
+
|
19
|
+
# Ruby's SignedURL::encode doesn't encode spaces correctly
|
20
|
+
def self.encode(string)
|
21
|
+
string.gsub(/([^ a-zA-Z0-9_.-]+)/n) do
|
22
|
+
'%' + $1.unpack('H2' * $1.size).join('%').upcase
|
23
|
+
end.gsub(' ', '%20')
|
24
|
+
end
|
25
|
+
|
26
|
+
# Modify the logger
|
27
|
+
attr_accessor :logger
|
28
|
+
|
29
|
+
# Create a new SignedURL
|
30
|
+
#
|
31
|
+
# [+credentails+] The credentials available when signing the request (required).
|
32
|
+
# [+url+] The URL (without parameters) to request (required)
|
33
|
+
# [+method+] The HTTP Request method that will be made (required)
|
34
|
+
def initialize(credentials,url,method,logger=nil)
|
35
|
+
raise ArgumentError.new("credentials is required") if credentials.nil?
|
36
|
+
raise ArgumentError.new("url is required") if url.nil?
|
37
|
+
raise ArgumentError.new("method is required") if method.nil?
|
38
|
+
|
39
|
+
@credentials = credentials
|
40
|
+
|
41
|
+
@logger = logger || Logger.new(STDOUT)
|
42
|
+
@logger.level = Logger::INFO
|
43
|
+
|
44
|
+
@params = {
|
45
|
+
'oauth_signature_method' => 'HMAC-SHA1',
|
46
|
+
'oauth_version' => '1.0',
|
47
|
+
}
|
48
|
+
@params['oauth_consumer_key'] = credentials.consumer_key
|
49
|
+
@params['oauth_token'] = credentials.access_token.token if credentials.access_token
|
50
|
+
@consumer_secret = credentials.consumer_secret
|
51
|
+
if credentials.access_token
|
52
|
+
@access_secret = credentials.access_token.secret
|
53
|
+
else
|
54
|
+
@access_secret = nil
|
55
|
+
end
|
56
|
+
@method = method.upcase
|
18
57
|
@url = url
|
19
58
|
end
|
20
59
|
|
21
60
|
# Sets a request parameter
|
22
61
|
#
|
23
|
-
# [param] the name of the parameter, as a string
|
62
|
+
# [param] the name of the parameter, as a string or symbol
|
24
63
|
# [value] the value of the parameter, unencoded
|
25
64
|
#
|
26
65
|
def []=(param,value)
|
27
|
-
|
28
|
-
|
66
|
+
raise ArgumentError.new("param may not be nil") if param.nil?
|
67
|
+
param = param.to_s
|
68
|
+
raise ArgumentError.new("You may not override #{param}") if READ_ONLY_PARAMS[param]
|
69
|
+
if value.nil?
|
70
|
+
@params.delete(param)
|
71
|
+
else
|
72
|
+
@params[param] = value.to_s
|
29
73
|
end
|
30
|
-
@params[param] = value
|
31
74
|
end
|
32
75
|
|
33
76
|
# Sets all request parameters to those in the hash.
|
34
77
|
def params=(params_hash)
|
35
|
-
|
36
|
-
|
37
|
-
|
78
|
+
raise ArgumentError.new('you may not set params to nil') if params_hash.nil?
|
79
|
+
params_hash.each do |k,v|
|
80
|
+
self[k]=v
|
81
|
+
end
|
38
82
|
end
|
39
83
|
|
40
84
|
# Gets the full URL, signed and ready to be requested
|
41
|
-
def full_url
|
85
|
+
def full_url(timestamp=nil,nonce=nil)
|
86
|
+
|
42
87
|
@logger.debug("Getting full_url of #{@url}")
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
signature = Digest::MD5.hexdigest(to_sign)
|
54
|
-
signature.gsub!(/^0/,'') while (signature =~ /^0/)
|
55
|
-
@logger.debug("signature == '#{signature}'")
|
56
|
-
url_params['signature'] = signature
|
88
|
+
@logger.debug("OAuth Part 1 : #{@method}")
|
89
|
+
|
90
|
+
escaped_url = SignedURL::encode(@url)
|
91
|
+
to_sign = @method + "&" + escaped_url + "&"
|
92
|
+
|
93
|
+
@logger.debug("OAuth Part 2 (raw) : #{@url}")
|
94
|
+
@logger.debug("OAuth Part 2 (esc) : #{escaped_url}")
|
95
|
+
|
96
|
+
timestamp=Time.now.to_i if timestamp.nil?
|
97
|
+
nonce=@credentials.nonce if nonce.nil?
|
57
98
|
|
58
|
-
|
99
|
+
param_part,url_params = handle_params(timestamp,nonce)
|
100
|
+
escaped_params = SignedURL::encode(param_part)
|
101
|
+
@logger.debug("OAuth Part 3 (raw) : #{param_part}")
|
102
|
+
@logger.debug("OAuth Part 3 (esc) : #{escaped_params}")
|
103
|
+
|
104
|
+
to_sign += escaped_params
|
105
|
+
|
106
|
+
signature = get_signature(to_sign)
|
107
|
+
|
108
|
+
url_params['oauth_signature'] = SignedURL::encode(signature)
|
109
|
+
|
110
|
+
assembled_url = assemble_url(url_params)
|
111
|
+
@logger.debug("Full URL is " + assembled_url)
|
112
|
+
return assembled_url
|
113
|
+
end
|
114
|
+
|
115
|
+
private
|
116
|
+
|
117
|
+
def assemble_url(url_params)
|
118
|
+
url = @url + '?'
|
59
119
|
url_params.keys.sort.each do |key|
|
60
|
-
val =
|
120
|
+
val = url_params[key]
|
61
121
|
url += "#{key}=#{val}&"
|
62
122
|
end
|
63
123
|
url.gsub!(/\&$/,'')
|
64
124
|
return url
|
65
125
|
end
|
126
|
+
|
127
|
+
def get_signature(to_sign)
|
128
|
+
signing_key = get_signing_key
|
129
|
+
@logger.debug("Signing '#{to_sign}' with key '#{signing_key}'")
|
130
|
+
|
131
|
+
sha1 = HMAC::SHA1.new(signing_key)
|
132
|
+
sha1 << to_sign
|
133
|
+
signature = Base64.encode64(sha1.digest())
|
134
|
+
signature.chomp!
|
135
|
+
@logger.debug("signature == '#{signature}'")
|
136
|
+
signature
|
137
|
+
end
|
138
|
+
|
139
|
+
def get_signing_key
|
140
|
+
SignedURL::encode(@consumer_secret) + "&" + SignedURL::encode(@access_secret.nil? ? "" : @access_secret)
|
141
|
+
end
|
142
|
+
|
143
|
+
def handle_params(timestamp,nonce)
|
144
|
+
url_params = Hash.new
|
145
|
+
param_part = ""
|
146
|
+
params = @params
|
147
|
+
params['oauth_timestamp'] = timestamp.to_s
|
148
|
+
params['oauth_nonce'] = nonce
|
149
|
+
params.keys.sort.each do |key|
|
150
|
+
value = params[key]
|
151
|
+
raise ArgumentError.new("#{key} is nil; don't set params to be nil") if value.nil?
|
152
|
+
|
153
|
+
@logger.debug("Adding param #{key} with value #{value} escaped as #{SignedURL::encode(value)}")
|
154
|
+
param_part += SignedURL::encode(key)
|
155
|
+
param_part += "="
|
156
|
+
param_part += SignedURL::encode(value)
|
157
|
+
param_part += '&'
|
158
|
+
url_params[key] = SignedURL::encode(value)
|
159
|
+
end
|
160
|
+
param_part.gsub!(/&$/,'')
|
161
|
+
[param_part,url_params]
|
162
|
+
end
|
66
163
|
end
|
67
164
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: davetron5000-gliffy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Copeland
|
@@ -9,26 +9,38 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-05-16 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
|
-
name:
|
16
|
+
name: httparty
|
17
|
+
type: :runtime
|
17
18
|
version_requirement:
|
18
19
|
version_requirements: !ruby/object:Gem::Requirement
|
19
20
|
requirements:
|
20
21
|
- - ">="
|
21
22
|
- !ruby/object:Gem::Version
|
22
|
-
version: 0.
|
23
|
+
version: 0.4.2
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: ruby-hmac
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.3.2
|
23
34
|
version:
|
24
35
|
- !ruby/object:Gem::Dependency
|
25
36
|
name: davetron5000-gli
|
37
|
+
type: :runtime
|
26
38
|
version_requirement:
|
27
39
|
version_requirements: !ruby/object:Gem::Requirement
|
28
40
|
requirements:
|
29
41
|
- - ">="
|
30
42
|
- !ruby/object:Gem::Version
|
31
|
-
version: 0.1.
|
43
|
+
version: 0.1.6
|
32
44
|
version:
|
33
45
|
description:
|
34
46
|
email: davidcopeland@naildrivin5.com
|
@@ -40,25 +52,13 @@ extra_rdoc_files:
|
|
40
52
|
- README.rdoc
|
41
53
|
files:
|
42
54
|
- ext/array_has_response.rb
|
43
|
-
-
|
44
|
-
- lib/gliffy/account.rb
|
45
|
-
- lib/gliffy/cli.rb
|
46
|
-
- lib/gliffy/commands/delete.rb
|
47
|
-
- lib/gliffy/commands/edit.rb
|
48
|
-
- lib/gliffy/commands/get.rb
|
49
|
-
- lib/gliffy/commands/list.rb
|
50
|
-
- lib/gliffy/commands/new.rb
|
51
|
-
- lib/gliffy/commands/url.rb
|
52
|
-
- lib/gliffy/commands.rb
|
53
|
-
- lib/gliffy/config.rb
|
54
|
-
- lib/gliffy/diagram.rb
|
55
|
-
- lib/gliffy/folder.rb
|
55
|
+
- lib/gliffy/credentials.rb
|
56
56
|
- lib/gliffy/handle.rb
|
57
|
+
- lib/gliffy/request.rb
|
57
58
|
- lib/gliffy/response.rb
|
58
|
-
- lib/gliffy/rest.rb
|
59
59
|
- lib/gliffy/url.rb
|
60
|
-
- lib/gliffy/user.rb
|
61
60
|
- lib/gliffy.rb
|
61
|
+
- bin/gliffy
|
62
62
|
- README.rdoc
|
63
63
|
has_rdoc: true
|
64
64
|
homepage: http://davetron5000.github.com/gliffy
|
@@ -91,6 +91,6 @@ rubyforge_project:
|
|
91
91
|
rubygems_version: 1.2.0
|
92
92
|
signing_key:
|
93
93
|
specification_version: 2
|
94
|
-
summary:
|
94
|
+
summary: Client to access the Gliffy API
|
95
95
|
test_files: []
|
96
96
|
|
data/lib/gliffy/account.rb
DELETED
@@ -1,55 +0,0 @@
|
|
1
|
-
require 'rexml/document'
|
2
|
-
require 'array_has_response'
|
3
|
-
require 'gliffy/rest'
|
4
|
-
|
5
|
-
include REXML
|
6
|
-
|
7
|
-
module Gliffy
|
8
|
-
|
9
|
-
# Represents on account
|
10
|
-
class Account < Response
|
11
|
-
|
12
|
-
attr_reader :name
|
13
|
-
attr_reader :id
|
14
|
-
# Either :basic or :premium
|
15
|
-
attr_reader :type
|
16
|
-
attr_reader :max_users
|
17
|
-
# A Time representing the date on which this account expires
|
18
|
-
attr_reader :expiration_date
|
19
|
-
|
20
|
-
attr_reader :users
|
21
|
-
|
22
|
-
def self.from_xml(element)
|
23
|
-
id = element.attributes['id'].to_i
|
24
|
-
type = element.attributes['account-type']
|
25
|
-
if type == 'Basic'
|
26
|
-
type = :basic
|
27
|
-
elsif type == 'Premium'
|
28
|
-
type = :premium
|
29
|
-
else
|
30
|
-
raise "Unknown type #{type}"
|
31
|
-
end
|
32
|
-
max_users = element.attributes['max-users'].to_i
|
33
|
-
expiration_date = Time.at(element.elements['expiration-date'].text.to_i / 1000)
|
34
|
-
name = element.elements['name'].text
|
35
|
-
users = Users.from_xml(element.elements['users'])
|
36
|
-
|
37
|
-
Account.new(id,type,name,max_users,expiration_date,users)
|
38
|
-
end
|
39
|
-
|
40
|
-
protected
|
41
|
-
|
42
|
-
def initialize(id,type,name,max_users,expiration_date,users=nil)
|
43
|
-
super()
|
44
|
-
@id = id
|
45
|
-
@type = type
|
46
|
-
@name = name
|
47
|
-
@max_users = max_users
|
48
|
-
@expiration_date = expiration_date
|
49
|
-
@users = users
|
50
|
-
end
|
51
|
-
|
52
|
-
end
|
53
|
-
|
54
|
-
class Accounts < ArrayResponseParser; end
|
55
|
-
end
|
data/lib/gliffy/cli.rb
DELETED
@@ -1,144 +0,0 @@
|
|
1
|
-
$:.unshift File.dirname(__FILE__)
|
2
|
-
require 'fileutils'
|
3
|
-
require 'yaml'
|
4
|
-
require 'gliffy'
|
5
|
-
require 'logger'
|
6
|
-
|
7
|
-
module Gliffy
|
8
|
-
extend self
|
9
|
-
|
10
|
-
# Represents the configuration for the command line client.
|
11
|
-
# This is a singleton
|
12
|
-
class CLIConfig
|
13
|
-
|
14
|
-
@@instance = nil
|
15
|
-
|
16
|
-
# Access to the singleton
|
17
|
-
def self.instance
|
18
|
-
@@instance = CLIConfig.new if !@@instance
|
19
|
-
@@instance
|
20
|
-
end
|
21
|
-
|
22
|
-
# Returns the config hash
|
23
|
-
attr_reader :config
|
24
|
-
|
25
|
-
# Loads the user's rc file if it exists, creating it if not
|
26
|
-
def load
|
27
|
-
if !File.exist?(@config_file_name)
|
28
|
-
puts "#{@config_file_name} not found. Create? [y/n]"
|
29
|
-
answer = STDIN.gets
|
30
|
-
if answer =~ /^[Yy]/
|
31
|
-
save
|
32
|
-
else
|
33
|
-
puts "Aborting..."
|
34
|
-
return false
|
35
|
-
end
|
36
|
-
end
|
37
|
-
yaml_config = File.open(@config_file_name) { |file| YAML::load(file) }
|
38
|
-
if (yaml_config)
|
39
|
-
@config = yaml_config
|
40
|
-
end
|
41
|
-
@config[:open_url] = default_open_url if !@config[:open_url]
|
42
|
-
@config[:open_image] = default_open_image if !@config[:open_image]
|
43
|
-
read_config_from_user('API Key',:api_key)
|
44
|
-
read_config_from_user('Secret Key',:secret_key)
|
45
|
-
read_config_from_user('Account Name',:account_name)
|
46
|
-
read_config_from_user('Username',:username)
|
47
|
-
save
|
48
|
-
config = Gliffy::Config.config
|
49
|
-
@config.each() do |key,value|
|
50
|
-
method = key.to_s + "="
|
51
|
-
if config.respond_to? method.to_sym
|
52
|
-
if (method == 'log_device=')
|
53
|
-
if (value == 'STDERR')
|
54
|
-
config.log_device = STDERR
|
55
|
-
elsif (value == 'STDOUT')
|
56
|
-
config.log_device = STDOUT
|
57
|
-
else
|
58
|
-
config.log_device = value
|
59
|
-
end
|
60
|
-
else
|
61
|
-
config.send(method.to_sym,value)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
# Saves the configration to the user's config file name as YAML
|
68
|
-
def save
|
69
|
-
ld = @config[:log_device]
|
70
|
-
@config[:log_device] = log_device_to_string(ld)
|
71
|
-
fp = File.open(@config_file_name,'w') { |out| YAML::dump(@config,out) }
|
72
|
-
@config[:log_device] = ld
|
73
|
-
end
|
74
|
-
|
75
|
-
private
|
76
|
-
|
77
|
-
def log_device_to_string(ld)
|
78
|
-
if ld == STDERR
|
79
|
-
'STDERR'
|
80
|
-
elsif ld == STDOUT
|
81
|
-
'STDOUT'
|
82
|
-
elsif !ld.kind_of?(String)
|
83
|
-
puts "Warning: don't know how to persist a #{ld.class.name}"
|
84
|
-
nil
|
85
|
-
else
|
86
|
-
ld
|
87
|
-
end
|
88
|
-
end
|
89
|
-
def read_config_from_user(name,symbol)
|
90
|
-
if (!@config[symbol])
|
91
|
-
puts "No #{name} configured. Enter #{name}"
|
92
|
-
@config[symbol] = STDIN.gets.chomp!
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
def initialize
|
97
|
-
@config_file_name = File.expand_path("~/.gliffyrc")
|
98
|
-
@config = {
|
99
|
-
:log_level => Gliffy::Config.config.log_level,
|
100
|
-
:log_device => log_device_to_string(Gliffy::Config.config.log_device),
|
101
|
-
:gliffy_app_root => Gliffy::Config.config.gliffy_app_root,
|
102
|
-
:gliffy_rest_context => Gliffy::Config.config.gliffy_rest_context,
|
103
|
-
:protocol => Gliffy::Config.config.protocol,
|
104
|
-
}
|
105
|
-
end
|
106
|
-
|
107
|
-
def default_open_url
|
108
|
-
# Cheesy defaults
|
109
|
-
if RUBY_PLATFORM =~ /win32/
|
110
|
-
# not sure, acutally
|
111
|
-
nil
|
112
|
-
elsif RUBY_PLATFORM =~ /linux/
|
113
|
-
'firefox "%s"'
|
114
|
-
elsif RUBY_PLATFORM =~ /darwin/
|
115
|
-
'open "%s"'
|
116
|
-
else
|
117
|
-
nil
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
def default_open_image
|
122
|
-
# Cheesy defaults
|
123
|
-
if RUBY_PLATFORM =~ /win32/
|
124
|
-
# not sure, acutally
|
125
|
-
nil
|
126
|
-
elsif RUBY_PLATFORM =~ /linux/
|
127
|
-
# not sure
|
128
|
-
nil
|
129
|
-
elsif RUBY_PLATFORM =~ /darwin/
|
130
|
-
'open "%s"'
|
131
|
-
else
|
132
|
-
nil
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
|
137
|
-
end
|
138
|
-
|
139
|
-
def format_date(date)
|
140
|
-
date.strftime('%m/%d/%y %H:%M')
|
141
|
-
end
|
142
|
-
|
143
|
-
end
|
144
|
-
|