app_manager 0.1.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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