appdirect_integration 0.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.
- checksums.yaml +7 -0
- data/.gitignore +16 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/CHANGELOG.md +6 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +107 -0
- data/Rakefile +7 -0
- data/app/assets/images/appdirect_integration/.keep +0 -0
- data/app/assets/javascripts/appdirect_integration/application.js +3 -0
- data/app/assets/stylesheets/appdirect_integration/application.css +4 -0
- data/app/controllers/appdirect_integration/appdirect_callbacks_controller.rb +139 -0
- data/app/controllers/appdirect_integration/application_controller.rb +4 -0
- data/app/helpers/appdirect_integration/application_helper.rb +4 -0
- data/app/views/layouts/appdirect_integration/application.html.erb +11 -0
- data/appdirect_integration.gemspec +33 -0
- data/bin/console +14 -0
- data/bin/rails +12 -0
- data/bin/setup +7 -0
- data/config/routes.rb +6 -0
- data/lib/appdirect_integration/configuration.rb +8 -0
- data/lib/appdirect_integration/engine.rb +5 -0
- data/lib/appdirect_integration/fields.rb +47 -0
- data/lib/appdirect_integration/util.rb +41 -0
- data/lib/appdirect_integration/version.rb +3 -0
- data/lib/appdirect_integration.rb +22 -0
- data/lib/generators/active_record/appdirect_integration_generator.rb +68 -0
- data/lib/generators/active_record/templates/migration.rb +13 -0
- data/lib/generators/active_record/templates/migration_existing.rb +20 -0
- data/lib/generators/appdirect_integration/USAGE +8 -0
- data/lib/generators/appdirect_integration/appdirect_integration_generator.rb +26 -0
- data/lib/generators/appdirect_integration/install_generator.rb +21 -0
- data/lib/generators/appdirect_integration/orm_helpers.rb +59 -0
- data/lib/generators/appdirect_integration/templates/README +15 -0
- data/lib/generators/appdirect_integration/templates/appdirect.rb +5 -0
- data/lib/generators/mongoid/appdirect_integration_generator.rb +32 -0
- metadata +211 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f3ba59cdf99d841fddeddae374b7aac811ef2e38
|
4
|
+
data.tar.gz: 3fc5c50a2c718b585009f8696603c7be0930fcda
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1da5398bc72302e7e6d5962c653b09fae877359f3c83fb3ddbb78755f65351a65a8d7fa04fe727b3a9295cc8906a85387a98bd5af5ae3b3bac1def9f498643f9
|
7
|
+
data.tar.gz: 0b158d5ffae19d4556f7e68ac6cd3029d64dd8f267ed98cd1b4dfacf18593594b8a3568194e445ef85f9201a43260511446cdef07a4199cbf9ce1c1d6df55182
|
data/.gitignore
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
.bundle/
|
2
|
+
.yardoc
|
3
|
+
Gemfile.lock
|
4
|
+
_yardoc/
|
5
|
+
coverage/
|
6
|
+
doc/
|
7
|
+
pkg/
|
8
|
+
spec/reports/
|
9
|
+
tmp/
|
10
|
+
log/*.log
|
11
|
+
spec/dummy/db/*.sqlite3
|
12
|
+
spec/dummy/db/*.sqlite3-journal
|
13
|
+
spec/dummy/log/*.log
|
14
|
+
spec/dummy/tmp/
|
15
|
+
spec/dummy/.sass-cache
|
16
|
+
.DS_Store
|
data/.rspec
ADDED
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 AppDirect, Inc.
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
# AppdirectIntegration
|
2
|
+
[](https://travis-ci.org/artgo/appdirect_integration)
|
3
|
+
|
4
|
+
Integration with AppDirect masrketplace.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem 'appdirect_integration'
|
12
|
+
```
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
|
16
|
+
$ bundle
|
17
|
+
|
18
|
+
Or install it yourself as:
|
19
|
+
|
20
|
+
$ gem install appdirect_integration
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
Add appdirect_integration gem to Gemfile
|
25
|
+
```ruby
|
26
|
+
gem 'appdirect_integration'
|
27
|
+
```
|
28
|
+
|
29
|
+
Add Genrate your Order scaffold
|
30
|
+
```ruby
|
31
|
+
rails g scaffold Order
|
32
|
+
```
|
33
|
+
|
34
|
+
Setup Order model to work with AppDirect and generate migrations
|
35
|
+
```ruby
|
36
|
+
rails g appdirect_integration Order
|
37
|
+
```
|
38
|
+
|
39
|
+
Generate configuration
|
40
|
+
```ruby
|
41
|
+
rails g appdirect_integration:install
|
42
|
+
```
|
43
|
+
which will generate `config/appdirect.rb` file which you need to check to setup (may be change your model name).
|
44
|
+
|
45
|
+
gem will automatically create (new) and save your Order ActiveRecord/Mongoid object
|
46
|
+
|
47
|
+
the list of supported fields:
|
48
|
+
* `company_uuid`
|
49
|
+
* `company_name`
|
50
|
+
* `company_email`
|
51
|
+
* `company_phone`
|
52
|
+
* `company_website`
|
53
|
+
* `company_country`
|
54
|
+
* `user_uuid`
|
55
|
+
* `user_open_id`
|
56
|
+
* `user_email`
|
57
|
+
* `user_first_name`
|
58
|
+
* `user_last_name`
|
59
|
+
* `user_language`
|
60
|
+
* `user_address_full_name`
|
61
|
+
* `user_address_company_name`
|
62
|
+
* `user_address_phone`
|
63
|
+
* `user_address_phone_extension`
|
64
|
+
* `user_address_fax`
|
65
|
+
* `user_address_fax_extension`
|
66
|
+
* `user_address_street1`
|
67
|
+
* `user_address_street2`
|
68
|
+
* `user_address_city`
|
69
|
+
* `user_address_state`
|
70
|
+
* `user_address_zip`
|
71
|
+
* `user_address_country`
|
72
|
+
* `user_address_pobox`
|
73
|
+
* `user_address_pozip`
|
74
|
+
* `status`
|
75
|
+
* `edition`
|
76
|
+
* `marketplace_url`
|
77
|
+
* `pricing_duration`
|
78
|
+
* `quantity`
|
79
|
+
* `unit`
|
80
|
+
* `quantity2`
|
81
|
+
* `unit2`
|
82
|
+
* `quantity3`
|
83
|
+
* `unit3`
|
84
|
+
* `all_data`
|
85
|
+
* `order_items` - should be mentioned as `has_many: order_items` for ActiveRecord or `embeds_many: order_items` for Mongoid
|
86
|
+
|
87
|
+
Fields for order_items OrderItem:
|
88
|
+
* `unit`
|
89
|
+
* `quantity`
|
90
|
+
|
91
|
+
## Development
|
92
|
+
|
93
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
94
|
+
|
95
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
96
|
+
|
97
|
+
## Contributing
|
98
|
+
|
99
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/artgo/appdirect_integration.
|
100
|
+
|
101
|
+
## CHANGELOG
|
102
|
+
|
103
|
+
See [here](CHANGELOG.md).
|
104
|
+
|
105
|
+
## Documentation
|
106
|
+
|
107
|
+
See AppDirect API documentation [here](http://info.appdirect.com/developers/docs/getting-started/introduction).
|
data/Rakefile
ADDED
File without changes
|
@@ -0,0 +1,139 @@
|
|
1
|
+
require 'oauth'
|
2
|
+
require 'rest-client'
|
3
|
+
require 'uri'
|
4
|
+
require 'appdirect_integration'
|
5
|
+
require 'appdirect_integration/util'
|
6
|
+
|
7
|
+
module AppdirectIntegration
|
8
|
+
class AppdirectCallbacksController < ApplicationController
|
9
|
+
def order
|
10
|
+
puts "Received order event from AppDirect, requesting info..."
|
11
|
+
|
12
|
+
parsed_result = read_event_data()
|
13
|
+
|
14
|
+
order = AppdirectIntegration.configuration.order_class.new
|
15
|
+
order = build_order_object(parsed_result, order)
|
16
|
+
|
17
|
+
order.status = 'ACTIVE' if order.respond_to?('status=')
|
18
|
+
|
19
|
+
if order.save
|
20
|
+
render json: success_response('Account creation successful', order.id.to_s)
|
21
|
+
else
|
22
|
+
render json: fault_response('Error creating account', 'UNKNOWN_ERROR')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def change
|
27
|
+
respond_to_event('change')
|
28
|
+
end
|
29
|
+
|
30
|
+
def cancel
|
31
|
+
respond_to_event('cancel')
|
32
|
+
end
|
33
|
+
|
34
|
+
def notify
|
35
|
+
respond_to_event('notify')
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
def event_url
|
40
|
+
params[:eventUrl]
|
41
|
+
end
|
42
|
+
|
43
|
+
def read_event_data
|
44
|
+
raise "mandatory eventUrl parameter is not provided" if event_url.blank?
|
45
|
+
|
46
|
+
puts "Got event URL #{event_url}"
|
47
|
+
|
48
|
+
event_uri = URI.parse(event_url)
|
49
|
+
|
50
|
+
site = "#{event_uri.scheme}://#{event_uri.host}"
|
51
|
+
site += ":#{event_uri.port.to_s}" if (event_uri.port != 80) && (event_uri.port != 443)
|
52
|
+
path = event_uri.path
|
53
|
+
|
54
|
+
puts "Unsigned event URL #{site}#{path}"
|
55
|
+
|
56
|
+
consumer = OAuth::Consumer.new(AppdirectIntegration.configuration.consumer_key.to_s,
|
57
|
+
AppdirectIntegration.configuration.consumer_secret.to_s,
|
58
|
+
{ :site => site, :scheme => :query_string })
|
59
|
+
req = consumer.create_signed_request(:get, path)
|
60
|
+
full_path = "#{site}#{req.path}"
|
61
|
+
|
62
|
+
puts "Requesting #{full_path}"
|
63
|
+
|
64
|
+
result = RestClient.get full_path, :content_type => :json, :accept => :json
|
65
|
+
|
66
|
+
puts "JSON Result: #{result.to_s}"
|
67
|
+
|
68
|
+
parsed_result = ActiveSupport::JSON.decode(result.to_s)
|
69
|
+
|
70
|
+
parsed_result
|
71
|
+
end
|
72
|
+
|
73
|
+
def respond_to_event(name)
|
74
|
+
puts "Received #{name} event from AppDirect, requesting info..."
|
75
|
+
|
76
|
+
parsed_result = read_event_data()
|
77
|
+
|
78
|
+
id = parsed_result["payload"]["account"]["accountIdentifier"]
|
79
|
+
|
80
|
+
order = AppdirectIntegration.configuration.order_class.find(id)
|
81
|
+
order = update_order_object(parsed_result, order)
|
82
|
+
|
83
|
+
if order.save
|
84
|
+
render json: success_response("Event #{name} processed successfuly", id)
|
85
|
+
else
|
86
|
+
render json: fault_response('Error updating account', 'UNKNOWN_ERROR')
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def build_order_object(parsed_result, order)
|
91
|
+
Util.copy_known_fields(order, parsed_result)
|
92
|
+
|
93
|
+
if parsed_result["payload"].present?
|
94
|
+
order_data = parsed_result["payload"]["order"]
|
95
|
+
|
96
|
+
if !order_data["items"].nil? && order_data["items"].length > 0
|
97
|
+
if order.respond_to?('order_items') && order.order_items.respond_to?('build')
|
98
|
+
order_data["items"].each do |item|
|
99
|
+
order_item = order.order_items.build()
|
100
|
+
order_item.quantity = order_item["quantity"] if order_item.respond_to?('quantity=')
|
101
|
+
order_item.unit = order_item["unit"] if order_item.respond_to?('unit=')
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
order.all_data = parsed_result.to_json if order.respond_to?('all_data=')
|
108
|
+
|
109
|
+
order
|
110
|
+
end
|
111
|
+
|
112
|
+
def update_order_object(parsed_result, order)
|
113
|
+
Util.copy_known_fields(order, parsed_result)
|
114
|
+
|
115
|
+
if parsed_result["payload"].present?
|
116
|
+
order_data = parsed_result["payload"]["order"]
|
117
|
+
|
118
|
+
if !order_data["items"].nil? && order_data["items"].length > 0
|
119
|
+
if order.respond_to?('order_items') && order.order_items.respond_to?('build')
|
120
|
+
order_data["items"].each do |item|
|
121
|
+
order_item = order.order_items.find_or_create_by(unit: order_item["unit"])
|
122
|
+
order_item.quantity = order_item["quantity"] if order_item.respond_to?('quantity=')
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
order
|
129
|
+
end
|
130
|
+
|
131
|
+
def success_response(message, account_id)
|
132
|
+
{success: true, message: message, accountIdentifier: account_id}.to_json
|
133
|
+
end
|
134
|
+
|
135
|
+
def fault_response(message, error_code)
|
136
|
+
{success: false, errorCode: error_code, message: message}.to_json
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'appdirect_integration/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "appdirect_integration"
|
8
|
+
spec.version = AppdirectIntegration::VERSION
|
9
|
+
spec.authors = ["Artem Golubev"]
|
10
|
+
spec.email = ["artem.golubev@appdirect.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Integration to AppDirect marketplace.}
|
13
|
+
spec.description = %q{Creates endpoints to integrate to callbacks from AppDirect marketplace to enable to sell subscriptions.}
|
14
|
+
spec.homepage = 'https://github.com/artgo/appdirect_integration'
|
15
|
+
spec.license = 'MIT'
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.bindir = 'bin'
|
20
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
21
|
+
spec.require_paths = ["lib"]
|
22
|
+
|
23
|
+
spec.add_dependency "rails", ">= 3.2.0"
|
24
|
+
spec.add_dependency "oauth"
|
25
|
+
spec.add_dependency "rest-client"
|
26
|
+
|
27
|
+
spec.add_development_dependency "sqlite3"
|
28
|
+
spec.add_development_dependency "bundler"
|
29
|
+
spec.add_development_dependency "rake"
|
30
|
+
spec.add_development_dependency "rspec", ">= 3.3.0"
|
31
|
+
spec.add_development_dependency "yard"
|
32
|
+
spec.add_development_dependency "coveralls"
|
33
|
+
end
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "appdirect_integration"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/rails
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This command will automatically be run when you run "rails" with Rails 4 gems installed from the root of your application.
|
3
|
+
|
4
|
+
ENGINE_ROOT = File.expand_path('../..', __FILE__)
|
5
|
+
ENGINE_PATH = File.expand_path('../../lib/appdirect_integration/engine', __FILE__)
|
6
|
+
|
7
|
+
# Set up gems listed in the Gemfile.
|
8
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
|
9
|
+
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
|
10
|
+
|
11
|
+
require 'rails/all'
|
12
|
+
require 'rails/engine/commands'
|
data/bin/setup
ADDED
data/config/routes.rb
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
Rails.application.routes.draw do
|
2
|
+
match '/appdirect/api/order' => 'appdirect_integration/appdirect_callbacks#order', via: [:get]
|
3
|
+
match '/appdirect/api/change' => 'appdirect_integration/appdirect_callbacks#change', via: [:get]
|
4
|
+
match '/appdirect/api/cancel' => 'appdirect_integration/appdirect_callbacks#cancel', via: [:get]
|
5
|
+
match '/appdirect/api/status' => 'appdirect_integration/appdirect_callbacks#status', via: [:get]
|
6
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module AppdirectIntegration
|
2
|
+
FIELDS = [
|
3
|
+
{name: 'user_uuid', type: :string, path: ["creator", "uuid"]},
|
4
|
+
{name: 'user_open_id', type: :string, path: ["creator", "openId"]},
|
5
|
+
{name: 'user_email', type: :string, path: ["creator", "email"]},
|
6
|
+
{name: 'user_first_name', type: :string, path: ["creator", "firstName"]},
|
7
|
+
{name: 'user_last_name', type: :string, path: ["creator", "lastName"]},
|
8
|
+
{name: 'user_language', type: :string, path: ["creator", "language"]},
|
9
|
+
{name: 'user_address_full_name', type: :string, path: ["creator", "address", "fullName"]},
|
10
|
+
{name: 'user_address_company_name', type: :string, path: ["creator", "address", "companyName"]},
|
11
|
+
{name: 'user_address_phone', type: :string, path: ["creator", "address", "phone"]},
|
12
|
+
{name: 'user_address_phone_extension', type: :string, path: ["creator", "address", "phoneExtension"]},
|
13
|
+
{name: 'user_address_fax', type: :string, path: ["creator", "address", "fax"]},
|
14
|
+
{name: 'user_address_fax_extension', type: :string, path: ["creator", "address", "faxExtension"]},
|
15
|
+
{name: 'user_address_street1', type: :string, path: ["creator", "address", "street1"]},
|
16
|
+
{name: 'user_address_street2', type: :string, path: ["creator", "address", "street2"]},
|
17
|
+
{name: 'user_address_city', type: :string, path: ["creator", "address", "city"]},
|
18
|
+
{name: 'user_address_state', type: :string, path: ["creator", "address", "state"]},
|
19
|
+
{name: 'user_address_zip', type: :string, path: ["creator", "address", "zip"]},
|
20
|
+
{name: 'user_address_country', type: :string, path: ["creator", "address", "country"]},
|
21
|
+
{name: 'user_address_pobox', type: :string, path: ["creator", "address", "pobox"]},
|
22
|
+
{name: 'user_address_pozip', type: :string, path: ["creator", "address", "pozip"]},
|
23
|
+
{name: 'company_uuid', type: :string, path: ["payload", "company", "uuid"]},
|
24
|
+
{name: 'company_name', type: :string, path: ["payload", "company", "name"]},
|
25
|
+
{name: 'company_email', type: :string, path: ["payload", "company", "email"]},
|
26
|
+
{name: 'company_phone', type: :string, path: ["payload", "company", "phoneNumber"]},
|
27
|
+
{name: 'company_website', type: :string, path: ["payload", "company", "website"]},
|
28
|
+
{name: 'company_country', type: :string, path: ["payload", "company", "country"]},
|
29
|
+
{name: 'status', type: :string, path: ["payload", "account", "status"]},
|
30
|
+
{name: 'edition', type: :string, path: ["payload", "order", "editionCode"]},
|
31
|
+
{name: 'pricing_duration', type: :string, path: ["payload", "order", "pricingDuration"]},
|
32
|
+
{name: 'marketplace_url', type: :string, path: ["marketplace", "baseUrl"]},
|
33
|
+
{name: 'quantity', type: :decimal, path: ["payload", "order", "items", 0, "quantity"]},
|
34
|
+
{name: 'unit', type: :string, path: ["payload", "order", "items", 0, "unit"]},
|
35
|
+
{name: 'quantity2', type: :decimal, path: ["payload", "order", "items", 1, "quantity"]},
|
36
|
+
{name: 'unit2', type: :string, path: ["payload", "order", "items", 1, "unit"]},
|
37
|
+
{name: 'quantity3', type: :decimal, path: ["payload", "order", "items", 2, "quantity"]},
|
38
|
+
{name: 'unit3', type: :string, path: ["payload", "order", "items", 2, "unit"]},
|
39
|
+
{name: 'all_data', type: :text, path: nil} ]
|
40
|
+
|
41
|
+
AR_TO_MONGOID = {
|
42
|
+
:string => 'String',
|
43
|
+
:decimal => 'BigDecimal',
|
44
|
+
:timestamp => 'DateTime',
|
45
|
+
:text => 'String'
|
46
|
+
}
|
47
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'appdirect_integration/fields'
|
2
|
+
|
3
|
+
module AppdirectIntegration
|
4
|
+
class Util
|
5
|
+
|
6
|
+
def self.copy_known_fields(to, from)
|
7
|
+
AppdirectIntegration::FIELDS.each do |field|
|
8
|
+
if field[:path].present?
|
9
|
+
Util.copy_path(to, field[:name], from, field[:path])
|
10
|
+
end
|
11
|
+
end
|
12
|
+
to
|
13
|
+
end
|
14
|
+
|
15
|
+
# path here is the array with size >= 1
|
16
|
+
def self.copy_path(to, field_name, from, path)
|
17
|
+
val = Util.val_by_path(from, path)
|
18
|
+
Util.copy_data(to, field_name, val)
|
19
|
+
end
|
20
|
+
|
21
|
+
# path here is the array with size >= 1
|
22
|
+
def self.val_by_path(from, path)
|
23
|
+
val = from
|
24
|
+
path.each do |index|
|
25
|
+
val = val[index]
|
26
|
+
if val.nil?
|
27
|
+
return val
|
28
|
+
end
|
29
|
+
end
|
30
|
+
val
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.copy_data(to, field_name, val)
|
34
|
+
method_name = field_name + '='
|
35
|
+
method_sym = method_name.to_sym
|
36
|
+
if val.present? && to.respond_to?(method_name)
|
37
|
+
to.send(method_sym, val)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'appdirect_integration/version'
|
2
|
+
require 'appdirect_integration/engine'
|
3
|
+
require 'appdirect_integration/configuration'
|
4
|
+
|
5
|
+
module AppdirectIntegration
|
6
|
+
mattr_accessor :configuration
|
7
|
+
|
8
|
+
def self.configure(&block)
|
9
|
+
self.configuration ||= Configuration.new
|
10
|
+
self.configuration.appdirect_url = 'https://www.appdirect.com'
|
11
|
+
block.call self.configuration
|
12
|
+
#if self.configuration.order_class.nil?
|
13
|
+
# raise "Please configure order_class to make AppDirect integration work. Use rake appdirect_integration:install to generate defaults"
|
14
|
+
#end
|
15
|
+
#if self.configuration.consumer_key.nil?
|
16
|
+
# raise "Please configure consumer_key to make AppDirect integration work. Use rake appdirect_integration:install to generate defaults"
|
17
|
+
#end
|
18
|
+
#if self.configuration.consumer_secret.nil?
|
19
|
+
# raise "Please configure consumer_secret to make AppDirect integration work. Use rake appdirect_integration:install to generate defaults"
|
20
|
+
#end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'rails/generators/active_record'
|
2
|
+
require 'generators/appdirect_integration/orm_helpers'
|
3
|
+
require 'appdirect_integration/fields'
|
4
|
+
|
5
|
+
module ActiveRecord
|
6
|
+
module Generators
|
7
|
+
class AppdirectIntegrationGenerator < ActiveRecord::Generators::Base
|
8
|
+
argument :attributes, type: :array, default: [], banner: "field:type field:type"
|
9
|
+
|
10
|
+
include AppdirectIntegration::Generators::OrmHelpers
|
11
|
+
source_root File.expand_path("../templates", __FILE__)
|
12
|
+
|
13
|
+
def copy_appdirect_integration_migration
|
14
|
+
if (behavior == :invoke && model_exists?) || (behavior == :revoke && migration_exists?(table_name))
|
15
|
+
migration_template "migration_existing.rb", "db/migrate/add_appdirect_integration_to_#{table_name}.rb"
|
16
|
+
else
|
17
|
+
migration_template "migration.rb", "db/migrate/appdirect_integration_create_#{table_name}.rb"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def generate_model
|
22
|
+
invoke "active_record:model", [name], migration: false unless model_exists? && behavior == :invoke
|
23
|
+
end
|
24
|
+
|
25
|
+
def inject_appdirect_integration_content
|
26
|
+
content = model_contents
|
27
|
+
|
28
|
+
class_path = if namespaced?
|
29
|
+
class_name.to_s.split("::")
|
30
|
+
else
|
31
|
+
[class_name]
|
32
|
+
end
|
33
|
+
|
34
|
+
indent_depth = class_path.size - 1
|
35
|
+
content = content.split("\n").map { |line| " " * indent_depth + line } .join("\n") << "\n"
|
36
|
+
|
37
|
+
inject_into_class(model_path, class_path.last, content) if model_exists?
|
38
|
+
end
|
39
|
+
|
40
|
+
def migration_data
|
41
|
+
data = "\n"
|
42
|
+
AppdirectIntegration::FIELDS.each do |field|
|
43
|
+
data += " t.#{field[:type]} :#{field[:name]}\n"
|
44
|
+
end
|
45
|
+
|
46
|
+
data
|
47
|
+
end
|
48
|
+
|
49
|
+
def ip_column
|
50
|
+
# Padded with spaces so it aligns nicely with the rest of the columns.
|
51
|
+
"%-8s" % (inet? ? "inet" : "string")
|
52
|
+
end
|
53
|
+
|
54
|
+
def inet?
|
55
|
+
rails4? && postgresql?
|
56
|
+
end
|
57
|
+
|
58
|
+
def rails4?
|
59
|
+
Rails.version.start_with? '4'
|
60
|
+
end
|
61
|
+
|
62
|
+
def postgresql?
|
63
|
+
config = ActiveRecord::Base.configurations[Rails.env]
|
64
|
+
config && config['adapter'] == 'postgresql'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class AppdirectIntegrationCreate<%= table_name.camelize %> < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table(:<%= table_name %>) do |t|
|
4
|
+
<%= migration_data -%>
|
5
|
+
|
6
|
+
<% attributes.each do |attribute| -%>
|
7
|
+
t.<%= attribute.type %> :<%= attribute.name %>
|
8
|
+
<% end -%>
|
9
|
+
|
10
|
+
t.timestamps null: false
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class AddAppdirectIntegrationTo<%= table_name.camelize %> < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
change_table(:<%= table_name %>) do |t|
|
4
|
+
<%= migration_data -%>
|
5
|
+
|
6
|
+
<% attributes.each do |attribute| -%>
|
7
|
+
t.<%= attribute.type %> :<%= attribute.name %>
|
8
|
+
<% end -%>
|
9
|
+
|
10
|
+
# Uncomment below if timestamps were not included in your original model.
|
11
|
+
# t.timestamps null: false
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.down
|
16
|
+
# By default, we don't want to make any assumption about how to roll back a migration when your
|
17
|
+
# model already existed. Please edit below which fields you would like to remove in this migration.
|
18
|
+
raise ActiveRecord::IrreversibleMigration
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rails/generators/named_base'
|
2
|
+
|
3
|
+
module AppdirectIntegration
|
4
|
+
module Generators
|
5
|
+
class AppdirectIntegrationGenerator < Rails::Generators::NamedBase
|
6
|
+
include Rails::Generators::ResourceHelpers
|
7
|
+
|
8
|
+
namespace "appdirect_integration"
|
9
|
+
source_root File.expand_path("../templates", __FILE__)
|
10
|
+
|
11
|
+
desc "Generates a model with the given NAME (if one does not exist) with appdirect_integration " <<
|
12
|
+
"configuration plus a migration file."
|
13
|
+
|
14
|
+
hook_for :orm
|
15
|
+
|
16
|
+
# class_option :routes, desc: "Generate routes", type: :boolean, default: true
|
17
|
+
|
18
|
+
# def add_appdirect_integration_routes
|
19
|
+
# appdirect_integration_route = "appdirect_integration_for :#{plural_name}"
|
20
|
+
# appdirect_integration_route << %Q(, class_name: "#{class_name}") if class_name.include?("::")
|
21
|
+
# appdirect_integration_route << %Q(, skip: :all) unless options.routes?
|
22
|
+
# route appdirect_integration_route
|
23
|
+
# end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rails/generators/base'
|
2
|
+
|
3
|
+
module AppdirectIntegration
|
4
|
+
class InstallGenerator < Rails::Generators::Base
|
5
|
+
source_root File.expand_path("../templates", __FILE__)
|
6
|
+
|
7
|
+
desc "Creates a AppdirectIntegration initializer and copy it to your application."
|
8
|
+
|
9
|
+
def copy_initializer
|
10
|
+
copy_file "appdirect.rb", "config/initializers/appdirect.rb"
|
11
|
+
end
|
12
|
+
|
13
|
+
def show_readme
|
14
|
+
readme "README" if behavior == :invoke
|
15
|
+
end
|
16
|
+
|
17
|
+
def rails_4?
|
18
|
+
Rails::VERSION::MAJOR == 4
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'appdirect_integration/fields'
|
2
|
+
|
3
|
+
module AppdirectIntegration
|
4
|
+
module Generators
|
5
|
+
module OrmHelpers
|
6
|
+
def model_contents
|
7
|
+
buffer = <<-CONTENT
|
8
|
+
# Prepared for integration with AppDirect
|
9
|
+
|
10
|
+
CONTENT
|
11
|
+
if needs_attr_accessible?
|
12
|
+
buffer += <<-CONTENT
|
13
|
+
# Setup accessible (or protected) attributes for your model
|
14
|
+
|
15
|
+
CONTENT
|
16
|
+
buffer += " attr_accessible"
|
17
|
+
AppdirectIntegration::FIELDS.each do |field|
|
18
|
+
buffer += " :#{field[:name]},"
|
19
|
+
end
|
20
|
+
|
21
|
+
# Remove last ','
|
22
|
+
buffer = buffer[0..-2]
|
23
|
+
end
|
24
|
+
|
25
|
+
buffer
|
26
|
+
end
|
27
|
+
|
28
|
+
def needs_attr_accessible?
|
29
|
+
rails_3? && !strong_parameters_enabled?
|
30
|
+
end
|
31
|
+
|
32
|
+
def rails_3?
|
33
|
+
Rails::VERSION::MAJOR == 3
|
34
|
+
end
|
35
|
+
|
36
|
+
def strong_parameters_enabled?
|
37
|
+
defined?(ActionController::StrongParameters)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def model_exists?
|
43
|
+
File.exists?(File.join(destination_root, model_path))
|
44
|
+
end
|
45
|
+
|
46
|
+
def migration_exists?(table_name)
|
47
|
+
Dir.glob("#{File.join(destination_root, migration_path)}/[0-9]*_*.rb").grep(/\d+_add_appdirect_integration_to_#{table_name}.rb$/).first
|
48
|
+
end
|
49
|
+
|
50
|
+
def migration_path
|
51
|
+
@migration_path ||= File.join("db", "migrate")
|
52
|
+
end
|
53
|
+
|
54
|
+
def model_path
|
55
|
+
@model_path ||= File.join("app", "models", "#{file_path}.rb")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
===============================================================================
|
2
|
+
|
3
|
+
Some setup you must do manually if you haven't yet:
|
4
|
+
|
5
|
+
1. Register with AppDirect (free): https://www.appdirect.com/developers/register
|
6
|
+
|
7
|
+
2. Create an application and and copy your consumer key and consumer secret.
|
8
|
+
|
9
|
+
3. Generate appdirect.rb initializer by running:
|
10
|
+
|
11
|
+
rails g appdirect_integration:install
|
12
|
+
|
13
|
+
4. Edit initializer config/initializers/appdirect.rb and specify your consumer key and consumer secret there.
|
14
|
+
|
15
|
+
===============================================================================
|
@@ -0,0 +1,5 @@
|
|
1
|
+
AppdirectIntegration.configure do |c|
|
2
|
+
c.order_class = Order # Order model, refer another one if you are using other model.
|
3
|
+
c.consumer_key = ENV['APPDIRECT_CONSUMER_KEY'] # See Edit Integration part of your Application configuration on AppDirect.
|
4
|
+
c.consumer_secret = ENV['APPDIRECT_CONSUMER_SECRET'] # See Edit Integration part of your Application configuration on AppDirect.
|
5
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'rails/generators/named_base'
|
2
|
+
require 'generators/appdirect_integration/orm_helpers'
|
3
|
+
require 'appdirect_integration/fields'
|
4
|
+
|
5
|
+
module Mongoid
|
6
|
+
module Generators
|
7
|
+
class AppdirectIntegrationGenerator < Rails::Generators::NamedBase
|
8
|
+
include AppdirectIntegration::Generators::OrmHelpers
|
9
|
+
|
10
|
+
def generate_model
|
11
|
+
invoke "mongoid:model", [name] unless model_exists? && behavior == :invoke
|
12
|
+
end
|
13
|
+
|
14
|
+
def inject_field_types
|
15
|
+
inject_into_file model_path, migration_data, after: "include Mongoid::Document\n" if model_exists?
|
16
|
+
end
|
17
|
+
|
18
|
+
def inject_appdirect_integration_content
|
19
|
+
inject_into_file model_path, model_contents, after: "include Mongoid::Document\n" if model_exists?
|
20
|
+
end
|
21
|
+
|
22
|
+
def migration_data
|
23
|
+
data = "\n"
|
24
|
+
AppdirectIntegration::FIELDS.each do |field|
|
25
|
+
data += " field :#{field[:name]}, type: #{AppdirectIntegration::AR_TO_MONGOID[field[:type]]}\n"
|
26
|
+
end
|
27
|
+
|
28
|
+
data
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
metadata
ADDED
@@ -0,0 +1,211 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: appdirect_integration
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Artem Golubev
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-08-05 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 3.2.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 3.2.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: oauth
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rest-client
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: sqlite3
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: bundler
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rspec
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 3.3.0
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 3.3.0
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: yard
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: coveralls
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
description: Creates endpoints to integrate to callbacks from AppDirect marketplace
|
140
|
+
to enable to sell subscriptions.
|
141
|
+
email:
|
142
|
+
- artem.golubev@appdirect.com
|
143
|
+
executables:
|
144
|
+
- console
|
145
|
+
- rails
|
146
|
+
- setup
|
147
|
+
extensions: []
|
148
|
+
extra_rdoc_files: []
|
149
|
+
files:
|
150
|
+
- ".gitignore"
|
151
|
+
- ".rspec"
|
152
|
+
- ".travis.yml"
|
153
|
+
- CHANGELOG.md
|
154
|
+
- Gemfile
|
155
|
+
- LICENSE.txt
|
156
|
+
- README.md
|
157
|
+
- Rakefile
|
158
|
+
- app/assets/images/appdirect_integration/.keep
|
159
|
+
- app/assets/javascripts/appdirect_integration/application.js
|
160
|
+
- app/assets/stylesheets/appdirect_integration/application.css
|
161
|
+
- app/controllers/appdirect_integration/appdirect_callbacks_controller.rb
|
162
|
+
- app/controllers/appdirect_integration/application_controller.rb
|
163
|
+
- app/helpers/appdirect_integration/application_helper.rb
|
164
|
+
- app/views/layouts/appdirect_integration/application.html.erb
|
165
|
+
- appdirect_integration.gemspec
|
166
|
+
- bin/console
|
167
|
+
- bin/rails
|
168
|
+
- bin/setup
|
169
|
+
- config/routes.rb
|
170
|
+
- lib/appdirect_integration.rb
|
171
|
+
- lib/appdirect_integration/configuration.rb
|
172
|
+
- lib/appdirect_integration/engine.rb
|
173
|
+
- lib/appdirect_integration/fields.rb
|
174
|
+
- lib/appdirect_integration/util.rb
|
175
|
+
- lib/appdirect_integration/version.rb
|
176
|
+
- lib/generators/active_record/appdirect_integration_generator.rb
|
177
|
+
- lib/generators/active_record/templates/migration.rb
|
178
|
+
- lib/generators/active_record/templates/migration_existing.rb
|
179
|
+
- lib/generators/appdirect_integration/USAGE
|
180
|
+
- lib/generators/appdirect_integration/appdirect_integration_generator.rb
|
181
|
+
- lib/generators/appdirect_integration/install_generator.rb
|
182
|
+
- lib/generators/appdirect_integration/orm_helpers.rb
|
183
|
+
- lib/generators/appdirect_integration/templates/README
|
184
|
+
- lib/generators/appdirect_integration/templates/appdirect.rb
|
185
|
+
- lib/generators/mongoid/appdirect_integration_generator.rb
|
186
|
+
homepage: https://github.com/artgo/appdirect_integration
|
187
|
+
licenses:
|
188
|
+
- MIT
|
189
|
+
metadata: {}
|
190
|
+
post_install_message:
|
191
|
+
rdoc_options: []
|
192
|
+
require_paths:
|
193
|
+
- lib
|
194
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
195
|
+
requirements:
|
196
|
+
- - ">="
|
197
|
+
- !ruby/object:Gem::Version
|
198
|
+
version: '0'
|
199
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
200
|
+
requirements:
|
201
|
+
- - ">="
|
202
|
+
- !ruby/object:Gem::Version
|
203
|
+
version: '0'
|
204
|
+
requirements: []
|
205
|
+
rubyforge_project:
|
206
|
+
rubygems_version: 2.4.8
|
207
|
+
signing_key:
|
208
|
+
specification_version: 4
|
209
|
+
summary: Integration to AppDirect marketplace.
|
210
|
+
test_files: []
|
211
|
+
has_rdoc:
|