sitepress-core 3.2.0 → 3.2.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: b2839172c3482bfcd76b700b47a31469caa3e76119f4671c77933f1ca26266e3
4
- data.tar.gz: da657c2dc3adf936890e9e51d404367e9de5d1cafa0c322e77b21284e605b5d8
3
+ metadata.gz: 0f5128994ea5970446da051ce17c700fd2a0ad99c1bd2716bc8628b244ca7e21
4
+ data.tar.gz: ce9393f3fa9218eda6fbc41523e2be852f91f069cb41a2fd50e8964e945a1555
5
5
  SHA512:
6
- metadata.gz: da9b20b6beddb74ea92903d2283938e6ba3ef442a875a724330e4225240e7865fcff208ef2251432814fd54b8ed12aa1eea43a994733b348950fddff8197929b
7
- data.tar.gz: 2da0235e25b98a8353ce7d254ccab76b3ef6148c09ba35a6ebfb4431c05187bb15ef20739903416f56940f1e53a17197160b80487fb75c8ade79377ceb05ce6e
6
+ metadata.gz: edc9fb30418337a90b81d0de0dd7a08c306222d3ac45598393a21586ba3cd6a9527f3d52820ae6844886adbea6b5a16b441a22cc2bb62e5a2d870617616436d1
7
+ data.tar.gz: 27b342cae371ec2a524c2a999c3f99abbf34ead1168d6650150fea5bfe450ea55f3d8b4bdd35f6d295f6560a8edf1a08e7bf38b9449fd18c1a4c05ebd097cb40
@@ -1,5 +1,6 @@
1
1
  require "mime/types"
2
2
  require "forwardable"
3
+ require "fileutils"
3
4
 
4
5
  module Sitepress
5
6
  # Represents a file on a web server that may be parsed to extract
@@ -19,7 +20,7 @@ module Sitepress
19
20
  attr_reader :path
20
21
 
21
22
  extend Forwardable
22
- def_delegators :parser, :data, :body
23
+ def_delegators :renderer, :render
23
24
  def_delegators :path, :handler, :node_name, :format, :exists?
24
25
 
25
26
  def initialize(path:, mime_type: nil, parser: DEFAULT_PARSER)
@@ -30,6 +31,14 @@ module Sitepress
30
31
  @parser_klass = parser
31
32
  end
32
33
 
34
+ def data
35
+ @data ||= exists? ? parse_error { parser.data } : {}
36
+ end
37
+
38
+ def body
39
+ @body ||= exists? ? parse_error { parser.body } : nil
40
+ end
41
+
33
42
  # Treat resources with the same request path as equal.
34
43
  def ==(asset)
35
44
  path == asset.path
@@ -39,8 +48,9 @@ module Sitepress
39
48
  @mime_type ||= inferred_mime_type || DEFAULT_MIME_TYPE
40
49
  end
41
50
 
42
- # Used by the Rails controller to short circuit additional processing if the
43
- # asset is not renderable (e.g. is it erb or haml?)
51
+ # Certain files, like binary file types, aren't something that we should try to
52
+ # parse. When this returns true in some cases, a reference to the file will be
53
+ # passed and skip all the overhead of trying to parse and render.
44
54
  def renderable?
45
55
  !!handler
46
56
  end
@@ -51,7 +61,33 @@ module Sitepress
51
61
  @parser_klass = parser_klass
52
62
  end
53
63
 
64
+ def updated_at
65
+ File.mtime path
66
+ end
67
+
68
+ def created_at
69
+ File.ctime path
70
+ end
71
+
72
+ def destroy
73
+ FIleUtils.rm path
74
+ end
75
+
76
+ def save
77
+ File.write path, render
78
+ end
79
+
80
+ def renderer
81
+ @parser_klass::Renderer.new(data: data, body: body)
82
+ end
83
+
54
84
  private
85
+ def parse_error(&parse)
86
+ parse.call
87
+ rescue StandardError => e
88
+ raise ParseError.new("Error parsing asset at #{path.to_s}: #{e}")
89
+ end
90
+
55
91
  def parser
56
92
  @parser ||= @parser_klass.new File.read path
57
93
  end
@@ -0,0 +1,47 @@
1
+ module Sitepress
2
+ class Data
3
+ def initialize(data)
4
+ @data = data
5
+ end
6
+
7
+ def fetch(key, *args, &block)
8
+ wrap_value { @data.fetch(key.to_s, *args, &block) }
9
+ end
10
+
11
+ def [](key)
12
+ wrap_value { @data[key.to_s] }
13
+ end
14
+
15
+ def method_missing(name, *args, **kwargs, &block)
16
+ if respond_to? name
17
+ self.send name, *args, **kwargs, &block
18
+ else
19
+ key, modifier, _ = name.to_s.partition("!")
20
+ wrap_value do
21
+ case modifier
22
+ when ""
23
+ @data[key]
24
+ when "!"
25
+ @data.fetch(key)
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ def dig(*args, **kwargs, &block)
32
+ wrap_value { @data.dig(*args, **kwargs, &block) }
33
+ end
34
+
35
+ private
36
+ def wrap_value(&block)
37
+ case value = block.call
38
+ when Hash
39
+ self.class.new value
40
+ when Array
41
+ value.map { |v| wrap_value { v } }
42
+ else
43
+ value
44
+ end
45
+ end
46
+ end
47
+ end
@@ -1,12 +1,46 @@
1
1
  require "yaml"
2
+ require "date"
2
3
 
3
4
  module Sitepress
4
5
  module Parsers
5
6
  # Parses metadata from the header of the page.
6
-
7
- # TODO: Redo this to use File readline and pos to
8
- # perform faster
9
7
  class Frontmatter < Base
8
+ class Renderer
9
+ attr_reader :body, :data
10
+
11
+ def initialize(body:, data:)
12
+ @body = body
13
+ @data = data
14
+ end
15
+
16
+ def dump_yaml(data)
17
+ if YAML.respond_to? :safe_dump
18
+ YAML.safe_dump data, permitted_classes: Frontmatter.permitted_classes
19
+ else
20
+ # Live dangerously, lol
21
+ YAML.dump data
22
+ end
23
+ end
24
+
25
+ def render
26
+ [
27
+ dump_yaml(data),
28
+ Frontmatter::DELIMITER,
29
+ $/,
30
+ $/,
31
+ body
32
+ ].join
33
+ end
34
+ end
35
+
36
+ # Default classes that we'll allow YAML to parse. Ideally this doesn't
37
+ # get too huge and we let users control it by setting
38
+ # `Sitepress::Parsers::Frontmatter.permitted_classes = [Whatever, SuperDanger]`
39
+ PERMITTED_CLASSES = [
40
+ Date,
41
+ Time
42
+ ]
43
+
10
44
  DELIMITER = "---".freeze
11
45
  NEWLINE = /\r\n?|\n/.freeze
12
46
  PATTERN = /\A(#{DELIMITER}#{NEWLINE}(.+?)#{NEWLINE}#{DELIMITER}#{NEWLINE}*)?(.+)\Z/m
@@ -16,7 +50,24 @@ module Sitepress
16
50
  end
17
51
 
18
52
  def data
19
- @data ? YAML.load(@data) : {}
53
+ @data ? load_yaml(@data) : {}
54
+ end
55
+
56
+ def load_yaml(data)
57
+ if YAML.respond_to? :safe_load
58
+ YAML.safe_load data, permitted_classes: self.class.permitted_classes
59
+ else
60
+ # Live dangerously, lol
61
+ YAML.load data
62
+ end
63
+ end
64
+
65
+ class << self
66
+ attr_writer :permitted_classes
67
+
68
+ def permitted_classes
69
+ @permitted_classes ||= PERMITTED_CLASSES
70
+ end
20
71
  end
21
72
  end
22
73
  end
@@ -49,7 +49,7 @@ module Sitepress
49
49
  end
50
50
 
51
51
  def exists?
52
- File.exists? path
52
+ File.exist? path
53
53
  end
54
54
 
55
55
  def expand_path
@@ -5,6 +5,9 @@ module Sitepress
5
5
  # resources that point to the same asset. Resources are immutable
6
6
  # and may be altered by the resource proxy.
7
7
  class Resource
8
+ extend Forwardable
9
+ def_delegators :asset, :renderable?
10
+
8
11
  attr_writer :body, :data
9
12
  attr_reader :node, :asset
10
13
 
@@ -62,12 +65,6 @@ module Sitepress
62
65
  @lineage ||= node.parents.reject(&:root?).reverse.map(&:name)
63
66
  end
64
67
 
65
- # Certain files, like binary file types, aren't something that we should try to
66
- # parse. When this returns true in some cases, a reference to the file will be
67
- # passed and skip all the overhead of trying to parse and render.
68
- def renderable?
69
- asset.renderable?
70
- end
71
68
 
72
69
  private
73
70
  # Filters parent/child/sibling resources by a type. The default behavior is to only return
@@ -1,3 +1,3 @@
1
1
  module Sitepress
2
- VERSION = "3.2.0".freeze
2
+ VERSION = "3.2.1".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sitepress-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.0
4
+ version: 3.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brad Gessler
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-12-05 00:00:00.000000000 Z
11
+ date: 2023-01-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -77,6 +77,7 @@ files:
77
77
  - lib/sitepress/asset.rb
78
78
  - lib/sitepress/asset_node_mapper.rb
79
79
  - lib/sitepress/asset_paths.rb
80
+ - lib/sitepress/data.rb
80
81
  - lib/sitepress/extensions/layouts.rb
81
82
  - lib/sitepress/extensions/proc_manipulator.rb
82
83
  - lib/sitepress/formats.rb
@@ -114,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
114
115
  - !ruby/object:Gem::Version
115
116
  version: '0'
116
117
  requirements: []
117
- rubygems_version: 3.3.7
118
+ rubygems_version: 3.4.1
118
119
  signing_key:
119
120
  specification_version: 4
120
121
  summary: An embeddable file-backed content management system.