From 1eea06052e2a928400afc9595f26aa3bfcc58eb0 Mon Sep 17 00:00:00 2001 From: Reinier Balt Date: Thu, 12 Apr 2012 11:34:08 +0200 Subject: [PATCH] store rendered notes of todos in database to avoid costly rendering when you load a page --- app/controllers/application_controller.rb | 8 ---- app/helpers/application_helper.rb | 18 -------- app/helpers/todos_helper.rb | 2 +- app/models/todo.rb | 9 ++++ .../20120412072508_add_rendered_notes.rb | 26 +++++++++++ lib/tracks/utils.rb | 45 +++++++++++++++++++ 6 files changed, 81 insertions(+), 27 deletions(-) create mode 100644 db/migrate/20120412072508_add_rendered_notes.rb create mode 100644 lib/tracks/utils.rb diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 9255fc3a..5c3d385c 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -143,14 +143,6 @@ class ApplicationController < ActionController::Base return json_elems end - # Uses RedCloth to transform text using either Textile or Markdown Need to - # require redcloth above RedCloth 3.0 or greater is needed to use Markdown, - # otherwise it only handles Textile - # - def markdown(text) - RedCloth.new(text).to_html - end - # Here's the concept behind this "mobile content negotiation" hack: In # addition to the main, AJAXy Web UI, Tracks has a lightweight low-feature # 'mobile' version designed to be suitablef or use from a phone or PDA. It diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 3744e1f2..f7a2e696 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -189,24 +189,6 @@ module ApplicationHelper end end - AUTO_LINK_MESSAGE_RE = %r{message://<[^>]+>} unless const_defined?(:AUTO_LINK_MESSAGE_RE) - - # Converts message:// links to href. This URL scheme is used on Mac OS X - # to link to a mail message in Mail.app. - def auto_link_message(text) - text.gsub(AUTO_LINK_MESSAGE_RE) do - href = $& - left, right = $`, $' - # detect already linked URLs and URLs in the middle of a tag - if left =~ /<[^>]+$/ && right =~ /^[^>]*>/ - # do not change string; URL is alreay linked - href - else - content = content_tag(:a, h(href), :href => h(href)) - end - end - end - def format_note(note) note = auto_link_message(note) note = markdown(note) diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb index 3f616b86..26fa7a8f 100644 --- a/app/helpers/todos_helper.rb +++ b/app/helpers/todos_helper.rb @@ -65,7 +65,7 @@ module TodosHelper def collapsed_notes_image(todo) link = link_to(image_tag( 'blank.png', :width=>'16', :height=>'16', :border=>'0' ), "#", {:class => 'show_notes', :title => 'Show notes'}) - notes = content_tag(:div, {:class => "todo_notes", :id => dom_id(todo, 'notes'), :style => "display:none"}) { format_note(todo.notes) } + notes = content_tag(:div, {:class => "todo_notes", :id => dom_id(todo, 'notes'), :style => "display:none"}) { todo.rendered_notes } return link+notes end diff --git a/app/models/todo.rb b/app/models/todo.rb index c056ff58..0e49cb3c 100644 --- a/app/models/todo.rb +++ b/app/models/todo.rb @@ -1,5 +1,6 @@ class Todo < ActiveRecord::Base + before_save :render_note after_save :save_predecessors # relations @@ -392,4 +393,12 @@ class Todo < ActiveRecord::Base return todo end + def render_note + unless notes.nil? + rendered_notes = Tracks::Utils.render_text(notes) + else + rendered_notes = nil + end + end + end diff --git a/db/migrate/20120412072508_add_rendered_notes.rb b/db/migrate/20120412072508_add_rendered_notes.rb new file mode 100644 index 00000000..25fa4603 --- /dev/null +++ b/db/migrate/20120412072508_add_rendered_notes.rb @@ -0,0 +1,26 @@ +class AddRenderedNotes < ActiveRecord::Migration + def self.up + add_column :todos, 'rendered_notes', :text + + puts "-- Clearing show_from dates from completed todos" + # clear up completed todos that have show_from set. These could have been left over from before the AASM migration + Todo.completed.find(:all, :conditions =>[ "NOT(show_from IS NULL)"]).each {|t| t.show_from=nil; t.save!} + puts "-- Generating new column values from notes. This may take a while." + # Call save! on each todo to force generation of rendered_todos + i=0; max = Todo.all.count; start = Time.now + Todo.all.each do |todo| + todo.save(false) + i = i + 1 + if i%250==0 + elapsed_sec = (Time.now-start) + remaining = (elapsed_sec / i)*(max-i) + puts "Progress: #{i} / #{max} (#{(i.to_f/max.to_f*100.0).floor}%) ETA=#{remaining.floor}s" + end + end + puts "Done: #{i} / #{max}" + end + + def self.down + remove_column :todos, 'rendered_notes' + end +end diff --git a/lib/tracks/utils.rb b/lib/tracks/utils.rb new file mode 100644 index 00000000..01368a03 --- /dev/null +++ b/lib/tracks/utils.rb @@ -0,0 +1,45 @@ +module Tracks + + class Utils + AUTO_LINK_MESSAGE_RE = %r{message://<[^>]+>} unless const_defined?(:AUTO_LINK_MESSAGE_RE) + + # Converts message:// links to href. This URL scheme is used on Mac OS X + # to link to a mail message in Mail.app. + def self.auto_link_message(text) + text.gsub(AUTO_LINK_MESSAGE_RE) do + href = $& + left, right = $`, $' + # detect already linked URLs and URLs in the middle of a tag + if left =~ /<[^>]+$/ && right =~ /^[^>]*>/ + # do not change string; URL is alreay linked + href + else + content = content_tag(:a, h(href), :href => h(href)) + end + end + end + + def self.render_text(text) + rendered = Tracks::Utils.auto_link_message(text) + rendered = markdown(rendered) + rendered = ActionController::Base.helpers.auto_link(rendered, :link => :urls) + + # add onenote and message protocols + Sanitize::Config::RELAXED[:protocols]['a']['href'] << 'onenote' + Sanitize::Config::RELAXED[:protocols]['a']['href'] << 'message' + + rendered = Sanitize.clean(rendered, Sanitize::Config::RELAXED) + return rendered + end + + # Uses RedCloth to transform text using either Textile or Markdown Need to + # require redcloth above RedCloth 3.0 or greater is needed to use Markdown, + # otherwise it only handles Textile + # + def self.markdown(text) + RedCloth.new(text).to_html + end + + end + +end \ No newline at end of file