From 374f8f2f69c428cdad4c0795311f0133b8516bb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Charignon?= Date: Thu, 10 Apr 2014 11:49:38 -0700 Subject: [PATCH] First attempt at a global latest changes overview. - uses a wiki_options entry named :latest_changes_count instead of a constant - lists modified pages with links --- lib/gollum/app.rb | 7 ++ lib/gollum/templates/latest_changes.mustache | 39 +++++++++ lib/gollum/templates/page.mustache | 3 + lib/gollum/views/latest_changes.rb | 90 ++++++++++++++++++++ test/test_latest_changes_view.rb | 45 ++++++++++ 5 files changed, 184 insertions(+) create mode 100644 lib/gollum/templates/latest_changes.mustache create mode 100644 lib/gollum/views/latest_changes.rb create mode 100644 test/test_latest_changes_view.rb diff --git a/lib/gollum/app.rb b/lib/gollum/app.rb index 600ec654..b84559d4 100644 --- a/lib/gollum/app.rb +++ b/lib/gollum/app.rb @@ -351,6 +351,13 @@ module Precious end end + get '/latest_changes' do + @wiki = wiki_new + max_count = settings.wiki_options.fetch(:latest_changes_count, 10) + @versions = @wiki.latest_changes({:max_count => max_count}) + mustache :latest_changes + end + post '/compare/*' do @file = params[:splat].first @versions = params[:versions] || [] diff --git a/lib/gollum/templates/latest_changes.mustache b/lib/gollum/templates/latest_changes.mustache new file mode 100644 index 00000000..9044c23a --- /dev/null +++ b/lib/gollum/templates/latest_changes.mustache @@ -0,0 +1,39 @@ +
+ +
+ +
+ + + + {{#versions}} + + + + + {{/versions}} + + +
+ {{>author_template}} + + {{date}}:  + {{message}} + [{{id7}}] + {{#files}} +
+ {{file}} + {{/files}} +
+
+
+ +
diff --git a/lib/gollum/templates/page.mustache b/lib/gollum/templates/page.mustache index d7b7a53a..ffeeb96a 100644 --- a/lib/gollum/templates/page.mustache +++ b/lib/gollum/templates/page.mustache @@ -34,6 +34,9 @@ Mousetrap.bind(['e'], function( e ) {
  • History
  • +
  • +
  • Latest Changes
  • {{/page_exists}} diff --git a/lib/gollum/views/latest_changes.rb b/lib/gollum/views/latest_changes.rb new file mode 100644 index 00000000..8707e489 --- /dev/null +++ b/lib/gollum/views/latest_changes.rb @@ -0,0 +1,90 @@ +module Precious + module Views + class LatestChanges < Layout + + attr_reader :wiki + + def title + "Latest Changes (Globally)" + end + + def versions + i = @versions.size + 1 + @versions.map do |v| + i -= 1 + { :id => v.id, + :id7 => v.id[0..6], + :num => i, + :author => v.author.name.respond_to?(:force_encoding) ? v.author.name.force_encoding('UTF-8') : v.author.name, + :message => v.message.respond_to?(:force_encoding) ? v.message.force_encoding('UTF-8') : v.message, + :date => v.authored_date.strftime("%B %d, %Y"), + :gravatar => Digest::MD5.hexdigest(v.author.email.strip.downcase), + :identicon => self._identicon_code(v.author.email), + :date_full => v.authored_date, + :files => v.stats.files.map { |f,*rest| + page_path = extract_renamed_path_destination(f) + page_path = remove_page_extentions(page_path) + { :file => f, + :link => "#{page_path}/#{v.id}" + } + } + } + end + end + + def remove_page_extentions(page_path) + Gollum::Markup.formats.values.each do |format| + page_path = page_path.gsub(/\.#{format[:regexp]}$/, '') + end + return page_path + end + + def extract_renamed_path_destination(file) + return file.gsub(/{.* => (.*)}/, '\1').gsub(/.* => (.*)/, '\1') + end + + # http://stackoverflow.com/questions/9445760/bit-shifting-in-ruby + def left_shift(int, shift) + r = ((int & 0xFF) << (shift & 0x1F)) & 0xFFFFFFFF + # 1>>31, 2**32 + (r & 2147483648) == 0 ? r : r - 4294967296 + end + + def string_to_code(string) + # sha bytes + b = [Digest::SHA1.hexdigest(string)[0, 20]].pack('H*').bytes.to_a + # Thanks donpark's IdenticonUtil.java for this. + # Match the following Java code + # ((b[0] & 0xFF) << 24) | ((b[1] & 0xFF) << 16) | + # ((b[2] & 0xFF) << 8) | (b[3] & 0xFF) + + return left_shift(b[0], 24) | + left_shift(b[1], 16) | + left_shift(b[2], 8) | + b[3] & 0xFF + end + + def _identicon_code(blob) + string_to_code blob + @request.host + end + + def use_identicon + @wiki.user_icons == 'identicon' + end + + def partial(name) + if name == :author_template + self.class.partial("history_authors/#{@wiki.user_icons}") + else + super + end + end + + def previous_link + end + + def next_link + end + end + end +end diff --git a/test/test_latest_changes_view.rb b/test/test_latest_changes_view.rb new file mode 100644 index 00000000..1af3ee53 --- /dev/null +++ b/test/test_latest_changes_view.rb @@ -0,0 +1,45 @@ +# ~*~ encoding: utf-8 ~*~ +require File.expand_path(File.join(File.dirname(__FILE__), 'helper')) +require File.expand_path '../../lib/gollum/views/latest_changes', __FILE__ + +context "Precious::Views::LatestChanges" do + include Rack::Test::Methods + + def app + Precious::App + end + + setup do + @path = cloned_testpath("examples/lotr.git") + @wiki = Gollum::Wiki.new(@path) + Precious::App.set(:gollum_path, @path) + Precious::App.set(:wiki_options, {:latest_changes_count => 10}) + end + + test "displays_latest_changes" do + get('/latest_changes') + body = last_response.body + assert body.include?('Charles Pence'), "/latest_changes should include the Author Charles Pence" + assert body.include?('60f12f4'), "/latest_changes should include the :latest_changes_count commit" + assert !body.include?('0ed8cbe'), "/latest_changes should not include more than latest_changes_count commits" + assert body.include?('Data-Two.csv'), "/latest_changes include links to modified files in #{body}" + assert body.include?('Hobbit.md'), "/latest_changes should include links to modified pages in #{body}" + assert body.include?('My-<b>Precious.md => My-Precious.md'), "/latest_changes should indicate renaming action in #{body}" + end + + test "extract destination file name in case of path renaming" do + view = Precious::Views::LatestChanges.new + assert_equal "newDirectoryName/fileName.md", view.extract_renamed_path_destination("{oldDirectoryName => newDirectoryName}/fileName.md") + end + + test "remove page extentions" do + view = Precious::Views::LatestChanges.new + assert_equal "page", view.remove_page_extentions("page.wiki") + assert_equal "page-wiki", view.remove_page_extentions("page-wiki.md") + assert_equal "file.any_extention", view.remove_page_extentions("file.any_extention") + end + + teardown do + FileUtils.rm_rf(@path) + end +end