Merge branch 'devel-1.5.4'
This commit is contained in:
commit
2a074386f5
15
CHANGELOG.md
15
CHANGELOG.md
@ -1,6 +1,21 @@
|
||||
Changelog for Redmine DMSF
|
||||
==========================
|
||||
|
||||
1.5.4 *2015-09-17*
|
||||
------------------
|
||||
|
||||
New DMSF macro for inline pictures
|
||||
File name updating when a new content is uploaded
|
||||
System files filtering when working with WebDAV
|
||||
|
||||
* Bug: #442 - Can't move directories
|
||||
* Bug: #441 - Drag'n'drop save only the picture thumbnail
|
||||
* New: #438 - The file name update when a new content is uploaded
|
||||
* Bug: #418 - Documents details from in IE
|
||||
* Bug: #417 - Selected column is not highlighted under mouse pointer in IE
|
||||
* New: #352 - DMSF Macro to display inline Pictures in wiki
|
||||
* New: #54 - Webdav: Filter Mac OS X "resource forks" files
|
||||
|
||||
1.5.3 *2015-08-10*
|
||||
------------------
|
||||
|
||||
|
||||
14
README.md
14
README.md
@ -1,7 +1,7 @@
|
||||
Redmine DMSF Plugin
|
||||
===================
|
||||
|
||||
The current version of Redmine DMSF is **1.5.3** [](https://travis-ci.org/danmunn/redmine_dmsf)
|
||||
The current version of Redmine DMSF is **1.5.4** [](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.
|
||||
|
||||
@ -116,6 +116,15 @@ The DMSF file/revision id can be found in link for file/revision download from w
|
||||
####Link to a folder with id 5 with link text "Folder"
|
||||
`{{dmsff(5, Folder)}}`
|
||||
|
||||
####An inline picture of the file with id 8; it must be an image file such as JPEG, PNG,...
|
||||
`{{dmsf_image(8)}}`
|
||||
|
||||
####An inline picture with custom size
|
||||
`{{dmsf_image(8, size=300)}}`
|
||||
|
||||
####An inline picture with custom size
|
||||
`{{dmsf_image(8, size=640x480)}}`
|
||||
|
||||
The DMSF folder id can be found in the link when opening folders within Redmine.
|
||||
|
||||
You can also publish Wiki help description:
|
||||
@ -132,6 +141,9 @@ In the file <redmine_root>/public/help/<language>/wiki_syntax_detailed.html, aft
|
||||
<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>
|
||||
<li><strong>{{dmsf_image(8)}} (an inline picture of the file with id 8; it must be an image file such as JPEG, PNG,...)</li>
|
||||
<li><strong>{{dmsf_image(8, size=300)}} (an inline picture with custom size)</li>
|
||||
<li><strong>{{dmsf_image(8, size=640x480)}} (an inline picture with custom size)</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.
|
||||
|
||||
@ -309,6 +309,7 @@ class DmsfController < ApplicationController
|
||||
@pathfolder = copy_folder(@folder)
|
||||
@folder.title = params[:dmsf_folder][:title]
|
||||
@folder.description = params[:dmsf_folder][:description]
|
||||
@folder.dmsf_folder_id = params[:dmsf_folder][:dmsf_folder_id]
|
||||
|
||||
# Custom fields
|
||||
if params[:dmsf_folder][:custom_field_values].present?
|
||||
|
||||
@ -155,13 +155,11 @@ class DmsfFilesController < ApplicationController
|
||||
|
||||
@file.name = revision.name
|
||||
|
||||
if revision.valid? && @file.valid?
|
||||
revision.save!
|
||||
if revision.save
|
||||
revision.assign_workflow(params[:dmsf_workflow_id])
|
||||
if file_upload
|
||||
revision.copy_file_content(file_upload)
|
||||
end
|
||||
|
||||
if @file.locked? && !@file.locks.empty?
|
||||
begin
|
||||
@file.unlock!
|
||||
@ -170,26 +168,30 @@ class DmsfFilesController < ApplicationController
|
||||
logger.error "Cannot unlock the file: #{e.message}"
|
||||
end
|
||||
end
|
||||
@file.save!
|
||||
@file.set_last_revision revision
|
||||
|
||||
flash[:notice] = (flash[:notice].nil? ? '' : flash[:notice]) + l(:notice_file_revision_created)
|
||||
log_activity('new revision')
|
||||
begin
|
||||
recipients = DmsfMailer.get_notify_users(@project, [@file])
|
||||
recipients.each do |u|
|
||||
DmsfMailer.files_updated(u, @project, [@file]).deliver
|
||||
end
|
||||
if Setting.plugin_redmine_dmsf[:dmsf_display_notified_recipients] == '1'
|
||||
unless recipients.empty?
|
||||
to = recipients.collect{ |r| r.name }.first(DMSF_MAX_NOTIFICATION_RECEIVERS_INFO).join(', ')
|
||||
to << ((recipients.count > DMSF_MAX_NOTIFICATION_RECEIVERS_INFO) ? ',...' : '.')
|
||||
flash[:warning] = l(:warning_email_notifications, :to => to)
|
||||
if @file.save
|
||||
@file.set_last_revision revision
|
||||
flash[:notice] = (flash[:notice].nil? ? '' : flash[:notice]) + l(:notice_file_revision_created)
|
||||
log_activity('new revision')
|
||||
begin
|
||||
recipients = DmsfMailer.get_notify_users(@project, [@file])
|
||||
recipients.each do |u|
|
||||
DmsfMailer.files_updated(u, @project, [@file]).deliver
|
||||
end
|
||||
if Setting.plugin_redmine_dmsf[:dmsf_display_notified_recipients] == '1'
|
||||
unless recipients.empty?
|
||||
to = recipients.collect{ |r| r.name }.first(DMSF_MAX_NOTIFICATION_RECEIVERS_INFO).join(', ')
|
||||
to << ((recipients.count > DMSF_MAX_NOTIFICATION_RECEIVERS_INFO) ? ',...' : '.')
|
||||
flash[:warning] = l(:warning_email_notifications, :to => to)
|
||||
end
|
||||
end
|
||||
rescue Exception => e
|
||||
logger.error "Could not send email notifications: #{e.message}"
|
||||
end
|
||||
rescue Exception => e
|
||||
logger.error "Could not send email notifications: #{e.message}"
|
||||
else
|
||||
flash[:error] = @file.errors.full_messages.join(', ')
|
||||
end
|
||||
else
|
||||
flash[:error] = revision.errors.full_messages.join(', ')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -402,5 +402,9 @@ class DmsfFile < ActiveRecord::Base
|
||||
end
|
||||
self.name
|
||||
end
|
||||
|
||||
|
||||
def image?
|
||||
self.last_revision && !!(self.last_revision.disk_filename =~ /\.(bmp|gif|jpg|jpe|jpeg|png)$/i)
|
||||
end
|
||||
|
||||
end
|
||||
@ -28,9 +28,7 @@ class DmsfFileRevision < ActiveRecord::Base
|
||||
belongs_to :deleted_by_user, :class_name => 'User', :foreign_key => 'deleted_by_user_id'
|
||||
has_many :access, :class_name => 'DmsfFileRevisionAccess', :foreign_key => 'dmsf_file_revision_id', :dependent => :destroy
|
||||
has_many :dmsf_workflow_step_assignment, :dependent => :destroy
|
||||
accepts_nested_attributes_for :access, :dmsf_workflow_step_assignment, :file, :user
|
||||
|
||||
attr_accessible :file, :title, :name, :description, :comment
|
||||
accepts_nested_attributes_for :access, :dmsf_workflow_step_assignment, :file, :user
|
||||
|
||||
# Returns a list of revisions that are not deleted here, or deleted at parent level either
|
||||
scope :visible, -> { where(deleted: false) }
|
||||
@ -53,7 +51,7 @@ class DmsfFileRevision < ActiveRecord::Base
|
||||
"INNER JOIN #{Project.table_name} ON #{DmsfFile.table_name}.project_id = #{Project.table_name}.id").
|
||||
where("#{DmsfFile.table_name}.deleted = :false", {:false => false})
|
||||
|
||||
validates :title, :name, :presence => true
|
||||
validates :title, :presence => true
|
||||
validates_format_of :name, :with => DmsfFolder.invalid_characters,
|
||||
:message => l(:error_contains_invalid_character)
|
||||
|
||||
|
||||
@ -77,13 +77,21 @@
|
||||
<p>
|
||||
<%= label_tag('file_upload', "#{l(:label_new_content)}:") %>
|
||||
</p>
|
||||
<div class="data">
|
||||
<%= file_field_tag('file_upload') %>
|
||||
<br/>
|
||||
<small>
|
||||
(<%= l(:label_max_size) %>: <%= number_to_human_size(Setting.attachment_max_size.to_i.kilobytes) %>)
|
||||
</small>
|
||||
</div>
|
||||
<span class="add_attachment">
|
||||
<%= file_field_tag 'file_upload',
|
||||
:id => nil,
|
||||
:class => 'file_selector',
|
||||
:multiple => false,
|
||||
:onchange => "$('#dmsf_file_revision_name').val(this.value)",
|
||||
:data => {
|
||||
:max_file_size => Setting.attachment_max_size.to_i.kilobytes,
|
||||
:max_file_size_message => l(:error_attachment_too_big, :max_size => number_to_human_size(Setting.attachment_max_size.to_i.kilobytes)),
|
||||
:max_concurrent_uploads => 1,
|
||||
:upload_path => uploads_path(:format => 'js')
|
||||
}
|
||||
%>
|
||||
(<%= l(:label_max_size) %>: <%= number_to_human_size(Setting.attachment_max_size.to_i.kilobytes) %>)
|
||||
</span>
|
||||
</div>
|
||||
<br style="clear: both"/>
|
||||
<div class="custom_fields">
|
||||
@ -106,4 +114,4 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= wikitoolbar_for 'dmsf_file_revision_description' %>
|
||||
<%= wikitoolbar_for 'dmsf_file_revision_description' %>
|
||||
@ -96,15 +96,7 @@
|
||||
|
||||
// Rename files by clicking on their titles
|
||||
rename: true,
|
||||
|
||||
// Resize images on clientside if we can
|
||||
resize : {
|
||||
width : 200,
|
||||
height : 200,
|
||||
quality : 90,
|
||||
crop: true // crop to exact dimensions
|
||||
},
|
||||
|
||||
|
||||
// Views to activate
|
||||
views: {
|
||||
list: true,
|
||||
|
||||
29
db/migrate/201500910153701_title_not_null.rb
Normal file
29
db/migrate/201500910153701_title_not_null.rb
Normal file
@ -0,0 +1,29 @@
|
||||
# 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 TitleNotNull < ActiveRecord::Migration
|
||||
def up
|
||||
change_column :dmsf_file_revisions, :title, :string, :null => false
|
||||
end
|
||||
|
||||
def down
|
||||
change_column :dmsf_file_revisions, :title, :string, :null => true
|
||||
end
|
||||
end
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,25 @@
|
||||
#!/usr/bin/ruby -W0
|
||||
# encoding: UTF-8
|
||||
|
||||
# Copied from https://github.com/xelkano/redmine_xapian
|
||||
# encoding: utf-8
|
||||
#
|
||||
# Redmine Xapian is a Redmine plugin to allow attachments searches by content.
|
||||
#
|
||||
# Copyright (C) 2010 Xabier Elkano
|
||||
# Copyright (C) 2015 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.
|
||||
|
||||
################################################################################################
|
||||
# BEGIN Configuration parameters
|
||||
@ -9,19 +27,19 @@
|
||||
################################################################################################
|
||||
|
||||
# Redmine installation directory
|
||||
$redmine_root = "/var/www/redmine"
|
||||
$redmine_root = '/opt/redmine'
|
||||
|
||||
# DMSF document location $redmine_root/$dmsf_root
|
||||
$dmsf_root = 'files/dmsf'
|
||||
# Files location
|
||||
$files = 'files'
|
||||
|
||||
# scriptindex binary path
|
||||
$scriptindex = "/usr/bin/scriptindex"
|
||||
$scriptindex = '/usr/bin/scriptindex'
|
||||
|
||||
# omindex binary path
|
||||
$omindex = "/usr/bin/omindex"
|
||||
$omindex = '/usr/bin/omindex'
|
||||
|
||||
# Directory containing xapian databases for omindex (Attachments indexing)
|
||||
$dbrootpath = "/var/tmp/dmsf-index"
|
||||
$dbrootpath = '/var/tmp/omindex'
|
||||
|
||||
# Verbose output, values of 0 no verbose, greater than 0 verbose output
|
||||
$verbose = 0
|
||||
@ -31,35 +49,33 @@ $verbose = 0
|
||||
# Available languages are danish dutch english finnish french german german2 hungarian italian kraaij_pohlmann lovins norwegian porter portuguese romanian russian spanish swedish turkish:
|
||||
$stem_langs = ['english']
|
||||
|
||||
#Project identifiers that will be indexed Ej [ 'prj_id1', 'prj_id2' ]
|
||||
$projects = [ 'prj_id1', 'prj_id2' ]
|
||||
# Project identifiers that will be indexed eg. [ 'prj_id1', 'prj_id2' ]
|
||||
projects = [ 'prj_id1', 'prj_id2' ]
|
||||
|
||||
# Temporary directory for indexing, it can be tmpfs
|
||||
$tempdir = "/tmp"
|
||||
$tempdir = '/tmp'
|
||||
|
||||
# Binaries for text conversion
|
||||
$pdftotext = "/usr/bin/pdftotext -enc UTF-8"
|
||||
$antiword = "/usr/bin/antiword"
|
||||
$catdoc = "/usr/bin/catdoc"
|
||||
$xls2csv = "/usr/bin/xls2csv"
|
||||
$catppt = "/usr/bin/catppt"
|
||||
$unzip = "/usr/bin/unzip -o"
|
||||
$unrtf = "/usr/bin/unrtf -t text 2>/dev/null"
|
||||
|
||||
$pdftotext = '/usr/bin/pdftotext -enc UTF-8'
|
||||
$antiword = '/usr/bin/antiword'
|
||||
$catdoc = '/usr/bin/catdoc'
|
||||
$xls2csv = '/usr/bin/xls2csv'
|
||||
$catppt = '/usr/bin/catppt'
|
||||
$unzip = '/usr/bin/unzip -o'
|
||||
$unrtf = '/usr/bin/unrtf -t text 2>/dev/null'
|
||||
|
||||
################################################################################################
|
||||
# END Configuration parameters
|
||||
################################################################################################
|
||||
|
||||
$environment = File.join($redmine_root, "config/environment.rb")
|
||||
$project=nil
|
||||
$databasepath=nil
|
||||
$repositories=nil
|
||||
$onlyfiles=nil
|
||||
$onlyrepos=nil
|
||||
$env='production'
|
||||
$userch=nil
|
||||
$resetlog=nil
|
||||
$environment = File.join($redmine_root, 'config/environment.rb')
|
||||
$project = nil
|
||||
$databasepath = nil
|
||||
$repositories = nil
|
||||
$onlyfiles = nil
|
||||
$onlyrepos = nil
|
||||
$env = 'production'
|
||||
$resetlog = nil
|
||||
|
||||
MIME_TYPES = {
|
||||
'application/pdf' => 'pdf',
|
||||
@ -94,116 +110,96 @@ FORMAT_HANDLERS = {
|
||||
|
||||
require 'optparse'
|
||||
|
||||
|
||||
VERSION = "0.1"
|
||||
SUPPORTED_SCM = %w( Subversion Darcs Mercurial Bazaar Git Filesystem )
|
||||
|
||||
VERSION = '0.1'
|
||||
SUPPORTED_SCM = %w(Subversion Darcs Mercurial Bazaar Git Filesystem)
|
||||
|
||||
optparse = OptionParser.new do |opts|
|
||||
opts.banner = "Usage: xapian_indexer.rb [OPTIONS...]"
|
||||
opts.separator("")
|
||||
opts.separator("Index redmine files and repositories")
|
||||
opts.separator("")
|
||||
#opts.on("-k", "--key KEY", "use KEY as the Redmine repository key") { |k| $key = k}
|
||||
opts.separator("")
|
||||
opts.separator("Options:")
|
||||
opts.on("-p", "--projects a,b,c",Array, "Comma separated list of projects to index") { |p| $projects=p }
|
||||
opts.on("-s", "--stemming_lang a,b,c",Array,"Comma separated list of stemming languages for indexing") { |s| $stem_langs=s }
|
||||
#opts.on("-t", "--test", "only show what should be done") {$test = true}
|
||||
#opts.on("-f", "--force", "force reindex") {$force = true}
|
||||
opts.on("-v", "--verbose", "verbose") {$verbose += 1}
|
||||
opts.on("-f", "--files", "Only index Redmine attachments") {$onlyfiles = 1}
|
||||
opts.on("-r", "--repositories", "Only index Redmine repositories") {$onlyrepos = 1}
|
||||
opts.on("-e", "--environment ENV", "Rails ENVIRONMENT (development, testing or production), default production") {|e| $env = e}
|
||||
opts.on("-t", "--temp-dir PATH", "Temporary directory for indexing"){ |t| $tempdir = t }
|
||||
#opts.on("-c", "--revision REV", "Use revision as base"){ |c| $userch = c }
|
||||
opts.on("-x", "--resetlog", "Reset index log"){ $resetlog = 1 }
|
||||
opts.on("-V", "--version", "show version and exit") {puts VERSION; exit}
|
||||
opts.on("-h", "--help", "show help and exit") {puts opts; exit }
|
||||
#opts.on("-q", "--quiet", "no log") {$quiet = true}
|
||||
opts.separator("")
|
||||
opts.separator("Examples:")
|
||||
opts.separator(" xapian_indexer.rb -f -s english,italian -v")
|
||||
opts.separator(" xapian_indexer.rb -p project_id -x -t /tmpfs -v")
|
||||
opts.separator("")
|
||||
|
||||
opts.banner = 'Usage: xapian_indexer.rb [OPTIONS...]'
|
||||
opts.separator('')
|
||||
opts.separator('Index redmine files and repositories')
|
||||
opts.separator('')
|
||||
opts.separator('')
|
||||
opts.separator('Options:')
|
||||
opts.on('-p', '--projects a,b,c', Array, 'Comma separated list of projects to index') { |p| projects = p }
|
||||
opts.on('-s', '--stemming_lang a,b,c', Array,'Comma separated list of stemming languages for indexing') { |s| $stem_langs = s }
|
||||
opts.on('-v', '--verbose', 'verbose') {$verbose += 1}
|
||||
opts.on('-f', '--files', 'Only index Redmine attachments') { $onlyfiles = 1 }
|
||||
opts.on('-r', '--repositories', 'Only index Redmine repositories') { $onlyrepos = 1 }
|
||||
opts.on('-e', '--environment ENV', 'Rails ENVIRONMENT (development, testing or production), default production') { |e| $env = e}
|
||||
opts.on('-t', '--temp-dir PATH', 'Temporary directory for indexing'){ |t| $tempdir = t }
|
||||
opts.on('-x', '--resetlog', 'Reset index log'){ $resetlog = 1 }
|
||||
opts.on('-V', '--version', 'show version and exit') { puts VERSION; exit}
|
||||
opts.on('-h', '--help', 'show help and exit') { puts opts; exit }
|
||||
opts.separator('')
|
||||
opts.separator('Examples:')
|
||||
opts.separator(' xapian_indexer.rb -f -s english,italian -v')
|
||||
opts.separator(' xapian_indexer.rb -p project_id -x -t /tmpfs -v')
|
||||
opts.separator('')
|
||||
opts.summary_width = 25
|
||||
end
|
||||
|
||||
optparse.parse!
|
||||
|
||||
ENV['RAILS_ENV'] = $env
|
||||
|
||||
|
||||
STATUS_SUCCESS = 1
|
||||
STATUS_FAIL = -1
|
||||
|
||||
ADD_OR_UPDATE = 1
|
||||
DELETE = 0
|
||||
|
||||
MAIN_REPOSITORY_IDENTIFIER = 'main'
|
||||
|
||||
|
||||
|
||||
class IndexingError < StandardError; end
|
||||
|
||||
|
||||
#@rwdb = Xapian::WritableDatabase.new(databasepath, Xapian::DB_CREATE_OR_OVERWRITE)
|
||||
def repo_name(repository)
|
||||
repository.identifier.blank? ? 'main' : repository.identifier
|
||||
end
|
||||
|
||||
|
||||
def indexing(repository)
|
||||
$repository=repository
|
||||
Rails.logger.info("Fetch changesets: %s - %s" % [$project.name,(repository.identifier or MAIN_REPOSITORY_IDENTIFIER)])
|
||||
log("- Fetch changesets: #{$project.name} - #{$repository.identifier}", :level=>1)
|
||||
$repository.fetch_changesets
|
||||
$repository.reload.changesets.reload
|
||||
def indexing(databasepath, project, repository)
|
||||
Rails.logger.info("Fetch changesets: #{project.name} - #{repo_name(repository)}")
|
||||
log("- Fetch changesets: #{project.name} - #{repo_name(repository)}", :level => 1)
|
||||
repository.fetch_changesets
|
||||
repository.reload.changesets.reload
|
||||
|
||||
latest_changeset = $repository.changesets.find(:first)
|
||||
return if not latest_changeset
|
||||
latest_changeset = repository.changesets.first
|
||||
return if not latest_changeset
|
||||
|
||||
Rails.logger.debug("Latest revision: %s - %s - %s" % [
|
||||
$project.name,
|
||||
($repository.identifier or MAIN_REPOSITORY_IDENTIFIER),
|
||||
latest_changeset.revision])
|
||||
#latest_indexed = Indexinglog.find_by_repository_id_and_status( repository.id, STATUS_SUCCESS, :first)
|
||||
latest_indexed = Indexinglog.where("repository_id=#{$repository.id} AND status=#{STATUS_SUCCESS}").last
|
||||
Rails.logger.debug "Debug latest_indexed " + latest_indexed.inspect
|
||||
Rails.logger.debug("Latest revision: #{project.name} - #{repo_name(repository)} - #{latest_changeset.revision}")
|
||||
latest_indexed = Indexinglog.where(:repository_id => repository.id, :status => STATUS_SUCCESS).last
|
||||
Rails.logger.debug "Debug latest_indexed #{latest_indexed.inspect}"
|
||||
begin
|
||||
$indexconf = Tempfile.new( "index.conf", $tempdir )
|
||||
$indexconf.write "url : field boolean=Q unique=Q\n"
|
||||
$indexconf.write "body : index truncate=400 field=sample\n"
|
||||
$indexconf.write "date: field=date\n"
|
||||
$indexconf.close
|
||||
indexconf = Tempfile.new('index.conf', $tempdir)
|
||||
indexconf.write "url : field boolean=Q unique=Q\n"
|
||||
indexconf.write "body : index truncate=400 field=sample\n"
|
||||
indexconf.write "date: field=date\n"
|
||||
indexconf.close
|
||||
if not latest_indexed
|
||||
Rails.logger.debug "DEBUG: repo #{$repository.identifier} not indexed, indexing all"
|
||||
log("\t>repo #{$repository.identifier} not indexed, indexing all", :level=>1)
|
||||
indexing_all($repository)
|
||||
Rails.logger.debug "Repository #{repo_name(repository)} not indexed, indexing all"
|
||||
log("\t>repo #{repo_name(repository)} not indexed, indexing all", :level => 1)
|
||||
indexing_all(databasepath, indexconf, project, repository)
|
||||
else
|
||||
Rails.logger.debug "DEBUG: repo #{$repository.identifier} indexed, indexing diff"
|
||||
log("\t>repo #{$repository.identifier} already indexed, indexing only diff", :level=>1)
|
||||
indexing_diff($repository, latest_indexed.changeset, latest_changeset)
|
||||
Rails.logger.debug "Repository #{repo_name(repository)} indexed, indexing diff"
|
||||
log("\t>repo #{repo_name(repository)} already indexed, indexing only diff", :level => 1)
|
||||
indexing_diff(databasepath, indexconf, project, repository,
|
||||
latest_indexed.changeset, latest_changeset)
|
||||
end
|
||||
$indexconf.unlink
|
||||
indexconf.unlink
|
||||
rescue IndexingError => e
|
||||
add_log($repository, latest_changeset, STATUS_FAIL, e.message)
|
||||
add_log(repository, latest_changeset, STATUS_FAIL, e.message)
|
||||
else
|
||||
add_log($repository, latest_changeset, STATUS_SUCCESS)
|
||||
Rails.logger.info("Successfully indexed: %s - %s - %s" % [
|
||||
$project.name,
|
||||
($repository.identifier or MAIN_REPOSITORY_IDENTIFIER),
|
||||
latest_changeset.revision])
|
||||
add_log(repository, latest_changeset, STATUS_SUCCESS)
|
||||
Rails.logger.info("Successfully indexed: #{project.name} - #{repo_name(repository)} - #{latest_changeset.revision}")
|
||||
end
|
||||
end
|
||||
|
||||
def supported_mime_type(entry)
|
||||
mtype=Redmine::MimeType.of(entry)
|
||||
mtype = Redmine::MimeType.of(entry)
|
||||
included = false
|
||||
included = MIME_TYPES.include?(mtype) || mtype.split('/').first.eql?("text") unless mtype.nil?
|
||||
#puts "Mtype for #{entry} is #{mtype} returning: #{included.inspect}"
|
||||
included = MIME_TYPES.include?(mtype) || mtype.split('/').first.eql?('text') unless mtype.nil?
|
||||
return included
|
||||
end
|
||||
|
||||
def add_log(repository, changeset, status, message=nil)
|
||||
log = Indexinglog.where("repository_id=#{repository.id}").last
|
||||
def add_log(repository, changeset, status, message = nil)
|
||||
log = Indexinglog.where(:repository_id => repository.id).last
|
||||
if not log
|
||||
log = Indexinglog.new
|
||||
log.repository = repository
|
||||
@ -211,80 +207,71 @@ def add_log(repository, changeset, status, message=nil)
|
||||
log.status = status
|
||||
log.message = message if message
|
||||
log.save!
|
||||
Rails.logger.info("New log for repo %s saved!"% [repository.identifier] )
|
||||
log("\t>New log for repo #{repository.identifier} saved!", :level=>1)
|
||||
Rails.logger.info "New log for repo #{repo_name(repository)} saved!"
|
||||
log("\t>New log for repo #{repo_name(repository)} saved!", :level => 1)
|
||||
else
|
||||
log.changeset_id=changeset.id
|
||||
log.status=status
|
||||
log.message = message if message
|
||||
log.save!
|
||||
Rails.logger.info("Log for repo %s updated!"% [repository.identifier] )
|
||||
log("\t>Log for repo #{repository.identifier} updated!", :level=>1)
|
||||
Rails.logger.info "Log for repo #{repo_name(repository)} updated!"
|
||||
log("\t>Log for repo #{repo_name(repository)} updated!", :level => 1)
|
||||
end
|
||||
end
|
||||
|
||||
def update_log(repository, changeset, status, message=nil)
|
||||
log = Indexinglog.where("repository_id=#{repository.id}").last
|
||||
def update_log(repository, changeset, status, message = nil)
|
||||
log = Indexinglog.where(:repository_id => repository.id).last
|
||||
if log
|
||||
log.changeset_id=changeset.id
|
||||
log.status=status if status
|
||||
log.changeset_id = changeset.id
|
||||
log.status = status if status
|
||||
log.message = message if message
|
||||
log.save!
|
||||
Rails.logger.info("Log for repo %s updated!"% [repository.identifier] )
|
||||
log("\t>Log for repo #{repository.identifier} updated!", :level=>1)
|
||||
Rails.logger.info("Log for repo #{repo_name(repository)} updated!")
|
||||
log("\t>Log for repo #{repo_name(repository)} updated!", :level => 1)
|
||||
end
|
||||
end
|
||||
|
||||
def delete_log(repository)
|
||||
Indexinglog.delete_all("repository_id=#{repository.id}")
|
||||
Rails.logger.info("Log for repo %s removed!"% [repository.identifier] )
|
||||
log("\t>Log for repo #{repository.identifier} removed!", :level=>1)
|
||||
Indexinglog.delete_all(:repository_id => repository.id)
|
||||
Rails.logger.info("Log for repo #{repo_name(repository)} removed!")
|
||||
log("\t>Log for repo #{repo_name(repository)} removed!", :level => 1)
|
||||
end
|
||||
|
||||
|
||||
def indexing_all(repository)
|
||||
def walk(repository, identifier, entries)
|
||||
Rails.logger.debug "DEBUG: walk entries size: " + entries.size.inspect
|
||||
return if entries.size < 1
|
||||
entries.each do |entry|
|
||||
Rails.logger.debug "DEBUG: walking into: " + entry.lastrev.time.inspect
|
||||
if entry.is_dir?
|
||||
walk(repository, identifier, repository.entries(entry.path, identifier))
|
||||
elsif entry.is_file?
|
||||
add_or_update_index(repository, identifier, entry.path, entry.lastrev, ADD_OR_UPDATE, MIME_TYPES[Redmine::MimeType.of(entry.path)] ) if supported_mime_type(entry.path)
|
||||
#if !Redmine::MimeType.is_type?('text', entry.path) then
|
||||
# mtype=Redmine::MimeType.of(entry.path)
|
||||
# log("Non text entry #{mtype.inspect} #{entry.path}", :level=>1)
|
||||
#end
|
||||
end
|
||||
def walk(databasepath, indexconf, project, repository, identifier, entries)
|
||||
return if entries.nil? || entries.size < 1
|
||||
Rails.logger.debug "Walk entries size: #{entries.size}"
|
||||
entries.each do |entry|
|
||||
Rails.logger.debug "Walking into: #{entry.lastrev.time}"
|
||||
if entry.is_dir?
|
||||
walk(databasepath, indexconf, project, repository, identifier, repository.entries(entry.path, identifier))
|
||||
elsif entry.is_file?
|
||||
add_or_update_index(databasepath, indexconf, project, repository, identifier, entry.path,
|
||||
entry.lastrev, ADD_OR_UPDATE, MIME_TYPES[Redmine::MimeType.of(entry.path)]) if supported_mime_type(entry.path)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Rails.logger.info("Indexing all: %s" % [
|
||||
(repository.identifier or MAIN_REPOSITORY_IDENTIFIER)])
|
||||
def indexing_all(databasepath, indexconf, project, repository)
|
||||
Rails.logger.info "Indexing all: #{repo_name(repository)}"
|
||||
if repository.branches
|
||||
repository.branches.each do |branch|
|
||||
Rails.logger.debug("Walking in branch: %s - %s" % [
|
||||
(repository.identifier or MAIN_REPOSITORY_IDENTIFIER), branch])
|
||||
walk(repository, branch, repository.entries(nil, branch))
|
||||
Rails.logger.debug "Walking in branch: #{repo_name(repository)} - #{branch}"
|
||||
walk(databasepath, indexconf, project, repository, branch, repository.entries(nil, branch))
|
||||
end
|
||||
else
|
||||
Rails.logger.debug("Walking in branch: %s - %s" % [
|
||||
(repository.identifier or MAIN_REPOSITORY_IDENTIFIER), "[NOBRANCH]"])
|
||||
walk(repository, nil, repository.entries(nil, nil))
|
||||
Rails.logger.debug "Walking in branch: #{repo_name(repository)} - [NOBRANCH]"
|
||||
walk(databasepath, indexconf, project, repository, nil, repository.entries(nil, nil))
|
||||
end
|
||||
if repository.tags
|
||||
repository.tags.each do |tag|
|
||||
Rails.logger.debug("Walking in tag: %s - %s" % [
|
||||
(repository.identifier or MAIN_REPOSITORY_IDENTIFIER), tag])
|
||||
walk(repository, tag, repository.entries(nil, tag))
|
||||
Rails.logger.debug "Walking in tag: #{repo_name(repository)} - #{tag}"
|
||||
walk(databasepath, indexconf, project, repository, tag, repository.entries(nil, tag))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def indexing_diff(repository, diff_from, diff_to)
|
||||
def walk(repository, identifier, changesets)
|
||||
Rails.logger.debug "DEBUG: walking into " + changesets.inspect
|
||||
def walkin(databasepath, indexconf, project, repository, identifier, changesets)
|
||||
Rails.logger.debug "Walking into #{changesets.inspect}"
|
||||
return if not changesets or changesets.size <= 0
|
||||
changesets.sort! { |a, b| a.id <=> b.id }
|
||||
|
||||
@ -295,69 +282,60 @@ def indexing_diff(repository, diff_from, diff_to)
|
||||
# * R - Replaced
|
||||
# * D - Deleted
|
||||
changesets.each do |changeset|
|
||||
Rails.logger.debug "DEBUG: changeset changes for #{changeset.id} " + changeset.filechanges.inspect
|
||||
Rails.logger.debug "Changeset changes for #{changeset.id} #{changeset.filechanges.inspect}"
|
||||
next unless changeset.filechanges
|
||||
changeset.filechanges.each do |change|
|
||||
if change.action == 'D'
|
||||
actions[change.path] = DELETE
|
||||
#entry = repository.entry(change.path, identifier)
|
||||
#add_or_update_index(repository, identifier, entry, DELETE )
|
||||
else
|
||||
actions[change.path] = ADD_OR_UPDATE
|
||||
#entry = repository.entry(change.path, identifier)
|
||||
#add_or_update_index(repository, identifier, entry, ADD_OR_UPDATE )
|
||||
end
|
||||
changeset.filechanges.each do |change|
|
||||
actions[change.path] = (change.action == 'D') ? DELETE : ADD_OR_UPDATE
|
||||
end
|
||||
end
|
||||
return unless actions
|
||||
actions.each do |path, action|
|
||||
entry = repository.entry(path, identifier)
|
||||
if (!entry.nil? and entry.is_file?) or action == DELETE
|
||||
log("Error indexing path: #{path.inspect}, action: #{action.inspect}, identifier: #{identifier.inspect}", :level=>1) if entry.nil? and action != DELETE
|
||||
Rails.logger.debug "DEBUG: entry to index " + entry.inspect
|
||||
lastrev=nil
|
||||
lastrev=entry.lastrev unless entry.nil?
|
||||
add_or_update_index(repository, identifier, path, lastrev, action, MIME_TYPES[Redmine::MimeType.of(path)] ) if supported_mime_type(path) or action == DELETE
|
||||
if ((!entry.nil? && entry.is_file?) || action == DELETE)
|
||||
log("Error indexing path: #{path.inspect}, action: #{action.inspect}, identifier: #{identifier.inspect}",
|
||||
:level => 1) if (entry.nil? && action != DELETE)
|
||||
Rails.logger.debug "Entry to index #{entry.inspect}"
|
||||
lastrev = entry.lastrev unless entry.nil?
|
||||
add_or_update_index(databasepath, indexconf, project, repository,
|
||||
identifier, path, lastrev, action, MIME_TYPES[Redmine::MimeType.of(path)]) if(supported_mime_type(path) || action == DELETE)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def indexing_diff(databasepath, indexconf, project, repository, diff_from, diff_to)
|
||||
if diff_from.id >= diff_to.id
|
||||
Rails.logger.info("Already indexed: %s (from: %s to %s)" % [
|
||||
(repository.identifier or MAIN_REPOSITORY_IDENTIFIER),diff_from.id, diff_to.id])
|
||||
log("\t>Already indexed: #{repository.identifier} (from #{diff_from.id} to #{diff_to.id})", :level=>1)
|
||||
Rails.logger.info "Already indexed: #{repo_name(repository)} (from: #{diff_from.id} to #{diff_to.id})"
|
||||
log("\t>Already indexed: #{repo_name(repository)} (from #{diff_from.id} to #{diff_to.id})", :level => 1)
|
||||
return
|
||||
end
|
||||
|
||||
Rails.logger.info("Indexing diff: %s (from: %s to %s)" % [
|
||||
(repository.identifier or MAIN_REPOSITORY_IDENTIFIER),diff_from.id, diff_to.id])
|
||||
Rails.logger.info("Indexing all: %s" % [
|
||||
(repository.identifier or MAIN_REPOSITORY_IDENTIFIER)])
|
||||
Rails.logger.info "Indexing diff: #{repo_name(repository)} (from: #{diff_from.id} to #{diff_to.id})"
|
||||
Rails.logger.info "Indexing all: #{repo_name(repository)}"
|
||||
|
||||
if repository.branches
|
||||
repository.branches.each do |branch|
|
||||
Rails.logger.debug("Walking in branch: %s - %s" % [(repository.identifier or MAIN_REPOSITORY_IDENTIFIER), branch])
|
||||
walk(repository, branch, repository.latest_changesets("", branch, diff_to.id - diff_from.id)\
|
||||
.select { |changeset| changeset.id > diff_from.id and changeset.id <= diff_to.id})
|
||||
|
||||
repository.branches.each do |branch|
|
||||
Rails.logger.debug "Walking in branch: #{repo_name(repository)} - #{branch}"
|
||||
walkin(databasepath, indexconf, project, repository, branch, repository.latest_changesets('', branch, diff_to.id - diff_from.id).select { |changeset|
|
||||
changeset.id > diff_from.id and changeset.id <= diff_to.id})
|
||||
end
|
||||
else
|
||||
Rails.logger.debug("Walking in branch: %s - %s" % [(repository.identifier or MAIN_REPOSITORY_IDENTIFIER), "[NOBRANCH]"])
|
||||
walk(repository, nil, repository.latest_changesets("", nil, diff_to.id - diff_from.id)\
|
||||
.select { |changeset| changeset.id > diff_from.id and changeset.id <= diff_to.id})
|
||||
Rails.logger.debug "Walking in branch: #{repo_name(repository)} - [NOBRANCH]"
|
||||
walkin(databasepath, indexconf, project, repository, nil, repository.latest_changesets('', nil, diff_to.id - diff_from.id).select { |changeset|
|
||||
changeset.id > diff_from.id and changeset.id <= diff_to.id})
|
||||
end
|
||||
if repository.tags
|
||||
repository.tags.each do |tag|
|
||||
Rails.logger.debug("Walking in tag: %s - %s" % [(repository.identifier or MAIN_REPOSITORY_IDENTIFIER), tag])
|
||||
walk(repository, tag, repository.latest_changesets("", tag, diff_to.id - diff_from.id)\
|
||||
.select { |changeset| changeset.id > diff_from.id and changeset.id <= diff_to.id})
|
||||
end
|
||||
repository.tags.each do |tag|
|
||||
Rails.logger.debug "Walking in tag: #{repo_name(repository)} - #{tag}"
|
||||
walkin(databasepath, indexconf, project, repository, tag, repository.latest_changesets('', tag, diff_to.id - diff_from.id).select { |changeset|
|
||||
changeset.id > diff_from.id and changeset.id <= diff_to.id})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def generate_uri(repository, identifier, path)
|
||||
def generate_uri(project, repository, identifier, path)
|
||||
return url_for(:controller => 'repositories',
|
||||
:action => 'entry',
|
||||
:id => $project,
|
||||
:id => project.identifier,
|
||||
:repository_id => repository.identifier,
|
||||
:rev => identifier,
|
||||
:path => repository.relative_path(path),
|
||||
@ -369,42 +347,41 @@ def print_and_flush(str)
|
||||
$stdout.flush
|
||||
end
|
||||
|
||||
|
||||
def convert_to_text(fpath, type)
|
||||
text = nil
|
||||
return text if !File.exists?(FORMAT_HANDLERS[type].split(' ').first)
|
||||
case type
|
||||
when "pdf"
|
||||
#fout=fpath.chomp(File.extname(fpath)) + ".txt"
|
||||
text=`#{FORMAT_HANDLERS[type]} #{fpath} -`
|
||||
#begin
|
||||
# text=File.read(fout)
|
||||
# File.unlink(fout)
|
||||
#rescue Exception => e
|
||||
# log("\tError: #{e.to_s} reading #{fout}", :level=>1)
|
||||
#end
|
||||
when /(xlsx|docx|odt|pptx)/i
|
||||
system "#{$unzip} -d #{$tempdir}/temp #{fpath} > /dev/null", :out=>'/dev/null'
|
||||
fout= "#{$tempdir}/temp/" + "xl/sharedStrings.xml" if type.eql?("xlsx")
|
||||
fout= "#{$tempdir}/temp/" + "word/document.xml" if type.eql?("docx")
|
||||
fout= "#{$tempdir}/temp/" + "content.xml" if type.eql?("odt")
|
||||
fout= "#{$tempdir}/temp/" + "docProps/app.xml" if type.eql?("pptx")
|
||||
begin
|
||||
text=File.read(fout)
|
||||
FileUtils.rm_rf("#{$tempdir}/temp")
|
||||
rescue Exception => e
|
||||
log("\tError: #{e.to_s} reading #{fout}", :level=>1)
|
||||
end
|
||||
else
|
||||
text = `#{FORMAT_HANDLERS[type]} #{fpath}`
|
||||
when 'pdf'
|
||||
text = "#{FORMAT_HANDLERS[type]} #{fpath} -"
|
||||
when /(xlsx|docx|odt|pptx)/i
|
||||
system "#{$unzip} -d #{$tempdir}/temp #{fpath} > /dev/null", :out=>'/dev/null'
|
||||
case type
|
||||
when 'xlsx'
|
||||
fout = "#{$tempdir}/temp/xl/sharedStrings.xml"
|
||||
when 'docx'
|
||||
fout = "#{$tempdir}/temp/word/document.xml"
|
||||
when 'odt'
|
||||
fout = "#{$tempdir}/temp/content.xml"
|
||||
when 'pptx'
|
||||
fout = "#{$tempdir}/temp/docProps/app.xml"
|
||||
end
|
||||
begin
|
||||
text = File.read(fout)
|
||||
FileUtils.rm_rf("#{$tempdir}/temp")
|
||||
rescue Exception => e
|
||||
log("\tError: #{e.to_s} reading #{fout}", :level => 1)
|
||||
end
|
||||
else
|
||||
text = "#{FORMAT_HANDLERS[type]} #{fpath}"
|
||||
end
|
||||
return text
|
||||
end
|
||||
|
||||
def add_or_update_index(repository, identifier, path, lastrev, action, type)
|
||||
uri = generate_uri(repository, identifier, path)
|
||||
def add_or_update_index(databasepath, indexconf, project, repository, identifier,
|
||||
path, lastrev, action, type)
|
||||
uri = generate_uri(project, repository, identifier, path)
|
||||
return unless uri
|
||||
text=nil
|
||||
text = nil
|
||||
if Redmine::MimeType.is_type?('text', path) #type eq 'txt'
|
||||
text = repository.cat(path, identifier)
|
||||
else
|
||||
@ -414,85 +391,76 @@ def add_or_update_index(repository, identifier, path, lastrev, action, type)
|
||||
File.open( "#{$tempdir}/#{fname}", 'wb+') do | bs |
|
||||
bs.write(bstr)
|
||||
end
|
||||
text = convert_to_text( "#{$tempdir}/#{fname}", type) if File.exists?("#{$tempdir}/#{fname}") and !bstr.nil?
|
||||
text = convert_to_text("#{$tempdir}/#{fname}", type) if File.exists?("#{$tempdir}/#{fname}") and !bstr.nil?
|
||||
File.unlink("#{$tempdir}/#{fname}")
|
||||
end
|
||||
#return delete_doc(uri) unless text
|
||||
#return unless text
|
||||
Rails.logger.debug "generated uri: " + uri.inspect
|
||||
#log("\t>Generated uri: #{uri.inspect}", :level=>1)
|
||||
Rails.logger.debug "Mime type text" if Redmine::MimeType.is_type?('text', path)
|
||||
log("\t>Indexing: #{path}", :level=>1)
|
||||
end
|
||||
log "generated uri: #{uri}", :lebel => 1
|
||||
log('Mime type text', :level => 1) if Redmine::MimeType.is_type?('text', path)
|
||||
log("\t>Indexing: #{path}", :level => 1)
|
||||
begin
|
||||
itext = Tempfile.new( "filetoindex.tmp", $tempdir )
|
||||
itext = Tempfile.new('filetoindex.tmp', $tempdir)
|
||||
itext.write("url=#{uri.to_s}\n")
|
||||
if action != DELETE then
|
||||
sdate = lastrev.time || Time.at(0).in_time_zone
|
||||
itext.write("date=#{sdate.to_s}\n")
|
||||
body=nil
|
||||
body = nil
|
||||
text.force_encoding('UTF-8')
|
||||
text.each_line do |line|
|
||||
#Rails.logger.debug "inspecting line: " + line.inspect
|
||||
text.each_line do |line|
|
||||
if body.blank?
|
||||
itext.write("body=#{line}")
|
||||
body=1
|
||||
body = 1
|
||||
else
|
||||
itext.write("=#{line}")
|
||||
end
|
||||
end
|
||||
#print_and_flush "A" if $verbose
|
||||
else
|
||||
#print_and_flush "D" if $verbose
|
||||
Rails.logger.debug "DEBUG path: %s should be deleted" % [path]
|
||||
end
|
||||
else
|
||||
log "Path: #{path} should be deleted", :level => 1
|
||||
end
|
||||
itext.close
|
||||
Rails.logger.debug "TEXT #{itext.path} generated "
|
||||
#@rwdb.close #Closing because of use of scriptindex
|
||||
Rails.logger.debug "DEBUG index cmd: #{$scriptindex} -s #{$user_stem_lang} #{$databasepath} #{$indexconf.path} #{itext.path}"
|
||||
system_or_raise("#{$scriptindex} -s english #{$databasepath} #{$indexconf.path} #{itext.path} " )
|
||||
itext.unlink
|
||||
Rails.logger.info ("New doc added to xapian database")
|
||||
rescue Exception => e
|
||||
Rails.logger.error("ERROR text not indexed beacause an error #{e.to_s}")
|
||||
itext.close
|
||||
log "TEXT #{itext.path} generated", :level => 1
|
||||
log "Index command: #{$scriptindex} -s #{$user_stem_lang} #{databasepath} #{indexconf.path} #{itext.path}", :level => 1
|
||||
system_or_raise("#{$scriptindex} -s english #{databasepath} #{indexconf.path} #{itext.path}")
|
||||
itext.unlink
|
||||
log 'New doc added to xapian database'
|
||||
rescue Exception => e
|
||||
log "Text not indexed beacause an error #{e.message}"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
#include RepositoryIndexer
|
||||
|
||||
def log(text, options={})
|
||||
level = options[:level] || 0
|
||||
dtext=Time.now.asctime.to_s + ": #{text}"
|
||||
puts dtext unless $quiet or level > $verbose
|
||||
dtext = Time.now.asctime.to_s + ": #{text}"
|
||||
puts dtext unless level > $verbose
|
||||
exit 1 if options[:exit]
|
||||
end
|
||||
|
||||
def system_or_raise(command)
|
||||
raise "\"#{command}\" failed" unless system command ,:out=>'/dev/null'
|
||||
if $verbose > 0
|
||||
raise "\"#{command}\" failed" unless system command
|
||||
else
|
||||
raise "\"#{command}\" failed" unless system command, :out => '/dev/null'
|
||||
end
|
||||
end
|
||||
|
||||
def find_project(prt)
|
||||
#puts "find project for #{prt}"
|
||||
def find_project(prt)
|
||||
scope = Project.active.has_module(:repository)
|
||||
project = nil
|
||||
project = scope.find_by_identifier(prt)
|
||||
Rails.logger.debug "DEBUG: project found: #{project.inspect}"
|
||||
Rails.logger.debug "Project found: #{project}"
|
||||
raise ActiveRecord::RecordNotFound unless project
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
log("- ERROR project #{prt} not found", :level => 1)
|
||||
@project=project
|
||||
@project = project
|
||||
end
|
||||
|
||||
def create_dir(path)
|
||||
$rdo=0
|
||||
def create_dir(path)
|
||||
begin
|
||||
Dir.mkdir(path)
|
||||
Dir.mkdir path
|
||||
sleep 1
|
||||
rescue SystemCallError
|
||||
$rdo=1
|
||||
return 1
|
||||
end
|
||||
$rdo
|
||||
return 0
|
||||
end
|
||||
|
||||
log("- Trying to load Redmine environment <<#{$environment}>>...", :level => 1)
|
||||
@ -509,12 +477,10 @@ include Rails.application.routes.url_helpers
|
||||
|
||||
log("- Redmine environment [RAILS_ENV=#{$env}] correctly loaded ...", :level => 1)
|
||||
|
||||
|
||||
if $test
|
||||
log("- Running in test mode ...")
|
||||
log('- Running in test mode ...')
|
||||
end
|
||||
|
||||
|
||||
# Indexing files
|
||||
if not $onlyrepos then
|
||||
if not File.exist?($omindex) then
|
||||
@ -522,65 +488,56 @@ if not $onlyrepos then
|
||||
exit 1
|
||||
end
|
||||
$stem_langs.each do | lang |
|
||||
$filespath=File.join($redmine_root, $dmsf_root)
|
||||
if not File.directory?($filespath) then
|
||||
log("- ERROR accessing #{$filespath}, exiting ...")
|
||||
filespath = File.join($redmine_root, $files)
|
||||
if not File.directory?(filespath) then
|
||||
log("- ERROR accessing #{filespath}, exiting...")
|
||||
exit 1
|
||||
end
|
||||
dbpath=File.join($dbrootpath,lang)
|
||||
dbpath = File.join($dbrootpath,lang)
|
||||
if not File.directory?(dbpath)
|
||||
log("- ERROR! #{dbpath} does not exist, creating ...")
|
||||
log("- #{dbpath} does not exist, creating ...")
|
||||
if not create_dir(dbpath) then
|
||||
log("- ERROR! #{dbpath} can not be created!, exiting ...")
|
||||
log("- ERROR! #{dbpath} can not be created!, exiting...")
|
||||
exit 1
|
||||
end
|
||||
end
|
||||
log("- Indexing files under #{$filespath} with omindex stemming in #{lang} ...", :level=>1)
|
||||
system_or_raise ("#{$omindex} -s #{lang} --db #{dbpath} #{$filespath} --url / > /dev/null")
|
||||
log("- Indexing files under #{filespath} with omindex stemming in #{lang} ...", :level => 1)
|
||||
system_or_raise ("#{$omindex} -s #{lang} --db #{dbpath} #{filespath} --url / > /dev/null")
|
||||
end
|
||||
log("- Redmine files indexed ...", :level=>1)
|
||||
log('- Redmine files indexed ...', :level => 1)
|
||||
end
|
||||
|
||||
# Indexing repositories
|
||||
unless $onlyfiles
|
||||
unless File.exist?($scriptindex)
|
||||
if not $onlyfiles then
|
||||
if not File.exist?($scriptindex) then
|
||||
log("- ERROR! #{$scriptindex} does not exist, exiting...")
|
||||
exit 1
|
||||
end
|
||||
$databasepath = File.join($dbrootpath.rstrip, 'repodb')
|
||||
unless File.directory?($databasepath)
|
||||
log("Db directory #{$databasepath} does not exist, creating...")
|
||||
databasepath = File.join($dbrootpath.rstrip, 'repodb')
|
||||
log(databasepath)
|
||||
if not File.directory?(databasepath)
|
||||
log("- Db directory #{databasepath} does not exist, creating...")
|
||||
begin
|
||||
Dir.mkdir($databasepath)
|
||||
Dir.mkdir(databasepath)
|
||||
sleep 1
|
||||
rescue SystemCallError
|
||||
log("ERROR! #{$databasepath} can not be created!, exiting ...")
|
||||
log("- ERROR! #{databasepath} can not be created!, exiting ...")
|
||||
exit 1
|
||||
end
|
||||
end
|
||||
|
||||
projects.each do |identifier|
|
||||
begin
|
||||
project = Project.active.find_by_identifier(identifier)
|
||||
begin
|
||||
project = Project.active.has_module(:repository).where(:identifier => identifier).preload(:repository).first
|
||||
raise ActiveRecord::RecordNotFound unless project
|
||||
raise ActiveRecord::RecordNotFound unless project.has_module(:repository)
|
||||
log("- Indexing repositories for #{project.name} ...", :level => 1)
|
||||
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
|
||||
repositories.each do |repository|
|
||||
delete_log(repository) if ($resetlog)
|
||||
indexing(databasepath, project, repository)
|
||||
end
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
log("- ERROR project identifier #{identifier} not found or repository module not enabled, ignoring...", :level => 1)
|
||||
Rails.logger.error "Project identifier #{identifier} not found "
|
||||
log("- WARNING project identifier #{identifier} not found or repository module not enabled, ignoring...", :level => 1)
|
||||
Rails.logger.error "Project identifier #{identifier} not found"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
42
init.rb
42
init.rb
@ -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.3'
|
||||
version '1.5.4'
|
||||
url 'http://www.redmine.org/plugins/dmsf'
|
||||
author_url 'https://github.com/danmunn/redmine_dmsf/graphs/contributors'
|
||||
|
||||
@ -108,7 +108,7 @@ Redmine::Plugin.register :redmine_dmsf do
|
||||
end
|
||||
end
|
||||
if User.current && User.current.allowed_to?(:view_dmsf_files, file.project)
|
||||
file_view_url = url_for({:only_path => false, :controller => :dmsf_files, :action => 'view', :id => file, :download => args[2]})
|
||||
file_view_url = url_for(:controller => :dmsf_files, :action => 'view', :id => file, :download => args[2])
|
||||
return link_to(h(args[1] ? args[1] : file.title),
|
||||
file_view_url,
|
||||
:target => '_blank',
|
||||
@ -118,13 +118,10 @@ Redmine::Plugin.register :redmine_dmsf do
|
||||
raise l(:notice_not_authorized)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
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 the link for folder opening."
|
||||
|
||||
"_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), dmsf_folder_url(@project)
|
||||
@ -137,14 +134,11 @@ Redmine::Plugin.register :redmine_dmsf do
|
||||
raise l(:notice_not_authorized)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Redmine::WikiFormatting::Macros.register do
|
||||
end
|
||||
|
||||
desc "Wiki link to DMSF document description:\n\n" +
|
||||
"{{dmsfd(file_id)}}\n\n" +
|
||||
"_file_id_ can be found in the link for file/revision download."
|
||||
|
||||
macro :dmsfd do |obj, args|
|
||||
raise ArgumentError if args.length < 1 # Requires file id
|
||||
file = DmsfFile.visible.find args[0].strip
|
||||
@ -152,10 +146,30 @@ Redmine::Plugin.register :redmine_dmsf do
|
||||
return file.description
|
||||
else
|
||||
raise l(:notice_not_authorized)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
desc "Wiki DMSF image:\n\n" +
|
||||
"{{dmsf_image(file_id)}}\n" +
|
||||
"{{dmsf_image(file_id, size=300)}} -- with custom title and size\n" +
|
||||
"{{dmsf_image(file_id, size=640x480)}}"
|
||||
macro :dmsf_image do |obj, args|
|
||||
args, options = extract_macro_options(args, :size, :title)
|
||||
file_id = args.first
|
||||
raise 'DMSF document ID required' unless file_id.present?
|
||||
size = options[:size]
|
||||
if file = DmsfFile.find_by_id(file_id)
|
||||
unless User.current && User.current.allowed_to?(:view_dmsf_files, file.project)
|
||||
raise l(:notice_not_authorized)
|
||||
end
|
||||
raise 'Not supported image format' unless file.image?
|
||||
url = url_for(:controller => :dmsf_files, :action => 'view', :id => file)
|
||||
image_tag(url, :alt => file.title, :size => size)
|
||||
else
|
||||
raise "Document ID #{file_id} not found"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
# Rubyzip configuration
|
||||
Zip.unicode_names = true
|
||||
|
||||
@ -179,7 +179,7 @@ module RedmineDmsf
|
||||
|
||||
def etag
|
||||
filesize = file ? file.size : 4096;
|
||||
fileino = (file && file.last_revision) ? File.stat(file.last_revision.disk_file).ino : 2;
|
||||
fileino = (file && file.last_revision && File.exist?(file.last_revision.disk_file)) ? File.stat(file.last_revision.disk_file).ino : 2;
|
||||
sprintf('%x-%x-%x', fileino, filesize, last_modified.to_i)
|
||||
end
|
||||
|
||||
@ -482,15 +482,20 @@ module RedmineDmsf
|
||||
raise Forbidden
|
||||
end
|
||||
|
||||
#
|
||||
#
|
||||
# HTTP POST request.
|
||||
def put(request, response)
|
||||
raise BadRequest if (collection?)
|
||||
|
||||
raise BadRequest if collection?
|
||||
raise Forbidden unless User.current.admin? || User.current.allowed_to?(:file_manipulation, project)
|
||||
|
||||
# Ignore Mac OS X resource forks and special Windows files.
|
||||
if basename.match(/^\._/i) || basename.match(/^Thumbs.db$/i)
|
||||
Rails.logger.info "#{basename} ignored"
|
||||
return NoContent
|
||||
end
|
||||
|
||||
new_revision = DmsfFileRevision.new
|
||||
if exist? && file # We're over-writing something, so ultimately a new revision
|
||||
|
||||
if exist? # We're over-writing something, so ultimately a new revision
|
||||
f = file
|
||||
last_revision = file.last_revision
|
||||
new_revision.source_revision = last_revision
|
||||
@ -518,6 +523,7 @@ module RedmineDmsf
|
||||
new_revision.comment = nil
|
||||
new_revision.increase_version(1, true)
|
||||
new_revision.mime_type = Redmine::MimeType.of(new_revision.name)
|
||||
|
||||
# Phusion passenger does not have a method "length" in its model
|
||||
# however includes a size method - so we instead use reflection
|
||||
# to determine best approach to problem
|
||||
@ -528,7 +534,15 @@ module RedmineDmsf
|
||||
else
|
||||
new_revision.size = request.content_length # Bad Guess
|
||||
end
|
||||
|
||||
# Ignore Mac OS X resource forks and special Windows files.
|
||||
unless new_revision.size > 0
|
||||
Rails.logger.info "#{basename} #{new_revision.size}b ignored"
|
||||
return Created
|
||||
end
|
||||
|
||||
raise InternalServerError unless new_revision.valid? && f.save
|
||||
|
||||
new_revision.disk_filename = new_revision.new_storage_filename
|
||||
|
||||
if new_revision.save
|
||||
@ -546,6 +560,9 @@ module RedmineDmsf
|
||||
# for lock information to be presented
|
||||
def get_property(element)
|
||||
raise NotImplemented if (element[:ns_href] != 'DAV:')
|
||||
unless folder?
|
||||
return NotFound unless (file && file.last_revision && File.exist?(file.last_revision.disk_file))
|
||||
end
|
||||
case element[:name]
|
||||
when 'supportedlock' then supported_lock
|
||||
when 'lockdiscovery' then discover_lock
|
||||
@ -566,7 +583,7 @@ module RedmineDmsf
|
||||
# implementation of service for request, which allows for us to pipe a single file through
|
||||
# also best-utilising DAV4Rack's implementation.
|
||||
def download
|
||||
raise NotFound unless file && file.last_revision
|
||||
raise NotFound unless (file && file.last_revision && file.last_revision.disk_file)
|
||||
|
||||
# If there is no range (start of ranged download, or direct download) then we log the
|
||||
# file access, so we can properly keep logged information
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user