app_manager 0.1.1 → 1.0.1

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: 484ae8af849021a80599d2c4fa25c5749df4d57808f9ab4e1b27b67b710c035c
4
- data.tar.gz: 021b9b80f1dbe4b0a2cd1c7a593b8e4c02c4581e6c65338bdbeb96437b6371f6
3
+ metadata.gz: 8e6965769520fe875a92f79820bd1288c4d46166b3527d3a6a4417d65b530510
4
+ data.tar.gz: e84cdb37ae65da5f86e86630b1892ba335939ff46e61309965c7c12a4974c51d
5
5
  SHA512:
6
- metadata.gz: a735b4356e0f8274be9a793a99da997fe1ece0320935f710364b1a0d9800a287ac92e0873323a79881600aa144772609c4679c5d2718d888e303390d0f744b5c
7
- data.tar.gz: 3af524d7cfaa472d5f65dd07e227ad6f96e23225acf007ab5c51ea69ef4b58d82f43d2ee898c8f9839d2678e9ccb5f91c6535bbea3205daf63ec313b723d1661
6
+ metadata.gz: f1241ef8b8d0bc7c754f0df7647d3c2402eef5eddbba89f6360844c73cdff81c79ec962bd6322aa8a265fcff07c8296abad3ea5034032eb5c2799262a2b39ad4
7
+ data.tar.gz: 43097bc92bad6bb5b7cc43c918b869d565f9bbc2c795312ec15933a71494673c00f79378f2c0e1afbc2cacc75020c05141375b4dec6a77518fb6106fb55318fc
@@ -23,15 +23,15 @@ jobs:
23
23
  runs-on: ubuntu-latest
24
24
  strategy:
25
25
  matrix:
26
- ruby-version: ['2.7', '3.0']
26
+ ruby-version: ['2.7']
27
27
 
28
28
  steps:
29
- - uses: actions/checkout@v3
29
+ - uses: actions/checkout@v2
30
30
  - name: Set up Ruby
31
31
  # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
32
32
  # change this to (see https://github.com/ruby/setup-ruby#versioning):
33
- # uses: ruby/setup-ruby@v1
34
- uses: ruby/setup-ruby@359bebbc29cbe6c87da6bc9ea3bc930432750108
33
+ uses: ruby/setup-ruby@v1
34
+ # uses: ruby/setup-ruby@359bebbc29cbe6c87da6bc9ea3bc930432750108
35
35
  with:
36
36
  ruby-version: ${{ matrix.ruby-version }}
37
37
  bundler-cache: true # runs 'bundle install' and caches installed gems automatically
data/Gemfile.lock CHANGED
@@ -1,9 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- app_manager (0.1.1)
4
+ app_manager (1.0.1)
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,22 +18,133 @@ 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
- APP_MANAGER_ACCESS_TOKEN: 'XXXXXXXXXXXXXXXXXXX'
102
+ APP_MANAGER_ACCESS_TOKEN: 'XXXXXXXXXXXXXXXXXXX'
103
+ APP_MANAGER_API_URL: 'https://XXXXXXXX.com'
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
+
27
121
 
28
122
  ## Usage
29
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
+
30
141
  #### As a helper:
31
142
 
32
143
 
33
144
  Then, initialize app_manager instance like with App Manager Portal access:
34
145
 
35
146
  ```ruby
36
- ob = AppManager::Client.new(ENV'APP_MANAGER_ACCESS_TOKEN')
147
+ ob = AppManager::Client.new(ENV['APP_MANAGER_ACCESS_TOKEN'])
37
148
  ```
38
149
 
39
150
  To get banners use this command:
@@ -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,159 @@
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
+ Thread.new do
109
+ @fs = AppManager::FailSafe.new
110
+ begin
111
+ @fs.sync_app_manager
112
+ rescue Exception => e
113
+ Rails.logger.info "APP MANGAGER >>>> LOCAL DB couldn't sync with POTAL DB #{e.inspect}"
114
+ end
115
+
116
+ begin
117
+ @fs.save_api_data(params)
118
+ rescue Exception => e
119
+ Rails.logger.info "APP MANGAGER >>>> #{e.inspect}"
120
+ end
121
+ end
122
+ head :ok
123
+ end
124
+
125
+
126
+ private
127
+
128
+ def params_permit
129
+ params.permit!
130
+ end
131
+
132
+ def model
133
+ @models = ActiveRecord::Base.connection.tables
134
+ @config_table = AppManager.configuration.shopify_table_name
135
+ @shopify_domain = AppManager.configuration.shopify_domain_field
136
+ @plan_field = AppManager.configuration.plan_id_or_name_field
137
+ @field_names = AppManager.configuration.field_names
138
+ @api_version = AppManager.configuration.shopify_api_version
139
+ if @models.include?(@config_table) && !@plan_field.nil?
140
+ return @config_table.classify.constantize
141
+ else
142
+ return nil
143
+ end
144
+ end
145
+
146
+ def shop_data
147
+ if model
148
+ return model.where(@shopify_domain => params[:shop_domain]).first rescue nil
149
+ else
150
+ return nil
151
+ end
152
+ end
153
+
154
+ def app_url
155
+ AppManager.configuration.app_url
156
+ end
157
+
158
+ end
159
+ 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