Class: Scriptorium::Post
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
Methods included from Contract
#assume, #check_invariants, enabled?, #invariant, #verify
Methods included from Helpers
#add_post_to_state_file, #cf_time, #change_config, #clean_slugify, #copy_gem_asset_to_user, #copy_to_clipboard, #d4, #escape_html, #find_asset, #format_date, #generate_missing_asset_svg, #get_asset_path, #get_from_clipboard, #getvars, #list_gem_assets, #make_dir, #make_tree, #need, #parse_commented_file, #post_compare, #post_in_state_file?, #read_commented_file, #read_file, #read_post_state_file, #remove_post_from_state_file, #see, #see_file, #slugify, #substitute, #system!, #tty, #view_dir, #write_file, #write_file!, #write_post_state_file, #ymdhms, #ymdhms_filename
Methods included from Exceptions
#make_exception
Constructor Details
#initialize(repo, num) ⇒ Post
Returns a new instance of Post.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
# File 'lib/scriptorium/post.rb', line 8
def initialize(repo, num)
assume { repo.is_a?(Scriptorium::Repo) }
assume { num.is_a?(Integer) || num.is_a?(String) }
validate_initialization(repo, num)
@repo = repo
@num = d4(num.to_i) @id = num.to_i @meta = nil
invariant { @id > 0 }
invariant { @repo.is_a?(Scriptorium::Repo) }
invariant { @num.match?(/^\d{4}$/) }
end
|
Instance Attribute Details
#id ⇒ Object
Returns the value of attribute id.
6
7
8
|
# File 'lib/scriptorium/post.rb', line 6
def id
@id
end
|
#num ⇒ Object
Returns the value of attribute num.
6
7
8
|
# File 'lib/scriptorium/post.rb', line 6
def num
@num
end
|
#repo ⇒ Object
Returns the value of attribute repo.
6
7
8
|
# File 'lib/scriptorium/post.rb', line 6
def repo
@repo
end
|
Class Method Details
.read(repo, num, deleted: false) ⇒ Object
New class method to read metadata and initialize the Post
196
197
198
199
200
201
|
# File 'lib/scriptorium/post.rb', line 196
def self.read(repo, num, deleted: false)
post = new(repo, num)
post.load_metadata
post.validate_metadata_consistency
post
end
|
Instance Method Details
#attrs(*keys) ⇒ Object
New method to access multiple attributes at once
191
192
193
|
# File 'lib/scriptorium/post.rb', line 191
def attrs(*keys)
keys.map { |key| send(key) }
end
|
#blurb ⇒ Object
70
71
72
|
# File 'lib/scriptorium/post.rb', line 70
def blurb
meta["post.blurb"]
end
|
#blurb_text ⇒ Object
66
67
68
|
# File 'lib/scriptorium/post.rb', line 66
def blurb_text
meta["post.blurb"]
end
|
#created ⇒ Object
86
87
88
|
# File 'lib/scriptorium/post.rb', line 86
def created
meta["post.created"]
end
|
#date ⇒ Object
90
91
92
|
# File 'lib/scriptorium/post.rb', line 90
def date
pubdate || created
end
|
#deleted ⇒ Object
164
165
166
167
168
169
170
171
172
173
174
175
176
177
|
# File 'lib/scriptorium/post.rb', line 164
def deleted
normal_dir = @repo.root/:posts/@num
deleted_dir = @repo.root/:posts/"_#{@num}"
if Dir.exist?(deleted_dir)
true
elsif Dir.exist?(normal_dir)
false
else
raise "Post directory for #{@num} not found"
end
end
|
#deleted=(value) ⇒ Object
179
180
181
182
183
184
185
186
187
188
|
# File 'lib/scriptorium/post.rb', line 179
def deleted=(value)
check_invariants
assume { [true, false].include?(value) }
meta["post.deleted"] = value ? "true" : "false"
save_metadata
verify { meta["post.deleted"] == (value ? "true" : "false") }
check_invariants
end
|
#dir ⇒ Object
31
32
33
|
# File 'lib/scriptorium/post.rb', line 31
def dir
repo.root/:posts/@num
end
|
Additional method to load metadata explicitly, so it’s only called once
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
|
# File 'lib/scriptorium/post.rb', line 230
def load_metadata
check_invariants
assume { File.exist?(meta_file) }
@meta = {}
@repo.tree("/tmp/tree.txt")
read_file(meta_file, lines: true, chomp: true).each do |line|
key, value = line.strip.split(/\s+/, 2)
next if key.nil? || key.empty?
@meta[key] = value
end
verify { @meta.is_a?(Hash) }
check_invariants
@meta
end
|
203
204
205
206
|
# File 'lib/scriptorium/post.rb', line 203
def meta
return @meta if @meta
@meta = File.exist?(meta_file) ? load_metadata : {}
end
|
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
# File 'lib/scriptorium/post.rb', line 35
def meta_file
normal_dir = @repo.root/:posts/@num
deleted_dir = @repo.root/:posts/"_#{@num}"
if Dir.exist?(normal_dir)
normal_dir/"meta.txt"
elsif Dir.exist?(deleted_dir)
deleted_dir/"meta.txt"
else
raise "Post directory for #{@num} not found"
end
end
|
#pubdate ⇒ Object
82
83
84
|
# File 'lib/scriptorium/post.rb', line 82
def pubdate
meta["post.pubdate"]
end
|
#pubdate_month_day_year ⇒ Object
140
141
142
|
# File 'lib/scriptorium/post.rb', line 140
def pubdate_month_day_year
[meta["post.pubdate.month"], meta["post.pubdate.day"], meta["post.pubdate.year"]]
end
|
247
248
249
250
251
252
253
254
255
256
257
|
# File 'lib/scriptorium/post.rb', line 247
def save_metadata
check_invariants
assume { @meta.is_a?(Hash) }
assume { !@meta.empty? }
lines = @meta.map { |k, v| sprintf("%-18s %s", k, v) }
write_file(meta_file, lines.join("\n"))
verify { File.exist?(meta_file) }
check_invariants
end
|
#set_pubdate(ymd, seconds: 0) ⇒ Object
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
# File 'lib/scriptorium/post.rb', line 94
def set_pubdate(ymd, seconds: 0)
check_invariants
assume { Scriptorium::Repo.testing }
assume { ymd.is_a?(String) }
assume { seconds.is_a?(Integer) && seconds >= 0 }
raise TestModeOnly unless Scriptorium::Repo.testing
validate_date_format(ymd)
yyyy, mm, dd = ymd.split("-")
t = Time.new(yyyy.to_i, mm.to_i, dd.to_i, 0, 0, seconds)
update_pubdate_metadata(t)
save_metadata
verify { meta["post.pubdate"].is_a?(String) }
check_invariants
end
|
#set_pubdate_with_seconds(ymd, seconds) ⇒ Object
Legacy method for backward compatibility - preserves 12:00 base time
128
129
130
131
132
133
134
135
136
137
138
|
# File 'lib/scriptorium/post.rb', line 128
def set_pubdate_with_seconds(ymd, seconds)
raise TestModeOnly unless Scriptorium::Repo.testing
validate_date_format(ymd)
yyyy, mm, dd = ymd.split("-")
t = Time.new(yyyy.to_i, mm.to_i, dd.to_i, 12, 0, seconds)
update_pubdate_metadata(t)
save_metadata
end
|
#slug ⇒ Object
78
79
80
|
# File 'lib/scriptorium/post.rb', line 78
def slug
meta["post.slug"]
end
|
154
155
156
|
# File 'lib/scriptorium/post.rb', line 154
def tags
meta["post.tags"]
end
|
158
159
160
161
162
|
# File 'lib/scriptorium/post.rb', line 158
def tags_array
tags_str = meta["post.tags"]
return [] if tags_str.nil? || tags_str.strip.empty?
tags_str.strip.split(/,\s*/)
end
|
#title ⇒ Object
74
75
76
|
# File 'lib/scriptorium/post.rb', line 74
def title
meta["post.title"]
end
|
120
121
122
123
124
125
|
# File 'lib/scriptorium/post.rb', line 120
def update_pubdate_metadata(time)
meta["post.pubdate"] = time.strftime("%Y-%m-%d %H:%M:%S")
meta["post.pubdate.month"] = time.strftime("%B")
meta["post.pubdate.day"] = time.strftime("%e")
meta["post.pubdate.year"] = time.strftime("%Y")
end
|
52
53
54
55
56
57
58
59
60
61
62
63
64
|
# File 'lib/scriptorium/post.rb', line 52
def validate_metadata_consistency
return unless File.exist?(meta_file)
normal_dir = @repo.root/:posts/@num
deleted_dir = @repo.root/:posts/"_#{@num}"
metadata_deleted = meta["post.deleted"] == "true"
if Dir.exist?(normal_dir) && metadata_deleted
raise "Inconsistency: Post #{@num} has normal directory but metadata shows deleted=true"
elsif Dir.exist?(deleted_dir) && !metadata_deleted
raise "Inconsistency: Post #{@num} has deleted directory but metadata shows deleted=false"
end
end
|
#vars ⇒ Object
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
|
# File 'lib/scriptorium/post.rb', line 208
def vars
return @vars if defined?(@vars)
@vars = Hash.new("")
meta.each_pair {|k,v| @vars[k.to_sym] = v }
date_value = pubdate || created
if date_value
begin
date_obj = Date.parse(date_value)
@vars[:"post.pubdate.month"] = date_obj.strftime("%B")
@vars[:"post.pubdate.day"] = date_obj.strftime("%e").strip
@vars[:"post.pubdate.year"] = date_obj.strftime("%Y")
rescue Date::Error
end
end
@vars
end
|
#views ⇒ Object
144
145
146
|
# File 'lib/scriptorium/post.rb', line 144
def views
meta["post.views"]
end
|
#views_array ⇒ Object
148
149
150
151
152
|
# File 'lib/scriptorium/post.rb', line 148
def views_array
views_str = meta["post.views"]
return [] if views_str.nil? || views_str.strip.empty?
views_str.strip.split(/\s+/)
end
|