devel-1.5.2 merged to the master

This commit is contained in:
Karel Pičman 2015-07-14 10:43:04 +02:00
commit 9b5d7b8942
87 changed files with 984 additions and 609 deletions

View File

@ -1,8 +1,36 @@
Changelog for Redmine DMSF
==========================
1.5.2 *2015-07-13*
------------------
Redmine >= 3.0 compatibility
* Bug: #404 - Deleted folder (still in trash) results in errors while accessing parent folder via webdav
* Bug: #401 - Link between project on Redmine 3.0
* Bug: #400 - internal server error fulltext search
* Bug: #396 - Error when uploading files
* Bug: #394 - DMSF install to Redmine 3.0.3 problem
* Bug: #393 - File can't be created in storage directory (Redmine 3.0.3)
* Bug: #392 - Redmine 3 Search screen error with Xapian
* New: #391 - Searchable document details
* Bug: #387 - Wrong sorting by Modified column
* Bug: #384 - Error when trying to uninstall DMSF
* New: #383 - Missleading number of entities in documents folder
* Bug: #382 - REST API - list of document produces invalid XML
* Bug: #380 - Internal Error 500 when dmsf page is accessed
* Bug: #378 - Revision view, delete revision bug
* Bug: #377 - Can access WebDAV when redmine is located under sub-URI
* Bug: #376 - Links to deleted documents
* Bug: #374 - Number of downloads
* Bug: #373 - internal 500 error : 1.5.1 stable with redmine 3.0.1 when search in dmsf enabled project
* New: #339 - Maximum Upload Size
* Bug: #319 - webdav problem after upgrading to 1.4.9 from 1.4.6
* New: #78 - Control DMSF via REST API
1.5.1: *2015-04-01*
-----------------------
-------------------
Approval workflow copying
Polish localization

View File

@ -1,7 +1,7 @@
Redmine DMSF Plugin
===================
The current version of Redmine DMSF is **1.5.1** [![Build Status](https://api.travis-ci.org/danmunn/redmine_dmsf.png)](https://travis-ci.org/danmunn/redmine_dmsf)
The current version of Redmine DMSF is **1.5.2** [![Build Status](https://api.travis-ci.org/danmunn/redmine_dmsf.png)](https://travis-ci.org/danmunn/redmine_dmsf)
Redmine DMSF is Document Management System Features plugin for Redmine issue tracking system; It is aimed to replace current Redmine's Documents module.
@ -42,7 +42,7 @@ Features
Dependencies
------------
* Redmine 2.5.0 or higher (Not yet fully compatible with Redmine 3.x but it should work in general)
* Redmine 2.5.0 or higher
### Fulltext search (optional)
@ -123,11 +123,12 @@ In the file <redmine_root>/public/help/<language>/wiki_syntax_detailed.html, aft
<li>
DMSF:
<ul>
<li><strong>{{dmsf(17)}}</strong> (link to file with id 17)</li>
<li><strong>{{dmsf(17,File)}}</strong> (link to file with id 17 with link text "File")</li>
<li><strong>{{dmsf(17,File,10)}}</strong> (link to file with id 17 with link text "File" and link pointing to revision 10)</li>
<li><strong>{{dmsff(5)}}</strong> (link to folder with id 5)</li>
<li><strong>{{dmsff(5,Folder)}}</strong> (link to folder with id 5 with link text "Folder")</li>
<li><strong>{{dmsf(17)}}</strong> (a link to the file with id 17)</li>
<li><strong>{{dmsf(17, File)}}</strong> (a link to the file with id 17 with the link text "File")</li>
<li><strong>{{dmsf(17, File, 10)}}</strong> (a link to the file with id 17 with the link text "File" and the link pointing to the revision 10)</li>
<li><strong>{{dmsfd(17)}}</strong> (a link to the description of the file with id 17)</li>
<li><strong>{{dmsff(5)}}</strong> (a link to the folder with id 5)</li>
<li><strong>{{dmsff(5, Folder)}}</strong> (a link to the folder with id 5 with the link text "Folder")</li>
</ul>
The DMSF file/revision id can be found in the link for file/revision download from within Redmine.<br />
The DMSF folder id can be found in the link when opening folders within Redmine.
@ -152,16 +153,24 @@ Before installing ensure that the Redmine instance is stopped.
6. You should configure plugin via Redmine interface: Administration -> Plugins -> DMSF -> Configure
7. Assign DMSF permissions to appropriate roles
8. There are two rake tasks:
a) To convert documents from the standard Redmine document module
Available options:
* project => id or identifier of project (defaults to all projects)
* dry => true or false (default false) to perform just check without any conversion
* invalid=replace => to perform document title invalid characters replacement for '-'
Example:
rake redmine:dmsf_convert_documents project=test RAILS_ENV="production"
b) To alert all users who are expected to do an approval in the current approval steps
Example:
rake redmine:dmsf_alert_approvals RAILS_ENV="production"
rake redmine:dmsf_alert_approvals RAILS_ENV="production"
### Fulltext search (optional)
If you want to use fulltext search features, you must setup file content indexing.
@ -174,8 +183,8 @@ It is necessary to index DMSF files with omega before searching attempts to rece
This command must be run on regular basis (e.g. from cron)
Example of cron job (once per hour at 8th minute):
`8 * * * * root /usr/bin/ruby redmine_dmsf/extra/xapian_indexer.rb -f`
8 * * * * root /usr/bin/ruby redmine_dmsf/extra/xapian_indexer.rb -f
See redmine_dmsf/extra/xapian_indexer.rb for help.

View File

@ -31,10 +31,12 @@ class DmsfController < ApplicationController
before_filter :authorize
before_filter :find_folder, :except => [:new, :create, :edit_root, :save_root]
before_filter :find_parent, :only => [:new, :create]
accept_api_auth :show, :create
helper :all
def show
def show
@folder_manipulation_allowed = User.current.allowed_to?(:folder_manipulation, @project)
@file_manipulation_allowed = User.current.allowed_to?(:file_manipulation, @project)
@file_delete_allowed = User.current.allowed_to?(:file_delete, @project)
@ -118,6 +120,12 @@ class DmsfController < ApplicationController
end
@locked_for_user = false
else
if @folder.deleted
render_404
return
end
@subfolders = @folder.subfolders.visible
@files = @folder.files.visible
@dir_links = @folder.folder_links.visible
@ -134,7 +142,14 @@ class DmsfController < ApplicationController
@trash_enabled = DmsfFolder.deleted.where(:project_id => @project.id).any? ||
DmsfFile.deleted.where(:project_id => @project.id).any? ||
DmsfLink.deleted.where(:project_id => @project.id).any?
end
respond_to do |format|
format.html {
render :layout => !request.xhr?
}
format.api
end
end
def trash
@folder_manipulation_allowed = User.current.allowed_to? :folder_manipulation, @project
@ -225,20 +240,15 @@ class DmsfController < ApplicationController
end
end
def entries_email
if (Rails::VERSION::MAJOR > 3)
@email_params = e_params
else
@email_params = params[:email]
end
if @email_params[:to].strip.blank?
def entries_email
if params[:email][:to].strip.blank?
flash.now[:error] = l(:error_email_to_must_be_entered)
render :action => 'email_entries'
return
end
DmsfMailer.send_documents(@project, User.current, @email_params).deliver
File.delete(@email_params['zipped_content'])
flash[:notice] = l(:notice_email_sent, @email_params['to'])
DmsfMailer.send_documents(@project, User.current, params[:email]).deliver
File.delete(params[:email][:zipped_content])
flash[:notice] = l(:notice_email_sent, params[:email][:to])
redirect_to dmsf_folder_path(:id => @project, :folder_id => @folder)
end
@ -249,13 +259,11 @@ class DmsfController < ApplicationController
render :action => 'edit'
end
def create
if (Rails::VERSION::MAJOR > 3)
@folder = DmsfFolder.new(
params.require(:dmsf_folder).permit(:title, :description, :dmsf_folder_id))
else
@folder = DmsfFolder.new(params[:dmsf_folder])
end
def create
@folder = DmsfFolder.new
@folder.title = params[:dmsf_folder][:title]
@folder.description = params[:dmsf_folder][:description]
@folder.dmsf_folder_id = params[:dmsf_folder][:dmsf_folder_id]
@folder.project = @project
@folder.user = User.current
@ -266,13 +274,26 @@ class DmsfController < ApplicationController
end
end
if @folder.save
flash[:notice] = l(:notice_folder_created)
redirect_to dmsf_folder_path(:id => @project, :folder_id => @folder)
else
@pathfolder = @parent
render :action => 'edit'
end
saved = @folder.save
respond_to do |format|
format.js
format.api {
unless saved
render_validation_errors(@folder)
end
}
format.html {
if saved
flash[:notice] = l(:notice_folder_created)
redirect_to dmsf_folder_path(:id => @project, :folder_id => @folder)
else
@pathfolder = @parent
render :action => 'edit'
end
}
end
end
def edit
@ -587,12 +608,16 @@ class DmsfController < ApplicationController
@folder = DmsfFolder.find params[:folder_id] if params[:folder_id].present?
rescue DmsfAccessError
render_403
rescue ActiveRecord::RecordNotFound
render_404
end
def find_parent
@parent = DmsfFolder.visible.find params[:parent_id] if params[:parent_id].present?
rescue DmsfAccessError
render_403
rescue ActiveRecord::RecordNotFound
render_404
end
def copy_folder(folder)
@ -608,7 +633,5 @@ class DmsfController < ApplicationController
:to, :zipped_content, :email,
:cc, :subject, :zipped_content => [], :files => [])
end
end
end

View File

@ -37,6 +37,7 @@ class DmsfFilesController < ApplicationController
@revision = @file.last_revision
check_project(@revision.file)
begin
raise ActionController::MissingFile if @file.deleted
log_activity('downloaded')
access = DmsfFileRevisionAccess.new
access.user = User.current
@ -47,8 +48,7 @@ class DmsfFilesController < ApplicationController
:filename => filename_for_content_disposition(@revision.name),
:type => @revision.detect_content_type,
:disposition => 'inline')
rescue ActionController::MissingFile => e
logger.error e.message
rescue ActionController::MissingFile
render_404
end
end
@ -67,17 +67,18 @@ class DmsfFilesController < ApplicationController
end
check_project(@revision.file)
begin
raise ActionController::MissingFile if @revision.file.deleted
log_activity('downloaded')
access = DmsfFileRevisionAccess.new
access.user = User.current
access.revision = @revision
access.action = DmsfFileRevisionAccess::DownloadAction
access.action = DmsfFileRevisionAccess::DownloadAction
access.save!
send_file(@revision.disk_file,
:filename => filename_for_content_disposition(@revision.name),
:type => @revision.detect_content_type,
:disposition => 'attachment')
rescue ActionController::MissingFile => e
logger.error e.message
rescue ActionController::MissingFile
render_404
end
return
@ -302,7 +303,7 @@ class DmsfFilesController < ApplicationController
end
def find_revision
@revision = DmsfFileRevision.visible.find(params[:id])
@revision = DmsfFileRevision.visible.find params[:id]
@file = @revision.file
@project = @file.project
rescue ActiveRecord::RecordNotFound

View File

@ -1,3 +1,5 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2011-15 Karel Pičman <karel.picman@kontron.com>
@ -24,12 +26,9 @@ class DmsfLinksController < ApplicationController
before_filter :find_link_project
before_filter :authorize
def new
if (Rails::VERSION::MAJOR > 3)
@dmsf_link = DmsfLink.new(l_params)
else
@dmsf_link = DmsfLink.new(:project_id => params[:project_id])
end
def new
@dmsf_link = DmsfLink.new
@dmsf_link.project_id = params[:project_id]
if params[:dmsf_link].present?
# Reload

View File

@ -26,10 +26,12 @@ class DmsfUploadController < ApplicationController
before_filter :find_project
before_filter :authorize
before_filter :find_folder, :except => [:upload_file]
before_filter :find_folder, :except => [:upload_file, :upload, :commit]
helper :all
helper :dmsf_workflows
accept_api_auth :upload, :commit
def upload_files
uploaded_files = params[:attachments]
@ -51,26 +53,23 @@ class DmsfUploadController < ApplicationController
end
# async single file upload handling
def upload_file
if (Rails::VERSION::MAJOR > 3)
@tempfile = params.require(:file)
else
@tempfile = params[:file]
end
def upload_file
@tempfile = params[:file]
unless @tempfile.original_filename
render_404
return
end
@disk_filename = DmsfHelper.temp_filename(@tempfile.original_filename)
File.open("#{DmsfHelper.temp_dir}/#{@disk_filename}", 'wb') do |f|
while (buffer = @tempfile.read(8192))
f.write(buffer)
end
begin
FileUtils.cp @tempfile.path, "#{DmsfHelper.temp_dir}/#{@disk_filename}"
rescue Exception => e
Rails.logger.error e.message
end
if File.size("#{DmsfHelper.temp_dir}/#{@disk_filename}") <= 0
begin
File.delete("#{DmsfHelper.temp_dir}/#{@disk_filename}")
rescue
File.delete "#{DmsfHelper.temp_dir}/#{@disk_filename}"
rescue Exception => e
Rails.logger.error e.message
end
render :layout => nil, :json => { :jsonrpc => '2.0',
:error => {
@ -85,14 +84,54 @@ class DmsfUploadController < ApplicationController
end
end
def commit_files
if (Rails::VERSION::MAJOR > 3)
commited_files = params.require(:commited_files)
else
commited_files = params[:commited_files]
# REST API document upload
def upload
unless request.content_type == 'application/octet-stream'
render :nothing => true, :status => 406
return
end
@attachment = Attachment.new(:file => request.raw_post)
@attachment.author = User.current
@attachment.filename = params[:filename].presence || Redmine::Utils.random_hex(16)
saved = @attachment.save
respond_to do |format|
format.js
format.api {
if saved
render :action => 'upload', :status => :created
else
render_validation_errors(@attachment)
end
}
end
end
def commit_files
commit_files_internal params[:commited_files]
end
# REST API file commit
def commit
attachments = params[:attachments]
if attachments && attachments.is_a?(Hash)
@folder = DmsfFolder.visible.find_by_id attachments[:folder_id].to_i if attachments[:folder_id].present?
# standard file input uploads
uploaded_files = attachments.select { |key, value| key == 'uploaded_file'}
uploaded_files.each_value do |uploaded_file|
upload = DmsfUpload.create_from_uploaded_attachment(@project, @folder, uploaded_file)
uploaded_file[:disk_filename] = upload.disk_filename
end
end
commit_files_internal uploaded_files
end
private
def commit_files_internal(commited_files)
if commited_files && commited_files.is_a?(Hash)
files = []
@files = []
failed_uploads = []
commited_files.each_value do |commited_file|
name = commited_file[:name]
@ -146,13 +185,6 @@ class DmsfUploadController < ApplicationController
new_revision.mime_type = Redmine::MimeType.of(new_revision.name)
new_revision.size = File.size(commited_disk_filepath)
file_upload = File.new(commited_disk_filepath, 'rb')
unless file_upload
failed_uploads.push(commited_file)
flash[:error] = l(:error_file_commit_require_uploaded_file)
next
end
if file.locked?
begin
file.unlock!
@ -179,23 +211,21 @@ class DmsfUploadController < ApplicationController
end
if new_revision.save
new_revision.assign_workflow(commited_file[:dmsf_workflow_id])
new_revision.copy_file_content(file_upload)
file_upload.close
File.delete(commited_disk_filepath)
new_revision.assign_workflow(commited_file[:dmsf_workflow_id])
FileUtils.mv(commited_disk_filepath, new_revision.disk_file)
file.set_last_revision new_revision
files.push(file)
@files.push(file)
else
failed_uploads.push(commited_file)
end
end
unless files.empty?
files.each { |file| log_activity(file, 'uploaded') if file }
unless @files.empty?
@files.each { |file| log_activity(file, 'uploaded') if file }
if (@folder && @folder.notification?) || (!@folder && @project.dmsf_notification?)
begin
recipients = DmsfMailer.get_notify_users(@project, files)
recipients = DmsfMailer.get_notify_users(@project, @files)
recipients.each do |u|
DmsfMailer.files_updated(u, @project, files).deliver
DmsfMailer.files_updated(u, @project, @files).deliver
end
if Setting.plugin_redmine_dmsf[:dmsf_display_notified_recipients] == '1'
unless recipients.empty?
@ -213,10 +243,15 @@ class DmsfUploadController < ApplicationController
flash[:warning] = l(:warning_some_files_were_not_commited, :files => failed_uploads.map{|u| u['name']}.join(', '))
end
end
redirect_to dmsf_folder_path(:id => @project, :folder_id => @folder)
respond_to do |format|
format.js
format.api {
render_validation_errors(failed_uploads) unless failed_uploads.empty?
}
format.html { redirect_to dmsf_folder_path(:id => @project, :folder_id => @folder) }
end
end
private
def log_activity(file, action)
Rails.logger.info "#{Time.now.strftime('%Y-%m-%d %H:%M:%S')} #{User.current.login}@#{request.remote_ip}/#{request.env['HTTP_X_FORWARDED_FOR']}: #{action} dmsf://#{file.project.identifier}/#{file.id}/#{file.last_revision.id}"

View File

@ -238,7 +238,7 @@ class DmsfWorkflowsController < ApplicationController
end
def update
if request.put? && params[:dmsf_workflow] && @dmsf_workflow.update_attributes(
if params[:dmsf_workflow] && @dmsf_workflow.update_attributes(
{:name => params[:dmsf_workflow][:name]})
flash[:notice] = l(:notice_successful_update)
if @project
@ -246,7 +246,8 @@ class DmsfWorkflowsController < ApplicationController
else
redirect_to dmsf_workflows_path
end
else
else
flash[:error] = @dmsf_workflow.errors.full_messages.to_sentence
redirect_to dmsf_workflow_path(@dmsf_workflow)
end
end
@ -269,27 +270,40 @@ class DmsfWorkflowsController < ApplicationController
render :layout => false
end
def new_step
@steps = @dmsf_workflow.dmsf_workflow_steps.collect{|s| s.step}.uniq
respond_to do |format|
format.html
format.js
end
end
def add_step
if request.post?
users = User.where(:id => params[:user_ids])
if request.post?
if params[:step] == '0'
step = @dmsf_workflow.dmsf_workflow_steps.collect{|s| s.step}.uniq.count + 1
else
step = params[:step].to_i
end
operator = (params[:commit] == l(:dmsf_and)) ? DmsfWorkflowStep::OPERATOR_AND : DmsfWorkflowStep::OPERATOR_OR
users.each do |user|
ws = DmsfWorkflowStep.new(
:dmsf_workflow_id => @dmsf_workflow.id,
:step => step,
:user_id => user.id,
:operator => operator)
if ws.save
@dmsf_workflow.dmsf_workflow_steps << ws
else
flash[:error] = l(:error_workflow_assign)
users = User.where(:id => params[:user_ids])
if users.count > 0
users.each do |user|
ws = DmsfWorkflowStep.new(
:dmsf_workflow_id => @dmsf_workflow.id,
:step => step,
:user_id => user.id,
:operator => operator)
if ws.save
@dmsf_workflow.dmsf_workflow_steps << ws
else
flash[:error] = @dmsf_workflow.errors.full_messages.to_sentence
end
end
end
else
flash[:error] = l(:error_workflow_assign)
end
end
respond_to do |format|
format.html

View File

@ -1,6 +1,8 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2011-14 Karel Picman <karel.picman@kontron.com>
# Copyright (C) 2011-15 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
@ -23,11 +25,15 @@ module DmsfWorkflowsHelper
principal_count = scope.count
principal_pages = Redmine::Pagination::Paginator.new principal_count, 10, params['page']
principals = scope.offset(principal_pages.offset).limit(principal_pages.per_page).all
if dmsf_workflow_step_assignment_id
s = content_tag('div', principals_radio_button_tags('step_action', principals), :id => 'users_for_delegate')
else
s = content_tag('div', principals_check_box_tags('user_ids[]', principals), :id => 'users')
if dmsf_workflow_step_assignment_id
s = content_tag('div',
content_tag('div', principals_radio_button_tags('user_ids[]', principals), :id => 'users_for_delegate'),
:class => 'objects-selection')
else
s = content_tag('div',
content_tag('div', principals_check_box_tags('user_ids[]', principals), :id => 'users'),
:class => 'objects-selection')
end
links = pagination_links_full(principal_pages, principal_count, :per_page_links => false) {|text, parameters, options|

View File

@ -29,11 +29,8 @@ end
class DmsfFile < ActiveRecord::Base
unloadable
include RedmineDmsf::Lockable
attr_accessor :event_description
attr_accessible :project
include RedmineDmsf::Lockable
belongs_to :project
belongs_to :folder, :class_name => 'DmsfFolder', :foreign_key => 'dmsf_folder_id'
@ -63,14 +60,13 @@ class DmsfFile < ActiveRecord::Base
if (Rails::VERSION::MAJOR > 3)
accepts_nested_attributes_for :revisions, :locks, :referenced_links
end
if (Rails::VERSION::MAJOR > 3)
scope :visible, -> { where(deleted: false) }
scope :deleted, -> { where(deleted: true) }
else
scope :visible, where(:deleted => false)
scope :deleted, where(:deleted => true)
end
scope :visible, lambda { |*args|
where(deleted: false)
}
scope :deleted, lambda { |*args|
where(deleted: true)
}
validates :name, :presence => true
validates_format_of :name, :with => DmsfFolder.invalid_characters,
@ -84,11 +80,29 @@ class DmsfFile < ActiveRecord::Base
existing_file.nil? || existing_file.id == self.id
end
acts_as_event :title => Proc.new {|o| "#{o.title} - #{o.name}"},
:description => Proc.new {|o| o.description },
:url => Proc.new {|o| {:controller => 'dmsf_files', :action => 'show', :id => o}},
:datetime => Proc.new {|o| o.updated_at },
:author => Proc.new {|o| o.last_revision.user }
acts_as_event :title => Proc.new { |o| o.name },
:description => Proc.new { |o|
if (Rails::VERSION::MAJOR > 3)
desc = Redmine::Search.cache_store.fetch("DmsfFile-#{o.id}")
if desc
Redmine::Search.cache_store.delete("DmsfFile-#{o.id}")
else
desc = o.description
desc += " / #{o.last_revision.comment}" if o.last_revision.comment.present?
end
else
desc = o.description
desc += " / #{o.last_revision.comment}" if o.last_revision.comment.present?
end
desc
},
:url => Proc.new { |o| {:controller => 'dmsf_files', :action => 'show', :id => o} },
:datetime => Proc.new { |o| o.updated_at },
:author => Proc.new { |o| o.last_revision.user }
acts_as_searchable :columns => ["#{table_name}.name", "#{DmsfFileRevision.table_name}.title", "#{DmsfFileRevision.table_name}.description", "#{DmsfFileRevision.table_name}.comment"],
:project_key => 'project_id',
:date_column => "#{table_name}.updated_at"
before_create :default_values
def default_values
@ -176,8 +190,8 @@ class DmsfFile < ActiveRecord::Base
end
def description
self.last_revision ? self.last_revision.description : ''
end
self.last_revision ? self.last_revision.description : ''
end
def version
self.last_revision ? self.last_revision.version : '0'
@ -292,39 +306,39 @@ class DmsfFile < ActiveRecord::Base
end
# To fulfill searchable module expectations
def self.search(tokens, projects = nil, options = {})
def self.search(tokens, projects = nil, options = {}, user = User.current)
tokens = [] << tokens unless tokens.is_a?(Array)
projects = [] << projects unless projects.nil? || projects.is_a?(Array)
find_options = {}
find_options[:order] = 'dmsf_files.updated_at ' + (options[:before] ? 'DESC' : 'ASC')
projects = [] << projects if projects.is_a?(Project)
project_ids = projects.collect(&:id) if projects
find_options = {}
limit_options = {}
limit_options[:limit] = options[:limit] if options[:limit]
if options[:offset]
limit_options[:conditions] = '(dmsf_files.updated_at ' + (options[:before] ? '<' : '>') + "'#{connection.quoted_date(options[:offset])}')"
end
columns = %w(dmsf_files.name dmsf_file_revisions.title dmsf_file_revisions.description)
columns = ['dmsf_file_revisions.title'] if options[:titles_only]
if options[:titles_only]
columns = [searchable_options[:columns][1]]
else
columns = searchable_options[:columns]
end
token_clauses = columns.collect {|column| "(LOWER(#{column}) LIKE ?)"}
sql = (['(' + token_clauses.join(' OR ') + ')'] * tokens.size).join(options[:all_words] ? ' AND ' : ' OR ')
find_options[:conditions] = [sql, * (tokens.collect {|w| "%#{w.downcase}%"} * token_clauses.size).sort]
project_conditions = []
project_conditions << Project.allowed_to_condition(User.current, :view_dmsf_files)
project_conditions << "#{DmsfFile.table_name}.project_id IN (#{projects.collect(&:id).join(',')})" unless projects.nil?
project_conditions << Project.allowed_to_condition(user, :view_dmsf_files)
project_conditions << "#{DmsfFile.table_name}.project_id IN (#{project_ids.join(',')})" if project_ids.present?
results = []
results_count = 0
results = []
includes(:project, :revisions).
where(project_conditions.join(' AND ') + " AND #{DmsfFile.table_name}.deleted = :false", {:false => false}).scoping do
where(find_options[:conditions]).order(find_options[:order]).scoping do
results_count = count(:all)
results = find(:all, limit_options)
visible.joins(:project, :revisions).
where(project_conditions.join(' AND ')).scoping do
where(find_options[:conditions]).scoping do
results = where(limit_options).uniq
end
end
@ -381,7 +395,7 @@ class DmsfFile < ActiveRecord::Base
next if dmsf_attrs.length == 0 || id_attribute == 0
next unless results.select{|f| f.id.to_s == id_attribute}.empty?
dmsf_file = DmsfFile.where(limit_options[:conditions]).where(:id => id_attribute, :deleted => false).first
dmsf_file = DmsfFile.visible.where(limit_options[:conditions]).where(:id => id_attribute).first
if dmsf_file
if options[:offset]
@ -390,29 +404,17 @@ class DmsfFile < ActiveRecord::Base
else
next if dmsf_file.updated_at > options[:offset]
end
end
end
allowed = User.current.allowed_to?(:view_dmsf_files, dmsf_file.project)
project_included = false
project_included = true unless projects
unless project_included
projects.each do |x|
if x.is_a?(ActiveRecord::Relation)
project_included = x.first.id == dmsf_file.project.id
else
if dmsf_file.project
project_included = x[:id] == dmsf_file.project.id
else
project_included = false
end
end
if user.allowed_to?(:view_dmsf_files, dmsf_file.project) &&
(project_ids.blank? || (project_ids.include?(dmsf_file.project.id)))
if (Rails::VERSION::MAJOR > 3)
Redmine::Search.cache_store.write("DmsfFile-#{dmsf_file.id}",
dochash['sample'].force_encoding('UTF-8')) if dochash['sample']
else
dmsf_file.event_description = dochash['sample'].force_encoding('UTF-8') if dochash['sample']
end
end
if (allowed && project_included)
dmsf_file.event_description = dochash['sample'].force_encoding('UTF-8') if dochash['sample']
results.push(dmsf_file)
results_count += 1
results << dmsf_file
end
end
end
@ -420,14 +422,14 @@ class DmsfFile < ActiveRecord::Base
end
end
end
[results, results_count]
[results, results.count]
end
def self.search_result_ranks_and_ids(tokens, user = User.current, projects = nil, options = {})
r = self.search(tokens, projects, options)[0]
r.each_index { |x| [x, r[1][x]] }
end
r = self.search(tokens, projects, options, user)[0]
r.map{ |f| [f.updated_at.to_i, f.id]}
end
def display_name
if self.name.length > 50
@ -436,4 +438,4 @@ class DmsfFile < ActiveRecord::Base
self.name
end
end
end

View File

@ -25,9 +25,7 @@ class DmsfFolder < ActiveRecord::Base
include RedmineDmsf::Lockable
cattr_reader :invalid_characters
@@invalid_characters = /\A[^\/\\\?":<>]*\z/
attr_accessible :title, :description, :dmsf_folder_id, :project
@@invalid_characters = /\A[^\/\\\?":<>]*\z/
belongs_to :project
belongs_to :folder, :class_name => 'DmsfFolder', :foreign_key => 'dmsf_folder_id'
@ -39,56 +37,67 @@ class DmsfFolder < ActiveRecord::Base
has_many :files, :class_name => 'DmsfFile', :foreign_key => 'dmsf_folder_id',
:dependent => :destroy
if (Rails::VERSION::MAJOR > 3)
has_many :folder_links, -> { where target_type: DmsfFolder.model_name },
has_many :folder_links, -> { where :target_type => 'DmsfFolder' },
:class_name => 'DmsfLink', :foreign_key => 'dmsf_folder_id', :dependent => :destroy
has_many :file_links, -> { where target_type: DmsfFile.model_name },
has_many :file_links, -> { where :target_type => 'DmsfFile' },
:class_name => 'DmsfLink', :foreign_key => 'dmsf_folder_id', :dependent => :destroy
has_many :url_links, -> { where target_type: 'DmsfUrl' },
has_many :url_links, -> { where :target_type => 'DmsfUrl' },
:class_name => 'DmsfLink', :foreign_key => 'dmsf_folder_id', :dependent => :destroy
has_many :referenced_links, -> { where target_type: DmsfFolder.model_name },
has_many :referenced_links, -> { where :target_type => 'DmsfFolder' },
:class_name => 'DmsfLink', :foreign_key => 'target_id', :dependent => :destroy
has_many :locks, -> { where(entity_type: 1).order("#{DmsfLock.table_name}.updated_at DESC") },
:class_name => 'DmsfLock', :foreign_key => 'entity_id', :dependent => :destroy
accepts_nested_attributes_for :user, :project, :folder, :subfolders, :files, :folder_links, :file_links, :url_links, :referenced_links, :locks
else
has_many :folder_links, :class_name => 'DmsfLink', :foreign_key => 'dmsf_folder_id',
:conditions => {:target_type => DmsfFolder.model_name}, :dependent => :destroy
:conditions => { :target_type => 'DmsfFolder' }, :dependent => :destroy
has_many :file_links, :class_name => 'DmsfLink', :foreign_key => 'dmsf_folder_id',
:conditions => {:target_type => DmsfFile.model_name}, :dependent => :destroy
:conditions => { :target_type => 'DmsfFile' }, :dependent => :destroy
has_many :url_links, :class_name => 'DmsfLink', :foreign_key => 'dmsf_folder_id',
:conditions => {:target_type => 'DmsfUrl'}, :dependent => :destroy
:conditions => { :target_type => 'DmsfUrl' }, :dependent => :destroy
has_many :referenced_links, :class_name => 'DmsfLink', :foreign_key => 'target_id',
:conditions => {:target_type => DmsfFolder.model_name}, :dependent => :destroy
:conditions => { :target_type => 'DmsfFolder' }, :dependent => :destroy
has_many :locks, :class_name => 'DmsfLock', :foreign_key => 'entity_id',
:order => "#{DmsfLock.table_name}.updated_at DESC",
:conditions => {:entity_type => 1},
:dependent => :destroy
end
if (Rails::VERSION::MAJOR > 3)
scope :visible, -> { where(deleted: false) }
scope :deleted, -> { where(deleted: true) }
else
scope :visible, where(:deleted => false)
scope :deleted, where(:deleted => true)
end
scope :visible, lambda { |*args|
where(deleted: false)
}
scope :deleted, lambda { |*args|
where(deleted: true)
}
acts_as_customizable
if (Rails::VERSION::MAJOR > 3)
acts_as_searchable :columns => ["#{self.table_name}.title", "#{self.table_name}.description"],
:project_key => 'project_id',
:date_column => 'updated_at',
:permission => :view_dmsf_files,
:scope => self.joins(:project)
else
acts_as_searchable :columns => ["#{self.table_name}.title", "#{self.table_name}.description"],
:project_key => 'project_id',
:date_column => 'updated_at',
:permission => :view_dmsf_files,
:include => :project
end
acts_as_event :title => Proc.new {|o| o.title},
:description => Proc.new {|o| o.description },
:url => Proc.new {|o| {:controller => 'dmsf', :action => 'show', :id => o.project, :folder_id => o}},
:datetime => Proc.new {|o| o.updated_at },
:author => Proc.new {|o| o.user }
validates :title, :presence => true
validates_uniqueness_of :title, :scope => [:dmsf_folder_id, :project_id, :deleted]
validates_format_of :title, :with => @@invalid_characters,
:message => l(:error_contains_invalid_character)
validate :check_cycle
acts_as_event :title => Proc.new {|o| o.title},
:description => Proc.new {|o| o.description },
:url => Proc.new {|o| {:controller => 'dmsf', :action => 'show', :id => o.project, :folder_id => o}},
:datetime => Proc.new {|o| o.updated_at },
:author => Proc.new {|o| o.user }
before_create :default_values
def default_values
@notifications = Setting.plugin_redmine_dmsf['dmsf_default_notifications']
@ -280,50 +289,7 @@ class DmsfFolder < ActiveRecord::Base
def available_custom_fields
DmsfFileRevisionCustomField.all
end
# To fullfill searchable module expectations
def self.search(tokens, projects = nil, options = {})
tokens = [] << tokens unless tokens.is_a?(Array)
projects = [] << projects unless projects.nil? || projects.is_a?(Array)
find_options = {}
find_options[:order] = 'dmsf_folders.updated_at ' + (options[:before] ? 'DESC' : 'ASC')
limit_options = {}
limit_options[:limit] = options[:limit] if options[:limit]
if options[:offset]
limit_options[:conditions] = '(dmsf_folders.updated_at ' + (options[:before] ? '<' : '>') + "'#{connection.quoted_date(options[:offset])}')"
end
columns = options[:titles_only] ? ['dmsf_folders.title'] : ['dmsf_folders.title', 'dmsf_folders.description']
token_clauses = columns.collect {|column| "(LOWER(#{column}) LIKE ?)"}
sql = (['(' + token_clauses.join(' OR ') + ')'] * tokens.size).join(options[:all_words] ? ' AND ' : ' OR ')
find_options[:conditions] = [sql, * (tokens.collect {|w| "%#{w.downcase}%"} * token_clauses.size).sort]
project_conditions = []
project_conditions << (Project.allowed_to_condition(User.current, :view_dmsf_files))
project_conditions << "project_id IN (#{projects.collect(&:id).join(',')})" if projects
results = []
results_count = 0
includes(:project).
where(project_conditions.join(' AND ')).scoping do
where(find_options[:conditions]).order(find_options[:order]).scoping do
results_count = count(:all)
results = find(:all, limit_options)
end
end
[results, results_count]
end
def self.search_result_ranks_and_ids(tokens, user = User.current, projects = nil, options = {})
self.search(tokens, :user => user, :projects => projects, :options => options)
end
def modified
last_update = updated_at
subfolders.each do |subfolder|
@ -343,6 +309,15 @@ class DmsfFolder < ActiveRecord::Base
end
last_update
end
# Number of items in the folder
def items
subfolders.visible.count +
files.visible.count +
folder_links.visible.count +
file_links.visible.count +
url_links.visible.count
end
private
@ -355,4 +330,4 @@ class DmsfFolder < ActiveRecord::Base
end
end
end
end

View File

@ -95,15 +95,13 @@ class DmsfLink < ActiveRecord::Base
end
def path
if self.target_type == DmsfFile.model_name
file = self.target_file
path = file.dmsf_path.map { |element| element.is_a?(DmsfFile) ? element.name : element.title }.join('/') if file
else
folder = self.target_folder
path = folder.dmsf_path_str if folder
if self.target_type == DmsfFile.model_name
path = self.target_file.dmsf_path.map { |element| element.is_a?(DmsfFile) ? element.name : element.title }.join('/') if self.target_file
else
path = self.target_folder ? self.target_folder.dmsf_path_str : ''
end
path.insert(0, "#{self.target_project.name}:") if self.project_id != self.target_project_id && path
if path.length > 50
path.insert(0, "#{self.target_project.name}:") if self.project_id != self.target_project_id
if path && path.length > 50
return "#{path[0, 25]}...#{path[-25, 25]}"
end
path

View File

@ -1,7 +1,9 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2011 Vít Jonáš <vit.jonas@gmail.com>
# Copyright (C) 2011-14 Karel Pičman <karel.picman@kontron.com>
# Copyright (C) 2011-15 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
@ -114,7 +116,7 @@ class DmsfMailer < Mailer
end
end
notify_members.collect { |m| m.user }
notify_members.collect { |m| m.user }.uniq
end
end

View File

@ -45,13 +45,7 @@ class DmsfUpload
:original_filename => a.filename,
:comment => uploaded_file[:description]
}
File.open(a.diskfile, 'rb') do |fr|
File.open("#{DmsfHelper.temp_dir}/#{uploaded[:disk_filename]}", 'wb') do |fw|
while (buffer = fr.read(8192))
fw.write(buffer)
end
end
end
FileUtils.mv(a.diskfile, "#{DmsfHelper.temp_dir}/#{uploaded[:disk_filename]}")
a.destroy
DmsfUpload.new(project, folder, uploaded)
end

View File

@ -1,7 +1,9 @@
<%#=
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2011-14 Karel Pičman <karel.picman@kontron.com>
# Copyright (C) 2011-15 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
@ -18,8 +20,8 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
%>
<% locked_for_user = subfolder.locked_for_user? %>
<% locked = subfolder.locked? %>
<% locked_for_user = subfolder && subfolder.locked_for_user? %>
<% locked = subfolder && subfolder.locked? %>
<td class="check"><%= check_box_tag(name, id, false,
:title => l(:title_check_for_zip_download_or_email)) %></td>
@ -30,11 +32,11 @@
<% if link %>
<div class="filename" title="<%= l(:label_target_folder)%>"><%= link.path %></div>
<% else %>
<div class="filename" title="<%= l(:title_number_of_files_in_directory)%>">[<%= subfolder.files.visible.count + subfolder.file_links.visible.count %>]</div>
<div class="filename" title="<%= l(:title_items)%>">[<%= subfolder.items %>]</div>
<% end %>
</td>
<td class="size"></td>
<td class="modified"><%= format_time(subfolder.modified) %>
<td class="modified"><%= format_time(subfolder.modified) if subfolder %>
<% if locked_for_user %>
<% if subfolder.lock.reverse[0].user %>
<%= link_to('',
@ -52,20 +54,24 @@
</td>
<td class="version"></td>
<td class="workflow"></td>
<td class="author"><%= h(subfolder.user) %></td>
<td class="author"><%= h(subfolder.user) if subfolder %></td>
<td class="actions">
<% if @folder_manipulation_allowed %>
<div class="right_icon_box">
<% unless locked %>
<%= link_to('',
edit_dmsf_path(:id => project, :folder_id => subfolder),
:title => l(:link_edit, :title => h(subfolder.title)),
:title => l(:link_edit, :title => subfolder ? h(subfolder.title) : project.name),
:class => 'icon icon-edit') %>
<%= link_to('',
lock_dmsf_path(:id => project, :folder_id => subfolder),
:title => l(:title_lock_file),
:class => 'icon icon-dmsf-lock') %>
<% if subfolder.notification %>
<% if subfolder %>
<%= link_to('',
lock_dmsf_path(:id => project, :folder_id => subfolder),
:title => l(:title_lock_file),
:class => 'icon icon-dmsf-lock') %>
<% else %>
<span class="icon"></span>
<% end %>
<% if (subfolder && subfolder.notification) || (!subfolder && project.dmsf_notification) %>
<%= link_to('',
notify_deactivate_dmsf_path(:id => project, :folder_id => subfolder),
:title => l(:title_notifications_active_deactivate),
@ -104,5 +110,5 @@
</td>
<td class="invisible">0</td>
<td class="invisible">0</td>
<td class="invisible"><%= subfolder.updated_at.to_i %></td>
<td class="invisible"><%= subfolder.modified.to_i if subfolder %></td>
<td class="invisible">0</td>

View File

@ -1,4 +1,6 @@
<%#=
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2011-15 Karel Pičman <karel.picman@kontron.com>
@ -27,12 +29,12 @@
<% if link %>
<div class="filename" title="<%= l(:label_target_folder)%>"><%= link.path %></div>
<% else %>
<div class="filename" title="<%= l(:title_number_of_files_in_directory)%>">[<%= subfolder.files.visible.count + subfolder.file_links.visible.count %>]</div>
<div class="filename" title="<%= l(:title_items)%>">[<%= subfolder.items %>]</div>
<% end %>
</td>
<td class="size"></td>
<td class="modified">
<%= format_time(subfolder.updated_at) %>
<%= format_time(subfolder.modified) if subfolder %>
</td>
<td class="version"></td>
<td class="workflow"></td>
@ -54,5 +56,5 @@
</td>
<td class="invisible">0</td>
<td class="invisible">0</td>
<td class="invisible"><%= subfolder.updated_at.to_i %></td>
<td class="invisible"><%= subfolder.modified.to_i if subfolder %></td>
<td class="invisible">0</td>

View File

@ -1,4 +1,6 @@
<%#=
# encode: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2011-15 Karel Pičman <karel.picman@kontron.com>

View File

@ -20,13 +20,10 @@
<td class="check"><%= check_box_tag(name, id, false,
:title => l(:title_check_for_restore_or_delete)) %></td>
<td class="title">
<% file_download_url = url_for({:only_path => false, :controller => :dmsf_files, :action => 'show', :id => file, :download => ''}) %>
<%= link_to(h(title),
file_download_url,
:class => "icon icon-file #{DmsfHelper.filetype_css(file.name)}",
:title => l(:title_title_version_version_download, :title => h(file.title), :version => file.version),
'data-downloadurl' => "#{file.last_revision.detect_content_type}:#{h(file.name)}:#{file_download_url}") %>
<td class="title">
<%= content_tag(:span, h(title),
:title => h(title),
:class => "icon icon-file #{DmsfHelper.filetype_css(file.name)}") %>
<div class="filename" title="<%= l(:title_filename_for_download)%>"><%= h(link ? link.path : file.display_name) %></div>
</td>
<td class="size"><%= number_to_human_size(file.last_revision.size) %></td>

View File

@ -1,7 +1,9 @@
<%#=
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2011-14 Karel Pičman <karel.picman@kontron.com>
# Copyright (C) 2011-15 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
@ -55,5 +57,5 @@
</td>
<td class="invisible">1</td>
<td class="invisible"></td>
<td class="invisible"></td>
<td class="invisible"></td>
<td class="invisible">link.updated_at.to_i</td>
<td class="invisible"></td>

View File

@ -1,4 +1,6 @@
<%#=
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2011-15 Karel Pičman <karel.picman@kontron.com>
@ -50,5 +52,5 @@
</td>
<td class="invisible">1</td>
<td class="invisible"></td>
<td class="invisible"></td>
<td class="invisible"></td>
<td class="invisible">link.updated_at.to_i</td>
<td class="invisible"></td>

View File

@ -0,0 +1,4 @@
api.dmsf_folder do
api.id @folder.id
api.title @folder.title
end

View File

@ -0,0 +1,32 @@
api.dmsf do
api.array :dmsf_folders, api_meta(:total_count => @subfolders.size) do
@subfolders.each do |folder|
api.folder do
api.id folder.id
api.title folder.title
end
end
end
api.array :dmsf_files, api_meta(:total_count => @files.size) do
@files.each do |file|
api.file do
api.id file.id
api.name file.name
end
end
end
api.array :dmsf_links, api_meta(:total_count => @dir_links.size + @file_links.size + @url_links.size) do
(@dir_links + @file_links + @url_links).each do |link|
api.link do
api.id link.id
api.name link.name
api.target_type link.target_type
api.target_id link.target_id
api.target_project_id link.target_project_id
api.external_url link.external_url if link.external_url.present?
end
end
end
end

View File

@ -153,7 +153,11 @@
:title => subfolder.title }) %>
</tr>
<% end %>
<% @dir_links.each do |link| %>
<% @dir_links.each do |link| %>
<% unless link.target_project %>
<% Rails.logger.error "Error: dmsf_link id #{link.id} has no target!" %>
<% next %>
<% end %>
<tr class="gray">
<%= render(:partial => 'dir',
:locals => {
@ -263,7 +267,7 @@
jQuery('div.controls').prependTo(jQuery('#browser_wrapper div.fg-toolbar')[0]);
},
'fnInfoCallback': function( oSettings, iStart, iEnd, iMax, iTotal, sPre ) {
return "<%= l(:label_number_of_folders)%>: <%= @subfolders.count + @dir_links.count %>, <%= l(:label_number_of_documents)%>: <%= @files.count + @file_links.count %>";
return "<%= l(:label_number_of_folders)%>: <%= @subfolders.count + @dir_links.count %>, <%= l(:label_number_of_documents)%>: <%= @files.count + @file_links.count + @url_links.count %>";
}
});

View File

@ -1,4 +1,6 @@
<%#=
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2011-15 Karel Pičman <karel.picman@kontron.com>
@ -184,7 +186,7 @@
jQuery('div.controls').prependTo(jQuery('#browser_wrapper div.fg-toolbar')[0]);
},
'fnInfoCallback': function( oSettings, iStart, iEnd, iMax, iTotal, sPre ) {
return "<%= l(:label_number_of_folders)%>: <%= @subfolders.count + @dir_links.count %>, <%= l(:label_number_of_documents)%>: <%= @files.count + @file_links.count %>";
return "<%= l(:label_number_of_folders)%>: <%= @subfolders.count + @dir_links.count %>, <%= l(:label_number_of_documents)%>: <%= @files.count + @file_links.count + @url_links.count %>";
}
});

View File

@ -1,8 +1,8 @@
api.file do
api.dmsf_file do
api.id @file.id
api.name @file.name
api.name @file.name
api.project_id @file.project_id
api.dmsf_folder_id @file.folder ? @file.dmsf_folder_id : -1
api.version "#{@file.last_revision.major_version}.#{@file.last_revision.minor_version}"
api.dmsf_folder_id @file.folder if @file.dmsf_folder_id
api.version "#{@file.last_revision.major_version}.#{@file.last_revision.minor_version}" if @file.last_revision
api.content_url url_for(:controller => :dmsf_files, :action => 'show', :download => '', :id => @file, :only_path => false)
end

View File

@ -1,4 +1,6 @@
<%#=
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2011 Vít Jonáš <vit.jonas@gmail.com>
@ -83,12 +85,12 @@
delete_revision_path(revision),
:data => {:confirm => l(:text_are_you_sure)},
:title => l(:title_delete_revision),
:class => 'icon icon-dmsf-rev-delete' if @file_delete_allowed %>
:class => 'icon icon-dmsf-rev-delete' if @file_delete_allowed && (@file.revisions.visible.count > 1) %>
</div>
<i><%= l(:info_revision, :rev => revision.id) %></i>
<%= (revision.source_revision.nil? ? l(:label_created) : l(:label_changed)).downcase %>
<%= l(:info_changed_by_user, :changed => format_time(revision.updated_at)) %>
<%= link_to(revision.user.name, user_path(revision.user)) %>
<%= link_to(revision.user.name, user_path(revision.user)) if revision.user %>
</div>
</div>
<div style="border: 1px solid #e4e4e4;">

View File

@ -0,0 +1,8 @@
api.array :dmsf_files, api_meta(:total_count => @files.size) do
@files.each do |file|
api.file do
api.id file.id
api.name file.name
end
end
end

View File

@ -0,0 +1,3 @@
api.upload do
api.token @attachment.token
end

View File

@ -0,0 +1,36 @@
<%
# encoding: utf-8
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2011-15 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.
%>
<fieldset class="box">
<legend><%=l(:label_dmsf_workflow_add_approver)%></legend>
<p><%= label_tag 'user_search', l(:label_user_search) %><%= text_field_tag 'user_search', nil %></p>
<%= javascript_tag "observeSearchfield('user_search', 'users', '#{ escape_javascript autocomplete_for_user_dmsf_workflow_path(@dmsf_workflow, :dmsf_workflow_step_assignment_id => nil, :dmsf_file_revision_id => nil, :project_id => @project ? @project.id : nil) }')" %>
<div id="users">
<%= render_principals_for_new_dmsf_workflow_users(@dmsf_workflow, nil, nil) %>
</div>
</fieldset>
<fieldset class="box">
<legend><%= l(:label_dmsf_workflow_step) %></legend>
<%= select_tag 'step', dmsf_workflow_steps_options_for_select(@steps),
:id => 'selected_step', :style => "width:100px" %>
</fieldset>

View File

@ -0,0 +1,31 @@
<%
# encoding: utf-8
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2011-15 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.
%>
<h3 class="title"><%= l(:dmsf_new_step) %></h3>
<%= form_for(:dmsf_workflow, {:url => edit_dmsf_workflow_path(@dmsf_workflow), :method => :post}) do |f| %>
<%= render :partial => 'new_step_form' %>
<p class="buttons">
<%= submit_tag l(:dmsf_and), :id => 'add-step-and' %>
<%= submit_tag l(:dmsf_or), :id => 'add-step-or' %>
<%= submit_tag l(:button_cancel), :name => nil, :onclick => 'hideModal(this);', :type => 'button' %>
</p>
<% end %>

View File

@ -1,6 +1,8 @@
<%# Redmine plugin for Document Management System "Features"
<%
# encoding: utf-8
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2013 Karel Pičman <karel.picman@kontron.com>
# Copyright (C) 2011-15 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
@ -14,7 +16,8 @@
#
# 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.%>
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
%>
<% if @dmsf_workflow.project %>
<h2><%= link_to l(:label_dmsf_workflow_plural), settings_project_path(@project, :tab => 'dmsf_workflow') %> &#187; <%=h @dmsf_workflow %></h2>
@ -29,67 +32,42 @@
</div>
<% end %>
<div class="tab-content" id="tab-content-members">
<div class="splitcontentleft">
<% steps = @dmsf_workflow.dmsf_workflow_steps.collect{|s| s.step}.uniq %>
<% if steps.any? %>
<table class="list">
<thead><tr>
<th><%= l(:label_dmsf_workflow_step) %></th>
<th><%= l(:label_dmsf_workflow_approval_plural) %></th>
<th><%= l(:button_sort)%></th>
<th/>
</tr></thead>
<tbody>
<% steps.each do |i|%>
<tr id="step-<%= i %>" class="<%= cycle 'odd', 'even' %> step">
<td class="step"><%= i %></td>
<td class="approval">
<% @dmsf_workflow.dmsf_workflow_steps.collect{|s| (s.step == i) ? s : nil}.compact.each_with_index do |step, j| %>
<% if j != 0 %>
<b><%= step.soperator %></b>&nbsp
<% end %>
<%= link_to_user step.user %>
<% end %>
</td>
<td class="reorder">
<%= reorder_links('workflow_step', {:action => 'edit', :id => @dmsf_workflow, :step => i}, :put) %>
</td>
<td class="buttons">
<%= delete_link edit_dmsf_workflow_path(@dmsf_workflow, :step => i) %>
</td>
</tr>
<% end; reset_cycle %>
</tbody>
</table>
<% else %>
<p class="nodata"><%= l(:label_no_data) %></p>
<% end %>
</div>
<div class="splitcontentright">
<%= form_for(@dmsf_workflow, :url => edit_dmsf_workflow_path(@dmsf_workflow),
:html => {:method => :post}) do |f| %>
<fieldset><legend><%=l(:label_user_new)%></legend>
<p><%= label_tag 'user_search', l(:label_user_search) %><%= text_field_tag 'user_search', nil %></p>
<%= javascript_tag "observeSearchfield('user_search', 'users', '#{ escape_javascript autocomplete_for_user_dmsf_workflow_path(@dmsf_workflow, :dmsf_workflow_step_assignment_id => nil, :dmsf_file_revision_id => nil, :project_id => @project ? @project.id : nil) }')" %>
<div id="users">
<%= render_principals_for_new_dmsf_workflow_users(@dmsf_workflow, nil, nil) %>
</div>
<p>
<%= l(:label_dmsf_workflow_step) %>
<%= select_tag 'step',
dmsf_workflow_steps_options_for_select(steps),
:id => 'selected_step', :style => "width:100px" %>
</p>
<p><%= l(:label_dmsf_workflow_add_approver) %></p>
<p><%= submit_tag l(:dmsf_and) %>&nbsp<%= l(:label_or) %>&nbsp<%= submit_tag l(:dmsf_or) %></p>
</fieldset>
<div class="tab-content" id="tab-content-members">
<p>
<%= link_to l(:dmsf_new_step), new_step_dmsf_workflow_path(@dmsf_workflow), :remote => true, :class => 'icon icon-add' %>
</p>
<% steps = @dmsf_workflow.dmsf_workflow_steps.collect{|s| s.step}.uniq %>
<% if steps.any? %>
<table class="list">
<thead><tr>
<th><%= l(:label_dmsf_workflow_step) %></th>
<th><%= l(:label_dmsf_workflow_approval_plural) %></th>
<th><%= l(:button_sort)%></th>
<th/>
</tr></thead>
<tbody>
<% steps.each do |i|%>
<tr id="step-<%= i %>" class="<%= cycle 'odd', 'even' %> step">
<td class="step"><%= i %></td>
<td class="approval">
<% @dmsf_workflow.dmsf_workflow_steps.collect{|s| (s.step == i) ? s : nil}.compact.each_with_index do |step, j| %>
<% if j != 0 %>
<b><%= step.soperator %></b>&nbsp
<% end %>
<%= link_to_user step.user %>
<% end %>
</td>
<td class="reorder">
<%= reorder_links('workflow_step', {:action => 'edit', :id => @dmsf_workflow, :step => i}, :put) %>
</td>
<td class="buttons">
<%= delete_link edit_dmsf_workflow_path(@dmsf_workflow, :step => i) %>
</td>
</tr>
<% end; reset_cycle %>
</tbody>
</table>
<% else %>
<p class="nodata"><%= l(:label_no_data) %></p>
<% end %>
</div>
</div>

View File

@ -1,6 +1,6 @@
<%# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2013 Karel Pičman <karel.picman@kontron.com>
# Copyright (C) 2011-15 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
@ -17,5 +17,5 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.%>
$('#ajax-modal').html('<%= escape_javascript(render :partial => 'action', :locals => {:workflow => @dmsf_workflow}) %>');
showModal('ajax-modal', '400px');
showModal('ajax-modal', '35%');
$('#ajax-modal').addClass('new-action');

View File

@ -1,6 +1,6 @@
<%# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2013 Karel Pičman <karel.picman@kontron.com>
# Copyright (C) 2011-15 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
@ -17,5 +17,5 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.%>
$('#ajax-modal').html('<%= escape_javascript(render :partial => 'assign', :locals => {:workflow => @dmsf_workflow}) %>');
showModal('ajax-modal', '400px');
showModal('ajax-modal', '30%');
$('#ajax-modal').addClass('assignment');

View File

@ -1,6 +1,6 @@
<%# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2013 Karel Pičman <karel.picman@kontron.com>
# Copyright (C) 2011-15 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
@ -17,5 +17,5 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.%>
$('#ajax-modal').html('<%= escape_javascript(render :partial => 'log', :locals => {:workflow => @dmsf_workflow}) %>');
showModal('ajax-modal', '800px');
showModal('ajax-modal', '90%');
$('#ajax-modal').addClass('workflow-log');

View File

@ -0,0 +1,19 @@
<%
# encoding: utf-8
#
# Redmine plugin for Kontron customisation
# Copyright (c) 2011-15 Kontron
# Karel Pičman <karel.picman@kontron.com>
#
# Repository folders
%>
<h2><%= l(:label_repository_folders) %></h2>
<%= form_for(:repository_folder, {:url => edit_dmsf_workflow_path(@dmsf_workflow), :method => :post}) do |f| %>
<%= render :partial => 'new_step_form' %>
<p>
<%= submit_tag l(:dmsf_and), :id => 'add-step-and' %>
<%= submit_tag l(:dmsf_or), :id => 'add-step-or' %>
</p>
<% end %>

View File

@ -0,0 +1,20 @@
<%# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2011-15 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.%>
$('#ajax-modal').html('<%= escape_javascript(render :partial => 'new_step_modal') %>');
showModal('ajax-modal', '40%');

Binary file not shown.

Before

Width:  |  Height:  |  Size: 803 B

After

Width:  |  Height:  |  Size: 566 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 419 B

After

Width:  |  Height:  |  Size: 385 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 759 B

After

Width:  |  Height:  |  Size: 490 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 416 B

After

Width:  |  Height:  |  Size: 362 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 764 B

After

Width:  |  Height:  |  Size: 427 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 401 B

After

Width:  |  Height:  |  Size: 348 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 719 B

After

Width:  |  Height:  |  Size: 421 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 413 B

After

Width:  |  Height:  |  Size: 350 B

View File

@ -22,9 +22,9 @@
cs:
dmsf: DMSF
label_dmsf_file_plural: Dmsf soubory
label_dmsf_file_revision_plural: Dmsf document revisions
label_dmsf_file_revision_access_plural: Dmsf document accesses
label_dmsf_file_plural: Dokumenty
label_dmsf_file_revision_plural: Revize dokumentů
label_dmsf_file_revision_access_plural: Přístupy k dokumentům
warning_no_entries_selected: Není nic vybráno
error_email_to_must_be_entered: Musí být zadán adresát
warning_file_already_locked: Soubor už je zamčen
@ -166,8 +166,8 @@ cs:
notice_entries_deleted: Položky smazány
warning_some_entries_were_not_deleted: "Některé položky nebyly smazány: %{entries}"
title_delete_checked: Smaž vybrané
title_number_of_files_in_directory: Počet souborů ve složce
title_filename_for_download: Název Zip archívu ke stažení
title_items: položek
title_filename_for_download: Název Zip archivu ke stažení
label_number_of_folders: Složky
label_number_of_documents: Dokumenty
error_file_storage_directory_does_not_exist: Cílová složka neexistuje a nemůže být vytvořena
@ -180,8 +180,8 @@ cs:
heading_access_downloads_emails: Stažené/Emaily
heading_access_first: První
heading_access_last: Poslední
label_dmsf_updated: DMSF změněno
label_dmsf_downloaded: DMSF document downloaded
label_dmsf_updated: Změněno
label_dmsf_downloaded: Staženo
title_total_size_of_all_files: Celková velikost všech souborů v adresáři
project_module_dmsf: DMSF
warning_no_project_to_copy_file_to: Neexistuje projekt, do kterého můžete kopírovat
@ -191,7 +191,7 @@ cs:
field_target_project: Cílový projekt
field_target_folder: Cílový adresář
title_copy_or_move: Kopírovat/Přesunout
label_dmsf_folder_plural: Dmsf složky
label_dmsf_folder_plural: Složky
comment_moved_from: "Přesunuto z %{source}"
error_target_folder_same: Cílový adresář a projekt jsou stejné jako aktuální
error_file_cannot_be_moved: Soubor nemůže být přesunut
@ -209,7 +209,7 @@ cs:
parent_directory: Nadřazený adresář
note_webdav: "Webdav je po založení k dispozici na http://.../dmsf/webdav/"
label_webdav: Webdav functionalita
label_dmsf_plural: "Kopíruj DMSF soubory a složky (%{files} souborů v %{folders} složkách)"
label_dmsf_plural: "Kopíruj dokumenty a složky (%{files} souborů v %{folders} složkách)"
warning_folder_already_locked: Tato složka je již zamčená
notice_folder_locked: Složka byla úspěšně zamčena
@ -290,13 +290,14 @@ cs:
label_notifications_off: Vypnout notifikace
field_target_file: Zdrojový soubor
title_download_entries: Historie stahování
label_external: Externí
label_link_name: Název odkazu
label_link_external_url: URL
label_target_folder: Cílový adresář
label_source_folder: Zdrojový adresář
label_target_project: Cílový projekt
label_source_project: Zdrojový projekt
label_external: Externí
label_source_project: Zdrojový projekt
text_email_doc_updated_subject: "Dokumenty projektu %{project} aktualizovány"
text_email_doc_updated: právě aktualizoval dokumenty projektu

View File

@ -23,6 +23,8 @@
de:
dmsf: DMS
label_dmsf_file_plural: DMS
label_dmsf_file_revision_plural: Dokumenteversion
label_dmsf_file_revision_access_plural: Dokumentezugriffe
warning_no_entries_selected: Keine Einträge ausgewählt
error_email_to_must_be_entered: Es muss ein Email-Empfänger angegeben werden.
warning_file_already_locked: Datei schon gesperrt
@ -81,7 +83,7 @@ de:
title_lock_file: Sperre um Änderungen anderer Nutzer zu verhindern
title_download_checked: Download der ausgewählten Dateien in einem ZIP-Archiv
title_send_checked_by_email: Sende gewählte Dateien per Email
link_user_preferences: Deine Einstellungen
link_user_preferences: Deine DMS Projekt Einstellungen
heading_send_documents_by_email: Sende Dateien per Email
label_email_from: Von
label_email_to: An
@ -143,16 +145,16 @@ de:
heading_uploaded_files: Hochgeladene Dateien
submit_commit: OK
link_documents: Dateien
permission_view_dmsf_file_revision_accesses: View downloads in Activity stream
permission_view_dmsf_file_revisions: View revisions in Activity stream
permission_view_dmsf_file_revision_accesses: Betrachte Dokumentezugriffe in Aktivitäten
permission_view_dmsf_file_revisions: Betrachte Dokumenteversion in Aktivitäten
permission_view_dmsf_folders: Durchforste Dateien
permission_user_preferences: Benutzereinstellungen
permission_view_dmsf_files: Betrachte Dateien
permission_folder_manipulation: Ordner bearbeiten
permission_file_manipulation: Dateien bearbeiten
permission_force_file_unlock: Erzwinge Aufhebung der Dateisperre
permission_file_delete: Datei löschen
permission_force_file_unlock: Erzwinge Aufhebung der Dateisperre
permission_manage_workflows: Workflows verwalten
permission_file_delete: Datei löschen
label_file: Datei
field_folder: Ordner
error_create_cycle_in_folder_dependency: Zirkelabhängigkeit in der Ordnerstruktur erstellt
@ -164,7 +166,7 @@ de:
notice_entries_deleted: Einträge löschen
warning_some_entries_were_not_deleted: "Enige Einträge wurden nicht gelöscht: %{entries}"
title_delete_checked: Löschen ausgewählt
title_number_of_files_in_directory: Dateianzahl in dem Ordner
title_items: items
title_filename_for_download: Dateiname beim Herunterladen oder in ZIP-Archiv verwenden
label_number_of_folders: Order
label_number_of_documents: Dokumente
@ -178,7 +180,8 @@ de:
heading_access_downloads_emails: Downloads oder Emailversand
heading_access_first: Erste
heading_access_last: Letzte
label_dmsf_updated: DMS aktualisiert
label_dmsf_updated: aktualisiert
label_dmsf_downloaded: gespeichert
title_total_size_of_all_files: Gesamtgröße aller Dateien in diesem Ordner
project_module_dmsf: DMS
warning_no_project_to_copy_file_to: Kein Projekt, in das die Datei kopiert werden kann.
@ -287,13 +290,14 @@ de:
label_notifications_off: Benachrichtigungen aus
field_target_file: Quelldatei
title_download_entries: Download entries
label_external: Außen
label_link_name: Name der Verknüpfung
label_link_external_url: URL
label_target_folder: Zielordner
label_source_folder: Quellordner
label_target_project: Zielprojekt
label_source_project: Quellprojekt
label_external: Außen
label_source_project: Quellprojekt
text_email_doc_updated_subject: "Dokumente im Projekt %{project} wurden aktualisiert"
text_email_doc_updated: hat folgende Dokumente bearbeitet

View File

@ -22,9 +22,9 @@
en:
dmsf: DMSF
label_dmsf_file_plural: Dmsf files
label_dmsf_file_revision_plural: Dmsf document revisions
label_dmsf_file_revision_access_plural: Dmsf document accesses
label_dmsf_file_plural: Documents
label_dmsf_file_revision_plural: Document revisions
label_dmsf_file_revision_access_plural: Document accesses
warning_no_entries_selected: No entries selected
error_email_to_must_be_entered: Email To must be entered
warning_file_already_locked: File already locked
@ -145,6 +145,8 @@ en:
heading_uploaded_files: Uploaded Files
submit_commit: Commit
link_documents: Documents
permission_view_dmsf_file_revision_accesses: View downloads in Activity stream
permission_view_dmsf_file_revisions: View revisions in Activity stream
permission_view_dmsf_folders: Browse documents
permission_user_preferences: User preferences
permission_view_dmsf_files: View documents
@ -164,7 +166,7 @@ en:
notice_entries_deleted: Entries deleted
warning_some_entries_were_not_deleted: "Some entries weren't deleted: %{entries}"
title_delete_checked: Delete checked
title_number_of_files_in_directory: Number of files in directory
title_items: items
title_filename_for_download: Filename used for download or in Zip archive
label_number_of_folders: Folders
label_number_of_documents: Documents
@ -178,8 +180,8 @@ en:
heading_access_downloads_emails: Downloads/Emails
heading_access_first: First
heading_access_last: Last
label_dmsf_updated: DMSF document updated
label_dmsf_downloaded: DMSF document downloaded
label_dmsf_updated: Updated
label_dmsf_downloaded: Downloaded
title_total_size_of_all_files: Total size of all files under this folder
project_module_dmsf: DMSF
warning_no_project_to_copy_file_to: No project to copy file to
@ -189,7 +191,7 @@ en:
field_target_project: Target project
field_target_folder: Target folder
title_copy_or_move: Copy/Move
label_dmsf_folder_plural: Dmsf folders
label_dmsf_folder_plural: Folders
comment_moved_from: "Moved from %{source}"
error_target_folder_same: Target folder and project are the same as current
error_file_cannot_be_moved: "File can't be moved"
@ -207,7 +209,7 @@ en:
parent_directory: Parent Directory
note_webdav: Webdav once enabled can be found at http://.../dmsf/webdav/
label_webdav: Webdav functionality
label_dmsf_plural: "Copy DMSF files and folders (%{files} files in %{folders} folders)"
label_dmsf_plural: "Copy Documents and folders (%{files} files in %{folders} folders)"
warning_folder_already_locked: This folder is already locked
notice_folder_locked: The folder was successfully locked

View File

@ -22,9 +22,9 @@
es:
dmsf: DMSF
label_dmsf_file_plural: DMSF Archivos
label_dmsf_file_revision_plural: Dmsf document revisions
label_dmsf_file_revision_access_plural: Dmsf document accesses
label_dmsf_file_plural: Archivos
label_dmsf_file_revision_plural: Document revisions
label_dmsf_file_revision_access_plural: Document accesses
warning_no_entries_selected: No ha seleccionado ningún ítem
error_email_to_must_be_entered: Ingrese un email
warning_file_already_locked: El archivo ya está bloqueado
@ -166,7 +166,7 @@ es:
notice_entries_deleted: Entradas eliminadas
warning_some_entries_were_not_deleted: "Algunas entradas no fueron eliminadas: %{entries}"
title_delete_checked: Eliminación chequeada
title_number_of_files_in_directory: Número de archivos en directorio
title_items: items
title_filename_for_download: Nombre de archivo utilizado para descargar o crear zip
label_number_of_folders: Directorios
label_number_of_documents: Documentos
@ -191,7 +191,7 @@ es:
field_target_project: Proyecto destino
field_target_folder: Directorio destino
title_copy_or_move: Copiar/Mover
label_dmsf_folder_plural: directorio Dmsf
label_dmsf_folder_plural: directorio
comment_moved_from: "Mover desde %{source}"
error_target_folder_same: El directorio y proyecto destino son el actual
error_file_cannot_be_moved: "Los archivos no puesen ser movidos"
@ -209,7 +209,7 @@ es:
parent_directory: Directorio padre
note_webdav: Si Webdav está habilitado, se puede encontrar en http://.../dmsf/webdav/
label_webdav: Funcionalidad Webdav
label_dmsf_plural: "Copiar archivos y directorios DMSF (%{files} archivos en %{folders} directorios)"
label_dmsf_plural: "Copiar archivos y directorios (%{files} archivos en %{folders} directorios)"
warning_folder_already_locked: El directorio ya se encuentra bloqueado
notice_folder_locked: "El directorio se bloqueó exitosamente"
@ -290,13 +290,14 @@ es:
label_notifications_off: Notificaciones OFF
field_target_file: Archivo fuente
title_download_entries: Entradas de descarga
label_external: External
label_link_name: Nombre de enlace
label_link_external_url: URL
label_target_folder: Directorio destino
label_source_folder: Directorio fuente
label_target_project: Proyecto destino
label_source_project: Proyecto fuente
label_external: External
label_source_project: Proyecto fuente
text_email_doc_updated_subject: "Documentos de %{project} actualizados"
text_email_doc_updated: acaba de actualizar los ducumentos de

View File

@ -1,3 +1,5 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2011 Vít Jonáš <vit.jonas@gmail.com>
@ -20,9 +22,9 @@
fr:
dmsf: DMSF
label_dmsf_file_plural: Fichiers DMSF
label_dmsf_file_revision_plural: Dmsf document revisions
label_dmsf_file_revision_access_plural: Dmsf document accesses
label_dmsf_file_plural: Fichiers
label_dmsf_file_revision_plural: Révisions du document
label_dmsf_file_revision_access_plural: Accès au document
warning_no_entries_selected: Aucun fichier sélectionné
error_email_to_must_be_entered: "La saisie d'une adresse mail est obligatoire"
warning_file_already_locked: Fichier déjà verrouillé
@ -61,14 +63,14 @@ fr:
submit_create: Ajouter
link_create_folder: Créer un sous-dossier
title_check_uncheck_all_for_zip_download_or_email: Sélectionner/Ignorer tous les documents pour le téléchargement ou pour la transmission par mail
title_check_uncheck_all_for_restore_or_delete: Check/Uncheck all for restore or delete
title_check_uncheck_all_for_restore_or_delete: Sélectionner/Ignorer pour restaurer ou supprimer
link_title: Titre
link_size: Taille
link_modified: Modifié
link_ver: Version
link_author: Auteur
title_check_for_zip_download_or_email: Sélectionner pour le téléchargement ou la transmission par mail
title_check_for_restore_or_delete: Check for restore or delete
title_check_for_restore_or_delete: Sélectionner pour restaurer ou supprimer
title_delete: Supprimer
title_notifications_active_deactivate: "Notifications activées : cliquer pour désactiver"
title_notifications_not_active_activate: "Notifications désactivées : cliquer pour activer"
@ -119,6 +121,7 @@ fr:
option_version_same: (identique)
option_version_minor: (modification mineure)
option_version_major: (modification majeure)
option_version_custom: Custom
label_new_content: Nouvelle version du fichier
label_maximum_files_upload: Nombre maximal de documents pouvant être transmis
note_maximum_number_of_files_uploaded: Nombre maximal de documents pouvant être transmis en une fois. La valeur 0 signifie illimité.
@ -142,8 +145,8 @@ fr:
heading_uploaded_files: Document(s) transmis
submit_commit: Appliquer
link_documents: Documents
permission_view_dmsf_file_revision_accesses: View downloads in Activity stream
permission_view_dmsf_file_revisions: View revisions in Activity stream
permission_view_dmsf_file_revision_accesses: Voir les téléchargements dans le flux d'activité
permission_view_dmsf_file_revisions: Voir les révisions dans le flux d'activité
permission_view_dmsf_folders: Parcourir les documents
permission_user_preferences: Préférences utilisateur
permission_view_dmsf_files: Afficher documents
@ -163,7 +166,7 @@ fr:
notice_entries_deleted: Elément(s) supprimé(s)
warning_some_entries_were_not_deleted: "Certains éléments n'ont pas été supprimés : %{entries}"
title_delete_checked: Supprimer les éléments sélectionnés
title_number_of_files_in_directory: Nombre de fichiers dans le dossier
title_items: items
title_filename_for_download: "Nom du fichier à utiliser lors du téléchargement ou de l'archive ZIP"
label_number_of_folders: Dossiers
label_number_of_documents: Fichiers
@ -178,7 +181,7 @@ fr:
heading_access_first: Premier
heading_access_last: Dernier
label_dmsf_updated: Dépôt ou mise à jour du document
label_dmsf_downloaded: DMSF document downloaded
label_dmsf_downloaded: Document DMSF téléchargé
title_total_size_of_all_files: Taille totale des fichiers de ce dossier
project_module_dmsf: DMSF
warning_no_project_to_copy_file_to: "Le projet de destination n'est pas défini"
@ -188,7 +191,7 @@ fr:
field_target_project: Projet cible
field_target_folder: Dossier cible
title_copy_or_move: Copie/Déplacement
label_dmsf_folder_plural: Les dossiers de DMSF
label_dmsf_folder_plural: Les dossiers
comment_moved_from: "Déplacé depuis %{source}"
error_target_folder_same: Le projet et le dossier cible sont identiques au projet et dossier source
error_file_cannot_be_moved: Le fichier ne peut pas être déplacé
@ -206,7 +209,7 @@ fr:
parent_directory: Dossier parent
note_webdav: "Après l'activation du module Webdav, celui-ci sera accessible par http://.../dmsf/webdav/"
label_webdav: Module Webdav
label_dmsf_plural: "Copier les fichiers et les dossiers DMSF (%{files} fichiers dans %{folders} dossiers)"
label_dmsf_plural: "Copier les fichiers et les dossiers (%{files} fichiers dans %{folders} dossiers)"
warning_folder_already_locked: Ce dossier est déjà verrouillé
notice_folder_locked: Dossier verrouillé
@ -287,13 +290,14 @@ fr:
label_notifications_off: Désactiver les notifications
field_target_file: Fichier source
title_download_entries: Historique des téléchargements
label_external: Externe
label_link_name: Nom du lien
label_link_external_url: Adresse Internet
label_target_folder: Dossier cible
label_source_folder: Dossier source
label_target_project: Projet cible
label_source_project: Projet source
label_external: External
label_source_project: Projet source
text_email_doc_updated_subject: "Documents de %{project} mis à jour"
text_email_doc_updated: a mis à jour des documents de
@ -311,8 +315,8 @@ fr:
notice_dmsf_file_restored: Le document a été récupéré avec succès
notice_dmsf_folder_restored: Le dossier a été récupéré avec succès
notice_dmsf_link_restored: Le lien a été récupéré avec succès
title_restore_checked: Restore checked
error_parent_folder: "The parent folder doesn't exist"
title_restore_checked: Restauration vérifiée
error_parent_folder: "Le dossier parent n'existe pas"
my:
blocks:

View File

@ -167,7 +167,7 @@ ja:
notice_entries_deleted: エントリーを削除しました
warning_some_entries_were_not_deleted: "いくつかのエントリーは削除されませんでした: %{entries}"
title_delete_checked: チェックしたものを削除します
title_number_of_files_in_directory: フォルダ内のファイル数
title_items: items
title_filename_for_download: ファイル名はダウンロードまたは Zip アーカイブに使われます
label_number_of_folders: フォルダ
label_number_of_documents: 文書

View File

@ -23,9 +23,9 @@
pl:
dmsf: DMSF
label_dmsf_file_plural: Pliki Dmsf
label_dmsf_file_revision_plural: Dmsf document revisions
label_dmsf_file_revision_access_plural: Dmsf document accesses
label_dmsf_file_plural: Pliki
label_dmsf_file_revision_plural: Document revisions
label_dmsf_file_revision_access_plural: Document accesses
warning_no_entries_selected: Nie zaznaczono żadnych wierszy
error_email_to_must_be_entered: Musisz podać adres email
warning_file_already_locked: Plik jest już zablokowany
@ -167,7 +167,7 @@ pl:
notice_entries_deleted: Wpisy usunięte
warning_some_entries_were_not_deleted: "Niektóre wpisy nie zostały usunięte: %{entries}"
title_delete_checked: Usuń zaznaczone
title_number_of_files_in_directory: Liczba plików w folderze
title_items: items
title_filename_for_download: Nazwa pliku używana do pobierania lub tworzenai archiwum Zip
label_number_of_folders: Foldery
label_number_of_documents: Dokumenty
@ -192,7 +192,7 @@ pl:
field_target_project: Projekt docelowy
field_target_folder: Folder docelowy
title_copy_or_move: Kopiuj/Przenieś
label_dmsf_folder_plural: Foldery Dmsf
label_dmsf_folder_plural: Foldery
comment_moved_from: "Przeniesiono z %{source}"
error_target_folder_same: Docelowy projekt i folder są identyczne z obecnym
error_file_cannot_be_moved: "Plik nie może zostać przeniesiony"
@ -210,7 +210,7 @@ pl:
parent_directory: Folder nadrzędny
note_webdav: Webdav once enabled can be found at http://.../dmsf/webdav/
label_webdav: Webdav functionality
label_dmsf_plural: "Skopiuj pliki i foldery DMSF (%{files} plików w %{folders} folderach)"
label_dmsf_plural: "Skopiuj pliki i foldery (%{files} plików w %{folders} folderach)"
warning_folder_already_locked: Folder jest już zablokowany
notice_folder_locked: Folder został zablokowany
@ -290,13 +290,14 @@ pl:
label_notifications_off: Powiadomienia wyłączone
field_target_file: Plik źródłowy
title_download_entries: Pobrane
label_external: External
label_link_name: Nazwa odnośnika
label_link_external_url: URL
label_target_folder: Folder docelowy
label_source_folder: Folder źródłowy
label_target_project: Projekt docelowy
label_source_project: Projekt źródłowy
label_external: External
label_source_project: Projekt źródłowy
text_email_doc_updated_subject: "Dokumenty projektu %{project} zostały zaktualizowane"
text_email_doc_updated: dokumenty zostały zaktualizowane

View File

@ -22,9 +22,9 @@
ru:
dmsf: DMSF
label_dmsf_file_plural: Файлы DMSF
label_dmsf_file_revision_plural: Dmsf document revisions
label_dmsf_file_revision_access_plural: Dmsf document accesses
label_dmsf_file_plural: Файлы
label_dmsf_file_revision_plural: Document revisions
label_dmsf_file_revision_access_plural: Document accesses
warning_no_entries_selected: Файлы не выбраны
error_email_to_must_be_entered: Нужно указать, на какую почту отправить письмо
warning_file_already_locked: Файл уже заблокирован
@ -166,7 +166,7 @@ ru:
notice_entries_deleted: Файлы удалены
warning_some_entries_were_not_deleted: "Некоторые файлы не были удалены: %{entries}"
title_delete_checked: Удалить выбранные документы
title_number_of_files_in_directory: Количество файлов в директории
title_items: items
title_filename_for_download: Имя файла для скачиваемого архива
label_number_of_folders: Папок
label_number_of_documents: Документов
@ -181,7 +181,7 @@ ru:
heading_access_first: Первый
heading_access_last: Последний
label_dmsf_updated: Документ обновлен
label_dmsf_downloaded: DMSF document downloaded
label_dmsf_downloaded: Документ downloaded
title_total_size_of_all_files: Общий размер всех файлов в этой папке
project_module_dmsf: DMSF
warning_no_project_to_copy_file_to: Не выбран проект, в который нужно скопировать файл
@ -191,7 +191,7 @@ ru:
field_target_project: Целевой проект
field_target_folder: Целевая папка
title_copy_or_move: Копировать/Переместить
label_dmsf_folder_plural: DMSF папки
label_dmsf_folder_plural: Папки
comment_moved_from: "Перемещен из %{source}"
error_target_folder_same: Целевая папка и проект совпадают с текущими
error_file_cannot_be_moved: Файл не может быть перемещен
@ -209,7 +209,7 @@ ru:
parent_directory: "Родительская директория"
note_webdav: "После включения, WebDAV можно найти по адресу http://redmine-host/dmsf/webdav/"
label_webdav: "Функциональность WebDAV"
label_dmsf_plural: "Скопировать DMSF файлы и папки (%{files} файлов в %{folders} папках)"
label_dmsf_plural: "Скопировать файлы и папки (%{files} файлов в %{folders} папках)"
warning_folder_already_locked: "Эта папка уже заблокирована"
notice_folder_locked: "Папка была успешно заблокирована"
@ -290,13 +290,14 @@ ru:
label_notifications_off: Notifications off
field_target_file: Source file
title_download_entries: Download entries
label_external: External
label_link_name: Link name
label_link_external_url: URL
label_target_folder: Target folder
label_source_folder: Source folder
label_target_project: Target project
label_source_project: Source project
label_external: External
label_source_project: Source project
text_email_doc_updated_subject: "Documents of %{project} updated"
text_email_doc_updated: has just actualized documents of

View File

@ -23,8 +23,8 @@
sl:
dmsf: Arhiv
label_dmsf_file_plural: Arhivske datoteke
label_dmsf_file_revision_plural: Dmsf document revisions
label_dmsf_file_revision_access_plural: Dmsf document accesses
label_dmsf_file_revision_plural: Document revisions
label_dmsf_file_revision_access_plural: Document accesses
warning_no_entries_selected: Ničesar niste izbrali
error_email_to_must_be_entered: Email Naslovnik mora bit izbran
warning_file_already_locked: Datoteka že zaklenjena
@ -166,7 +166,7 @@ sl:
notice_entries_deleted: Izbrane enote izbrisane
warning_some_entries_were_not_deleted: "Nekatere enote niso izbrisane: %{entries}"
title_delete_checked: Izbriši izbrano
title_number_of_files_in_directory: Število datotek v mapi
title_items: items
title_filename_for_download: Naziv datoteke za prenos dol ali Zip arhiva
label_number_of_folders: Mapa
label_number_of_documents: Dokumentacija
@ -181,7 +181,7 @@ sl:
heading_access_first: Prvi
heading_access_last: Zadnji
label_dmsf_updated: Arhiv posodobljen
label_dmsf_downloaded: DMSF document downloaded
label_dmsf_downloaded: Arhiv downloaded
title_total_size_of_all_files: Skupna velikost vseh datotek v tej mapi
project_module_dmsf: Arhiv
warning_no_project_to_copy_file_to: Ni projekta kamor bi kopiral datoteko
@ -290,13 +290,14 @@ sl:
label_notifications_off: Notifications off
field_target_file: Source file
title_download_entries: Download entries
label_external: External
label_link_name: Link name
label_link_external_url: URL
label_target_folder: Target folder
label_source_folder: Source folder
label_target_project: Target project
label_source_project: Source project
label_external: External
label_source_project: Source project
text_email_doc_updated_subject: "Documents of %{project} updated"
text_email_doc_updated: has just actualized documents of

View File

@ -23,8 +23,8 @@
zh-TW:
dmsf: 文件總管
label_dmsf_file_plural: 文件檔案
label_dmsf_file_revision_plural: Dmsf document revisions
label_dmsf_file_revision_access_plural: Dmsf document accesses
label_dmsf_file_revision_plural: Document revisions
label_dmsf_file_revision_access_plural: Document accesses
warning_no_entries_selected: 尚未選取任何項目
error_email_to_must_be_entered: 請輸入收件者的電子郵件
warning_file_already_locked: 檔案己經鎖定
@ -80,10 +80,8 @@ zh-TW:
title_waiting_for_approval: 等待批准
title_approved: 已經被批准
title_unlock_file: 解除鎖定。允許其它使用者修改。
title_lock_file: 鎖定檔案。禁止其它使用者修改。
submit_download: 下載
title_download_checked: 以ZIP下載所選取的檔案
submit_email: 電子郵件
title_lock_file: 鎖定檔案。禁止其它使用者修改。
title_download_checked: 以ZIP下載所選取的檔案
title_send_checked_by_email: 以電子郵件發送所選取的檔案
link_user_preferences: 你的DMSF的系統偏好設定
heading_send_documents_by_email: 電子郵件寄送檔案
@ -156,6 +154,7 @@ zh-TW:
permission_file_manipulation: 文件操作
permission_force_file_unlock: 強制解除檔案鎖定
permission_manage_workflows: Manage workflows
permission_file_delete: Delete documents
label_file: 檔案
field_folder: 資料夾
error_create_cycle_in_folder_dependency: 資料夾之間的關係不得為一個cycle循環。
@ -167,7 +166,7 @@ zh-TW:
notice_entries_deleted: 項目己刪除
warning_some_entries_were_not_deleted: "部份項目無法刪除: %{entries}"
title_delete_checked: 刪除選取項目
title_number_of_files_in_directory: 資料夾的檔案數量
title_items: items
title_filename_for_download: 下載時的檔名或是ZIP的檔案名稱。
label_number_of_folders: 資料夾
label_number_of_documents: 文件檔案
@ -181,8 +180,8 @@ zh-TW:
heading_access_downloads_emails: 下載/電子郵件
heading_access_first: First
heading_access_last: Last
label_dmsf_updated: DMSF updated
label_dmsf_downloaded: DMSF document downloaded
label_dmsf_updated: Updated
label_dmsf_downloaded: Downloaded
title_total_size_of_all_files: 資料夾所有檔案的檔案大小
project_module_dmsf: 文件總管
warning_no_project_to_copy_file_to: No project to copy file to
@ -192,7 +191,7 @@ zh-TW:
field_target_project: Target project
field_target_folder: Target folder
title_copy_or_move: Copy/Move
label_dmsf_folder_plural: Dmsf folders
label_dmsf_folder_plural: Folders
comment_moved_from: "Moved from %{source}"
error_target_folder_same: Target folder and project are the same as current
error_file_cannot_be_moved: "File can't be moved"
@ -291,13 +290,14 @@ zh-TW:
label_notifications_off: Notifications off
field_target_file: Source file
title_download_entries: Download entries
label_external: External
label_link_name: Link name
label_link_external_url: URL
label_target_folder: Target folder
label_source_folder: Source folder
label_target_project: Target project
label_source_project: Source project
label_external: External
label_source_project: Source project
text_email_doc_updated_subject: "Documents of %{project} updated"
text_email_doc_updated: has just actualized documents of
@ -309,6 +309,14 @@ zh-TW:
label_display_notified_recipients: Display notified recipients
note_display_notified_recipients: The user will be informed about all recipients of just sent the email notification.
warning_email_notifications: "Email notifications sent to %{to}"
link_trash_bin: Trash bin
title_restore: Restore
notice_dmsf_file_restored: The document has been successfully restored
notice_dmsf_folder_restored: The folder has been successfully restored
notice_dmsf_link_restored: The link has been successfully restored
title_restore_checked: Restore checked
error_parent_folder: "The parent folder doesn't exist"
my:
blocks:
@ -316,4 +324,4 @@ zh-TW:
open_approvals: Open approvals
label_maximum_ajax_upload_filesize: Maximum file size uploadable via AJAX
note_maximum_ajax_upload_filesize: Limits maximum file size that can uploaded via standard AJAX interface otherwise Redmine standard upload form must be used. Number is in MB.
note_maximum_ajax_upload_filesize: Limits maximum file size that can uploaded via standard AJAX interface otherwise Redmine standard upload form must be used. Number is in MB.

View File

@ -22,9 +22,9 @@
zh:
dmsf: 文档管家
label_dmsf_file_plural: Dmsf files
label_dmsf_file_revision_plural: Dmsf document revisions
label_dmsf_file_revision_access_plural: Dmsf document accesses
label_dmsf_file_plural: Documents
label_dmsf_file_revision_plural: Document revisions
label_dmsf_file_revision_access_plural: Document accesses
warning_no_entries_selected: 未选择任何条目
error_email_to_must_be_entered: 请输入电子邮件
warning_file_already_locked: 文件已经锁定
@ -166,7 +166,7 @@ zh:
notice_entries_deleted: 条目已删除
warning_some_entries_were_not_deleted: "某些条目未被删除: %{entries}"
title_delete_checked: 删除选中
title_number_of_files_in_directory: 目录总文件个数
title_items: items
title_filename_for_download: 用于下载或zip归档的文件名
label_number_of_folders: Folders
label_number_of_documents: Documents
@ -191,7 +191,7 @@ zh:
field_target_project: Target project
field_target_folder: Target folder
title_copy_or_move: Copy/Move
label_dmsf_folder_plural: Dmsf folders
label_dmsf_folder_plural: Folders
comment_moved_from: "Moved from %{source}"
error_target_folder_same: Target folder and project are the same as current
error_file_cannot_be_moved: "File can't be moved"
@ -209,7 +209,7 @@ zh:
parent_directory: Parent Directory
note_webdav: Webdav once enabled can be found at http://.../dmsf/webdav/
label_webdav: Webdav functionality
label_dmsf_plural: "Copy DMSF files and folders (%{files} files in %{folders} folders)"
label_dmsf_plural: "Copy documents and folders (%{files} files in %{folders} folders)"
warning_folder_already_locked: This folder is already locked
notice_folder_locked: The folder was successfully locked
@ -290,13 +290,14 @@ zh:
label_notifications_off: Notifications off
field_target_file: Source file
title_download_entries: Download entries
label_external: External
label_link_name: Link name
label_link_external_url: URL
label_target_folder: Target folder
label_source_folder: Source folder
label_target_project: Target project
label_source_project: Source project
label_external: External
label_source_project: Source project
text_email_doc_updated_subject: "Documents of %{project} updated"
text_email_doc_updated: has just actualized documents of

View File

@ -58,7 +58,9 @@ RedmineApp::Application.routes.draw do
post '/projects/:id/dmsf/upload/files', :controller => 'dmsf_upload', :action => 'upload_files'
post '/projects/:id/dmsf/upload/file', :controller => 'dmsf_upload', :action => 'upload_file'
post '/projects/:id/dmsf/upload', :controller => 'dmsf_upload', :action => 'upload'
post '/projects/:id/dmsf/upload/commit', :controller => 'dmsf_upload', :action => 'commit_files'
post '/projects/:id/dmsf/commit', :controller => 'dmsf_upload', :action => 'commit'
#
# dmsf_files controller
@ -109,7 +111,7 @@ RedmineApp::Application.routes.draw do
# DAV4Rack implementation of Webdav [note: if changing path you'll need to update lib/redmine_dmsf/webdav/no_parse.rb also]
# /dmsf/webdav
mount DAV4Rack::Handler.new(
:root_uri_path => "/dmsf/webdav",
:root_uri_path => "#{Redmine::Utils::relative_url_root}/dmsf/webdav",
:resource_class => RedmineDmsf::Webdav::ResourceProxy,
:controller_class => RedmineDmsf::Webdav::Controller
), :at => "/dmsf/webdav"
@ -124,9 +126,10 @@ RedmineApp::Application.routes.draw do
post 'new_action'
get 'start'
post 'assignment'
get 'new_step'
end
end
match 'dmsf_workflows/:id/edit', :controller => 'dmsf_workflows', :action => 'add_step', :id => /\d+/, :via => :post
match 'dmsf_workflows/:id/edit', :controller => 'dmsf_workflows', :action => 'remove_step', :id => /\d+/, :via => :delete
match 'dmsf_workflows/:id/edit', :controller => 'dmsf_workflows', :action => 'reorder_steps', :id => /\d+/, :via => :put

View File

@ -1,6 +1,8 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2013 Karel Picman <karel.picman@kontron.com>
# Copyright (C) 2011-15 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

View File

@ -1,6 +1,8 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2013 Karel Picman <karel.picman@kontron.com>
# Copyright (C) 2011-15 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

View File

@ -1,6 +1,8 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2013 Karel Picman <karel.picman@kontron.com>
# Copyright (C) 2011-15 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

View File

@ -1,6 +1,8 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2013 Karel Picman <karel.picman@kontron.com>
# Copyright (C) 2011-15 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

View File

@ -1,6 +1,8 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2013 Karel Picman <karel.picman@kontron.com>
# Copyright (C) 2011-15 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

View File

@ -1,6 +1,8 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2013 Karel Picman <karel.picman@kontron.com>
# Copyright (C) 2011-15 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

View File

@ -1,6 +1,8 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2013 Karel Picman <karel.picman@kontron.com>
# Copyright (C) 2011-15 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

View File

@ -1,6 +1,8 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2013 Karel Picman <karel.picman@kontron.com>
# Copyright (C) 2011-15 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

View File

@ -1,6 +1,8 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2013 Karel Picman <karel.picman@kontron.com>
# Copyright (C) 2011-15 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

View File

@ -1,6 +1,8 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2014 Karel Pičman <karel.picman@lbcfree.net>
# Copyright (C) 2011-15 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

View File

@ -1,6 +1,8 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2014 Karel Pičman <karel.picman@lbcfree.net>
# Copyright (C) 2011-15 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
@ -25,6 +27,6 @@ class NotificationsOn < ActiveRecord::Migration
def down
change_column :projects, :dmsf_notification, :boolean, :default => false, :null => true
change_column :dmsf_folders, :notification, :boolean, :default => false, :null => false
change_column :dmsf_folders, :notification, :boolean, :default => false
end
end

View File

@ -1,6 +1,8 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2011-14 Karel Pičman <karel.picman@kontron.com>
# Copyright (C) 2011-15 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

View File

@ -1,6 +1,8 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2011-14 Karel Pičman <karel.picman@kontron.com>
# Copyright (C) 2011-15 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

View File

@ -1,6 +1,8 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2011-14 Karel Pičman <karel.picman@kontron.com>
# Copyright (C) 2011-15 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
@ -19,9 +21,5 @@
class RemoveUniquenessFromWf < ActiveRecord::Migration
def up
remove_index :dmsf_workflows, :name
end
def down
add_index :dmsf_workflows, [:name], :unique => true
end
end
end

View File

@ -2,7 +2,7 @@
#
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2011-15 Karel Pičman <karel.picman@lbcfree.net>
# Copyright (C) 2011-15 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

View File

@ -1,13 +1,30 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2011-15 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 AddExternal < ActiveRecord::Migration
def up
change_column :dmsf_links, :target_id, :integer, :null => true
add_column :dmsf_links, :external_url, :string, :null => true
end
def down
change_column :dmsf_links, :target_id, :integer, :null => false
def down
remove_column :dmsf_links, :external_url
end
end

View File

@ -1,3 +1,23 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2011-15 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 AddUserToLinks < ActiveRecord::Migration
def up
add_column :dmsf_links, :user_id, :integer

Binary file not shown.

View File

@ -1,3 +1,5 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2011-15 Karel Pičman <karel.picman@kontron.com>
@ -19,22 +21,25 @@
require 'rubygems'
require 'active_resource'
# Simple REST API client in Ruby
# usage: ruby api_client.rb [login] [password]
# Dmsf file
class DmsfFile < ActiveResource::Base
self.site = 'http://localhost:3000/'
self.user = 'kpicman'
self.password = 'Kontron2014+'
self.site = 'https://localhost:3000/'
self.user = ARGV[0]
self.password = ARGV[1]
end
# Retrieving a file
file = DmsfFile.find 17200
# 2. Get a document
FILE_ID = 41532
file = DmsfFile.find FILE_ID
if file
puts file.id
puts file.name
puts file.version
puts file.project_id
puts file.dmsf_folder_id
puts file.project_id
puts file.content_url
else
puts 'No file with id = 1 found'
end
puts "No file with id = #{FILE_ID} found"
end

43
extra/api/api_client.sh Normal file
View File

@ -0,0 +1,43 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2011-15 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.
#!/bin/bash
# Authentication as input parameters either as login + password or the API key
# -u ${1}:${2}
# -H "X-Redmine-API-Key: ${1}"
# BOTH XML and JSON formats are supported.
# Just replace .xml with .json
# 1. List of documents in a given folder or the root folder
curl -v -H "Content-Type: application/xml" -X GET -u ${1}:${2} http://localhost:3000/projects/12/dmsf.xml
#curl -v -H "Content-Type: application/xml" -X GET -u ${1}:${2} http://localhost:3000/projects/12/dmsf.xml?folder_id=5155
# 2. Get a document
#curl -v -H "Content-Type: application/xml" -X GET -u ${1}:${2} http://localhost:3000/dmsf/files/17216.xml
#curl -v -H "Content-Type: application/octet-stream" -X GET -u ${1}:${2} http://localhost:3000/dmsf/files/41532/download > file.txt
# 3. Create a folder
#curl -v -H "Content-Type: application/xml" -X POST --data "@folder.xml" -u ${1}:${2} http://localhost:3000/projects/12/dmsf/create.xml
# 4. Upload a document into a given folder or the root folder
#curl --data-binary "@cat.gif" -H "Content-Type: application/octet-stream" -X POST -u ${1}:${2} http://localhost:3000/projects/12/dmsf/upload.xml?filename=cat.gif
#curl -v -H "Content-Type: application/xml" -X POST --data "@file.xml" -u ${1}:${2} http://localhost:3000/projects/12/dmsf/commit.xml

BIN
extra/api/cat.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

13
extra/api/file.xml Normal file
View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8" ?>
<attachments>
<folder_id>6118</folder_id>
<uploaded_file>
<disk_filename>cat.gif</disk_filename>
<name>cat.gif</name>
<title>cat.gif</title>
<description>REST API</description>
<comment>From API</comment>
<version/>
<token>15838.c49f68ff81b552d315927df2e27df506</token>
</uploaded_file>
</attachments>

6
extra/api/folder.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<dmsf_folder>
<title>rest_api</title>
<description>A folder created via REST API</description>
<dmsf_folder_id/>
</dmsf_folder>

View File

@ -542,13 +542,13 @@ if not $onlyrepos then
end
# Indexing repositories
if not $onlyfiles then
if not File.exist?($scriptindex) then
unless $onlyfiles
unless File.exist?($scriptindex)
log("- ERROR! #{$scriptindex} does not exist, exiting...")
exit 1
end
$databasepath = File.join( $dbrootpath.rstrip, "repodb" )
if not File.directory?($databasepath)
$databasepath = File.join($dbrootpath.rstrip, 'repodb')
unless File.directory?($databasepath)
log("Db directory #{$databasepath} does not exist, creating...")
begin
Dir.mkdir($databasepath)
@ -557,32 +557,32 @@ if not $onlyfiles then
log("ERROR! #{$databasepath} can not be created!, exiting ...")
exit 1
end
end
$project=nil
$projects.each do |proj|
begin
scope = Project.active.has_module(:repository)
$project = scope.find_by_identifier(proj)
raise ActiveRecord::RecordNotFound unless $project
log("- Indexing repositories for #{$project.name} ...", :level=>1)
$repositories = $project.repositories.select { |repository| repository.supports_cat? }
$repositories.each do |repository|
if repository.identifier.nil? then
log("\t>Ignoring repo id #{repository.id}, repo has undefined identifier", :level=>1)
else
if !$userch.nil? then
changeset=Changeset.where("revision='#{$userch}' and repository_id='#{repository.id}'").first
update_log(repository,changeset,nil,nil) unless changeset.nil?
end
delete_log(repository) if ($resetlog)
end
projects.each do |identifier|
begin
project = Project.active.find_by_identifier(identifier)
raise ActiveRecord::RecordNotFound unless project
raise ActiveRecord::RecordNotFound unless project.has_module(:repository)
log("- Indexing repositories for #{project.name} ...", :level => 1)
repositories = project.repositories.select { |repository| repository.supports_cat? }
repositories.each do |repository|
if repository.identifier.nil? then
log("\t>Ignoring repo id #{repository.id}, repo has undefined identifier", :level => 1)
else
if $userch
changeset = Changeset.where(:revision => $userch, :repository_id => repository.id).first
update_log(repository, changeset, nil, nil) if changeset
end
delete_log(repository) if ($resetlog)
indexing(repository)
end
end
end
rescue ActiveRecord::RecordNotFound
log("- ERROR project identifier #{proj} not found, ignoring...", :level => 1)
Rails.logger.error "Project identifier #{proj} not found "
log("- ERROR project identifier #{identifier} not found or repository module not enabled, ignoring...", :level => 1)
Rails.logger.error "Project identifier #{identifier} not found "
end
end
end
exit 0
exit 0

54
init.rb
View File

@ -28,7 +28,7 @@ Redmine::Plugin.register :redmine_dmsf do
name 'DMSF'
author 'Vit Jonas / Daniel Munn / Karel Picman'
description 'Document Management System Features'
version '1.5.1 stable'
version '1.5.2'
url 'http://www.redmine.org/plugins/dmsf'
author_url 'https://github.com/danmunn/redmine_dmsf/graphs/contributors'
@ -74,7 +74,7 @@ Redmine::Plugin.register :redmine_dmsf do
{:dmsf => [:new, :create, :delete, :edit, :save, :edit_root, :save_root, :lock, :unlock, :notify_activate, :notify_deactivate, :restore]}
permission :file_manipulation,
{:dmsf_files => [:create_revision, :lock, :unlock, :delete_revision, :notify_activate, :notify_deactivate, :restore],
:dmsf_upload => [:upload_files, :upload_file, :commit_files],
:dmsf_upload => [:upload_files, :upload_file, :upload, :commit_files, :commit],
:dmsf_links => [:new, :create, :destroy, :restore]
}
permission :file_delete,
@ -84,27 +84,25 @@ Redmine::Plugin.register :redmine_dmsf do
permission :file_approval,
{:dmsf_workflows => [:action, :new_action, :autocomplete_for_user, :start, :assign, :assignment]}
permission :manage_workflows,
{:dmsf_workflows => [:index, :new, :create, :destroy, :show, :add_step, :remove_step, :reorder_steps, :update]}
{:dmsf_workflows => [:index, :new, :create, :destroy, :show, :new_step, :add_step, :remove_step, :reorder_steps, :update]}
end
# Administration menu extension
Redmine::MenuManager.map :admin_menu do |menu|
menu.push :approvalworkflows, {:controller => 'dmsf_workflows', :action => 'index'}, :caption => :label_dmsf_workflow_plural
menu.push :approvalworkflows, {:controller => 'dmsf_workflows', :action => 'index'}, :caption => :label_dmsf_workflow_plural
end
Redmine::WikiFormatting::Macros.register do
desc "Wiki link to DMSF file:\n\n" +
"!{{dmsf(file_id [, title [, revision_id]])}}\n\n" +
"_file_id_ / _revision_id_ can be found in link for file/revision download."
"{{dmsf(file_id [, title [, revision_id]])}}\n\n" +
"_file_id_ / _revision_id_ can be found in the link for file/revision download."
macro :dmsf do |obj, args|
return nil if args.length < 1 # require file id
entry_id = args[0].strip
entry = DmsfFile.find(entry_id)
if entry && !entry.deleted && User.current && User.current.allowed_to?(:view_dmsf_files, entry.project)
title = args[1] ? args[1] : entry.title
revision = args[2] ? args[2] : ''
return link_to h(title), download_revision_path(entry, revision, :only_path => false)
return nil if args.length < 1 # require file id
entry = DmsfFile.visible.find_by_id args[0].strip
if entry && User.current && User.current.allowed_to?(:view_dmsf_files, entry.project)
title = args[1] ? args[1] : entry.title
return link_to h(title), dmsf_file_url(entry, :download => args[2])
end
nil
end
@ -112,18 +110,17 @@ Redmine::Plugin.register :redmine_dmsf do
Redmine::WikiFormatting::Macros.register do
desc "Wiki link to DMSF folder:\n\n" +
"!{{dmsff(folder_id [, title])}}\n\n" +
"_folder_id_ may be missing. _folder_id_ can be found in link for folder opening."
"{{dmsff(folder_id [, title])}}\n\n" +
"_folder_id_ may be missing. _folder_id_ can be found in the link for folder opening."
macro :dmsff do |obj, args|
if args.length < 1
return link_to l(:link_documents), :controller => 'dmsf', :action => 'show', :id => @project, :only_path => false
else
entry_id = args[0].strip
entry = DmsfFolder.find(entry_id)
return link_to l(:link_documents), dmsf_folder_url(@project)
else
entry = DmsfFolder.visible.find_by_id args[0].strip
if entry && User.current && User.current.allowed_to?(:view_dmsf_folders, entry.project)
title = args[1] ? args[1] : entry.title
return link_to h(title), dmsf_folder_path(entry.project, :folder_id => entry, :only_path => false)
return link_to h(title), dmsf_folder_url(entry.project, :folder_id => entry)
end
end
nil
@ -132,19 +129,18 @@ Redmine::Plugin.register :redmine_dmsf do
Redmine::WikiFormatting::Macros.register do
desc "Wiki link to DMSF document description:\n\n" +
"{{dmsfd(file_id [, title])}}\n\n" +
"_file_id_ / _revision_id_ can be found in link for file/revision download."
"{{dmsfd(file_id)}}\n\n" +
"_file_id_ can be found in the link for file/revision download."
macro :dmsfd do |obj, args|
return nil if args.length < 1 # require file id
entry_id = args[0].strip
entry = DmsfFile.find(entry_id)
if entry && !entry.deleted && User.current && User.current.allowed_to?(:view_dmsf_files, entry.project)
title = args[1] ? args[1] : entry.title
return link_to h(title), dmsf_file_path(entry, :only_path => false)
return nil if args.length < 1 # require file id
entry = DmsfFile.visible.find_by_id args[0].strip
if entry && User.current && User.current.allowed_to?(:view_dmsf_files, entry.project)
return entry.description
end
nil
end
end
# Rubyzip configuration
@ -154,4 +150,4 @@ end
Redmine::Search.map do |search|
search.register :dmsf_files
search.register :dmsf_folders
end
end

View File

@ -67,8 +67,8 @@ module RedmineDmsf
module InstanceMethods
def dmsf_count
file_count = self.dmsf_files.visible.count + self.file_links.count
folder_count = self.dmsf_folders.visible.count + self.folder_links.count
file_count = self.dmsf_files.visible.count + self.file_links.visible.count
folder_count = self.dmsf_folders.visible.count + self.folder_links.visible.count
self.dmsf_folders.visible.each do |f|
file_count += f.deep_file_count
folder_count += f.deep_folder_count

View File

@ -78,7 +78,7 @@ module RedmineDmsf
'-',
'',
'',
] + entities unless parent.nil?
] + entities if parent
@response.body << index_page % [ path.empty? ? '/' : path, path.empty? ? '/' : path , entities ]
end

View File

@ -1,7 +1,9 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2012 Daniel Munn <dan.munn@munnster.co.uk>
# Copyright (C) 2011-14 Karel Picman <karel.picman@kontron.com>
# Copyright (C) 2011-15 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

View File

@ -54,7 +54,7 @@ module RedmineDmsf
return @children if @children
@children = []
return [] unless collection?
folder.subfolders.map do |p|
folder.subfolders.visible.map do |p|
@children.push child(p.title)
end
folder.files.visible.map do |p|
@ -81,13 +81,13 @@ module RedmineDmsf
# Todo: Move folder data retrieval into folder function, and use folder method to determine existence
def folder
return @folder unless @folder == false
return nil if project.nil? || project.id.nil? #if the project doesnt exist, this entity can't exist
return nil if project.nil? || project.id.nil? #if the project doesn't exist, this entity can't exist
@folder = nil
# Note: Folder is searched for as a generic search to prevent SQL queries being generated:
# if we were to look within parent, we'd have to go all the way up the chain as part of the
# existence check, and although I'm sure we'd love to access the heirarchy, I can't yet
# existence check, and although I'm sure we'd love to access the hierarchy, I can't yet
# see a practical need for it
folders = DmsfFolder.visible.where(:project_id => project.id, :title => basename).order('title ASC').all
folders = DmsfFolder.visible.where(:project_id => project.id, :title => basename).order('title ASC').to_a
return nil unless folders.length > 0
if (folders.length > 1) then
folders.delete_if { |x| '/' + x.dmsf_path_str != projectless_path }
@ -132,7 +132,7 @@ module RedmineDmsf
# If folder is false, means it couldn't pick up parent,
# as such its probably fine to bail out, however we'll
# perform a search in this scenario
files = DmsfFile.visible.where(:project_id => project.id, :name => basename).order('name ASC').all
files = DmsfFile.visible.where(:project_id => project.id, :name => basename).order('name ASC').to_a
files.delete_if {|x| File.dirname('/' + x.dmsf_path_str) != File.dirname(projectless_path)}
if files.length > 0
@file = files[0]
@ -252,55 +252,42 @@ module RedmineDmsf
# Behavioural differences between collection and single entity
# Todo: Support overwrite between both types of entity, and implement better checking
def move(dest, overwrite)
# All of this should carry accrross the ResourceProxy frontend, we ensure this to
# prevent unexpected errors
if dest.is_a?(ResourceProxy)
resource = dest.resource
else
resource = dest
end
# prevent unexpected errors
resource = dest.is_a?(ResourceProxy) ? dest.resource : dest
return PreconditionFailed if !resource.is_a?(DmsfResource) || resource.project.nil? || resource.project.id == 0
parent = resource.parent
if (collection?)
#At the moment we don't support cross project destinations
return MethodNotImplemented unless project.id == resource.project.id
raise Forbidden unless User.current.admin? || User.current.allowed_to?(:folder_manipulation, project)
#Current object is a folder, so now we need to figure out information about Destination
if(dest.exist?) then
if dest.exist?
MethodNotAllowed
else
if(parent.projectless_path == '/') #Project root
folder.dmsf_folder_id = nil
else
return PreconditionFailed unless parent.exist? && parent.folder?
folder.dmsf_folder_id = parent.folder.id
folder.dmsf_folder_id = parent.folder.id
end
folder.title = resource.basename
folder.save ? Created : PreconditionFailed
end
else
raise Forbidden unless User.current.admin? ||
User.current.allowed_to?(:folder_manipulation, project) ||
User.current.allowed_to?(:folder_manipulation, resource.project)
User.current.allowed_to?(:folder_manipulation, resource.project)
if(dest.exist?) then
methodNotAllowed
if dest.exist?
methodNotAllowed
# Files cannot be merged at this point, until a decision is made on how to merge them
# ideally, we would merge revision history for both, ensuring the origin file wins with latest revision.
# ideally, we would merge revision history for both, ensuring the origin file wins with latest revision.
else
if(parent.projectless_path == '/') #Project root
f = nil
else
@ -311,8 +298,11 @@ module RedmineDmsf
return InternalServerError unless file.move_to(resource.project, f)
# Update Revision and names of file [We can link to old physical resource, as it's not changed]
file.last_revision.name = resource.basename if file.last_revision
file.name = resource.basename
if file.last_revision
file.last_revision.name = resource.basename
file.last_revision.title = DmsfFileRevision.filename_to_title(resource.basename)
end
file.name = resource.basename
# Save Changes
(file.last_revision.save! && file.save!) ? Created : PreconditionFailed

View File

@ -46,5 +46,6 @@ end
# This should probably be configurable somehow or better have the module hunt for the correct pathing
# automatically without the need to add a "/dmsf/webdav" configuration to it, as if the route is changed
# the functonality of this patch will effectively break.
Rails.configuration.middleware.insert_before(ActionDispatch::ParamsParser,
RedmineDmsf::NoParse, :urls => ['/dmsf/webdav'])
Rails.configuration.middleware.insert_before(
ActionDispatch::ParamsParser,
RedmineDmsf::NoParse, :urls => ["#{Redmine::Utils::relative_url_root}/dmsf/webdav"])

View File

@ -1,7 +1,9 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2012 Daniel Munn <dan.munn@munnster.co.uk>
# Copyright (C) 2011-14 Karel Picman <karel.picman@kontron.com>
# Copyright (C) 2011-15 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

View File

@ -141,19 +141,12 @@ class DmsfConvertDocuments
revision.comment = 'Converted from documents'
revision.mime_type = attachment.content_type
revision.disk_filename = revision.new_storage_filename
attachment_file = File.open(attachment.diskfile, 'rb')
revision.disk_filename = revision.new_storage_filename
unless dry
File.open(revision.disk_file, 'wb') do |f|
while (buffer = attachment_file.read(8192))
f.write(buffer)
end
end
FileUtils.cp(attachment.diskfile, revision.disk_file)
revision.size = File.size(revision.disk_file)
end
attachment_file.close
end
if dry
puts "Dry check revision: #{revision.title}"