departr 0.2

Sign up to get free protection for your applications and to get access to all the features.
data/lib/jsmin.rb ADDED
@@ -0,0 +1,280 @@
1
+ #--
2
+ # jsmin.rb - Ruby implementation of Douglas Crockford's JSMin.
3
+ #
4
+ # This is a port of jsmin.c, and is distributed under the same terms, which are
5
+ # as follows:
6
+ #
7
+ # Copyright (c) 2002 Douglas Crockford (www.crockford.com)
8
+ #
9
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ # of this software and associated documentation files (the "Software"), to deal
11
+ # in the Software without restriction, including without limitation the rights
12
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ # copies of the Software, and to permit persons to whom the Software is
14
+ # furnished to do so, subject to the following conditions:
15
+ #
16
+ # The above copyright notice and this permission notice shall be included in all
17
+ # copies or substantial portions of the Software.
18
+ #
19
+ # The Software shall be used for Good, not Evil.
20
+ #
21
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27
+ # SOFTWARE.
28
+ #++
29
+
30
+ require 'strscan'
31
+
32
+ # = JSMin
33
+ #
34
+ # Ruby implementation of Douglas Crockford's JavaScript minifier, JSMin.
35
+ #
36
+ # *Author*:: Ryan Grove (mailto:ryan@wonko.com)
37
+ # *Version*:: 1.0.1 (2008-11-10)
38
+ # *Copyright*:: Copyright (c) 2008 Ryan Grove. All rights reserved.
39
+ # *Website*:: http://github.com/rgrove/jsmin
40
+ #
41
+ # == Example
42
+ #
43
+ # require 'rubygems'
44
+ # require 'jsmin'
45
+ #
46
+ # File.open('example.js', 'r') {|file| puts JSMin.minify(file) }
47
+ #
48
+ module JSMin
49
+ CHR_APOS = "'".freeze
50
+ CHR_ASTERISK = '*'.freeze
51
+ CHR_BACKSLASH = '\\'.freeze
52
+ CHR_CR = "\r".freeze
53
+ CHR_FRONTSLASH = '/'.freeze
54
+ CHR_LF = "\n".freeze
55
+ CHR_QUOTE = '"'.freeze
56
+ CHR_SPACE = ' '.freeze
57
+
58
+ ORD_LF = ?\n
59
+ ORD_SPACE = ?\
60
+ ORD_TILDE = ?~
61
+
62
+ class ParseError < RuntimeError
63
+ attr_accessor :source, :line
64
+ def initialize(err, source, line)
65
+ @source = source,
66
+ @line = line
67
+ super "JSMin Parse Error: #{err} at line #{line} of #{source}"
68
+ end
69
+ end
70
+
71
+ class << self
72
+ def raise(err)
73
+ super ParseError.new(err, @source, @line)
74
+ end
75
+
76
+ # Reads JavaScript from _input_ (which can be a String or an IO object) and
77
+ # returns a String containing minified JS.
78
+ def minify(input)
79
+ @js = StringScanner.new(input.is_a?(IO) ? input.read : input.to_s)
80
+ @source = input.is_a?(IO) ? input.inspect : input.to_s[0..100]
81
+ @line = 1
82
+
83
+ @a = "\n"
84
+ @b = nil
85
+ @lookahead = nil
86
+ @output = ''
87
+
88
+ action_get
89
+
90
+ while !@a.nil? do
91
+ case @a
92
+ when CHR_SPACE
93
+ if alphanum?(@b)
94
+ action_output
95
+ else
96
+ action_copy
97
+ end
98
+
99
+ when CHR_LF
100
+ if @b == CHR_SPACE
101
+ action_get
102
+ elsif @b =~ /[{\[\(+-]/
103
+ action_output
104
+ else
105
+ if alphanum?(@b)
106
+ action_output
107
+ else
108
+ action_copy
109
+ end
110
+ end
111
+
112
+ else
113
+ if @b == CHR_SPACE
114
+ if alphanum?(@a)
115
+ action_output
116
+ else
117
+ action_get
118
+ end
119
+ elsif @b == CHR_LF
120
+ if @a =~ /[}\]\)\\"+-]/
121
+ action_output
122
+ else
123
+ if alphanum?(@a)
124
+ action_output
125
+ else
126
+ action_get
127
+ end
128
+ end
129
+ else
130
+ action_output
131
+ end
132
+ end
133
+ end
134
+
135
+ @output
136
+ end
137
+
138
+ private
139
+
140
+ # Corresponds to action(1) in jsmin.c.
141
+ def action_output
142
+ @output << @a
143
+ action_copy
144
+ end
145
+
146
+ # Corresponds to action(2) in jsmin.c.
147
+ def action_copy
148
+ @a = @b
149
+
150
+ if @a == CHR_APOS || @a == CHR_QUOTE
151
+ loop do
152
+ @output << @a
153
+ @a = get
154
+
155
+ break if @a == @b
156
+
157
+ if @a[0] <= ORD_LF
158
+ raise "unterminated string literal: #{@a.inspect}"
159
+ end
160
+
161
+ if @a == CHR_BACKSLASH
162
+ @output << @a
163
+ @a = get
164
+
165
+ if @a[0] <= ORD_LF
166
+ raise "unterminated string literal: #{@a.inspect}"
167
+ end
168
+ end
169
+ end
170
+ end
171
+
172
+ action_get
173
+ end
174
+
175
+ # Corresponds to action(3) in jsmin.c.
176
+ def action_get
177
+ @b = nextchar
178
+
179
+ if @b == CHR_FRONTSLASH && (@a == CHR_LF || @a =~ /[\(,=:\[!&|?{};]/)
180
+ @output << @a
181
+ @output << @b
182
+
183
+ loop do
184
+ @a = get
185
+
186
+ # Inside a regex [...] set, which MAY contain a '/' itself.
187
+ # Example:
188
+ # mootools Form.Validator near line 460:
189
+ # return Form.Validator.getValidator('IsEmpty').test(element) || (/^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]\.?){0,63}[a-z0-9!#$%&'*+/=?^_`{|}~-]@(?:(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\])$/i).test(element.get('value'));
190
+ if @a == '['
191
+ loop do
192
+ @output << @a
193
+ @a = get
194
+ case @a
195
+ when ']' then break
196
+ when CHR_BACKSLASH then
197
+ @output << @a
198
+ @a = get
199
+ when @a[0] <= ORD_LF
200
+ raise "JSMin parse error: unterminated regular expression " +
201
+ "literal: #{@a}"
202
+ end
203
+ end
204
+ elsif @a == CHR_FRONTSLASH
205
+ break
206
+ elsif @a == CHR_BACKSLASH
207
+ @output << @a
208
+ @a = get
209
+ elsif @a[0] <= ORD_LF
210
+ raise "unterminated regular expression : #{@a.inspect}"
211
+ end
212
+
213
+ @output << @a
214
+ end
215
+
216
+ @b = nextchar
217
+ end
218
+ end
219
+
220
+ # Returns true if +c+ is a letter, digit, underscore, dollar sign,
221
+ # backslash, or non-ASCII character.
222
+ def alphanum?(c)
223
+ c.is_a?(String) && !c.empty? && (c[0] > ORD_TILDE || c =~ /[0-9a-z_$\\]/i)
224
+ end
225
+
226
+ # Returns the next character from the input. If the character is a control
227
+ # character, it will be translated to a space or linefeed.
228
+ def get
229
+ if @lookahead
230
+ c = @lookahead
231
+ @lookahead = nil
232
+ else
233
+ c = @js.getch
234
+ if c == CHR_LF || c == CHR_CR
235
+ @line += 1
236
+ return CHR_LF
237
+ end
238
+ return ' ' unless c.nil? || c[0] >= ORD_SPACE
239
+ end
240
+ c
241
+ end
242
+
243
+ # Gets the next character, excluding comments.
244
+ def nextchar
245
+ c = get
246
+ return c unless c == CHR_FRONTSLASH
247
+
248
+ case peek
249
+ when CHR_FRONTSLASH
250
+ loop do
251
+ c = get
252
+ return c if c[0] <= ORD_LF
253
+ end
254
+
255
+ when CHR_ASTERISK
256
+ get
257
+ loop do
258
+ case get
259
+ when CHR_ASTERISK
260
+ if peek == CHR_FRONTSLASH
261
+ get
262
+ return ' '
263
+ end
264
+
265
+ when nil
266
+ raise 'unterminated comment'
267
+ end
268
+ end
269
+
270
+ else
271
+ return c
272
+ end
273
+ end
274
+
275
+ # Gets the next character without getting it.
276
+ def peek
277
+ @lookahead = get
278
+ end
279
+ end
280
+ end
data/lib/rpx.rb ADDED
@@ -0,0 +1,102 @@
1
+ require 'uri'
2
+ require 'net/http'
3
+ require 'net/https'
4
+ require 'json'
5
+ require 'cgi'
6
+
7
+ module Rpx
8
+ class RpxException < StandardError
9
+ attr_reader :http_response
10
+
11
+ def initialize(http_response)
12
+ @http_response = http_response
13
+ end
14
+ end
15
+
16
+ class RpxHelper
17
+ attr_reader :api_key, :base_url, :realm
18
+
19
+ def initialize(api_key, base_url, realm)
20
+ @api_key = api_key
21
+ @base_url = base_url.sub(/\/*$/, '')
22
+ @realm = realm
23
+ end
24
+
25
+ def auth_info(token, token_url)
26
+ data = api_call 'auth_info', :token => token, :tokenUrl => token_url
27
+ data['profile']
28
+ end
29
+
30
+ def auth_info_iphone(token)
31
+ data = api_call 'auth_info', :token => token
32
+ data['profile']
33
+ end
34
+
35
+ def mappings(primary_key)
36
+ data = api_call 'mappings', :primaryKey => primary_key
37
+ data['identifiers']
38
+ end
39
+
40
+ def all_mappings
41
+ data = api_call 'all_mappings'
42
+ data['mappings']
43
+ end
44
+
45
+ def map(identifier, key)
46
+ api_call 'map', :primaryKey => key, :identifier => identifier
47
+ end
48
+
49
+ def unmap(identifier, key)
50
+ api_call 'unmap', :primaryKey => key, :identifier => identifier
51
+ end
52
+
53
+ def signin_url(dest)
54
+ "#{rp_url}/openid/signin?token_url=#{CGI.escape(dest)}"
55
+ end
56
+
57
+ private
58
+
59
+ def rp_url
60
+ parts = @base_url.split('://', 2)
61
+ parts = parts.insert(1, '://' + @realm + '.')
62
+ return parts.join('')
63
+ end
64
+
65
+ def api_call(method_name, partial_query)
66
+ url = URI.parse("#{@base_url}/api/v2/#{method_name}")
67
+
68
+ query = partial_query.dup
69
+ query['format'] = 'json'
70
+ query['apiKey'] = @api_key
71
+
72
+ http = Net::HTTP.new(url.host, url.port)
73
+ if url.scheme == 'https'
74
+ http.use_ssl = true
75
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
76
+ end
77
+
78
+ data = query.map { |k,v|
79
+ "#{CGI::escape k.to_s}=#{CGI::escape v.to_s}"
80
+ }.join('&')
81
+
82
+ resp = http.post(url.path, data)
83
+
84
+ if resp.code == '200'
85
+ begin
86
+ data = JSON.parse(resp.body)
87
+ rescue JSON::ParserError => err
88
+ raise RpxException.new(resp), 'Unable to parse JSON response'
89
+ end
90
+ else
91
+ raise RpxException.new(resp), "Unexpected HTTP status code from server: #{resp.code}"
92
+ end
93
+
94
+ if data['stat'] != 'ok'
95
+ raise RpxException.new(resp), 'Unexpected API error'
96
+ end
97
+
98
+ return data
99
+ end
100
+ end
101
+
102
+ end
Binary file