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")

Attributes

type_filter  [RW] 

Public Class methods

return the latest version of page in a site

[Source]

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

Public Instance methods

[Source]

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

TODO this doesn‘t add value

[Source]

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

[Source]

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

[Source]

    # File app/models/version.rb, line 72
72:   def current_version
73:     return self.page.current_version
74:   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 104
104:   def html
105:     IO.readlines(self.path).join
106:   end

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

[Source]

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

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

[Source]

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

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

[Source]

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

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

[Source]

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

[Source]

    # File app/models/version.rb, line 58
58:   def previous_version
59:     case self.version
60:     when 0 then nil 
61:     when nil then self.page.current_version 
62:     else Version.find(:first, :conditions => ['page_id=? and version=?', self.page_id, self.version - 1])
63:     end
64:   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 89
89:     def rel_path_root
90:     return self.path.gsub("#{ENV['EPFWIKI_ROOT_DIR']}#{ENV['EPFWIKI_PUBLIC_FOLDER']}/", '')
91:   end

Relative path to the diff file

[Source]

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

def diff_area_links end

[Source]

     # File app/models/version.rb, line 213
213:   def template?
214:     self.wiki.title == 'Templates' 
215:   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 96
96:   def tidy
97:     logger.info("Tidying file " + path)
98:     tidy_file(path)
99:   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 241
241:   def uma_type_descr
242:     logger.debug("Returning uma_type_description from: #{self.inspect}")
243:     if self.note.blank? || self.note == 'Automatically created'
244:       match = /<table class="overviewTable".*?<td valign="top">(.*?)<\/td>/m.match(self.html)
245:       if match
246:         self.note = match[1]
247:         self.save!
248:         logger.info("Match found: #{self.note}")
249:       else
250:         logger.debug('No match')
251:       end
252:     end
253:     return self.note
254:   end

[Source]

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

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

[Source]

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

Create diff results using XHTMLDiff

[Source]

     # File app/models/version.rb, line 143
143:   def xhtmldiff(from_version)
144:     content_from = "<div>\n" + from_version.html4diff + "\n</div>"
145:     content_to = "<div>\n" + self.html4diff + "\n</div>"
146: 
147:     diff_doc = REXML::Document.new
148:     diff_doc << (div = REXML::Element.new 'div')
149:     hd = XHTMLDiff.new(div)
150:     
151:     parsed_from_content = REXML::HashableElementDelegator.new(REXML::XPath.first(REXML::Document.new(content_from), '/div'))
152:     parsed_to_content = REXML::HashableElementDelegator.new(REXML::XPath.first(REXML::Document.new(content_to), '/div'))
153:     Diff::LCS.traverse_balanced(parsed_from_content, parsed_to_content , hd)
154:     diffs = ''
155:     diff_doc.write(diffs, -1, true, true)
156:     diffs    
157:   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 160
160:   def xhtmldiffpage(from_version, force = false)
161:     p = path_to_diff(from_version)
162:       if !File.exists?(p) || !from_version.checkout.nil? || !self.checkout.nil? || force
163:       logger.info("Generating xhtmldiffpage #{p}")
164:       diffs = xhtmldiff(from_version)
165:       h = page.html
166:       body_tag = Page::BODY_TAG_PATTERN.match(h)[0]
167:       h = h.gsub(BODY_PATTERN,body_tag + diffs + '</body>')
168:       h = h.gsub('</head>',DIFF_STYLE + '</head>')
169:       h = h.gsub(Page::PAGE_HEAD_SNIPPET_PATTERN, '')
170:       file = File.new(p, 'w')
171:       file.puts(h)
172:       file.close
173:     end
174:   end

[Validate]