nekonote-framework 1.0.0.pre.beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +22 -0
  3. data/README.md +49 -0
  4. data/bin/nekonote +45 -0
  5. data/data/structure/Gemfile +25 -0
  6. data/data/structure/config.ru +14 -0
  7. data/data/structure/handler/base.rb +21 -0
  8. data/data/structure/handler/error.rb +35 -0
  9. data/data/structure/handler/welcome.rb +11 -0
  10. data/data/structure/lib/.gitkeep +0 -0
  11. data/data/structure/preference/development/logger.yml +62 -0
  12. data/data/structure/preference/development/middlewares.rb +152 -0
  13. data/data/structure/preference/development/public.yml +29 -0
  14. data/data/structure/preference/development/route.yml +30 -0
  15. data/data/structure/preference/development/route_error.yml +28 -0
  16. data/data/structure/preference/development/route_include.yml +22 -0
  17. data/data/structure/preference/development/server/puma.rb +63 -0
  18. data/data/structure/preference/development/setting/example.yml +40 -0
  19. data/data/structure/preference/development/setting/site.yml +3 -0
  20. data/data/structure/preference/development/setting/welcome.yml +7 -0
  21. data/data/structure/public/css/layout/common.css +11 -0
  22. data/data/structure/public/css/layout/default.css +3 -0
  23. data/data/structure/public/css/layout/error.css +3 -0
  24. data/data/structure/public/css/welcome.css +47 -0
  25. data/data/structure/public/favicon.ico +0 -0
  26. data/data/structure/public/img/.gitkeep +0 -0
  27. data/data/structure/public/img/logo.png +0 -0
  28. data/data/structure/public/js/.gitkeep +0 -0
  29. data/data/structure/static/layout/default.tpl +19 -0
  30. data/data/structure/static/layout/error.tpl +15 -0
  31. data/data/structure/static/sass/welcome.scss +52 -0
  32. data/data/structure/static/template/error.tpl +4 -0
  33. data/data/structure/static/template/welcome/index.tpl +26 -0
  34. data/data/structure/tmp/pids/.gitkeep +0 -0
  35. data/lib/loader.rb +83 -0
  36. data/lib/nekonote.rb +9 -0
  37. data/lib/nekonote/cli.rb +702 -0
  38. data/lib/nekonote/cmd_parser.rb +55 -0
  39. data/lib/nekonote/core.rb +116 -0
  40. data/lib/nekonote/env.rb +56 -0
  41. data/lib/nekonote/exception/cli_error.rb +34 -0
  42. data/lib/nekonote/exception/error.rb +75 -0
  43. data/lib/nekonote/exception/handler_error.rb +5 -0
  44. data/lib/nekonote/exception/logger_error.rb +8 -0
  45. data/lib/nekonote/exception/page_cache_error.rb +6 -0
  46. data/lib/nekonote/exception/preference_error.rb +11 -0
  47. data/lib/nekonote/exception/view_error.rb +7 -0
  48. data/lib/nekonote/handler.rb +274 -0
  49. data/lib/nekonote/handler/protected_methods.rb +119 -0
  50. data/lib/nekonote/liquid/tag_env_get.rb +12 -0
  51. data/lib/nekonote/liquid/tag_setting_get.rb +12 -0
  52. data/lib/nekonote/logger.rb +135 -0
  53. data/lib/nekonote/page_cache.rb +111 -0
  54. data/lib/nekonote/preference.rb +215 -0
  55. data/lib/nekonote/puma.rb +131 -0
  56. data/lib/nekonote/rack/rack_static.rb +17 -0
  57. data/lib/nekonote/rack/rack_static_file.rb +19 -0
  58. data/lib/nekonote/rack/url_mapper.rb +193 -0
  59. data/lib/nekonote/rackup.rb +319 -0
  60. data/lib/nekonote/request.rb +295 -0
  61. data/lib/nekonote/setting.rb +59 -0
  62. data/lib/nekonote/spec.rb +22 -0
  63. data/lib/nekonote/util/filer.rb +69 -0
  64. data/lib/nekonote/util/process.rb +43 -0
  65. data/lib/nekonote/view.rb +398 -0
  66. data/lib/nekonote/yaml_access.rb +60 -0
  67. metadata +144 -0
@@ -0,0 +1,119 @@
1
+ # protected methods for conclete handlers
2
+ module Nekonote
3
+ class Handler
4
+ module ProtectedMethods
5
+ # assign variables into tempate and layout
6
+ # @param hash list
7
+ # @throw ::Nekonote::Error
8
+ protected
9
+ def __assign(list)
10
+ @view.assign_variables list
11
+ end
12
+
13
+ # @param type string|symbol
14
+ protected
15
+ def __set_content_type(type)
16
+ @view.set_content_type type
17
+ end
18
+
19
+ # @param string|symbol subject
20
+ # @param mixed value
21
+ protected
22
+ def __set_header(subject, value)
23
+ @view.set_header(subject, value)
24
+ end
25
+
26
+ # @param hash headers
27
+ protected
28
+ def __set_headers(headers)
29
+ raise HandlerError, HandlerError::MSG_WRONG_TYPE%[headers.class, 'Hash'] if !headers.is_a?(Hash)
30
+ headers.each_pair do |key, val|
31
+ @view.set_header(key, val)
32
+ end
33
+ end
34
+
35
+ # @param string|symbol subject
36
+ # @param mixed value
37
+ # @param string delimiter
38
+ protected
39
+ def __add_header(subject, value, delimiter = '; ')
40
+ @view.add_header subject, value, delimiter
41
+ end
42
+
43
+ # @param int code
44
+ protected
45
+ def __set_code(code)
46
+ @view.set_code code
47
+ end
48
+
49
+ # @param string body
50
+ protected
51
+ def __set_body(body)
52
+ @view.set_body body
53
+ end
54
+
55
+ # @param string body
56
+ protected
57
+ def __add_body(body)
58
+ @view.add_body body
59
+ end
60
+
61
+ # @param hash body
62
+ protected
63
+ def __set_json_body(body)
64
+ raise HandlerError, HandlerError::MSG_WRONG_TYPE%[body.class, 'Hash'] if !body.is_a?(Hash)
65
+ require 'json' if !defined? JSON
66
+ __set_body JSON.pretty_generate(body)
67
+ end
68
+
69
+ # Get values in a specified field(s).
70
+ # @param string|synbol fields you can set plual arguments like field1, field2, field3, ...
71
+ # @return mixed|nil in the case of that missing specified key or missing fields will return nil
72
+ protected
73
+ def __setting_get(*fields)
74
+ return Nekonote::Setting.get fields
75
+ end
76
+
77
+ # @return array
78
+ protected
79
+ def __setting_keys
80
+ return Nekonote::Setting.keys
81
+ end
82
+
83
+ # Get values in a specified field
84
+ # @param string|synbol|nil field
85
+ # @return mixed|nil in the case of that missing specified key or missing fields will return nil
86
+ protected
87
+ def __env_get(field = nil)
88
+ return Nekonote::Env.get field
89
+ end
90
+
91
+ # @return array
92
+ protected
93
+ def __env_keys
94
+ return Nekonote::Env.keys
95
+ end
96
+
97
+
98
+ # @param string dest
99
+ # @param int code
100
+ protected
101
+ def __redirect(dest, code=302)
102
+ # validation for types
103
+ raise HandlerError, HandlerError::MSG_WRONG_TYPE%[dest.class, 'String'] if !dest.is_a?(String)
104
+ if !code.is_a?(Fixnum)
105
+ begin
106
+ code = code.to_i
107
+ rescue
108
+ raise HandlerError, HandlerError::MSG_WRONG_TYPE%[code.class, 'Fixnum or convertible types into Fixnum']
109
+ end
110
+ end
111
+
112
+ # set redirect information
113
+ __set_code code
114
+ __set_header 'Location', dest
115
+ @view.is_redirect = true
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,12 @@
1
+ module Nekonote
2
+ class TagEnvGet < Liquid::Tag
3
+ def initialize(tag_name, val, parse_context)
4
+ super
5
+ @val = val.strip
6
+ end
7
+
8
+ def render(context)
9
+ return Env.get @val
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ module Nekonote
2
+ class TagSettingGet < Liquid::Tag
3
+ def initialize(tag_name, val, parse_context)
4
+ super
5
+ @val = val.strip.split ','
6
+ end
7
+
8
+ def render(context)
9
+ return Nekonote::Setting.get @val
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,135 @@
1
+ module Nekonote
2
+ class Logger
3
+ include Singleton
4
+ DEBUG = 0
5
+ INFO = 1
6
+ WARN = 2
7
+ ERROR = 3
8
+ FATAL = 4
9
+
10
+ public
11
+ def init(pref)
12
+ logf = pref['logfile']%Nekonote.get_env
13
+ limit = pref['limit']
14
+ keep = pref['keep'].to_i
15
+
16
+ if logf == nil || limit == nil || keep == nil
17
+ raise LoggerError, LoggerError::MSG_MISSING_LOGFILE
18
+ end
19
+
20
+ if !logf.start_with? '/'
21
+ # when log file path is relative
22
+ logf = Nekonote.get_root_path + logf
23
+ end
24
+
25
+ # initialize logger
26
+ @logger = SimpleRotate.instance
27
+ set_optional pref
28
+ begin
29
+ @logger.init logf, limit, keep
30
+ rescue
31
+ msg = $/ + Error::SPACE + "Logger definitions are: logfile = #{logf}, limit = #{limit}, keep = #{keep}"
32
+ raise LoggerError, LoggerError::MSG_FAILED_INITIALIZE%[ENV['USER'], logf] + msg
33
+ end
34
+
35
+ # set default log level
36
+ @default_log_level = get_log_level_by_name pref['default_log_level']
37
+ switch_level @default_log_level
38
+ end
39
+
40
+ # @param mixed msg
41
+ public
42
+ def write(msg, level = nil)
43
+ if level != nil
44
+ switch_level level
45
+ end
46
+ @logger << msg
47
+ end
48
+
49
+ public
50
+ def set_level_default
51
+ switch_level @default_log_level
52
+ end
53
+
54
+ # @param string log_level_name
55
+ private
56
+ def get_log_level_by_name(log_level_name)
57
+ case log_level_name
58
+ when 'debug'
59
+ level = DEBUG
60
+ when 'info'
61
+ level = INFO
62
+ when 'warn'
63
+ level = WARN
64
+ when 'error'
65
+ level = ERROR
66
+ when 'fatal'
67
+ level = FATAL
68
+ else
69
+ # set default level for missing or unknown value is given
70
+ level = INFO
71
+ end
72
+ return level
73
+ end
74
+
75
+ # @param int level
76
+ private
77
+ def switch_level(level)
78
+ case level
79
+ when DEBUG
80
+ @logger.debug
81
+ when INFO
82
+ @logger.info
83
+ when WARN
84
+ @logger.warn
85
+ when ERROR
86
+ @logger.error
87
+ when FATAL
88
+ @logger.fatal
89
+ else
90
+ raise LoggerError. LoggerError::MSG_UNDIFINED_LOG_LEVEL
91
+ end
92
+ end
93
+
94
+ # set optional preferences to @logger
95
+ # @param array pref
96
+ private
97
+ def set_optional(pref)
98
+ begin
99
+ @logger.logging_format = pref['format']['log']
100
+ @logger.date_format = pref['format']['datetime']
101
+ @logger.threshold = pref['threshold'].upcase
102
+ @logger.sleep_time = pref['sleeptime']
103
+
104
+ if pref['compress']['enabled'] == true
105
+ @logger.compress_level pref['compress']['level']
106
+ end
107
+
108
+ if pref['with_stdout'] == true
109
+ @logger.with_stdout
110
+ end
111
+
112
+ if pref['verbose'] == false
113
+ @logger.silence
114
+ end
115
+
116
+ if pref['psync'] == true
117
+ @logger.psync
118
+ end
119
+
120
+ if pref['flush'] == true
121
+ @logger.enable_wflush
122
+ end
123
+
124
+ rescue
125
+ raise LoggerError, LoggerError::MSG_FAILED_DEF_OPT
126
+ end
127
+ end
128
+ end
129
+ end
130
+
131
+ # @param mixed msg
132
+ # @param int level
133
+ def logwrite(msg, level = nil)
134
+ Nekonote::Logger.instance.write msg, level
135
+ end
@@ -0,0 +1,111 @@
1
+ module Nekonote
2
+ class PageCache
3
+ include Singleton
4
+ CACHE_DIR = 'cache'
5
+
6
+ def initialize
7
+ @cache_path = Nekonote.get_root_path + CACHE_DIR
8
+
9
+ # check the accessibility
10
+ if !Util::Filer.available_dir? @cache_path
11
+ raise PageCacheError, PageCacheError::MSG_CHACHE_DIR_WRONG_PERMIT% @cache_path
12
+ end
13
+ end
14
+
15
+ # @return bool
16
+ public
17
+ def cache_clear
18
+ files = Dir.glob("#{@cache_path}/*")
19
+ if files.size > 0
20
+ deleted = true
21
+ else
22
+ deleted = false
23
+ end
24
+
25
+ begin
26
+ files.each do |full_path|
27
+ File.delete full_path
28
+ end
29
+ rescue Errno::EISDIR
30
+ raise PageCacheError, PageCacheError::MSG_THERE_IS_DIRECTORY
31
+ end
32
+
33
+ return deleted
34
+ end
35
+
36
+ # Makes a cache file newly.
37
+ # The cache files will be created under 'cache' directory and its filename is SHA-256 hash value.
38
+ # @param string uri
39
+ # @param int code
40
+ # @param hash header
41
+ # @param array body
42
+ public
43
+ def make_cache(uri, code, header, body)
44
+ created_at = Time.now.to_i
45
+ data = {
46
+ :code => code,
47
+ :header => header,
48
+ :body => body
49
+ }
50
+ data = [code, header, body]
51
+ serialized_data = Marshal.dump data
52
+
53
+ # create new page cache file, delete it if it already exists
54
+ File.open(get_cache_file_path(uri), File::RDWR|File::CREAT|File::TRUNC) do |f|
55
+ f.flock File::LOCK_EX
56
+ f.puts created_at
57
+ f.print serialized_data
58
+ f.flock File::LOCK_UN
59
+ end
60
+ end
61
+
62
+ # @param string uri
63
+ # array
64
+ public
65
+ def get_page_cache(uri)
66
+ response_data = []
67
+ File.open(get_cache_file_path(uri), 'r') do |f|
68
+ f.flock File::LOCK_SH
69
+ f.readline
70
+ response_data = Marshal.load(f.read)
71
+ f.flock File::LOCK_UN
72
+ end
73
+ return response_data
74
+ end
75
+
76
+ # Returns true if cache file exists and its valid time hasn't passed.
77
+ # @param string uri
78
+ # @param int page_cache_time
79
+ # @return bool
80
+ public
81
+ def has_available_cache?(uri, page_cache_time)
82
+ path = get_cache_file_path uri
83
+ # check cache file exists?
84
+ return false if !Util::Filer.available_file? path
85
+
86
+ # check expiration
87
+ latest_access = 0
88
+ File.open(get_cache_file_path(uri), 'r') do |f|
89
+ f.flock File::LOCK_SH
90
+ latest_access = f.readline.strip.to_i
91
+ f.flock File::LOCK_UN
92
+ end
93
+ sec_passed = Time.now.to_i - latest_access # passed sec
94
+
95
+ # return false if page_cache_time has passed
96
+ if page_cache_time < sec_passed
97
+ return false
98
+ end
99
+
100
+ # availale
101
+ return true
102
+ end
103
+
104
+ # @param string uri
105
+ # @return string SHA-256 hash value
106
+ public
107
+ def get_cache_file_path(uri)
108
+ return "#{@cache_path}/#{Digest::SHA256.hexdigest(uri)}"
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,215 @@
1
+ module Nekonote
2
+ class Preference
3
+ include Singleton
4
+
5
+ # hidden file name for reloading preferences
6
+ FILE_NAME_FOR_RELOAD = '.reload_preference'
7
+
8
+ # for route.yml
9
+ FIELD_ROUTE_INCLUDE = 'include'
10
+
11
+ # for route options
12
+ FIELD_OPTION_ROUTE = 'preference'
13
+ FIELD_OPTION_ROUTE_REGEXP = 'path_as_regexp'
14
+ FIELD_OPTION_ALLOW_DUP_SLASH = 'allow_dup_slash'
15
+
16
+ # for route_error.yml
17
+ FIELD_ROUTE_ERR_MISSING_ROUTE = 'missing_route'
18
+ FIELD_ROUTE_ERR_WRONG_METHOD = 'wrong_http_method'
19
+ FIELD_ROUTE_ERR_FATAL = 'fatal'
20
+ FIELD_ROUTE_ERR_NOT_FOUND = 'not_found'
21
+
22
+ # for route.yml and route_error.yml
23
+ FIELD_ROUTE_PATH = 'path'
24
+ FIELD_ROUTE_EXEC_METHOD = 'execute'
25
+ FIELD_ROUTE_ALLOW_METHODS = 'method'
26
+ FIELD_ROUTE_PARAMS = 'params'
27
+ FIELD_ROUTE_CONTENT_TYPE = 'content'
28
+ FIELD_ROUTE_TEMPLATE = 'template'
29
+ FIELD_ROUTE_LAYOUT = 'layout'
30
+ FIELD_ROUTE_PAGE_CACHE_TIME = 'page_cache_time'
31
+ FIELD_ROUTE_HANDLER = 'handler'
32
+
33
+ # Except these fields are custom fields
34
+ FIELDS_IN_ROUTE = [
35
+ FIELD_ROUTE_PATH,
36
+ FIELD_ROUTE_EXEC_METHOD,
37
+ FIELD_ROUTE_ALLOW_METHODS,
38
+ FIELD_ROUTE_PARAMS,
39
+ FIELD_ROUTE_CONTENT_TYPE,
40
+ FIELD_ROUTE_TEMPLATE,
41
+ FIELD_ROUTE_LAYOUT,
42
+ FIELD_ROUTE_PAGE_CACHE_TIME,
43
+ FIELD_ROUTE_HANDLER
44
+ ]
45
+ FIELDS_IN_ROUTE_ERROR = [
46
+ FIELD_ROUTE_HANDLER,
47
+ FIELD_ROUTE_EXEC_METHOD,
48
+ FIELD_ROUTE_CONTENT_TYPE,
49
+ FIELD_ROUTE_TEMPLATE,
50
+ FIELD_ROUTE_LAYOUT,
51
+ FIELD_ROUTE_PAGE_CACHE_TIME
52
+ ]
53
+
54
+ # allowed to read or write from context of outside
55
+ attr_accessor :is_enabled_show_exceptions
56
+
57
+ # only reading is allowed
58
+ attr_reader :path_route_yml,
59
+ :path_route_include_yml,
60
+ :path_route_error_yml,
61
+ :path_public_yml,
62
+ :path_middlewares_rb,
63
+ :path_logger_yml
64
+
65
+ def initialize
66
+ env = Nekonote.get_env
67
+ path = Nekonote.get_root_path + YamlAccess::DIR_PREFERENCE + "/#{env}/"
68
+
69
+ @path_route_yml = path + 'route.yml'
70
+ @path_route_include_yml = path + 'route_include.yml'
71
+ @path_route_error_yml = path + 'route_error.yml'
72
+ @path_public_yml = path + 'public.yml'
73
+ @path_middlewares_rb = path + 'middlewares.rb'
74
+ @path_logger_yml = path + 'logger.yml'
75
+
76
+ @parsed_route_yml = nil
77
+ @parsed_route_include_yml = nil
78
+ @parsed_route_error_yml = nil
79
+ @parsed_public_yml = nil
80
+ @parsed_mw_yml = nil
81
+ @parsed_logger_yml = nil
82
+
83
+ # in route.yml
84
+ @is_path_regexp = nil
85
+ @is_allow_dup_slash = nil
86
+
87
+ # in middleware.yml
88
+ @is_enabled_show_exceptions = nil
89
+
90
+ # check there are required yaml files
91
+ if !Util::Filer.available_file? 'config.ru'
92
+ msg = Error::MSG_MISSING_RACKUP% @@root_path + $/
93
+ msg += Error::SPACE + Error::MSG_WRONG_ROOT
94
+ raise Error, msg
95
+ end
96
+
97
+ if !Util::Filer.available_file? @path_route_yml
98
+ raise PreferenceError, Error::MSG_MISSING_FILE% @path_route_yml
99
+ end
100
+ end
101
+
102
+ # @param string field
103
+ # @return bool
104
+ public
105
+ def has_error_route?(field)
106
+ pref = get_route_error
107
+
108
+ # missing route_error.yml
109
+ if pref == nil
110
+ Error.warning "Missing a file which for error routes #{@path_route_error_yml}."
111
+ return false
112
+ end
113
+
114
+ return pref[field].is_a?(Hash) && pref[field][FIELD_ROUTE_HANDLER].is_a?(String)
115
+ end
116
+
117
+ # @param bool fresh
118
+ # @return hash or exit from program
119
+ public
120
+ def get_route(fresh = false)
121
+ if !@parsed_route_yml.is_a?(Hash) || fresh
122
+ @parsed_route_yml = YamlAccess::get_parsed_route @path_route_yml
123
+ if @parsed_route_yml.size == 0
124
+ raise PreferenceError, PreferenceError::MSG_EMPTY_YAML% @path_route_yml
125
+ end
126
+ end
127
+ return @parsed_route_yml
128
+ end
129
+
130
+ # @param bool fresh
131
+ # @return hash
132
+ public
133
+ def get_route_include(fresh = false)
134
+ if !@parsed_route_include_yml.is_a?(Hash) || fresh
135
+ @parsed_route_include_yml = YamlAccess::get_parsed @path_route_include_yml
136
+ end
137
+ return @parsed_route_include_yml
138
+ end
139
+
140
+ # @param bool fresh
141
+ # @return hash
142
+ public
143
+ def get_route_error(fresh = false)
144
+ if !@parsed_route_error_yml.is_a?(Hash) || fresh
145
+ @parsed_route_error_yml = YamlAccess::get_parsed @path_route_error_yml
146
+ end
147
+ return @parsed_route_error_yml
148
+ end
149
+
150
+ # @param bool fresh
151
+ # @return hash
152
+ public
153
+ def get_public(fresh = false)
154
+ if !@parsed_public_yml.is_a?(Hash) || fresh
155
+ @parsed_public_yml = YamlAccess::get_parsed @path_public_yml
156
+ end
157
+ return @parsed_public_yml
158
+ end
159
+
160
+ # @param bool fresh
161
+ # @return hash
162
+ public
163
+ def get_logger(fresh = false)
164
+ if !@parsed_logger_yml.is_a?(Hash) || fresh
165
+ @parsed_logger_yml = YamlAccess::get_parsed @path_logger_yml
166
+ end
167
+ return @parsed_logger_yml
168
+ end
169
+
170
+ # @param bool fresh
171
+ # @return bool
172
+ public
173
+ def is_path_regexp?(fresh = false)
174
+ if @is_path_regexp == nil || fresh
175
+ pref = YamlAccess::get_parsed @path_route_yml
176
+
177
+ if pref[FIELD_OPTION_ROUTE].is_a?(Hash) \
178
+ && (pref[FIELD_OPTION_ROUTE][FIELD_OPTION_ROUTE_REGEXP] == true || pref[FIELD_OPTION_ROUTE][FIELD_OPTION_ROUTE_REGEXP] == 1)
179
+ @is_path_regexp = true # using Nekonote::URLMapper
180
+ else
181
+ @is_path_regexp = false # using ::Rack::URLMap
182
+ end
183
+ end
184
+
185
+ return @is_path_regexp
186
+ end
187
+
188
+ # @param bool fresh
189
+ # @return bool
190
+ public
191
+ def is_allow_dup_slash?(fresh = false)
192
+ if @is_allow_dup_slash == nil || fresh
193
+ pref = YamlAccess::get_parsed @path_route_yml
194
+ if pref[FIELD_OPTION_ROUTE].is_a?(Hash) && pref[FIELD_OPTION_ROUTE][FIELD_OPTION_ALLOW_DUP_SLASH] != nil
195
+ @is_allow_dup_slash = pref[FIELD_OPTION_ROUTE][FIELD_OPTION_ALLOW_DUP_SLASH]
196
+ else
197
+ @is_allow_dup_slash = false
198
+ end
199
+ end
200
+
201
+ return @is_allow_dup_slash
202
+ end
203
+
204
+ # @param array info information about route
205
+ # @param bool is_error_route
206
+ def self.get_custom_fields(info, is_error_route = false)
207
+ except_fields = is_error_route ? FIELDS_IN_ROUTE_ERROR : FIELDS_IN_ROUTE
208
+ except_fields.each do |field_name|
209
+ info.delete field_name
210
+ end
211
+
212
+ return info
213
+ end
214
+ end
215
+ end