qoobaa-opensocial 0.1.8 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -30,7 +30,7 @@ module OpenSocial #:nodoc:
30
30
  def initialize(json)
31
31
  if json
32
32
  json.each do |key, value|
33
- proper_key = key.snake_case
33
+ proper_key = key.underscore
34
34
  begin
35
35
  self.send("#{proper_key}=", value)
36
36
  rescue NoMethodError
@@ -12,14 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- require "net/http"
16
- require "uri"
17
-
18
- # Use json/pure if you opt-out of including the validation code in
19
- # opensocial/auth. This gem adds standard to_json behavior for the
20
- # request classes, instead of using ActiveSupport.
21
- require "rubygems"
22
-
23
15
  module OpenSocial #:nodoc:
24
16
 
25
17
  # Provides base functionality for the OpenSocial child classes.
@@ -30,7 +30,7 @@ module OpenSocial #:nodoc:
30
30
  def initialize(json)
31
31
  if json
32
32
  json.each do |key, value|
33
- proper_key = key.snake_case
33
+ proper_key = key.underscore
34
34
  begin
35
35
  self.send("#{proper_key}=", value)
36
36
  rescue NoMethodError
@@ -38,7 +38,7 @@ module OpenSocial #:nodoc:
38
38
  def initialize(json)
39
39
  if json
40
40
  json.each do |key, value|
41
- proper_key = key.snake_case
41
+ proper_key = key.underscore
42
42
  begin
43
43
  self.send("#{proper_key}=", value)
44
44
  rescue NoMethodError
@@ -68,7 +68,7 @@ module OpenSocial #:nodoc:
68
68
  data = dispatch(uri)
69
69
 
70
70
  if unescape
71
- JSON.parse(data.os_unescape)
71
+ JSON.parse(os_unescape(data))
72
72
  else
73
73
  JSON.parse(data)
74
74
  end
@@ -76,6 +76,13 @@ module OpenSocial #:nodoc:
76
76
 
77
77
  private
78
78
 
79
+ def os_unescape(string)
80
+ unescaped = string.gsub(/\\\"/, '"')
81
+ unescaped = unescaped.gsub('"{', "{")
82
+ unescaped = unescaped.gsub('}"', "}")
83
+ unescaped = unescaped.gsub(/\"\"/, "\"")
84
+ end
85
+
79
86
  # Dispatches a request to a given URI with optional POST data. If a
80
87
  # request's connection has specified HMAC-SHA1 authentication, OAuth
81
88
  # parameters and signature are appended to the request.
@@ -210,7 +217,7 @@ module OpenSocial #:nodoc:
210
217
  # Activity, etc.)
211
218
  def parse_response(response, unescape)
212
219
  if unescape
213
- parsed = JSON.parse(response.os_unescape)
220
+ parsed = JSON.parse(os_unescape(response))
214
221
  else
215
222
  parsed = JSON.parse(response)
216
223
  end
@@ -0,0 +1,3 @@
1
+ module OpenSocial
2
+ VERSION = "0.2.0"
3
+ end
data/lib/opensocial.rb CHANGED
@@ -13,19 +13,20 @@
13
13
  # limitations under the License.
14
14
 
15
15
  require "active_support"
16
+ require "active_support/core_ext/string/inflections"
16
17
  require "oauth"
17
18
  require "oauth/consumer"
18
- require "oauth/request_proxy/action_controller_request"
19
+
20
+ require "net/http"
19
21
  require "uri"
20
22
 
21
23
  require "opensocial/base"
22
24
  require "opensocial/request"
23
25
  require "opensocial/activity"
24
26
  require "opensocial/appdata"
25
- require "opensocial/auth/action_controller_request"
26
- require "opensocial/auth/base"
27
27
  require "opensocial/connection"
28
28
  require "opensocial/group"
29
29
  require "opensocial/person"
30
+ require "opensocial/version"
30
31
  require "opensocial/string/merb_string"
31
32
  require "opensocial/string/os_string"
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qoobaa-opensocial
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 23
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
- - 1
8
- - 8
9
- version: 0.1.8
8
+ - 2
9
+ - 0
10
+ version: 0.2.0
10
11
  platform: ruby
11
12
  authors:
12
13
  - "Jakub Ku\xC5\xBAma"
@@ -15,143 +16,135 @@ autorequire:
15
16
  bindir: bin
16
17
  cert_chain: []
17
18
 
18
- date: 2010-03-31 00:00:00 +02:00
19
+ date: 2010-06-22 00:00:00 +02:00
19
20
  default_executable:
20
21
  dependencies:
21
22
  - !ruby/object:Gem::Dependency
22
23
  name: oauth
23
24
  prerelease: false
24
25
  requirement: &id001 !ruby/object:Gem::Requirement
26
+ none: false
25
27
  requirements:
26
28
  - - ">="
27
29
  - !ruby/object:Gem::Version
30
+ hash: 3
28
31
  segments:
29
32
  - 0
30
33
  version: "0"
31
34
  type: :runtime
32
35
  version_requirements: *id001
33
36
  - !ruby/object:Gem::Dependency
34
- name: test-unit
37
+ name: activesupport
35
38
  prerelease: false
36
39
  requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ hash: 3
45
+ segments:
46
+ - 0
47
+ version: "0"
48
+ type: :runtime
49
+ version_requirements: *id002
50
+ - !ruby/object:Gem::Dependency
51
+ name: test-unit
52
+ prerelease: false
53
+ requirement: &id003 !ruby/object:Gem::Requirement
54
+ none: false
37
55
  requirements:
38
56
  - - ">="
39
57
  - !ruby/object:Gem::Version
58
+ hash: 7
40
59
  segments:
41
60
  - 2
42
61
  version: "2"
43
62
  type: :development
44
- version_requirements: *id002
63
+ version_requirements: *id003
45
64
  - !ruby/object:Gem::Dependency
46
65
  name: json_pure
47
66
  prerelease: false
48
- requirement: &id003 !ruby/object:Gem::Requirement
67
+ requirement: &id004 !ruby/object:Gem::Requirement
68
+ none: false
49
69
  requirements:
50
70
  - - ">="
51
71
  - !ruby/object:Gem::Version
72
+ hash: 3
52
73
  segments:
53
74
  - 0
54
75
  version: "0"
55
76
  type: :development
56
- version_requirements: *id003
77
+ version_requirements: *id004
57
78
  - !ruby/object:Gem::Dependency
58
79
  name: mocha
59
80
  prerelease: false
60
- requirement: &id004 !ruby/object:Gem::Requirement
81
+ requirement: &id005 !ruby/object:Gem::Requirement
82
+ none: false
61
83
  requirements:
62
84
  - - ">="
63
85
  - !ruby/object:Gem::Version
86
+ hash: 3
64
87
  segments:
65
88
  - 0
66
89
  version: "0"
67
90
  type: :development
68
- version_requirements: *id004
91
+ version_requirements: *id005
69
92
  description: OpenSocial Google Gem
70
93
  email: qoobaa@gmail.com
71
94
  executables: []
72
95
 
73
96
  extensions: []
74
97
 
75
- extra_rdoc_files:
76
- - LICENSE
77
- - README.rdoc
98
+ extra_rdoc_files: []
99
+
78
100
  files:
79
- - .document
80
- - .gitignore
81
- - LICENSE
82
- - NOTICE
83
- - README.rdoc
84
- - Rakefile
85
- - VERSION
86
101
  - lib/opensocial.rb
87
- - lib/opensocial/activity.rb
88
- - lib/opensocial/appdata.rb
89
- - lib/opensocial/auth/action_controller_request.rb
90
- - lib/opensocial/auth/base.rb
91
102
  - lib/opensocial/base.rb
92
- - lib/opensocial/connection.rb
93
- - lib/opensocial/group.rb
94
103
  - lib/opensocial/person.rb
104
+ - lib/opensocial/version.rb
105
+ - lib/opensocial/activity.rb
106
+ - lib/opensocial/group.rb
107
+ - lib/opensocial/appdata.rb
95
108
  - lib/opensocial/request.rb
96
- - lib/opensocial/string/merb_string.rb
97
- - lib/opensocial/string/os_string.rb
98
- - qoobaa-opensocial.gemspec
99
- - test/fixtures/activities.json
100
- - test/fixtures/activity.json
101
- - test/fixtures/appdata.json
102
- - test/fixtures/appdatum.json
103
- - test/fixtures/group.json
104
- - test/fixtures/groups.json
105
- - test/fixtures/people.json
106
- - test/fixtures/person.json
107
- - test/fixtures/person_appdata_rpc.json
108
- - test/fixtures/person_rpc.json
109
- - test/helper.rb
110
- - test/test_activity.rb
111
- - test/test_appdata.rb
112
- - test/test_connection.rb
113
- - test/test_group.rb
114
- - test/test_online.rb
115
- - test/test_person.rb
116
- - test/test_request.rb
117
- - test/test_rpcrequest.rb
109
+ - lib/opensocial/connection.rb
110
+ - LICENSE
111
+ - NOTICE
112
+ - README.rdoc
118
113
  has_rdoc: true
119
114
  homepage: http://github.com/qoobaa/opensocial
120
115
  licenses: []
121
116
 
122
117
  post_install_message:
123
- rdoc_options:
124
- - --charset=UTF-8
118
+ rdoc_options: []
119
+
125
120
  require_paths:
126
121
  - lib
127
122
  required_ruby_version: !ruby/object:Gem::Requirement
123
+ none: false
128
124
  requirements:
129
125
  - - ">="
130
126
  - !ruby/object:Gem::Version
127
+ hash: 3
131
128
  segments:
132
129
  - 0
133
130
  version: "0"
134
131
  required_rubygems_version: !ruby/object:Gem::Requirement
132
+ none: false
135
133
  requirements:
136
134
  - - ">="
137
135
  - !ruby/object:Gem::Version
136
+ hash: 23
138
137
  segments:
139
- - 0
140
- version: "0"
138
+ - 1
139
+ - 3
140
+ - 6
141
+ version: 1.3.6
141
142
  requirements: []
142
143
 
143
144
  rubyforge_project:
144
- rubygems_version: 1.3.6
145
+ rubygems_version: 1.3.7
145
146
  signing_key:
146
147
  specification_version: 3
147
148
  summary: OpenSocial Google Gem
148
- test_files:
149
- - test/test_request.rb
150
- - test/test_rpcrequest.rb
151
- - test/test_connection.rb
152
- - test/test_appdata.rb
153
- - test/test_person.rb
154
- - test/test_activity.rb
155
- - test/helper.rb
156
- - test/test_group.rb
157
- - test/test_online.rb
149
+ test_files: []
150
+
data/.document DELETED
@@ -1,5 +0,0 @@
1
- README.rdoc
2
- lib/**/*.rb
3
- bin/*
4
- features/**/*.feature
5
- LICENSE
data/.gitignore DELETED
@@ -1,21 +0,0 @@
1
- ## MAC OS
2
- .DS_Store
3
-
4
- ## TEXTMATE
5
- *.tmproj
6
- tmtags
7
-
8
- ## EMACS
9
- *~
10
- \#*
11
- .\#*
12
-
13
- ## VIM
14
- *.swp
15
-
16
- ## PROJECT::GENERAL
17
- coverage
18
- rdoc
19
- pkg
20
-
21
- ## PROJECT::SPECIFIC
data/Rakefile DELETED
@@ -1,58 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
-
3
- require "rubygems"
4
- require "rake"
5
-
6
- begin
7
- require "jeweler"
8
- Jeweler::Tasks.new do |gem|
9
- gem.name = "qoobaa-opensocial"
10
- gem.summary = %Q{OpenSocial Google Gem}
11
- gem.description = %Q{OpenSocial Google Gem}
12
- gem.email = "qoobaa@gmail.com"
13
- gem.homepage = "http://github.com/qoobaa/opensocial"
14
- gem.authors = ["Jakub Kuźma", "Piotr Sarnacki"]
15
- gem.add_dependency "oauth"
16
- gem.add_development_dependency "test-unit", ">= 2"
17
- gem.add_development_dependency "json_pure"
18
- gem.add_development_dependency "mocha"
19
- # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
20
- end
21
- Jeweler::GemcutterTasks.new
22
- rescue LoadError
23
- puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
24
- end
25
-
26
- require "rake/testtask"
27
- Rake::TestTask.new(:test) do |test|
28
- test.libs << "lib" << "test"
29
- test.pattern = "test/**/test_*.rb"
30
- test.verbose = true
31
- end
32
-
33
- begin
34
- require "rcov/rcovtask"
35
- Rcov::RcovTask.new do |test|
36
- test.libs << "test"
37
- test.pattern = "test/**/test_*.rb"
38
- test.verbose = true
39
- end
40
- rescue LoadError
41
- task :rcov do
42
- abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
43
- end
44
- end
45
-
46
- task :test => :check_dependencies
47
-
48
- task :default => :test
49
-
50
- require "rake/rdoctask"
51
- Rake::RDocTask.new do |rdoc|
52
- version = File.exist?("VERSION") ? File.read("VERSION") : ""
53
-
54
- rdoc.rdoc_dir = "rdoc"
55
- rdoc.title = "opensocial #{version}"
56
- rdoc.rdoc_files.include("README*")
57
- rdoc.rdoc_files.include("lib/**/*.rb")
58
- end
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 0.1.8
@@ -1,90 +0,0 @@
1
- # Copyright (c) 2007 Blaine Cook, Larry Halff, Pelle Braendgaard
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining
4
- # a copy of this software and associated documentation files (the
5
- # "Software"), to deal in the Software without restriction, including
6
- # without limitation the rights to use, copy, modify, merge, publish,
7
- # distribute, sublicense, and/or sell copies of the Software, and to
8
- # permit persons to whom the Software is furnished to do so, subject to
9
- # the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be
12
- # included in all copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
- #
22
- # Includes modifications by Robin Luckey from:
23
- # http://github.com/robinluckey/oauth/tree/master/lib%2Foauth%2Frequest_proxy%2Faction_controller_request.rb
24
-
25
- module OAuth::RequestProxy #:nodoc: all
26
- class ActionControllerRequest < OAuth::RequestProxy::Base
27
- if defined?(ActionDispatch::Request)
28
- proxies(ActionDispatch::Request)
29
- elsif defined?(ActionController::AbstractRequest)
30
- proxies(ActionController::AbstractRequest)
31
- else
32
- proxies(ActionController::Request)
33
- end
34
-
35
- def method
36
- (request.env["rack.methodoverride.original_method"] || request.method).to_s.upcase
37
- end
38
-
39
- def uri
40
- uri = URI.parse(request.protocol + request.host + request.port_string + request.path)
41
- uri.query = nil
42
- uri.to_s
43
- end
44
-
45
- def parameters
46
- if options[:clobber_request]
47
- options[:parameters] || {}
48
- else
49
- params = request_params.merge(query_params).merge(header_params)
50
- params.stringify_keys! if params.respond_to?(:stringify_keys!)
51
- params.merge(options[:parameters] || {})
52
- end
53
- end
54
-
55
- # Override from OAuth::RequestProxy::Base to avoid roundtrip
56
- # conversion to Hash or Array and thus preserve the original
57
- # parameter names
58
- def parameters_for_signature
59
- params = []
60
- params << options[:parameters].to_query if options[:parameters]
61
-
62
- unless options[:clobber_request]
63
- params << header_params.to_query
64
- params << CGI.unescape(request.query_string) unless request.query_string.blank?
65
- if request.content_type == Mime::Type.lookup("application/x-www-form-urlencoded")
66
- if request.env["rack.formunencoder.original_input"]
67
- raw_post_data = request.env["rack.formunencoder.original_input"].read
68
- request.env["rack.formunencoder.original_input"].rewind if request.env["rack.formunencoder.original_input"].respond_to?(:rewind)
69
- params << CGI.unescape(raw_post_data)
70
- else
71
- params << CGI.unescape(request.raw_post)
72
- end
73
- end
74
- end
75
-
76
- params.join("&").split("&").reject { |kv| kv =~ /^oauth_signature=.*/}.reject(&:blank?).map { |p| p.split("=", 2) }.uniq
77
- end
78
-
79
- protected
80
-
81
- def query_params
82
- request.query_parameters
83
- end
84
-
85
- def request_params
86
- request.request_parameters
87
- end
88
-
89
- end
90
- end
@@ -1,109 +0,0 @@
1
- # Copyright (c) 2008 Google Inc.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- module OpenSocial #:nodoc:
16
-
17
- # Provides helper classes to be used in verifying and validating the user.
18
- # In particular, support is provided for:
19
- #
20
- # * Verification of signed makeRequest using OAuth/HMAC-SHA1
21
- # class ExampleController < ApplicationController
22
- # OpenSocial::Auth::CONSUMER_KEY = "623061448914"
23
- # OpenSocial::Auth::CONSUMER_SECRET = "uynAeXiWTisflWX99KU1D2q5"
24
- #
25
- # include OpenSocial::Auth
26
- #
27
- # before_filter :validate
28
- #
29
- # def return_private_data
30
- # end
31
- # end
32
- #
33
- # * Request for an OAuth request token
34
- #
35
- # * Request for an OAuth access token, when supplied with a request token
36
- #
37
-
38
-
39
- module Auth
40
-
41
- # Validates an incoming request by using the OAuth library and the supplied
42
- # key and secret.
43
- def validate(key = CONSUMER_KEY, secret = CONSUMER_SECRET)
44
- consumer = OAuth::Consumer.new(key, secret)
45
- begin
46
- signature = OAuth::Signature.build(request) do
47
- [nil, consumer.secret]
48
- end
49
- pass = signature.verify
50
- rescue OAuth::Signature::UnknownSignatureMethod => e
51
- logger.error "An unknown signature method was supplied: " + e.to_s
52
- end
53
- return pass
54
- end
55
-
56
- # Gets an OAuth request token, and redirects the user to authorize the app
57
- # to access data on their behalf.
58
- def get_oauth_token(key, secret, container, callback)
59
- consumer = OAuth::Consumer.new(key, secret, {
60
- :site => container[:base_uri],
61
- :request_token_path => container[:request_token_path],
62
- :authorize_path => container[:authorize_path],
63
- :access_token_path => container[:access_token_path],
64
- :http_method => container[:http_method]
65
- })
66
- request_token = consumer.get_request_token
67
-
68
- session[:token] = request_token.token
69
- session[:secret] = request_token.secret
70
-
71
- redirect_to request_token.authorize_url + "&oauth_callback=" + CGI.escape(callback)
72
- end
73
-
74
- # If neccesary, swaps an existing request token and secret for an access
75
- # token, storing it in the Connection class, and returning the access token
76
- # and secret for later use.
77
- def get_access_token(connection, token, secret)
78
- if (token && secret)
79
- consumer = OAuth::Consumer.new(connection.consumer_key,
80
- connection.consumer_secret,
81
- connection.container)
82
-
83
- if connection.consumer_token.token.empty? &&
84
- connection.consumer_token.secret.empty?
85
- connection.consumer_token = OAuth::Token.new(token, secret)
86
-
87
- uri = URI.parse(connection.container[:base_uri] +
88
- connection.container[:access_token_path])
89
- http = Net::HTTP.new(uri.host, uri.port)
90
- req = Net::HTTP::Get.new(uri.request_uri)
91
- connection.sign!(http, req)
92
-
93
- resp = http.get(req.path)
94
-
95
- matches = resp.body.match(/oauth_token=(.*?)&oauth_token_secret=(.*)/)
96
- access_token = matches[1]
97
- access_secret = matches[2]
98
- end
99
-
100
- reusable_token = OAuth::AccessToken.new(consumer, access_token, access_secret)
101
- connection.consumer_token = reusable_token
102
-
103
- return access_token, access_secret
104
- end
105
-
106
- return nil, nil
107
- end
108
- end
109
- end
@@ -1,32 +0,0 @@
1
- # Copyright (c) 2008 Engine Yard
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining
4
- # a copy of this software and associated documentation files (the
5
- # "Software"), to deal in the Software without restriction, including
6
- # without limitation the rights to use, copy, modify, merge, publish,
7
- # distribute, sublicense, and/or sell copies of the Software, and to
8
- # permit persons to whom the Software is furnished to do so, subject to
9
- # the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be
12
- # included in all copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
-
22
- class String #:nodoc:
23
- def snake_case
24
- gsub(/\B[A-Z]/, '_\&').downcase
25
- end
26
-
27
- def camel_case
28
- words = split('_')
29
- camel = words[1..-1].map { |e| e.capitalize }.join
30
- words[0] + camel
31
- end
32
- end
@@ -1,23 +0,0 @@
1
- # Copyright (c) 2008 Google Inc.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- class String #:nodoc:
16
- # Removes backslash escaping.
17
- def os_unescape
18
- unescaped = self.gsub(/\\\"/, '"')
19
- unescaped = unescaped.gsub('"{', "{")
20
- unescaped = unescaped.gsub('}"', "}")
21
- unescaped = unescaped.gsub(/\"\"/, "\"")
22
- end
23
- end