Class Version
In: app/models/version.rb
Parent: ActiveRecord::Base

Methods

Constants

BODY_PATTERN = /<body.*<\/body>/m
LINKS_PATTERN = /<a.*?href=".*?".*?<\/a>/
HREF_PATTERN = /href="(.*?)"/
DIFF_STYLE = ["<style type=\"text/css\">", " .diffdel,del.diffmod, .diffdel *, del.diffmod * {", " background-color:#FAA;", " text-decoration:line-through;", " }", " .diffins,ins.diffmod, .diffins *, ins.diffmod * {", " background-color:#AFA;", " text-decoration:underline;", " }", " .diffmod, .diffmod * {", " border: 2px solid #FE0;", "}", "</style>"].join("\n")

Public Class methods

return the latest version of page in a site

[Source]

    # File app/models/version.rb, line 75
75:   def self.find_latest_version(site, page)
76:     return Version.find(:first ,:order => 'version DESC', :conditions => ["page_id=? and wiki_id =?", page.id, site.id])    
77:   end

Public Instance methods

[Source]

     # File app/models/version.rb, line 215
215:   def base_version?
216:     !user_version?
217:   end

TODO this doesn‘t add value

[Source]

    # File app/models/version.rb, line 65
65:   def baseversion
66:     return Version.find(:first, :conditions => ['wiki_id = ? and page_id=? and version=0',
67:     self.wiki_id, self.page_id])
68:   end

[Source]

     # File app/models/version.rb, line 233
233:   def before_destroy
234:     logger.debug("Before Destroy: deleting file #{self.path}")
235:     File.delete(self.path)
236:   end

[Source]

    # File app/models/version.rb, line 70
70:   def current_version
71:     return self.page.current_version
72:   end

method html read or writes the HTML of a version from or to the version file. When writing HTML Tidy is used to cleanup the file

[Source]

     # File app/models/version.rb, line 102
102:   def html
103:     IO.readlines(self.path).join
104:   end

Create the tmp diff source file, clean it using Tidy and prepare for use with XHTMLDiff

[Source]

     # File app/models/version.rb, line 107
107:   def html4diff(h = nil)
108:     logger.info("Create tmp diff source file #{self.path_to_tmp_diff_html} using #{self.path}")    
109:     File.copy(self.path, self.path_to_tmp_diff_html)
110:     tidy_file(self.path_to_tmp_diff_html)    
111:     h = IO.readlines(self.path_to_tmp_diff_html).join if h.nil?
112:     h = BODY_PATTERN.match(h)[0]
113:     h = h.gsub(Page::TREEBROWSER_PLACEHOLDER, '').gsub(Page::TREEBROWSER_PATTERN, '')
114:     h = h.gsub(Page::SHIM_TAG_PATTERN, Page::SHIM_TAG) # TODO remove? This should not be necessary, see html
115:     h = h.gsub(/<!-- epfwiki.*end -->/m, '') # TODO remove?
116:     h = h.gsub('</body>','').gsub(/<body.*>/, '')
117:     
118:     # If the html originates from TinyMCE it contains extra tbody tags.
119:     # TinyMCE adds those and this is good XHTML but if
120:     # we strip those so we get better diff results
121:     # Because without it, compare with the baseversion (not modified by TinyMCE) will 
122:     # result false positives (changes)
123:     h = h.gsub(/<[\/]{0,1}(tbody){1}[.]*>/, '') 
124:     
125:     # TODO Workaround for Tidy adding title attributes which causes false changes
126:     #--
127:     # The question mark makes it lazy, so it won't match for instance  
128:     # title="Org"></a><span class="overview" it will match
129:     # title="Org" only
130:     #++
131:     h = h.gsub(/title="(.*?)"/, '') # WE REMOVE ALL TITLE ATTRIBUTES FOR BETTER DIFFS
132:     logger.debug("html4diff #{self.path}: ")
133:     #logger.debug(h)
134:     file = File.new(self.path_to_tmp_diff_html, 'w')
135:     file.puts(h)
136:     file.close    
137:     h 
138:   end

return the latest version based on a version TODO use page.last_version

[Source]

    # File app/models/version.rb, line 81
81:   def latest_version
82:     return Version.find(:first ,:order => 'version DESC', :conditions => ["page_id=? and wiki_id =?", self.page, self.wiki])    
83:   end

Absolute path to the diff file and paths to the intermediate (tidied, cleaned) HTML files

[Source]

     # File app/models/version.rb, line 175
175:   def path_to_diff(from_version)
176:     return "#{ENV['EPFWIKI_ROOT_DIR']}#{ENV['EPFWIKI_PUBLIC_FOLDER']}/#{relpath_to_diff(from_version)}"
177:   end

Path intermediate (tidied, cleaned) HTML files, prepared for XHTMLDiff

[Source]

     # File app/models/version.rb, line 185
185:   def path_to_tmp_diff_html
186:     File.makedirs(ENV['EPFWIKI_DIFFS_PATH']) unless File.exists?(ENV['EPFWIKI_DIFFS_PATH'])    
187:     "#{ENV['EPFWIKI_DIFFS_PATH']}#{self.id.to_s}.html"  
188:   end

[Source]

    # File app/models/version.rb, line 56
56:   def previous_version
57:     case self.version
58:     when 0 then nil 
59:     when nil then self.page.current_version 
60:     else Version.find(:first, :conditions => ['page_id=? and version=?', self.page_id, self.version - 1])
61:     end
62:   end

Returns relative path of a version in folder ‘public’, the column rel_path stores the relatieve path in a Site folder

[Source]

    # File app/models/version.rb, line 87
87:     def rel_path_root
88:     return self.path.gsub("#{ENV['EPFWIKI_ROOT_DIR']}#{ENV['EPFWIKI_PUBLIC_FOLDER']}/", '')
89:   end

Relative path to the diff file

[Source]

     # File app/models/version.rb, line 180
180:   def relpath_to_diff(from_version)
181:     return '/' + self.wiki.rel_path + '/' + self.page.rel_path + "_EPFWIKI_DIFF_V#{from_version.version}_V#{self.version}.html"  
182:   end

def diff_area_links end

[Source]

     # File app/models/version.rb, line 211
211:   def template?
212:     self.wiki.title == 'Templates' 
213:   end

use tidy to tidy the file using HTML Tidy. This also removes any empty lines that may have been created by PinEdit.

[Source]

    # File app/models/version.rb, line 94
94:   def tidy
95:     logger.info("Tidying file " + path)
96:     tidy_file(path)
97:   end

uma_type_descr is used to retrieve the brief description for a template, see app/views/pages/new

[Source]

     # File app/models/version.rb, line 239
239:   def uma_type_descr
240:     logger.debug("Returning uma_type_description from: #{self.inspect}")
241:     if self.note.blank? || self.note == 'Automatically created'
242:       match = /<table class="overviewTable".*?<td valign="top">(.*?)<\/td>/m.match(self.html)
243:       if match
244:         self.note = match[1]
245:         self.save!
246:         logger.info("Match found: #{self.note}")
247:       else
248:         logger.debug('No match')
249:       end
250:     end
251:     return self.note
252:   end

[Source]

     # File app/models/version.rb, line 219
219:   def user_version?
220:     baseline_process_id.nil?
221:   end

version_text returns version number, site title and baseline, for example 1 from OpenUP(OUP_20060721)

[Source]

     # File app/models/version.rb, line 225
225:   def version_text
226:     if self.base_version? 
227:       return self.version.to_s + ' from ' + self.wiki.title + ' (' + self.baseline_process.title+ ')'
228:     else
229:       return self.version.to_s + ' from ' + self.wiki.title + ' (' + self.user.name + ')'
230:     end
231:   end

Create diff results using XHTMLDiff

[Source]

     # File app/models/version.rb, line 141
141:   def xhtmldiff(from_version)
142:     content_from = "<div>\n" + from_version.html4diff + "\n</div>"
143:     content_to = "<div>\n" + self.html4diff + "\n</div>"
144: 
145:     diff_doc = REXML::Document.new
146:     diff_doc << (div = REXML::Element.new 'div')
147:     hd = XHTMLDiff.new(div)
148:     
149:     parsed_from_content = REXML::HashableElementDelegator.new(REXML::XPath.first(REXML::Document.new(content_from), '/div'))
150:     parsed_to_content = REXML::HashableElementDelegator.new(REXML::XPath.first(REXML::Document.new(content_to), '/div'))
151:     Diff::LCS.traverse_balanced(parsed_from_content, parsed_to_content , hd)
152:     diffs = ''
153:     diff_doc.write(diffs, -1, true, true)
154:     diffs    
155:   end

Create diff file using xhtmldiff. The file is generated if doesn‘t exist of if one of the versions is checked out.

[Source]

     # File app/models/version.rb, line 158
158:   def xhtmldiffpage(from_version, force = false)
159:     p = path_to_diff(from_version)
160:       if !File.exists?(p) || !from_version.checkout.nil? || !self.checkout.nil? || force
161:       logger.info("Generating xhtmldiffpage #{p}")
162:       diffs = xhtmldiff(from_version)
163:       h = page.html
164:       body_tag = Page::BODY_TAG_PATTERN.match(h)[0]
165:       h = h.gsub(BODY_PATTERN,body_tag + diffs + '</body>')
166:       h = h.gsub('</head>',DIFF_STYLE + '</head>')
167:       h = h.gsub(Page::PAGE_HEAD_SNIPPET_PATTERN, '')
168:       file = File.new(p, 'w')
169:       file.puts(h)
170:       file.close
171:     end
172:   end

[Validate]