disco_app 0.13.6 → 0.13.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/models/disco_app/concerns/can_be_liquified.rb +5 -4
- data/app/services/disco_app/partner_app_service.rb +139 -0
- data/lib/disco_app/version.rb +1 -1
- data/lib/generators/disco_app/disco_app_generator.rb +15 -13
- data/lib/tasks/partner_app.rake +26 -0
- data/test/fixtures/liquid/model.liquid +8 -8
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5983b34e8629a83463ee62e1f91048a02c2e3828d15e4fe25bc692d82ea91ea4
|
4
|
+
data.tar.gz: 96b93719faed53ed578a03a7fc7c0352bae2fac7d79051708e8910863c8f10e8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 51ebc9ca906a78457968f99343b2c4baa2ead374ed8534cdbeeef2a25af93b9559a0d556a658697d3c40e960d1671df1f09506888026e2d003cb0aef57b5b846
|
7
|
+
data.tar.gz: ded7d2a2698176ec21f44fbd77def3e147c26ae1220301368ae4140122b1674a3a9a8ba51ae962424e3bec020a3d1019dad89d9dc662f5fb148928e102514cab
|
@@ -5,14 +5,15 @@ module DiscoApp::Concerns::CanBeLiquified
|
|
5
5
|
|
6
6
|
included do
|
7
7
|
|
8
|
-
# Return this model as
|
8
|
+
# Return this model as a hash for use with `to_liquid`. Returns `as_json` by default but is provided here as a hook
|
9
|
+
# for potential overrides.
|
9
10
|
def as_liquid
|
10
|
-
as_json
|
11
|
+
as_json
|
11
12
|
end
|
12
13
|
|
13
|
-
# Render this model as a series of concatenated Liquid {
|
14
|
+
# Render this model as a series of concatenated Liquid {%- assign -%} statements.
|
14
15
|
def to_liquid
|
15
|
-
as_liquid.join("\n")
|
16
|
+
as_liquid.map { |k, v| "{%- assign #{liquid_model_name}_#{k} = #{as_liquid_value(k, v)} -%}" }.join("\n")
|
16
17
|
end
|
17
18
|
|
18
19
|
# Method to allow override of the model name in Liquid. Useful for models
|
@@ -0,0 +1,139 @@
|
|
1
|
+
module DiscoApp
|
2
|
+
class PartnerAppService
|
3
|
+
|
4
|
+
def initialize(params)
|
5
|
+
@email = params[:email]
|
6
|
+
@password = params[:password]
|
7
|
+
@app_name = params[:app_name]
|
8
|
+
@app_url = params[:app_url]
|
9
|
+
@organization = params[:organization]
|
10
|
+
|
11
|
+
@agent = Mechanize.new do |a|
|
12
|
+
a.user_agent_alias = 'Mac Safari'
|
13
|
+
a.follow_meta_refresh = true
|
14
|
+
a.keep_alive = false
|
15
|
+
a.pre_connect_hooks << lambda do |_agent, request|
|
16
|
+
request['Accept'] = 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def generate_partner_app
|
22
|
+
begin
|
23
|
+
# Login to Shopify Partners
|
24
|
+
login
|
25
|
+
# Access Partner dashboard
|
26
|
+
org_link = organizations
|
27
|
+
dashboard = dashboard_page(org_link)
|
28
|
+
# Create App
|
29
|
+
apps_page = refresh_page(dashboard)
|
30
|
+
create_partner_app(apps_page)
|
31
|
+
# Configure newly created app with embedded app use
|
32
|
+
apps_page = refresh_page(dashboard)
|
33
|
+
embedded_admin_app(apps_page)
|
34
|
+
# Fetch API credentials
|
35
|
+
apps_page = refresh_page(dashboard)
|
36
|
+
api_key, secret = api_credentials(apps_page)
|
37
|
+
rescue Mechanize::Error => e
|
38
|
+
puts 'Error while trying to create partner app'
|
39
|
+
puts "Error #{e}, message : #{e.message}"
|
40
|
+
return
|
41
|
+
end
|
42
|
+
# Add them to .env.local file
|
43
|
+
append_credentials(api_key, secret)
|
44
|
+
puts '#' * 80
|
45
|
+
puts 'New Partner App successfully created!'
|
46
|
+
puts 'API Credentials have been pasted to your .env.local file'
|
47
|
+
puts '#' * 80
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def login
|
53
|
+
@agent.get('https://accounts.shopify.com/login') do |page|
|
54
|
+
page.form do |form|
|
55
|
+
form['account[email]'] = @email
|
56
|
+
form['account[password]'] = @password
|
57
|
+
end.submit
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def organizations
|
62
|
+
organizations = @agent.get('https://partners.shopify.com/organizations/')
|
63
|
+
organizations.links.select { |link| link.text[/#{@organization}/] }.first.href
|
64
|
+
end
|
65
|
+
|
66
|
+
def dashboard_page(org_link)
|
67
|
+
@agent.get('https://partners.shopify.com' + org_link)
|
68
|
+
end
|
69
|
+
|
70
|
+
def create_partner_app(apps_page)
|
71
|
+
apps_page.form do |form|
|
72
|
+
# App name
|
73
|
+
form['create_form[title]'] = @app_name
|
74
|
+
|
75
|
+
# App URL
|
76
|
+
form['create_form[application_url]'] = @app_url
|
77
|
+
|
78
|
+
# Accept TOS
|
79
|
+
unless form['create_form[accepted]'].blank?
|
80
|
+
form['create_form[accepted]'] = '1'
|
81
|
+
form.hiddens.last.value = 1
|
82
|
+
end
|
83
|
+
end.submit
|
84
|
+
end
|
85
|
+
|
86
|
+
def api_credentials(apps_page)
|
87
|
+
app = apps_page.link_with(text: @app_name).click
|
88
|
+
app_info = app.link_with(text: 'App info').click
|
89
|
+
add_whitelist_url(app_info)
|
90
|
+
api_key = app_info.search('#api_key').first.values[3]
|
91
|
+
secret = app_info.search('#settings_form_secrets').first.values[3]
|
92
|
+
[api_key, secret]
|
93
|
+
end
|
94
|
+
|
95
|
+
def embedded_admin_app(apps_page)
|
96
|
+
app = apps_page.link_with(text: @app_name).click
|
97
|
+
extensions = app.link_with(text: 'Extensions').click
|
98
|
+
extensions.form do |form|
|
99
|
+
form['extensions_form[embedded]'] = '1'
|
100
|
+
end.submit
|
101
|
+
end
|
102
|
+
|
103
|
+
# Write credentials of newly created app to .env.local file
|
104
|
+
def append_credentials(api_key, secret)
|
105
|
+
original_file = '.env.local'
|
106
|
+
new_file = original_file + '.new'
|
107
|
+
File.open(new_file, 'w') do |file|
|
108
|
+
File.foreach(original_file) do |line|
|
109
|
+
if line.include?('SHOPIFY_APP_API_KEY')
|
110
|
+
file.puts "SHOPIFY_APP_API_KEY=#{api_key}"
|
111
|
+
elsif line.include?('SHOPIFY_APP_SECRET')
|
112
|
+
file.puts "SHOPIFY_APP_SECRET=#{secret}"
|
113
|
+
else
|
114
|
+
file.puts line
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
File.delete(original_file)
|
119
|
+
File.rename(new_file, original_file)
|
120
|
+
end
|
121
|
+
|
122
|
+
def add_whitelist_url(app_info)
|
123
|
+
app_info.form do |form|
|
124
|
+
form['info_form[redirect_url_whitelist]'] = callback_url
|
125
|
+
end.submit
|
126
|
+
end
|
127
|
+
|
128
|
+
# Access the "Apps" section of the dashboard, also used to reload the dashboard
|
129
|
+
# When an action has been taken
|
130
|
+
def refresh_page(dashboard)
|
131
|
+
dashboard.link_with(text: ' Apps').click
|
132
|
+
end
|
133
|
+
|
134
|
+
def callback_url
|
135
|
+
[@app_url + '/auth/shopify/callback', @app_url + '/auth/shopify_user/callback'].join("\n")
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
end
|
data/lib/disco_app/version.rb
CHANGED
@@ -6,10 +6,11 @@ class DiscoAppGenerator < Rails::Generators::Base
|
|
6
6
|
#
|
7
7
|
# - .env and .env.local for settings environment variables in development with dotenv-rails;
|
8
8
|
# - Slightly customised version of the default Rails .gitignore;
|
9
|
-
# - Default simple Procfile for Heroku
|
9
|
+
# - Default simple Procfile for Heroku;
|
10
|
+
# - .editorconfig to help enforce 2-space tabs, newlines and truncated whitespace for editors that support it.
|
10
11
|
#
|
11
12
|
def copy_root_files
|
12
|
-
%w(.env .env.local .gitignore .rubocop.yml .codeclimate.yml Procfile CHECKS).each do |file|
|
13
|
+
%w(.editorconfig .env .env.local .gitignore .rubocop.yml .codeclimate.yml Procfile CHECKS).each do |file|
|
13
14
|
copy_file "root/#{file}", file
|
14
15
|
end
|
15
16
|
end
|
@@ -27,28 +28,28 @@ class DiscoAppGenerator < Rails::Generators::Base
|
|
27
28
|
gsub_file 'Gemfile', /^# Use sqlite3 as the database for Active Record\ngem 'sqlite3'/m, ''
|
28
29
|
|
29
30
|
# Add gem requirements.
|
30
|
-
gem 'shopify_app'
|
31
|
-
gem 'pg'
|
32
|
-
gem 'sidekiq'
|
33
|
-
gem 'rollbar'
|
34
|
-
gem 'newrelic_rpm'
|
35
|
-
gem 'react-rails'
|
36
|
-
gem 'classnames-rails'
|
37
|
-
gem 'premailer-rails'
|
38
|
-
gem 'rails-bigint-pk'
|
39
|
-
gem 'acts_as_singleton'
|
40
31
|
gem 'active_link_to'
|
32
|
+
gem 'acts_as_singleton'
|
33
|
+
gem 'classnames-rails'
|
34
|
+
gem 'newrelic_rpm'
|
41
35
|
gem 'nokogiri'
|
42
36
|
gem 'oj'
|
37
|
+
gem 'pg'
|
38
|
+
gem 'premailer-rails'
|
39
|
+
gem 'rails-bigint-pk'
|
40
|
+
gem 'react-rails'
|
43
41
|
gem 'render_anywhere'
|
42
|
+
gem 'rollbar'
|
43
|
+
gem 'shopify_app'
|
44
|
+
gem 'sidekiq'
|
44
45
|
|
45
46
|
# Specify the threadsafe version of ActiveResource.
|
46
47
|
gem 'activeresource', git: 'https://github.com/shopify/activeresource.git', tag: '4.2-threadsafe'
|
47
48
|
|
48
49
|
# Indicate which gems should only be used in production.
|
49
50
|
gem_group :production do
|
50
|
-
gem 'rails_12factor'
|
51
51
|
gem 'mailgun_rails'
|
52
|
+
gem 'rails_12factor'
|
52
53
|
end
|
53
54
|
|
54
55
|
# Indicate which gems should only be used in development and test.
|
@@ -56,6 +57,7 @@ class DiscoAppGenerator < Rails::Generators::Base
|
|
56
57
|
gem 'dotenv-rails'
|
57
58
|
gem 'minitest-reporters'
|
58
59
|
gem 'webmock'
|
60
|
+
gem 'mechanize'
|
59
61
|
end
|
60
62
|
end
|
61
63
|
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
namespace :generate do
|
4
|
+
desc 'Generate new Shopify app from partner dashboard'
|
5
|
+
task partner_app: :environment do
|
6
|
+
begin
|
7
|
+
config_path = File.join(ENV['HOME'], '.disco_app.yml')
|
8
|
+
config = YAML.load_file(config_path)
|
9
|
+
rescue StandardError
|
10
|
+
abort("Could not load configuration file from #{config_path}, aborting.")
|
11
|
+
end
|
12
|
+
|
13
|
+
if config
|
14
|
+
params = {
|
15
|
+
email: config['params']['PARTNER_EMAIL'].to_s,
|
16
|
+
password: config['params']['PARTNER_PASSWORD'].to_s,
|
17
|
+
organization: config['params']['PARTNER_ORGANIZATION'].to_s,
|
18
|
+
app_name: ENV['SHOPIFY_APP_NAME'],
|
19
|
+
app_url: ENV['DEFAULT_HOST']
|
20
|
+
}
|
21
|
+
|
22
|
+
service = DiscoApp::PartnerAppService.new(params)
|
23
|
+
service.generate_partner_app
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -1,8 +1,8 @@
|
|
1
|
-
{
|
2
|
-
{
|
3
|
-
{
|
4
|
-
{
|
5
|
-
{
|
6
|
-
{
|
7
|
-
{
|
8
|
-
{
|
1
|
+
{%- assign model_numeric = 42 -%}
|
2
|
+
{%- assign model_boolean = true -%}
|
3
|
+
{%- assign model_empty = nil -%}
|
4
|
+
{%- assign model_string = 'The cat's pyjamas are "great".' -%}
|
5
|
+
{%- assign model_string_html = 'The cat's pyjamas are <strong style="color: red;">great</strong>.' -%}
|
6
|
+
{%- assign model_array_of_numerics = '1@!@2@!@3' | split: '@!@' -%}
|
7
|
+
{%- assign model_array_of_strings = 'A@!@B@!@C' | split: '@!@' -%}
|
8
|
+
{%- assign model_hash = '{}' -%}
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: disco_app
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.13.
|
4
|
+
version: 0.13.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gavin Ballard
|
@@ -605,6 +605,7 @@ files:
|
|
605
605
|
- app/resources/disco_app/admin/resources/shop_resource.rb
|
606
606
|
- app/services/disco_app/carrier_request_service.rb
|
607
607
|
- app/services/disco_app/charges_service.rb
|
608
|
+
- app/services/disco_app/partner_app_service.rb
|
608
609
|
- app/services/disco_app/proxy_service.rb
|
609
610
|
- app/services/disco_app/request_validation_service.rb
|
610
611
|
- app/services/disco_app/subscription_service.rb
|
@@ -673,6 +674,7 @@ files:
|
|
673
674
|
- lib/tasks/api.rake
|
674
675
|
- lib/tasks/carrier_service.rake
|
675
676
|
- lib/tasks/database.rake
|
677
|
+
- lib/tasks/partner_app.rake
|
676
678
|
- lib/tasks/sessions.rake
|
677
679
|
- lib/tasks/shops.rake
|
678
680
|
- lib/tasks/start.rake
|