leanweb 0.3.0 → 0.4.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: d4e80c5813858b838b39fea56bb96b2fb28f7749d22f02ab04694662a8595d96
4
- data.tar.gz: c2fdc8ebf92d647516db11352e5a6cb7bc36f1489dfabe69c095e7090f1b7970
3
+ metadata.gz: 9c2c8b263119a2bfb7a4a812f4ffeb66bc9444bfc65a5ea0ab99d627d227e307
4
+ data.tar.gz: bbb016308a12268ee78694e378e931c016475ca8cf9ff4264d017f79664911f3
5
5
  SHA512:
6
- metadata.gz: 1bed8458a93a2f0139609f17fe3402f69065182607b6b6664cc0c6d90ab3815f4dca7cd08c165dab17e5448d9c3f7d3c44ef8e1f28468cd3e4c42a66b096c8b8
7
- data.tar.gz: 320c619aedd70c9bd0ed5e698ef456e293d3cf754bbe3ca939a7669b45ad117a371089db15737edf0c5c271ad638b84784e6ee3a730093a82a16843828a1074c
6
+ metadata.gz: 52c6e7bdd02a5c2797d20cd6979574cec8a4d8333ab659f3332fa6b4e3bce906a69f950124453621e12dee38c0c585ac3abace0a8041c54d444524c0a21bbba3
7
+ data.tar.gz: 64ec617d144264edce4922fa2258173f6cc139a20102a9ba4c4290adb6ec06d13be4b5f265af715fdcd82005ae03c66ac447c7dd79bc30dce0c3235d4a4f8e22
data/bin/leanweb CHANGED
@@ -88,6 +88,12 @@ files = [
88
88
  %body
89
89
  %h1 It works!
90
90
  HAML
91
+ }, {
92
+ filename: '.gitignore'
93
+ content: <<~GITIGNORE
94
+ /.bundle
95
+ /public/**/*.html
96
+ GITIGNORE
91
97
  }
92
98
  ]
93
99
 
@@ -28,15 +28,19 @@ class Hawese
28
28
  end
29
29
  ORIGIN = ENV.fetch('HAWESE_ORIGIN')
30
30
 
31
- def payment_methods
32
- uri = URI("#{ENDPOINT}/gateways/payment-methods/purchase")
33
- JSON.parse(Net::HTTP.get(uri))
31
+ def payment_methods(country = '*', currency = nil)
32
+ endpoint = String.new(
33
+ "#{ENDPOINT}/gateways/payment-methods/purchase?country=#{country}"
34
+ )
35
+ endpoint << "&currency=#{currency}" if currency
36
+ uri = URI(endpoint)
37
+ JSON.parse(Net::HTTP.get(uri), symbolize_names: true)
34
38
  end
35
39
 
36
40
  def gateway_schema(gateway, query_params, schema = 'purchase')
37
41
  uri = URI("#{ENDPOINT}/gateways/#{gateway}/schemas/#{schema}")
38
42
  uri.query = URI.encode_www_form(query_params)
39
- JSON.parse(Net::HTTP.get(uri))
43
+ JSON.parse(Net::HTTP.get(uri), symbolize_names: true)
40
44
  end
41
45
 
42
46
  def purchase(gateway, fields)
@@ -48,15 +52,25 @@ class Hawese
48
52
  fields.to_json,
49
53
  'Content-Type' => 'application/json'
50
54
  )
51
- JSON.parse(response.body)
55
+ JSON.parse(response.body, symbolize_names: true)
52
56
  end
53
57
 
54
58
  def purchase_from_schema(gateway, schema)
55
59
  fields = {}
56
- schema['properties'].each do |property, contents|
57
- fields[property] = contents['default'] if contents.include?('default')
60
+ schema[:properties].each do |property, contents|
61
+ fields[property] = contents[:default] if contents.include?(:default)
58
62
  end
59
63
  purchase(gateway, fields)
60
64
  end
65
+
66
+ def payment(uuid)
67
+ uri = URI("#{ENDPOINT}/payments/#{uuid}")
68
+ Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
69
+ req = Net::HTTP::Get.new(uri)
70
+ req['Authorization'] = "Bearer #{ENV.fetch('HAWESE_AUTH_TOKEN')}"
71
+ response = http.request(req)
72
+ JSON.parse(response.body, symbolize_names: true)
73
+ end
74
+ end
61
75
  end
62
76
  end
@@ -12,7 +12,7 @@ module LeanWeb
12
12
  module ControllerMixins
13
13
  # {render_with_layout} for {Controller} with ERB, HAML, Tilt::EmacsOrg and
14
14
  # Redcarpet Markdown support.
15
- module RenderWithLayout
15
+ module RenderWithLayout # rubocop:disable Metrics/ModuleLength
16
16
  # Render a response with a layout.
17
17
  #
18
18
  # Depending on the `path` file contents and options `@content_for` might
@@ -43,15 +43,21 @@ module LeanWeb
43
43
  head: nil,
44
44
  layout: 'layout.haml',
45
45
  sub_layout: nil,
46
- options: {},
46
+ options: nil,
47
47
  &block
48
48
  )
49
49
  @content_for[:title] = title unless title.nil?
50
50
  content = render_by_extension(path, sub_layout, options, &block)
51
- prepare_head(head) unless head.nil?
51
+ prepare_head(**head) unless head.nil?
52
52
  render_response(layout, 'text/html'){ content }
53
53
  end
54
54
 
55
+ # Render response for missing static action methods. Called from
56
+ # {Route#respond}.
57
+ def default_static_action(view_path)
58
+ render_with_layout(view_path)
59
+ end
60
+
55
61
  protected
56
62
 
57
63
  # @param path [String]
@@ -60,8 +66,8 @@ module LeanWeb
60
66
  # @option options [String] :setupfile can be absolute or relative to
61
67
  # {VIEW_PATH}.
62
68
  def render_org(path, layout: nil, options: {})
63
- options[:setupfile] = "#{VIEW_PATH}/#{options[:setupfile]}" \
64
- if options.include?(:setupfile) && options[:setupfile][0] != '/'
69
+ options[:setupfile] = absolute_view_path(options[:setupfile]) \
70
+ if options.include?(:setupfile)
65
71
 
66
72
  org_template = create_template(path, options)
67
73
 
@@ -83,6 +89,10 @@ module LeanWeb
83
89
  def render_markdown(path, layout: nil, options: {})
84
90
  maybe_render_markdown_toc!(path, options)
85
91
  markdown_template = create_template(path, options)
92
+
93
+ @content_for[:title] = find_title('md', path) \
94
+ unless @content_for.include?(:title)
95
+
86
96
  if layout
87
97
  create_template(layout).render(self){ markdown_template.render(self) }
88
98
  else
@@ -104,6 +114,23 @@ module LeanWeb
104
114
  options[:with_toc_data] = true
105
115
  end
106
116
 
117
+ def find_title(ext, path)
118
+ regex = find_title_ext_regex(ext)
119
+ title = nil
120
+ File.foreach(absolute_view_path(path)) do |line|
121
+ matches = line.match(regex)
122
+ (title = matches[1]) && break if matches
123
+ end
124
+ title
125
+ end
126
+
127
+ def find_title_ext_regex(ext)
128
+ case ext
129
+ when 'md' then /#(?!#)\s?(.+)/
130
+ when 'haml' then /%h1[^\s]*\s(.+)/
131
+ end
132
+ end
133
+
107
134
  # @param path [String]
108
135
  # @param layout [String]
109
136
  # @param options [Hash] Check `Haml` options.
@@ -119,16 +146,24 @@ module LeanWeb
119
146
  end
120
147
  end
121
148
 
149
+ # rubocop:disable Metrics/MethodLength
122
150
  def render_by_extension(path, layout, options, &block)
123
- case File.extname(path)
124
- when '.org'
125
- render_org(path, layout: layout, options: options)
126
- when '.md'
127
- render_markdown(path, layout: layout, options: options)
128
- else
129
- render_other(path, layout: layout, options: options, &block)
151
+ ext = File.extname(path)[1..]
152
+ options = options || template_defaults[ext] || {}
153
+
154
+ case ext
155
+ when 'org'
156
+ return render_org(path, layout: layout, options: options)
157
+ when 'md'
158
+ return render_markdown(path, layout: layout, options: options)
159
+ when 'haml'
160
+ @content_for[:title] = find_title('haml', path) \
161
+ unless @content_for.include?(:title)
130
162
  end
163
+
164
+ render_other(path, layout: layout, options: options, &block)
131
165
  end
166
+ # rubocop:enable Metrics/MethodLength
132
167
 
133
168
  def prepare_head(js: nil, jsm: nil, css: nil, raw: nil)
134
169
  head = String.new
@@ -59,6 +59,12 @@ module LeanWeb
59
59
  Tilt[ext].new(path, 1, options || template_defaults[ext] || {})
60
60
  end
61
61
 
62
+ # Render response for missing static action methods. Called from
63
+ # {Route#respond}.
64
+ def default_static_action(view_path)
65
+ render_response(view_path)
66
+ end
67
+
62
68
  # Relative route to path from public directory considering current route.
63
69
  #
64
70
  # @param path [String] path from public directory, never begins with `/`.
@@ -70,9 +76,28 @@ module LeanWeb
70
76
  @base_url + path
71
77
  end
72
78
 
79
+ # Get absolute path for a file within {VIEW_PATH}.
80
+ # @param path [String] Can be:
81
+ # - A full path, starts with `/`.
82
+ # - A path relative to {VIEW_PATH}.
83
+ # - A path relative to current @route.path directory, starts with `./`.
84
+ # @return [String] Absolute path.
85
+ def absolute_view_path(path)
86
+ return path if path.start_with?('/')
87
+
88
+ view_path = String.new(LeanWeb::VIEW_PATH)
89
+
90
+ if path.start_with?('./')
91
+ view_path << @route.path.sub(%r{/[^/]*$}, '')
92
+ path = path[2..]
93
+ end
94
+
95
+ path == '' ? view_path : "#{view_path}/#{path}"
96
+ end
97
+
73
98
  # Request params.
74
99
  def params
75
- @request.params
100
+ @request&.params
76
101
  end
77
102
 
78
103
  protected
@@ -81,11 +106,5 @@ module LeanWeb
81
106
  def template_defaults
82
107
  {}
83
108
  end
84
-
85
- # @param path [String]
86
- # @return [String] Full path.
87
- def absolute_view_path(path)
88
- path[0] == '/' ? path : "#{LeanWeb::VIEW_PATH}/#{path}"
89
- end
90
109
  end
91
110
  end
data/lib/leanweb/route.rb CHANGED
@@ -63,12 +63,20 @@ module LeanWeb
63
63
  str_path[-1] == '/' ? 'index' : File.basename(str_path)
64
64
  end
65
65
 
66
+ # Respond with a proc, controller method, or in case of true static routes
67
+ # a rendering of {VIEW_PATH}/{path} with any file extension.
68
+ #
66
69
  # @param request [Rack::Request]
67
70
  # @return [Array] a valid rack response.
68
71
  def respond(request)
69
72
  return respond_proc(request) if @action.instance_of?(Proc)
70
73
 
71
74
  respond_method(request)
75
+ rescue NoMethodError
76
+ raise unless @static == true && (view_path = guess_view_path)
77
+
78
+ controller = default_controller_class.new(self)
79
+ controller.default_static_action(view_path)
72
80
  end
73
81
 
74
82
  # String path, independent if {#path} is Regexp or String.
@@ -141,7 +149,14 @@ module LeanWeb
141
149
  end
142
150
 
143
151
  def default_action_action
144
- "#{path_basename.gsub('-', '_')}_#{@method.downcase}".to_sym
152
+ "#{path_basename.gsub(/[.-]/, '_')}_#{@method.downcase}".to_sym
153
+ end
154
+
155
+ def default_controller_class
156
+ require_relative("#{CONTROLLER_PATH}/#{DEFAULT_CONTROLLER.to_s.snakeize}")
157
+ Object.const_get(DEFAULT_CONTROLLER)
158
+ rescue LoadError
159
+ Controller
145
160
  end
146
161
 
147
162
  # @param request [Rack::Request]
@@ -160,8 +175,7 @@ module LeanWeb
160
175
  # @return [Array] a valid Rack response.
161
176
  def respond_proc(request)
162
177
  params = action_params(request.path)
163
- require_relative("#{CONTROLLER_PATH}/#{DEFAULT_CONTROLLER.to_s.snakeize}")
164
- controller = Object.const_get(DEFAULT_CONTROLLER).new(self, request)
178
+ controller = default_controller_class.new(self, request)
165
179
  return controller.instance_exec(**params, &@action) \
166
180
  if params.instance_of?(Hash)
167
181
 
@@ -188,7 +202,7 @@ module LeanWeb
188
202
  def output_path(path, content_type)
189
203
  out_path =
190
204
  if path[-1] == '/'
191
- String.new("#{PUBLIC_PATH}#{path}/index")
205
+ String.new("#{PUBLIC_PATH}#{path}index")
192
206
  else
193
207
  String.new("#{PUBLIC_PATH}#{path}")
194
208
  end
@@ -199,5 +213,15 @@ module LeanWeb
199
213
 
200
214
  out_path
201
215
  end
216
+
217
+ def guess_view_path
218
+ return if @path.instance_of?(Regexp)
219
+
220
+ view_path = String.new("#{LeanWeb::VIEW_PATH}#{@path}")
221
+ view_path << 'index' if @path[-1] == '/' # add index if is index
222
+ view_path.sub!(%r{\.[^/]+$}, '') # drop static file extension if set
223
+
224
+ Dir["#{view_path}.*"].first # return first file match or nil
225
+ end
202
226
  end
203
227
  end
@@ -9,5 +9,5 @@
9
9
 
10
10
 
11
11
  module LeanWeb
12
- VERSION = '0.3.0'
12
+ VERSION = '0.4.0'
13
13
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: leanweb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Felix Freeman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-10-14 00:00:00.000000000 Z
11
+ date: 2022-11-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -222,7 +222,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
222
222
  - !ruby/object:Gem::Version
223
223
  version: '0'
224
224
  requirements: []
225
- rubygems_version: 3.3.21
225
+ rubygems_version: 3.3.23
226
226
  signing_key:
227
227
  specification_version: 4
228
228
  summary: LeanWeb is a minimal hybrid static / dynamic web framework