Class: Mist::Post
Constant Summary
collapse
- TAG_DELIM =
/\s*,\s*/
Class Method Summary
collapse
Instance Method Summary
collapse
Methods included from Permalink
#permalink
Methods inherited from GitModel
#==, #attributes, #class_name, #commit, #commit_message, #default_attributes!, #destroy, #initialize, #inspect, #new_record?, #path, #path_was, #persisted?, #save, #save!, #save_record_file, #update_attributes
#[], #add_attribute_default, #add_attribute_getter, #add_attribute_setter, #all, #attribute, #count, #create!, #exist?, extended, #find, #inherited, #last, #load, #meta_file_path, #record_path, #save_meta_data, #table_name, #timestamps
Constructor Details
This class inherits a constructor from Mist::GitModel
Class Method Details
.all_by_publication_date(include_unpublished = false) ⇒ Object
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
# File 'app/models/mist/post.rb', line 55
def all_by_publication_date(include_unpublished = false)
publications = self[:published_at].sort do |(ka,va), (kb,vb)|
if va.nil?
vb.nil? ? 0 : -1
else
vb.nil? ? 1 : -(va <=> vb)
end
end
unless include_unpublished
publications = publications.select { |(post, publish_date)| !publish_date.blank? }
end
load_existing_with_attribute :published_at, publications
end
|
.increase_popularity(post) ⇒ Object
38
39
40
41
42
|
# File 'app/models/mist/post.rb', line 38
def increase_popularity(post)
self[:popular_posts][post.id] = popularity_for(post.id) + 1
save_meta_data :popular_posts
post.popularity = self[:popular_posts][post.id]
end
|
.load_existing_with_attribute(attribute_name, array) ⇒ Object
29
30
31
|
# File 'app/models/mist/post.rb', line 29
def load_existing_with_attribute(attribute_name, array)
array.collect { |(post_id, attribute_value)| find post_id, attribute_name => attribute_value }.reject { |i| i.nil? }
end
|
71
72
73
74
75
|
# File 'app/models/mist/post.rb', line 71
def matching_tags(tags)
return [] if tags.blank?
matches = self[:tags].inject({}) { |h,(k,v)| ((t = v.split(TAG_DELIM)) & tags).size > 0 ? h[k] = t : nil; h }
load_existing_with_attribute :tags, matches.sort { |a, b| -((a[1] & tags).size <=> (b[1] & tags).size) }
end
|
.most_popular(count) ⇒ Object
33
34
35
36
|
# File 'app/models/mist/post.rb', line 33
def most_popular(count)
load_existing_with_attribute :popularity, self[:popular_posts].sort { |a, b| -(a[1].to_i <=> b[1].to_i) }
end
|
.popularity_for(post_id) ⇒ Object
44
45
46
|
# File 'app/models/mist/post.rb', line 44
def popularity_for(post_id)
self[:popular_posts][post_id] || 0
end
|
.recently_published(count, include_unpublished = false) ⇒ Object
48
49
50
51
52
53
|
# File 'app/models/mist/post.rb', line 48
def recently_published(count, include_unpublished = false)
recent = all_by_publication_date(include_unpublished)
recent.tap do |result|
result.pop while result.length > count
end
end
|
Instance Method Details
#content=(c) ⇒ Object
138
139
140
|
# File 'app/models/mist/post.rb', line 138
def content=(c)
attributes[:content] = c.gsub(/\r/, "")
end
|
#content_as_html ⇒ Object
165
166
167
|
# File 'app/models/mist/post.rb', line 165
def content_as_html
GitHub::Markup.render("#{title}.markdown", content_with_embedded_gists).html_safe
end
|
#content_as_html_preview ⇒ Object
169
170
171
172
173
174
|
# File 'app/models/mist/post.rb', line 169
def content_as_html_preview
first_paragraph = /\A(.+?)(\n\n|\n |\z)/m.match(content.gsub(/\r/, ''))
GitHub::Markup.render("#{title}.markdown", first_paragraph[1]).html_safe
end
|
#content_with_embedded_gists ⇒ Object
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
|
# File 'app/models/mist/post.rb', line 176
def content_with_embedded_gists
return content.dup if gist_id.blank?
template = '<script src="https://gist.github.com/__ID__.js?file=__FILENAME__"></script>'
template['__ID__'] = gist_id.to_s
content.dup.tap do |result|
code_examples.reverse.each do |example|
result[example.offset] = template.sub(/__FILENAME__/, example.filename) + "\n"
end
end
end
|
#destroy_gist ⇒ Object
247
248
249
|
# File 'app/models/mist/post.rb', line 247
def destroy_gist
gist.destroy if gist && gist.persisted?
end
|
#draft? ⇒ Boolean
122
123
124
|
# File 'app/models/mist/post.rb', line 122
def draft?
!published?
end
|
#generated_gist_description ⇒ Object
142
143
144
|
# File 'app/models/mist/post.rb', line 142
def generated_gist_description
'Code examples for "%s" - %s' % [title, url]
end
|
#gist ⇒ Object
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
# File 'app/models/mist/post.rb', line 146
def gist
@gist ||= begin
if gist_id.blank?
if has_code_examples?
ActiveGist.new(:description => generated_gist_description, :public => true)
else
nil
end
else
begin
ActiveGist.find(gist_id)
rescue RestClient::ResourceNotFound
self.gist_id = nil
nil
end
end
end
end
|
#has_code_examples? ⇒ Boolean
193
194
195
|
# File 'app/models/mist/post.rb', line 193
def has_code_examples?
code_examples.length > 0
end
|
#load_code_examples_from_gist ⇒ Object
201
202
203
204
205
206
207
208
209
210
211
212
213
|
# File 'app/models/mist/post.rb', line 201
def load_code_examples_from_gist
if gist && gist.persisted?
self.content = self.content.dup.tap do |result|
code_examples.reverse.each do |example|
if gist.files[example.filename]
lines = gist.files[example.filename][:content].split("\n")
lines.unshift " file: #{example.filename}"
result[example.offset] = lines.join("\n ") + "\n"
end
end
end
end
end
|
#publish ⇒ Object
126
127
128
|
# File 'app/models/mist/post.rb', line 126
def publish
self.published_at = Time.now unless published?
end
|
#published=(bool) ⇒ Object
134
135
136
|
# File 'app/models/mist/post.rb', line 134
def published=(bool)
bool ? publish : unpublish
end
|
#published? ⇒ Boolean
118
119
120
|
# File 'app/models/mist/post.rb', line 118
def published?
!published_at.blank?
end
|
#set_gist_data ⇒ Object
Assigns the file contents of each file in the gist according to what’s found in #content. Does not save the gist. Returns the list of files themselves.
217
218
219
220
221
222
223
224
|
# File 'app/models/mist/post.rb', line 217
def set_gist_data
gist.description = generated_gist_description
gist.files.keys.each { |filename| gist.files[filename] = nil }
code_examples.each do |example|
gist.files[example.filename] = { :content => example }
end
gist.files
end
|
#similar_posts(max_count = nil) ⇒ Object
78
79
80
81
82
83
84
85
|
# File 'app/models/mist/post.rb', line 78
def similar_posts(max_count = nil)
self.class.matching_tags(tags).tap do |matching|
matching.delete self while max_count && matching.length > max_count
matching.pop
end
end
end
|
87
88
89
90
91
92
93
|
# File 'app/models/mist/post.rb', line 87
def tags=(t)
if t.kind_of?(String)
attributes[:tags] = t.split(TAG_DELIM)
else
attributes[:tags] = t
end
end
|
#title=(value) ⇒ Object
114
115
116
|
# File 'app/models/mist/post.rb', line 114
def title=(value)
attributes[:title] = value
end
|
#unpublish ⇒ Object
130
131
132
|
# File 'app/models/mist/post.rb', line 130
def unpublish
self.published_at = nil
end
|
#update_gist_if_necessary ⇒ Object
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
|
# File 'app/models/mist/post.rb', line 230
def update_gist_if_necessary
return unless errors.empty?
if has_code_examples?
set_gist_data
if gist.changed?
errors.add(:gist, "could not be saved: #{gist.errors.full_messages.join('; ')}") unless gist.save
end
self.gist_id = gist.id
else
gist.destroy if gist && gist.persisted?
end
end
|
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
# File 'app/models/mist/post.rb', line 95
def update_meta
if popularity_changed? || new_record?
self.class[:popular_posts][id] = popularity
self.class.save_meta_data :popular_posts
end
if published_at_changed? || new_record?
self.class[:published_at][id] = published_at
self.class.save_meta_data :published_at
end
if tags && !tags.empty?
self.class[:tags][id] = tags.join(', ')
else
self.class[:tags].delete id
end
self.class.save_meta_data :tags
end
|
#url(options = {}) ⇒ Object
226
227
228
|
# File 'app/models/mist/post.rb', line 226
def url(options = {})
Mist::Engine.routes.url_helpers.post_path(id, options.reverse_merge(:only_path => false).reverse_merge(Rails.application.default_url_options))
end
|