C0 code coverage information
Generated on Fri Aug 25 11:26:26 PDT 2006 with rcov 0.7.0
Code reported as executed by Ruby looks like this...
and this: this line is also marked as covered.
Lines considered as run by rcov, but not reported by Ruby, look like this,
and this: these lines were inferred by rcov (using simple heuristics).
Finally, here's a line marked as not executed.
1 require 'auditor'
2 require 'yaml'
3 require 'article_page'
4 require 'link'
5 require 'media_link'
6
7 class Article < ActiveRecord::Base
8 include Auditor
9 include ActionView::Helpers::TextHelper
10
11 acts_as_versioned :limit => 10
12
13 self.non_versioned_columns << 'created_at' << 'type' << 'assignment_id' << 'cache_dirty'
14
15 attr_accessor :editor, :dont_timestamp
16
17 after_create :audit_create
18 after_update :audit_update
19 after_destroy :audit_destroy
20 before_save :dump_collections
21
22 @@audit_switch = true
23
24 belongs_to :sub_category
25 belongs_to :download_type
26 belongs_to :author,
27 :class_name => "User",
28 :foreign_key => "author_id"
29
30 belongs_to :assignment
31 belongs_to :sub_category
32 has_and_belongs_to_many :lists
33
34 belongs_to :image
35 belongs_to :alt_image,
36 :class_name => "Image",
37 :foreign_key => "alt_image_id"
38
39 validates_presence_of :title
40 validates_uniqueness_of :old_path, :if => Proc.new { |article| not article.old_path.nil? and article.old_path != "" }
41
42 def Article::audit_off
43 @@audit_switch = false
44 end
45
46 def Article::audit_on
47 @@audit_switch = true
48 end
49
50 def Article::audit_switch?
51 @@audit_switch
52 end
53
54
55 def to_param
56 new_array = [artist, truncate_title(50, false)]
57 munge_title new_array
58 end
59
60 def truncate_title(width=33, ellipses=true)
61 truncator full_title, width, ellipses
62 end
63
64 def increment_read
65 #Thread.new(self) do | article |
66 counter = ReadCount.find(:first, :conditions => ["article_id = ?", self[:id]])
67 if counter
68 counter.count += 1
69 counter.save
70 else
71 ReadCount.create( { :article_id => self[:id], :count => 1, :article_type => self.class.to_s } )
72 end
73 #end
74 end
75
76 def full_title
77 self.title
78 end
79
80 def article_pages= (pages_array)
81 unless pages_array.is_a? Array
82 raise ArgumentError("article_pages= can only be set to a class of type Array.")
83 end
84 @article_pages = pages_array
85 end
86
87 def article_pages
88 unless @article_pages
89 yaml = read_attribute("article_pages_data")
90 if yaml
91 @article_pages = YAML.load(yaml)
92 @article_pages.sort! { |x, y| x.page_number.to_i <=> y.page_number.to_i }
93 else
94 @article_pages = []
95 end
96 end
97 @article_pages
98 end
99
100 def links= (links_array)
101 unless links_array.is_a? Array
102 raise ArgumentError("links= can only be set to a class of type Array.")
103 end
104 @links = links_array
105 end
106
107 def links
108 unless @links
109 yaml = read_attribute("links_data")
110 if yaml
111 @links = YAML.load(yaml)
112 else
113 @links =[]
114 end
115 end
116 @links
117 end
118
119 def media_links= (media_links_array)
120 unless media_links_array.is_a? Array
121 raise ArgumentError("media_links= can only be set to a class of type Array.")
122 end
123 @media_links = media_links_array
124 end
125
126 def media_links
127 unless @media_links
128 yaml = read_attribute("media_links_data")
129 if yaml
130 @media_links = YAML.load(yaml)
131 else
132 @media_links =[]
133 end
134 end
135 @media_links
136 end
137
138 def approved?
139 self.approved == 1
140 end
141
142 def submitted?
143 self.submitted == 1
144 end
145
146 def suppress_byline?
147 self.suppress_byline == 1
148 end
149
150 def pin_article?
151 self.pin_article == 1
152 end
153
154 def display_author
155 if self.custom_author
156 return self.custom_author
157 else
158 if self.author
159 return self.author.display_name
160 else
161 return nil
162 end
163 end
164 end
165
166 def self.find_recent(options = {})
167 default_options = {
168 :limit => 5,
169 :order => 'published_at DESC, premiere_position',
170 :select => 'id, type, title, artist, abstract, author_id, custom_author, image_id, alt_image_id, article_pages_data, published_at, sub_category_id, download_type_id, premiere_position',
171 :conditions => ['published_at <= ? AND approved = 1', Time.now]
172 }
173
174 default_options.update options
175 self.find :all, default_options
176 end
177
178 def self.create_search_condition(params)
179 sqlstring = "(published_at <= CURDATE() OR published_at IS NULL) AND approved = 1 AND ("
180 and_bits = []
181 vars = {}
182 if params[:artist] and params[:artist] != ""
183 terms = tokenize_terms(params[:artist])
184 or_bits = []
185 terms.each_with_index {|term, index| or_bits << "artist LIKE :artist_#{index}"; vars["artist_#{index}".to_sym] = term }
186
187 and_bits << "(#{or_bits.join(" OR ")})"
188 end
189 if params[:title] and params[:title] != ""
190 terms = tokenize_terms(params[:title])
191 or_bits = []
192 terms.each_with_index {|term, index| or_bits << "title LIKE :title_#{index}"; vars["title_#{index}".to_sym] = term }
193
194 and_bits << "(#{or_bits.join(" OR ")})"
195 end
196 if params[:record_label] and params[:record_label] != ""
197 terms = tokenize_terms(params[:record_label])
198 or_bits = []
199 terms.each_with_index {|term, index| or_bits << "record_label LIKE :record_label_#{index}"; vars["record_label_#{index}".to_sym] = term }
200
201 and_bits << "(#{or_bits.join(" OR ")})"
202 end
203 if params[:author] and params[:author] != ""
204 terms = tokenize_terms(params[:author])
205 or_bits = []
206 terms.each_with_index {|term, index| or_bits << "(custom_author LIKE :author_#{index} OR display_name LIKE :author_#{index})"; vars["author_#{index}".to_sym] = term }
207
208 and_bits << "(#{or_bits.join(" OR ")})"
209 end
210 if params[:keywords] and params[:keywords] != ""
211 terms = tokenize_terms(params[:keywords])
212 or_bits = []
213 terms.each_with_index {|term, index| or_bits << "(artist LIKE :keywords_#{index} OR " +
214 "title LIKE :keywords_#{index} OR " +
215 "record_label LIKE :keywords_#{index} OR " +
216 "subtitle LIKE :keywords_#{index} OR " +
217 "bside_artist LIKE :keywords_#{index} OR " +
218 "bside_title LIKE :keywords_#{index} OR " +
219 "reissue_label LIKE :keywords_#{index} OR " +
220 "genre LIKE :keywords_#{index} OR " +
221 "source LIKE :keywords_#{index} OR " +
222 "custom_author LIKE :keywords_#{index})"; vars["keywords_#{index}".to_sym] = term}
223
224 and_bits << "(#{or_bits.join(" OR ")})"
225 end
226
227 if params[:max_score] and params[:max_score] != ""
228 and_bits << "rating <= :max_score"
229 vars[:max_score] = params[:max_score]
230 end
231
232 if params[:min_score] and params[:min_score] != ""
233 and_bits << "rating >=:min_score"
234 vars[:min_score] = params[:min_score]
235 end
236
237 sqlstring << and_bits.join(" AND ")
238 sqlstring << ")"
239 [sqlstring, vars]
240 end
241
242 def published_at_index
243 if self.published_at
244 self.published_at.to_i
245 else
246 nil
247 end
248 end
249
250 def related(limit)
251 terms, like_statement = like_terms
252
253 results = []
254
255 results = Article.find(
256 :all,
257 :select => "id, type, title, artist, sub_category_id, published_at, abstract, article_pages_data, image_id, source",
258 :limit => limit,
259 :order => 'published_at DESC, updated_at DESC',
260 :conditions => ["(artist #{like_statement.join('OR artist ')}) AND (type = 'RecordReview' OR type = 'TrackReview') " +
261 "AND (published_at <= NOW() OR published_at IS NULL) AND approved = 1 AND id != #{self[:id]} "].concat(terms))
262
263 results.concat Article.find(
264 :all,
265 :select => "id, type, title, artist, sub_category_id, published_at, abstract, article_pages_data, image_id, source",
266 :limit => limit,
267 :order => 'published_at DESC, updated_at DESC',
268 :conditions => ["((artist #{like_statement.join('OR artist ')}) OR (title #{like_statement.join('OR title ')})) AND (type = 'News' OR type = 'NewsBlurb') " +
269 "AND (published_at <= NOW() OR published_at IS NULL) AND approved = 1 AND id != #{self[:id]} "].concat(terms).concat(terms))
270
271 sort_and_limit_related(results, limit)
272 end
273
274 def related_news(limit)
275 terms, like_statement = like_terms
276
277 Article.find(
278 :all,
279 :select => "id, type, title, artist, sub_category_id, published_at, abstract, article_pages_data, image_id, source",
280 :limit => limit,
281 :order => 'published_at DESC, updated_at DESC',
282 :conditions => ["((artist #{like_statement.join('OR artist ')}) OR (title #{like_statement.join('OR title ')})) AND (type = 'News' OR type = 'NewsBlurb') " +
283 "AND (published_at <= NOW() OR published_at IS NULL) AND approved = 1 AND id != #{self[:id]} "].concat(terms).concat(terms))
284 end
285
286 def related_reviews_features(limit)
287 terms, like_statement = like_terms
288
289 results = []
290
291 results = Article.find(
292 :all,
293 :select => "id, type, title, artist, sub_category_id, published_at, abstract, article_pages_data, image_id, source",
294 :limit => limit,
295 :order => 'published_at DESC, updated_at DESC',
296 :conditions => ["(artist #{like_statement.join('OR artist ')}) AND (type = 'RecordReview' OR type = 'TrackReview') " +
297 "AND (published_at <= NOW() OR published_at IS NULL) AND approved = 1 AND id != #{self[:id]}"].concat(terms))
298
299 results.concat Feature.find(
300 :all,
301 :select => "id, type, title, artist, sub_category_id, published_at, abstract, article_pages_data, image_id, source",
302 :limit => limit,
303 :order => 'published_at DESC, updated_at DESC',
304 :conditions => ["((artist #{like_statement.join('OR artist ')}) OR (title #{like_statement.join('OR title ')})) " +
305 "AND (published_at <= NOW() OR published_at IS NULL) AND approved = 1 AND id != #{self[:id]}"].concat(terms).concat(terms))
306
307 sort_and_limit_related(results, limit)
308 end
309
310 protected
311
312 def truncator(title, width, ellipses)
313 if tilde = title =~ /~/
314 if ellipses
315 title[0...tilde] << '...'
316 else
317 title[0...tilde]
318 end
319 else
320 if ellipses
321 truncate(title, width, '...')
322 else
323 truncate(title, width, '')
324 end
325 end
326 end
327
328 def dump_collections
329 if @article_pages
330 @article_pages.sort! {|x, y| x.page_number.to_i <=> y.page_number.to_i }
331 write_attribute("article_pages_data", YAML.dump_stream(@article_pages))
332 end
333
334 if @links
335 write_attribute("links_data", YAML.dump_stream(@links))
336 end
337
338 if @media_links
339 write_attribute("media_links_data", YAML.dump_stream(@media_links))
340 end
341 end
342 #def new_record=(value)
343 # @new_record = value
344 #end
345
346 def munge_title(title_items)
347 title_items.delete("")
348 title_items.compact!
349 title_items.each_with_index do |item, index|
350 title_items[index] = strip_tags(item).gsub(/(\s|\/|\.{1,3})|(&)|([\W])/) do |m|
351 if $1
352 "_"
353 elsif $2
354 "_and_"
355 else
356 ""
357 end
358 end
359 end
360 title_string = title_items.join("_")
361 while title_string['__']
362 title_string = title_string.gsub('__', '_')
363 end
364 title_string.slice!(1) if title_string.first == '_'
365 last = title_string.size - 1
366 title_string.slice!(last) if title_string[last] == '_'
367 title_string
368 end
369
370 def self.tokenize_terms(terms)
371 terms.split(/[\/\[\]]|OR/).collect { |sub_term| "%#{sub_term.gsub(/and|[&]|the/i, '%').gsub(/ø|Ø|Ǿ|ǿ/, 'o').strip}%" }
372 end
373
374 def like_terms
375 terms = Article.tokenize_terms(self[(artist and artist != "") ? :artist : :title])
376 like_statement = []
377 terms.size.times { like_statement << 'LIKE ? ' }
378 [terms, like_statement]
379 end
380
381 def sort_and_limit_related(results, limit)
382 results.sort! do | a, b |
383 if a.nil? and not b.nil?
384 1
385 elsif b.nil? and not a.nil?
386 -1
387 elsif a.nil? and b.nil?
388 0
389 elsif a.published_at.nil? and not b.published_at.nil?
390 1
391 elsif b.published_at.nil? and not a.published_at.nil?
392 -1
393 elsif a.published_at.nil? and b.published_at.nil?
394 0
395 else
396 b.published_at <=> a.published_at
397 end
398 end
399
400 results[0...limit]
401 end
402
403 end
404
Generated using the rcov code coverage analysis tool for Ruby version 0.7.0.