Class: OakTree::PostData

Inherits:
Object
  • Object
show all
Defined in:
lib/oaktree/post_data.rb

Overview

Contains the contents of a single post under the sources/ directory. Unlike past versions of PostData, this does not synchronize with the source file every time a member is accessed. It’s assumed that what you got when you loaded the post is what you wanted and that any further changes must be explicitly synchronized.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source_name, spec) ⇒ PostData

Loads a new post from the source file using the given Specification. The source file should be the full filename of the source file, but without any other path components.



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/oaktree/post_data.rb', line 51

def initialize(source_name, spec)
  set_post_defaults

  @metadata = {}

  self.spec = spec

  self.hash = nil
  self.last_read_time = Time.at(0).to_datetime

  self.source_name = source_name
  self.source_path = File.absolute_path(source_name,
                                        spec.sources_root).freeze()

  raise "File doesn't exist: #{@source_path}"  if ! File.exists? @source_path

  sync_changes true
end

Instance Attribute Details

#contentObject

The post’s body – that is, the actual content of the blog post.



27
28
29
# File 'lib/oaktree/post_data.rb', line 27

def content
  @content
end

#hashObject

Returns the value of attribute hash.



37
38
39
# File 'lib/oaktree/post_data.rb', line 37

def hash
  @hash
end

#kindObject

The kind of post this is. Expected to be either :post or :static, though the value is arbitrary.



33
34
35
# File 'lib/oaktree/post_data.rb', line 33

def kind
  @kind
end

#last_read_timeObject

The time when the file was last read. Used to determine if sync_changes will reload the file. Defaults to the Unix epoch.



30
31
32
# File 'lib/oaktree/post_data.rb', line 30

def last_read_time
  @last_read_time
end

Returns the value of attribute link.



21
22
23
# File 'lib/oaktree/post_data.rb', line 21

def link
  @link
end

Returns the value of attribute permalink.



22
23
24
# File 'lib/oaktree/post_data.rb', line 22

def permalink
  @permalink
end

#public_pathObject

The path to the HTML file that’s written when compiling the post.



19
20
21
# File 'lib/oaktree/post_data.rb', line 19

def public_path
  @public_path
end

#slugObject

The post’s slug, a filesystem- and URL-friendly string.



25
26
27
# File 'lib/oaktree/post_data.rb', line 25

def slug
  @slug
end

#source_nameObject

Returns the value of attribute source_name.



16
17
18
# File 'lib/oaktree/post_data.rb', line 16

def source_name
  @source_name
end

#source_pathObject

Returns the value of attribute source_path.



17
18
19
# File 'lib/oaktree/post_data.rb', line 17

def source_path
  @source_path
end

#specObject

Returns the value of attribute spec.



38
39
40
# File 'lib/oaktree/post_data.rb', line 38

def spec
  @spec
end

#statusObject

The post’s status. Either :published or :unpublished, though only :published holds meaning – other values are assumed to be unpublished.



36
37
38
# File 'lib/oaktree/post_data.rb', line 36

def status
  @status
end

#timeObject

Returns the value of attribute time.



23
24
25
# File 'lib/oaktree/post_data.rb', line 23

def time
  @time
end

#titleObject

Returns the value of attribute title.



20
21
22
# File 'lib/oaktree/post_data.rb', line 20

def title
  @title
end

Class Method Details

.default_kindObject

Returns the default ‘kind’ a post should be. Typically means :post, though it may change in the future.



73
74
75
# File 'lib/oaktree/post_data.rb', line 73

def self.default_kind
  :post
end

.default_statusObject

Returns the default ‘status’ a post should have. Typically :published, but this may change in the future.



80
81
82
# File 'lib/oaktree/post_data.rb', line 80

def self.default_status
  :published
end

.metadata_separatorObject

The regexp for identifying the line that separates the post head from the post body. This is typically three or more hyphens.



86
87
88
# File 'lib/oaktree/post_data.rb', line 86

def self.
  /^-{3,}\s*$/
end

Instance Method Details

#metadataObject



43
44
45
# File 'lib/oaktree/post_data.rb', line 43

def 
  @metadata
end

#sync_changes(forced = false) ⇒ Object

Synchronizes changes between the post’s file and the post data object. If

'forced' is true (or non-false/nil), it will reload the file regardless of
whether it's considered necessary.

A "necessary" reload is when the file's hash changes or the file's last
modification time is more recent than what the post data last read.


97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/oaktree/post_data.rb', line 97

def sync_changes(forced = false)
  raise "Source file does not exist."  unless File.exists? @source_path

  source_differs  = !! forced
  source_mtime    = File.mtime(@source_path).to_datetime()
  source_contents = File.open(@source_path, 'r') { |io| io.read }
  source_hash     = Digest::SHA1.hexdigest(source_contents).freeze()

  if ! forced
    # Check that the source differs from what was last checked.
    source_differs = (hash != source_hash)
    public_exists  = (@public_path && File.exists?(@public_path))

    # Check if the public file is older than the current source file.
    if ! source_differs && public_exists
      public_mtime = File.mtime(@public_path).to_datetime()

      source_differs = true  if public_mtime < source_mtime
    end

    if ! source_differs && @last_read_time < source_mtime
      source_differs = true
    end
  end # ! forced

  return  if ! source_differs

  self.last_read_time = source_mtime

  # Reset the post's members to an unloaded state
  set_post_defaults
  self.hash = source_hash

  source_split = source_contents.partition(self.class.)

  load_header source_split[0]
  self.content = source_split[2]

  self
end