app_manager 0.1.2 → 1.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a9e83adb4c7828d26d8c6479837f58ea9e168726669c7a1d68f21e717a7802a4
4
- data.tar.gz: 2d8f6811b2c09d80d268289b7e1b745583d1cec54b7bd7e9384544d3fa516caf
3
+ metadata.gz: 5d1ca5e305b62425f916bcb20e5677a2bc0be1e4b16f2d68879dcce443da5ffe
4
+ data.tar.gz: 1d174e5fbd19029a498c539ae908089dfcab7dea8b4d2f43d8e3bf48b9b354ca
5
5
  SHA512:
6
- metadata.gz: fdf9b28f822093de96a8dd4f4324e1dd10c543a6667f9b76cc959ebe3ca2e65736b37388db7c400f3b08b441637c97ec39497001e32e597e073f85545319491b
7
- data.tar.gz: 44d81124d5e88947f08648381705a309d86b8f789c450760c2f589ae585f63ac4dd02aaf9e640eafd585acfe8bc74ca59d8a6c86df346ead925de06854736df4
6
+ metadata.gz: 1b846e8b38a8fcb8301715c137f23e875828195c9b73bca8e1bbb814cf66fee9565690a296465757955d267fc290f574ba3434a63449657444c52144e0ad7c31
7
+ data.tar.gz: 00cdb184943ace69f37c5e166950791e193c67e071a88692a7b81d45de79a5d648ee2c70887c5f3cc1eea1d2ec5df82a7632aa9ae241c7f518c7f8ef52f31abe
data/Gemfile.lock CHANGED
@@ -1,9 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- app_manager (0.1.2)
4
+ app_manager (1.0.0)
5
5
  httparty
6
+ kaminari (>= 0.16.3)
6
7
  rails (>= 5.2.0)
8
+ sqlite3 (~> 1.3.0)
7
9
 
8
10
  GEM
9
11
  remote: https://rubygems.org/
@@ -94,6 +96,18 @@ GEM
94
96
  i18n (1.10.0)
95
97
  concurrent-ruby (~> 1.0)
96
98
  io-wait (0.2.1)
99
+ kaminari (1.2.2)
100
+ activesupport (>= 4.1.0)
101
+ kaminari-actionview (= 1.2.2)
102
+ kaminari-activerecord (= 1.2.2)
103
+ kaminari-core (= 1.2.2)
104
+ kaminari-actionview (1.2.2)
105
+ actionview
106
+ kaminari-core (= 1.2.2)
107
+ kaminari-activerecord (1.2.2)
108
+ activerecord
109
+ kaminari-core (= 1.2.2)
110
+ kaminari-core (1.2.2)
97
111
  loofah (2.15.0)
98
112
  crass (~> 1.0.2)
99
113
  nokogiri (>= 1.5.9)
@@ -178,6 +192,7 @@ GEM
178
192
  diff-lcs (>= 1.2.0, < 2.0)
179
193
  rspec-support (~> 3.11.0)
180
194
  rspec-support (3.11.0)
195
+ sqlite3 (1.3.13)
181
196
  strscan (3.0.1)
182
197
  thor (1.2.1)
183
198
  timeout (0.2.0)
data/README.md CHANGED
@@ -18,17 +18,126 @@ Step 2) Execute following in terminal:
18
18
  rails g app_manager:install
19
19
 
20
20
 
21
- this install command will mount routes in your rails route.
21
+ this install command will mount routes in your rails route and will create a config file at ```config/initializers/app_manager.rb```
22
22
 
23
+ ```
24
+ AppManager.configure do |config|
25
+ config.enable_caching = false # Optional, True to enable app-manager api response caching, default is enabled from gem
26
+ config.expires_in = 1.days # Optional, Example: 30.seconds, 5.minutes or 2.days Default caching is for 1.days from gem
27
+ config.app_url = '' # App URL like https://volumediscount.hulkapps.dev/ or #https://5044-2409-4052-209a-69da-9d7-925a-9418-a9c3.ngrok.io
28
+ config.shopify_api_key = '' # Shopify api key of app
29
+ config.shopify_api_version = '' # Must be 2022-04 or latest
30
+ config.shopify_table_name = 'shops' # Table name which is generated by shopify mostly it is 'shops'
31
+ config.shopify_domain_field = 'shopify_domain' #shopify domain field
32
+ config.plan_id_or_name_field = 'plan_id'
33
+ config.field_names = {
34
+ 'name' => 'shopify_domain', # demo-rahul-tiwari.myshopify.com
35
+ 'shopify_email' => 'email', # rahul.t@hulkapps.com
36
+ 'shopify_token' => 'shopify_token',
37
+ 'shopify_plan' => 'plan_name', # partner_test
38
+ 'plan_id' => 'plan_id', # 1. t
39
+ 'created_at' => 'created_at', # 2022-04-15 10:43:05
40
+ 'trial_activated_at' => 'trial_activated_at' # field name that stores trial start/activated date
41
+ }
42
+ config.plan_features = [
43
+ {
44
+ "uuid" => "b48a3a6c-c1fb-11ec-9d64-0242ac120002",
45
+ "name" => "Features 1",
46
+ "slug" => "feature-1",
47
+ "description" => "Feature Description",
48
+ "value_type" => "integer",
49
+ "format" => "count",
50
+ "display_order" => 1
51
+ },
52
+ {
53
+ "uuid" => "9f18f95a-bfaf-11ec-9d64-0242ac120002",
54
+ "name" => "Features 2",
55
+ "slug" => "feature-2",
56
+ "description" => "Feature Description",
57
+ "value_type" => "boolean",
58
+ "format" => "percentage",
59
+ "display_order" => 2
60
+ },
61
+ {
62
+ "uuid" => "9f190a26-bfaf-11ec-9d64-0242ac120002",
63
+ "name" => "Features 3",
64
+ "slug" => "feature-3",
65
+ "description" => "Feature Description",
66
+ "value_type" => "string",
67
+ "format" => "string",
68
+ "display_order" => 3
69
+ },
70
+ {
71
+ "uuid" => "9f191340-bfaf-11ec-9d64-0242ac12000",
72
+ "name" => "Features 4",
73
+ "slug" => "feature-4",
74
+ "description" => "Feature Description",
75
+ "value_type" => "array",
76
+ "values" => [
77
+ "val 1",
78
+ "val 2"
79
+ ],
80
+ "format" => "string",
81
+ "display_order" => 4
82
+ }
83
+ ] #Required, Values type : integer, boolean, string, array
84
+ end
85
+ ```
86
+
87
+
88
+ Please note: Your shops table must have 'plan_id' as int/bigint and 'trial_activated_at' as datetime otherwise add its migration. Sample example:
89
+ ```
90
+ class AddPlanIdToShops < ActiveRecord::Migration[5.2]
91
+ def change
92
+ add_column :shops, :plan_id, :bigint
93
+ add_column :shops, :trial_activated_at, :datetime
94
+ end
95
+ end
96
+ ```
97
+
98
+ and map these new fields in 'config.field_names' in above initializer file.
23
99
 
24
100
  Step 3) You must have to set ENV variable with key 'APP_MANAGER_ACCESS_TOKEN' in your application.yml or .env file like this:
25
101
 
26
102
  APP_MANAGER_ACCESS_TOKEN: 'XXXXXXXXXXXXXXXXXXX'
27
103
  APP_MANAGER_API_URL: 'https://XXXXXXXX.com'
28
104
 
105
+ Steps 4) App Manager provides a rake task that must needs to include in your existing app cron for every 10 minutes. Like if you are using [whenever](https://github.com/javan/whenever) gem then you must need to include following rake take in your 'schedule.rb' (created by whenever gem)
106
+
107
+ ```
108
+ every 10.minutes do
109
+ rake 'sync:local_app_manager'
110
+ end
111
+ ```
112
+
113
+ Steps 5) App Manager provides a helper module which needs to include in your 'shop' model something like below
114
+
115
+ ```
116
+ class Shop < ActiveRecord::Base
117
+ include AppManager::Model
118
+ end
119
+ ```
120
+
29
121
 
30
122
  ## Usage
31
123
 
124
+ Using above 5th step you can access following methods from your shop object.
125
+
126
+ ```
127
+ @shop.has_plan # return true or false
128
+
129
+ @shop.plan_features # return array of plan features of your shop's plan
130
+
131
+ @shop.has_feature('feature-1') # provide slug of feature which you set in your 'config.plan_features' in config/initializers/app_manager.rb
132
+ #return true/false
133
+
134
+ @shop.get_feature('feature-3') # provide slug of feature and this returns value of feature which is set in portal.
135
+
136
+ @shop.get_remaining_days # return integer based on trial activated date.
137
+ ```
138
+
139
+
140
+
32
141
  #### As a helper:
33
142
 
34
143
 
@@ -1,5 +1,12 @@
1
1
  module AppManager
2
2
  class ApplicationController < ActionController::Base
3
+ include AppManager::Actions
4
+ cache_response_of_app_manager
3
5
  protect_from_forgery with: :exception
6
+ include AppManager::Authenticate
7
+ # rescue_from StandardError do |exception|
8
+ # render json: { :error => exception.message }, :status => 500
9
+ # end
10
+
4
11
  end
5
12
  end
@@ -3,8 +3,13 @@ require_dependency "app_manager/application_controller"
3
3
  module AppManager
4
4
  class BannersController < ApplicationController
5
5
  def marketing_banner
6
- banner_obj = AppManager::Client.new
7
- render json: banner_obj.get_banners
6
+ begin
7
+ banner_obj = AppManager::Client.new
8
+ render json: banner_obj.get_banners
9
+ rescue Exception => e
10
+ @fs = AppManager::FailSafe.new
11
+ render json: @fs.get_local_app_structures
12
+ end
8
13
  end
9
14
  end
10
15
  end
@@ -0,0 +1,122 @@
1
+ require_dependency "app_manager/application_controller"
2
+
3
+ module AppManager
4
+ class ChargesController < ApplicationController
5
+ include HTTParty
6
+ skip_before_action :verify_authenticity_token, :only => [:process_plan]
7
+ before_action :params_permit
8
+ require 'time'
9
+ require 'rack'
10
+
11
+ def process_plan
12
+ if params[:shop].present? && params[:plan_id].present?
13
+ @shop = shop_data
14
+ if !@shop.nil?
15
+ plan_obj = AppManager::Client.new
16
+ plan_data = plan_obj.get_plan(params[:plan_id],params[:shop])
17
+ if plan_data.present? && plan_data.is_a?(Hash)
18
+ request_data = {'shop' => @shop.shopify_domain, 'timestamp' => Time.now.to_i, 'plan' => params[:plan_id]}
19
+ return_url = "#{app_url}#{plan_callback_path}?#{Rack::Utils.build_query(request_data)}"
20
+ gq_obj = AppManager::GraphqlHelper.new(@shop.shopify_domain,@shop.shopify_token)
21
+ data = gq_obj.recurring_charge_api_call(plan_data,return_url,@shop)
22
+ if !data["errors"].present? && (data["data"].present? && data["data"]["appSubscriptionCreate"].present? && ( !data["data"]["appSubscriptionCreate"]["userErrors"].any? && data["data"]["appSubscriptionCreate"]["confirmationUrl"]))
23
+ redirect_charge = data["data"]["appSubscriptionCreate"]["confirmationUrl"]
24
+ render json: {'redirect_url' => redirect_charge}
25
+ else
26
+ render json: {'error' => data["errors"].as_json}
27
+ end
28
+ else
29
+ render json: {'error' => data["errors"]}
30
+ end
31
+ else
32
+ render json: {'error' => 'Shop not found'}
33
+ end
34
+ else
35
+ render json: {'error' => 'Missing Shop domain or plan id in params'}
36
+ end
37
+ end
38
+
39
+
40
+ def callback
41
+ if params[:charge_id].present? && params[:shop].present? && params[:plan].present?
42
+ @shop = shop_data
43
+ shopify_token = @field_names['shopify_token']
44
+ shopify_domain = @field_names['name']
45
+ if !@shop.nil?
46
+ headers = {"X-Shopify-Access-Token" => @shop[shopify_token]}
47
+ charges = HTTParty.get('https://'+@shop[shopify_domain]+'/admin/api/'+@api_version+'/recurring_application_charges/'+params[:charge_id]+'.json', :headers => headers)
48
+
49
+ if charges.parsed_response && charges.parsed_response.is_a?(Hash) && charges.parsed_response.has_key?('recurring_application_charge')
50
+
51
+ plan_obj = AppManager::Client.new
52
+ plan_data = plan_obj.get_plan(params[:plan],params[:shop])
53
+
54
+ charge = charges.parsed_response['recurring_application_charge']
55
+ charge['charge_id'] = charge['id'];
56
+ charge['type'] = 'recurring';
57
+ charge['plan_id'] = params[:plan];
58
+ charge['shop_domain'] = params[:shop];
59
+ charge['interval'] = plan_data['interval']['value'];
60
+
61
+ if !@plan_field.nil?
62
+ begin
63
+ plan_obj.cancel_charge(@shop[shopify_domain],@shop[@plan_field])
64
+ rescue Exception => e
65
+
66
+ end
67
+ end
68
+ charge_ob = AppManager::Client.new(nil,json_req=true)
69
+ response = charge_ob.store_charge(charge.to_json)
70
+
71
+ if response['message'] == "success"
72
+ model.update(@plan_field => params[:plan])
73
+ end
74
+ redirect_to "/?shop=#{params[:shop]}"
75
+ else
76
+
77
+ render json: {'error' => 'Invalid shopify charge'}
78
+ end
79
+ else
80
+ render json: {'error' => 'Shop not found'}
81
+ end
82
+ else
83
+ render json: {'error' => 'Invalid params'}
84
+ end
85
+ end
86
+
87
+ private
88
+
89
+ def params_permit
90
+ params.permit!
91
+ end
92
+
93
+ def model
94
+ @models = ActiveRecord::Base.connection.tables
95
+ @config_table = AppManager.configuration.shopify_table_name
96
+ @shopify_domain = AppManager.configuration.shopify_domain_field
97
+ @plan_field = AppManager.configuration.plan_id_or_name_field
98
+ @field_names = AppManager.configuration.field_names
99
+ @api_version = AppManager.configuration.shopify_api_version
100
+ if @models.include?(@config_table) && !@plan_field.nil?
101
+ return @config_table.classify.constantize
102
+ else
103
+ return nil
104
+ end
105
+ end
106
+
107
+ def shop_data
108
+ if model
109
+ return model.where(@shopify_domain => params[:shop]).first rescue nil
110
+ else
111
+ return nil
112
+ end
113
+ end
114
+
115
+ def app_url
116
+ AppManager.configuration.app_url
117
+ end
118
+
119
+
120
+
121
+ end
122
+ end
@@ -0,0 +1,157 @@
1
+ require_dependency "app_manager/application_controller"
2
+
3
+ module AppManager
4
+ class PlansController < ApplicationController
5
+ skip_before_action :verify_authenticity_token, :only => [:active_without_plan,:burst_cache,:fail_safe_backup]
6
+ def index
7
+ render :json => {"features" => AppManager.configuration.plan_features || []}
8
+ end
9
+
10
+
11
+ def plans
12
+ active_plan_id_or_name = shopify_plan = plan = nil
13
+ default_plan_id = nil
14
+ plan_obj = AppManager::Client.new
15
+ plans = plan_obj.get_plans
16
+ if params[:shop_domain].present? && !AppManager.configuration.plan_features.nil?
17
+ @shop = shop_data
18
+ if !@shop.nil?
19
+ active_plan_id_or_name = @shop[@plan_field]
20
+ if !@field_names.nil? && @field_names.has_key?('shopify_plan') && !@field_names.nil?
21
+ shopify_plan_field = AppManager.configuration.field_names['shopify_plan']
22
+ shopify_plan = @shop[shopify_plan_field] rescue nil
23
+ plan = plans.any? && !active_plan_id_or_name.nil? ? (plans.find{|x| x["id"] == active_plan_id_or_name}.present? ? plans.find{|x| x["id"] == active_plan_id_or_name} : nil ) : nil
24
+ end
25
+ else
26
+ Rails.logger.info "APP MANGAGER >>>> Either model is defined wrong or config.plan_id_or_name_field is nil in initializer ==="
27
+ end
28
+ else
29
+ Rails.logger.info "APP MANGAGER >>>> Either params missing store_domain or config.plan_features is nil in initializer ==="
30
+ end
31
+
32
+
33
+ default_plan_id = 0;
34
+ default_plan_data = plans.select{|x| x['interval'] == 'EVERY_30_DAYS' }.sort_by { |k| -k["price"] }
35
+ store_base_plan = default_plan_data.map{|e| e['store_base_plan']}.first rescue false
36
+
37
+ if store_base_plan
38
+ begin
39
+ shopify_plans = default_plan_data.map { |e| e.map { |key, value| [e['shopify_plans'], e['id']] }.to_h }
40
+ shopify_plans.each do |shp|
41
+ if shp.keys && shp.keys.first && shp.keys.first.class == Array
42
+ if shp.keys.first.include?(shopify_plan) && shp.values && shp.values.first && shp.values.first.to_i > 0
43
+ default_plan_id = shp.values.first.to_i
44
+ break
45
+ end
46
+ end
47
+ end
48
+ rescue Exception => e
49
+ Rails.logger.info "APP MANGAGER >>>> ERROR #{e.inspect}"
50
+ end
51
+ else
52
+ default_plan_id = default_plan_data.map{|e| e['id']}.first if default_plan_data.any? rescue nil
53
+ end
54
+
55
+ response = {
56
+ 'plans' => plan_obj.get_plans,
57
+ 'shopify_plan' => shopify_plan,
58
+ 'plan' => plan,
59
+ 'default_plan_id' => default_plan_id
60
+ }
61
+ render json: response
62
+ end
63
+
64
+ def users
65
+ if model
66
+ data = model.page(params[:page]).per(10)
67
+ users = {
68
+ "current_page" => data.current_page,
69
+ "data" => data.collect{|st| @field_names.map{ |key, value| [key, "#{st[value]}"] }.to_h },
70
+ "first_page_url" => "#{app_url}/api/app-manager/users?page=1",
71
+ "from" => data.total_pages ? 1 : nil,
72
+ "last_page" => data.total_pages,
73
+ "last_page_url" => data.total_pages ? "#{app_url}/api/app-manager/users?page=#{data.total_pages}" : nil,
74
+ "links"=> '',
75
+ "next_page_url" => data.next_page ? "#{app_url}/api/app-manager/users?page=#{data.next_page}" : nil,
76
+ "path" => "#{app_url}/api/app-manager/users",
77
+ "per_page" => 1,
78
+ "prev_page_url" => data.prev_page ? "#{app_url}/api/app-manager/users?page=#{data.prev_page}" : nil,
79
+ "to" => data.total_pages,
80
+ "total" => data.total_pages
81
+ }
82
+ render json: users
83
+
84
+ else
85
+ render json: nil
86
+ end
87
+ end
88
+
89
+ def active_without_plan
90
+ if params[:shop_domain].present? && params[:plan_id].present? && model
91
+ @trial_activated_field = AppManager.configuration.field_names['trial_activated_at']
92
+ model.update(@plan_field => params[:plan_id],@trial_activated_field => DateTime.now)
93
+ render json: {'status' => true}
94
+ else
95
+ render json: {'status' => false,'error' => 'Shop not found or missing shop'}, status: 422
96
+ end
97
+ end
98
+
99
+
100
+ def burst_cache
101
+ AppManager.clear_cache
102
+ head :ok
103
+ end
104
+
105
+
106
+ def fail_safe_backup
107
+ params_permit
108
+ @fs = AppManager::FailSafe.new
109
+ begin
110
+ @fs.sync_app_manager
111
+ rescue Exception => e
112
+ Rails.logger.info "APP MANGAGER >>>> LOCAL DB couldn't sync with POTAL DB #{e.inspect}"
113
+ end
114
+
115
+ begin
116
+ @fs.save_api_data(params)
117
+ rescue Exception => e
118
+ Rails.logger.info "APP MANGAGER >>>> #{e.inspect}"
119
+ end
120
+ head :ok
121
+ end
122
+
123
+
124
+ private
125
+
126
+ def params_permit
127
+ params.permit!
128
+ end
129
+
130
+ def model
131
+ @models = ActiveRecord::Base.connection.tables
132
+ @config_table = AppManager.configuration.shopify_table_name
133
+ @shopify_domain = AppManager.configuration.shopify_domain_field
134
+ @plan_field = AppManager.configuration.plan_id_or_name_field
135
+ @field_names = AppManager.configuration.field_names
136
+ @api_version = AppManager.configuration.shopify_api_version
137
+ if @models.include?(@config_table) && !@plan_field.nil?
138
+ return @config_table.classify.constantize
139
+ else
140
+ return nil
141
+ end
142
+ end
143
+
144
+ def shop_data
145
+ if model
146
+ return model.where(@shopify_domain => params[:shop_domain]).first rescue nil
147
+ else
148
+ return nil
149
+ end
150
+ end
151
+
152
+ def app_url
153
+ AppManager.configuration.app_url
154
+ end
155
+
156
+ end
157
+ end
@@ -0,0 +1,10 @@
1
+ module AppManager
2
+ module Authenticate
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ include AppManager::Protection
7
+ before_action :authorize_request, :only => [:users]
8
+ end
9
+ end
10
+ end
data/app_manager.gemspec CHANGED
@@ -32,8 +32,8 @@ Gem::Specification.new do |spec|
32
32
  # spec.add_dependency "example-gem", "~> 1.0"
33
33
  spec.add_dependency "httparty"
34
34
  spec.add_dependency "rails", '>= 5.2.0'
35
-
36
-
35
+ spec.add_dependency "kaminari", '>= 0.16.3'
36
+ spec.add_dependency "sqlite3", '~> 1.3.0'
37
37
  # For more information and examples about making a new gem, checkout our
38
38
  # guide at: https://bundler.io/guides/creating_gem.html
39
39
  end
data/config/routes.rb CHANGED
@@ -1,5 +1,18 @@
1
1
  AppManager::Engine.routes.draw do
2
2
  scope 'api/app-manager' do
3
3
  get 'marketing-banners' => 'banners#marketing_banner'
4
+
5
+ get 'plan-features' => 'plans#index'
6
+ get 'plans' => 'plans#plans'
7
+ get 'users' => 'plans#users'
8
+ post 'active-without-plan' => 'plans#active_without_plan'
9
+ post 'burst-cache' => 'plans#burst_cache'
10
+ post 'fail-safe-backup' => 'plans#fail_safe_backup'
11
+ get 'plan/process/:plan_id' => 'charges#process_plan'
12
+ get 'plan/callback' => 'charges#callback', as: :plan_callback
13
+
14
+ scope 'app-manager-api' do
15
+ post 'store-charge' => 'plans#store_charge'
16
+ end
4
17
  end
5
- end
18
+ end
@@ -0,0 +1,10 @@
1
+ module AppManager
2
+ module Actions
3
+ extend ActiveSupport::Concern
4
+ module ClassMethods
5
+ def cache_response_of_app_manager
6
+ around_action ApiCacheHandler.new
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,67 @@
1
+ module AppManager
2
+ module Actions
3
+ class ApiCacheHandler
4
+ def initialize
5
+
6
+ end
7
+
8
+
9
+ def around(controller)
10
+ init(controller)
11
+ if should_response_cache?
12
+ log_info
13
+ render_cached_response
14
+ else
15
+ yield
16
+ @response_cache.write_cache(controller.response) if @request.get?
17
+ end
18
+ end
19
+
20
+ protected
21
+
22
+ def should_response_cache?
23
+ return @request.get? && @response_cache.cached_response.present?
24
+ end
25
+
26
+ def log_info
27
+ # processor = "#{@controller.class.name}##{@controller.action_name}".blue
28
+ # responder = Rainbow('API Response Cache').green
29
+ Rails.logger.info "=== #{@controller.class.name}##{@controller.action_name} response by App Manager Response Cache ==="
30
+ end
31
+
32
+ def init(controller)
33
+ @controller = controller
34
+ @request = controller.request
35
+ @response_cache = ResponseCache.new(cache_path)
36
+ end
37
+
38
+ def cache_path
39
+ @cache_path = "app-manager-cache"
40
+
41
+ path_only = @request.fullpath.split('?').first
42
+ @cache_path = "#{@cache_path}#{path_only}"
43
+
44
+ if AppManager.configuration.cache_by_headers.present?
45
+ headers = AppManager.configuration.cache_by_headers.map do |header|
46
+ @request.headers[header].to_s
47
+ end
48
+ headers_cache_path = headers.join('-')
49
+ @cache_path = "#{@cache_path}/#{headers_cache_path}"
50
+ end
51
+
52
+ @cache_path
53
+ end
54
+
55
+ def render_cached_response
56
+ body = @response_cache.body
57
+ status = @response_cache.status
58
+ headers = @response_cache.headers
59
+ headers.try(:each) do |key, value|
60
+ @controller.response.headers[key] = value
61
+ end
62
+ @controller.render plain: body, status: status
63
+ end
64
+ end
65
+ end
66
+ end
67
+
@@ -2,7 +2,7 @@ module AppManager
2
2
  class Client
3
3
  module Banners
4
4
 
5
- def get_banners(options = {})
5
+ def get_banners(options = {})
6
6
  get("/static-contents", options)
7
7
  end
8
8
 
@@ -24,9 +24,19 @@ module AppManager
24
24
 
25
25
  def request(http_method, path, options)
26
26
  response = self.class.send(http_method, path, { body: options })
27
- return nil unless response
28
- data = response.parsed_response
29
- data = parse_data(response.parsed_response)
27
+ if path.include? "/get-status"
28
+ data = response
29
+ elsif path.include? "/sync-charge"
30
+ data = response.parsed_response
31
+ data = parse_data(response.parsed_response)
32
+ else
33
+ if response.code.to_s.start_with?('2') or response.code.to_s.start_with?('4')
34
+ data = response.parsed_response
35
+ data = parse_data(response.parsed_response)
36
+ else
37
+ data = response_from_failsafe(path,options)
38
+ end
39
+ end
30
40
  end
31
41
 
32
42
  def parse_data(original_data)
@@ -36,7 +46,31 @@ module AppManager
36
46
  else
37
47
  return original_data
38
48
  end
49
+ end
39
50
 
51
+ def response_from_failsafe(path,options)
52
+ params = Rack::Utils.parse_query URI(path).query
53
+ path = path.delete_prefix('/')
54
+ path = path[/[^?]+/]
55
+ @fs = AppManager::FailSafe.new
56
+ case path
57
+ when "static-contents"
58
+ return @fs.get_local_app_structures
59
+ when 'plans'
60
+ return @fs.get_local_plans
61
+ when 'plan'
62
+ return @fs.get_local_plan(params)
63
+ when 'store-charge'
64
+ return @fs.store_local_charge(params,options)
65
+ when 'cancel-charge'
66
+ return @fs.store_cancel_charge(params,options)
67
+ when 'get-remaining-days'
68
+ return @fs.get_local_remaining_days(params,options)
69
+ when 'get-charge'
70
+ return @fs.get_local_charge(params,options)
71
+ else
72
+ return nil
73
+ end
40
74
  end
41
75
 
42
76
  end