Add MD5 of each revision in the detail view of documents #527
This commit is contained in:
parent
8507ee9b09
commit
52f245e913
@ -139,10 +139,16 @@ class DmsfFilesController < ApplicationController
|
||||
revision.size = last_revision.size
|
||||
revision.disk_filename = last_revision.disk_filename
|
||||
revision.mime_type = last_revision.mime_type
|
||||
if last_revision.digest.blank?
|
||||
revision.digest = DmsfFileRevision.create_digest last_revision.disk_file
|
||||
else
|
||||
revision.digest = last_revision.digest
|
||||
end
|
||||
else
|
||||
revision.size = file_upload.size
|
||||
revision.disk_filename = revision.new_storage_filename
|
||||
revision.mime_type = Redmine::MimeType.of(file_upload.original_filename)
|
||||
revision.digest = DmsfFileRevision.create_digest file_upload.path
|
||||
end
|
||||
|
||||
# Custom fields
|
||||
|
||||
@ -187,6 +187,7 @@ class DmsfUploadController < ApplicationController
|
||||
end
|
||||
new_revision.mime_type = Redmine::MimeType.of(new_revision.name)
|
||||
new_revision.size = File.size(commited_disk_filepath)
|
||||
new_revision.digest = DmsfFileRevision.create_digest commited_disk_filepath
|
||||
|
||||
# Need to save file first to generate id for it in case of creation.
|
||||
# File id is needed to properly generate revision disk filename
|
||||
|
||||
@ -67,17 +67,6 @@ module DmsfHelper
|
||||
return "#{Redmine::Utils.relative_url_root}/plugin_assets/#{plugin}/#{asset_type}/#{source}"
|
||||
end
|
||||
|
||||
def self.to_time(obj)
|
||||
#Right, enough of bugs, let's try a better approach here.
|
||||
return unless obj
|
||||
return obj.to_time(ActiveRecord::Base.default_timezone) if obj.is_a?(String)
|
||||
|
||||
# Why can't Mysql::Time conform to time object? - without a utc? method it breaks redmine's
|
||||
# rendering method, so we convert it to string, and back into time - not the most efficient
|
||||
# of methods - however seems functional. Not sure if MySQL
|
||||
(obj.class.name == 'Mysql::Time') ? obj.to_s.to_time(ActiveRecord::Base.default_timezone) : obj
|
||||
end
|
||||
|
||||
def self.dmsf_tree(parent, obj, tree = nil)
|
||||
tree ||= []
|
||||
# Folders && files && links
|
||||
|
||||
@ -19,6 +19,8 @@
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
require 'digest/md5'
|
||||
|
||||
class DmsfFileRevision < ActiveRecord::Base
|
||||
unloadable
|
||||
belongs_to :dmsf_file
|
||||
@ -159,6 +161,7 @@ class DmsfFileRevision < ActiveRecord::Base
|
||||
new_revision.source_revision = self
|
||||
new_revision.user = User.current
|
||||
new_revision.name = self.name
|
||||
new_revision.digest = self.digest
|
||||
new_revision
|
||||
end
|
||||
|
||||
@ -262,4 +265,23 @@ class DmsfFileRevision < ActiveRecord::Base
|
||||
format + ext
|
||||
end
|
||||
|
||||
def self.create_digest(path)
|
||||
begin
|
||||
Digest::MD5.file(path).hexdigest
|
||||
rescue Exception => e
|
||||
Rails.logger.error e.message
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def create_digest
|
||||
begin
|
||||
self.digest = Digest::MD5.file(self.disk_file).hexdigest
|
||||
true
|
||||
rescue Exception => e
|
||||
Rails.logger.error e.message
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@ -22,23 +22,23 @@
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
%>
|
||||
|
||||
<table class="display access-table list">
|
||||
<table class="display list dmsf_list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><%= l(:field_user) %></th>
|
||||
<th><%= l(:heading_access_downloads_emails) %></th>
|
||||
<th><%= l(:heading_access_first) %></th>
|
||||
<th><%= l(:heading_access_last) %></th>
|
||||
<th class="dmsf_th"><%= l(:field_user) %></th>
|
||||
<th class="dmsf_th"><%= l(:heading_access_downloads_emails) %></th>
|
||||
<th class="dmsf_th"><%= l(:heading_access_first) %></th>
|
||||
<th class="dmsf_th"><%= l(:heading_access_last) %></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% revision.access_grouped.each do |access| %>
|
||||
<tr>
|
||||
<td><%= link_to_user(access.user) %></td>
|
||||
<td class="dmsf_version"><%= access['count'] %></td>
|
||||
<td class="dmsf_modified"><%= format_time(DmsfHelper::to_time(access.first_at)) %></td>
|
||||
<td class="dmsf_modified"><%= format_time(DmsfHelper::to_time(access.last_at)) %></td>
|
||||
<td class="dmsf_author"><%= link_to_user(access.user) %></td>
|
||||
<td class="dmsf_version"><%= access.count %></td>
|
||||
<td class="dmsf_modified"><%= format_time(access.first_at) %></td>
|
||||
<td class="dmsf_modified"><%= format_time(access.last_at) %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
</table>
|
||||
|
||||
@ -98,70 +98,68 @@
|
||||
<%= link_to(revision.user.name, user_path(revision.user)) if revision.user %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dmsf_revision_inner_box">
|
||||
<div class="clear">
|
||||
<div class="attributes dmsf_revision_inner_box">
|
||||
<div class="splitcontent">
|
||||
<div class="splitcontentleft">
|
||||
<p>
|
||||
<%= label_tag('', l(:label_title)) %>
|
||||
<%= h(revision.title) %>
|
||||
</p>
|
||||
</div>
|
||||
<div class="splitcontentright">
|
||||
<p>
|
||||
<%= label_tag('', l(:label_file)) %>
|
||||
<%= ("#{h(revision.dmsf_file.dmsf_folder.dmsf_path_str)}/") if revision.dmsf_file.dmsf_folder %><%= h(revision.name) %>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<% if revision.description.present? %>
|
||||
<p>
|
||||
<%= label_tag('', l(:label_description)) %>
|
||||
<div class="wiki">
|
||||
<%= textilizable(revision.description) %>
|
||||
</div>
|
||||
</p>
|
||||
<% end %>
|
||||
<div class="clear">
|
||||
<div class="splitcontentleft">
|
||||
<% if revision.description.present? %>
|
||||
<p>
|
||||
<%= label_tag('', l(:label_description)) %>
|
||||
<div class="wiki">
|
||||
<%= textilizable(revision.description) %>
|
||||
</div>
|
||||
</p>
|
||||
<% end %>
|
||||
<p>
|
||||
<%= label_tag('', l(:label_version)) %>
|
||||
<%= revision.major_version %>.<%= revision.minor_version %>
|
||||
</p>
|
||||
<p>
|
||||
<%= label_tag('', l(:link_workflow)) %>
|
||||
<% wf = DmsfWorkflow.find_by_id(revision.dmsf_workflow_id) %>
|
||||
<% if wf %>
|
||||
<%= label_tag('', l(:label_size)) %>
|
||||
<%= number_to_human_size(revision.size) %>
|
||||
</p>
|
||||
<% wf = DmsfWorkflow.find_by_id(revision.dmsf_workflow_id) %>
|
||||
<% if wf %>
|
||||
<p>
|
||||
<%= label_tag('', l(:link_workflow)) %>
|
||||
<%= "#{wf.name} - " %>
|
||||
<%= link_to(revision.workflow_str(false),
|
||||
log_dmsf_workflow_path(:project_id => @project.id,
|
||||
:id => wf.id, :dmsf_file_revision_id => revision.id),
|
||||
:title => DmsfWorkflow.assignments_to_users_str(wf.next_assignments(revision.id)),
|
||||
:remote => true) %>
|
||||
<% else %>
|
||||
<%= revision.workflow_str(true) %>
|
||||
<% end %>
|
||||
</p>
|
||||
</p>
|
||||
<% end %>
|
||||
<% if revision.comment.present? %>
|
||||
<p>
|
||||
<%= label_tag('', l(:label_comment)) %>
|
||||
<div class="wiki">
|
||||
<%= textilizable(revision.comment) %>
|
||||
</div>
|
||||
</p>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="splitcontentright">
|
||||
<p>
|
||||
<%= label_tag('', l(:label_file)) %>
|
||||
<%= ("#{h(revision.dmsf_file.dmsf_folder.dmsf_path_str)}/") if revision.dmsf_file.dmsf_folder %><%= h(revision.name) %>
|
||||
</p>
|
||||
<p>
|
||||
<%= label_tag('', l(:label_mime)) %>
|
||||
<%= h(revision.mime_type) %>
|
||||
</p>
|
||||
<p>
|
||||
<%= label_tag('', l(:label_size)) %>
|
||||
<%= number_to_human_size(revision.size) %>
|
||||
</p>
|
||||
<% if revision.digest.present? %>
|
||||
<p>
|
||||
<%= label_tag('', 'MD5') %>
|
||||
<%= revision.digest %>
|
||||
</p>
|
||||
<% end %>
|
||||
<%= render 'dmsf/custom_fields', :object => revision %>
|
||||
</div>
|
||||
</div>
|
||||
<%= render 'dmsf/custom_fields', :object => revision %>
|
||||
<% if revision.comment.present? %>
|
||||
<p>
|
||||
<%= label_tag('', l(:label_comment)) %>
|
||||
<div class="wiki">
|
||||
<%= textilizable(revision.comment) %>
|
||||
</div>
|
||||
</p>
|
||||
<% end %>
|
||||
<div id="<%= "revision_access-#{revision.id}" %>" style="display:none">
|
||||
<%= render(:partial => 'revision_access', :locals => {:revision => revision}) if User.current.allowed_to?(:file_manipulation, @file.project) %>
|
||||
</div>
|
||||
@ -208,7 +206,7 @@
|
||||
}
|
||||
});
|
||||
|
||||
$('.access-table').dataTable({
|
||||
$('.dmsf_list').dataTable({
|
||||
'bJQueryUI': true,
|
||||
'oLanguage': {
|
||||
'sUrl': '/plugin_assets/<%= :redmine_dmsf %>/javascripts/<%= url %>'
|
||||
|
||||
29
db/migrate/20160421150501_add_digest_to_revision.rb
Normal file
29
db/migrate/20160421150501_add_digest_to_revision.rb
Normal file
@ -0,0 +1,29 @@
|
||||
# encoding: utf-8
|
||||
#
|
||||
# Redmine plugin for Document Management System "Features"
|
||||
#
|
||||
# Copyright (C) 2011-16 Karel Pičman <karel.picman@kontron.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class AddDigestToRevision < ActiveRecord::Migration
|
||||
def up
|
||||
add_column :dmsf_file_revisions, :digest, :string, :limit => 40, :default => '', :null => false
|
||||
end
|
||||
|
||||
def down
|
||||
remove_column :dmsf_file_revisions, :digest
|
||||
end
|
||||
end
|
||||
63
lib/tasks/dmsf_create_digests.rake
Normal file
63
lib/tasks/dmsf_create_digests.rake
Normal file
@ -0,0 +1,63 @@
|
||||
# encoding: utf-8
|
||||
#
|
||||
# Redmine plugin for Document Management System "Features"
|
||||
#
|
||||
# Copyright (C) 2011-16 Karel Pičman <karel.picman@kontron.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
desc <<-END_DESC
|
||||
DMSF maintenance task
|
||||
* Create missing MD5 digest for all file revisions
|
||||
|
||||
Available options:
|
||||
*dry_run - test, no changes to he database
|
||||
|
||||
Example:
|
||||
bundle exec rake redmine:dmsf_create_digests RAILS_ENV="production"
|
||||
bundle exec rake redmine:dmsf_create_digests dry_run=1 RAILS_ENV="production"
|
||||
END_DESC
|
||||
|
||||
namespace :redmine do
|
||||
task :dmsf_create_digests => :environment do
|
||||
m = DmsfDigest.new
|
||||
m.create_digests
|
||||
end
|
||||
end
|
||||
|
||||
class DmsfDigest
|
||||
|
||||
def initialize
|
||||
@dry_run = ENV['dry_run']
|
||||
end
|
||||
|
||||
def create_digests
|
||||
revisions = DmsfFileRevision.where("digest IS NULL OR digest = ''").all
|
||||
count = revisions.count
|
||||
n = 0
|
||||
revisions.each_with_index do |rev, i|
|
||||
if rev.create_digest
|
||||
rev.save unless @dry_run
|
||||
n += 1
|
||||
end
|
||||
# Progress bar
|
||||
print "\r#{i * 100 / count}%"
|
||||
end
|
||||
print "\r100%\n"
|
||||
# Result
|
||||
puts "#{n}/#{DmsfFileRevision.count} revisions updated."
|
||||
end
|
||||
|
||||
end
|
||||
Loading…
x
Reference in New Issue
Block a user