lib/reports/Report.rb in taskjuggler-0.0.5 vs lib/reports/Report.rb in taskjuggler-0.0.6
- old
+ new
@@ -46,10 +46,38 @@
# The generate function is where the action happens in this class. The
# report defined by all the class attributes and report elements is
# generated according the the requested output format(s).
def generate
begin
+ generateIntermediateFormat
+
+ # Then generate the actual output format.
+ get('formats').each do |format|
+ case format
+ when :html
+ generateHTML
+ copyAuxiliaryFiles
+ when :csv
+ generateCSV
+ when :niku
+ generateNiku
+ when :tjp
+ generateTJP
+ else
+ raise 'Unknown report output format #{format}.'
+ end
+ end
+ rescue TjException
+ error('reporting_failed', $!.message)
+ end
+ 0
+ end
+
+ # Generate an output format agnostic version that can later be turned into
+ # the respective output formats.
+ def generateIntermediateFormat
+ begin
@content = nil
case @typeSpec
when :export
@content = TjpExportRE.new(self)
when :niku
@@ -69,38 +97,26 @@
end
# Most output format can be generated from a common intermediate
# representation of the elements. We generate that IR first.
@content.generateIntermediateFormat if @content
-
- # Then generate the actual output format.
- get('formats').each do |format|
- case format
- when :html
- generateHTML
- copyAuxiliaryFiles
- when :csv
- generateCSV
- when :niku
- generateNiku
- when :tjp
- generateTJP
- else
- raise 'Unknown report output format #{format}.'
- end
- end
rescue TjException
- error('reporting_failed', $!.message)
+ error('report_IR_generattion_failed', $!.message)
end
- 0
end
# Render the content of the report as HTML (without the framing).
def to_html
@content ? @content.to_html : nil
end
+ # Return true if the report should be rendered in the interactive version,
+ # false if not. The top-level report defines the output format and the
+ # interactive setting.
+ def interactive?
+ @project.reportContexts.first.report.get('interactive')
+ end
private
# Convenience function to access a report attribute
def a(attribute)
get(attribute)
@@ -112,18 +128,14 @@
head = html.generateHead("TaskJuggler Report - #{@name}",
'description' => 'TaskJuggler Report',
'keywords' => 'taskjuggler, project, management')
if a('selfcontained')
auxSrcDir = AppConfig.dataDirs('data/css')[0]
- cssFileName = auxSrcDir + '/tjreport.css'
+ cssFileName = (auxSrcDir ? auxSrcDir + '/tjreport.css' : '')
+ # Raise an error if we haven't found the data directory
if auxSrcDir.nil? || !File.exists?(cssFileName)
- raise TjException.new, <<"EOT"
-Cannot find '#{cssFileName}'. This is usually the result of an improper
-TaskJuggler installation. If you know where to find the data directory, you
-can use the TASKJUGGLER_DATA_PATH environment variable to specify the
-location. The variable should be set to the path without the /data at the end.
-EOT
+ dataDirError(cssFileName)
end
cssFile = IO.read(cssFileName)
if cssFile.empty?
raise TjException.new, <<"EOT"
Cannot read '#{cssFileName}'. Make sure the file is not empty and you have
@@ -137,10 +149,12 @@
else
head << XMLElement.new('link', 'rel' => 'stylesheet',
'type' => 'text/css',
'href' => 'css/tjreport.css')
end
+ html << XMLComment.new("Dynamic Report ID: " +
+ "#{@project.reportContexts.last.dynamicReportId}")
html << (body = XMLElement.new('body'))
unless a('selfcontained')
body << XMLElement.new('script', 'type' => 'text/javascript',
'src' => 'scripts/wz_tooltip.js')
@@ -170,12 +184,21 @@
"with ")
div << XMLNamedText.new("#{AppConfig.softwareName}", 'a',
'href' => "#{AppConfig.contact}")
div << XMLText.new(" v#{AppConfig.version}")
- html.write(((@name[0] == '/' ? '' : @project.outputDir) +
- @name + (@name == '.' ? '' : '.html')).untaint)
+ fileName =
+ if a('interactive') || @name == '.'
+ # Interactive HTML reports are always sent to stdout.
+ '.'
+ else
+ # Prepend the specified output directory unless the provided file
+ # name is an absolute file name.
+ ((@name[0] == '/' ? '' : @project.outputDir) +
+ @name + '.html').untaint
+ end
+ html.write(fileName)
end
# Generate a CSV version of the report.
def generateCSV
return nil unless @content
@@ -251,11 +274,12 @@
error('write_niku', "Cannot write to file #{@name}.\n#{$!}")
end
end
def copyAuxiliaryFiles
- return if @name == '.' # Don't copy files if output is stdout.
+ # Don't copy files if output is stdout.
+ return if @name == '.' || a('interactive')
copyDirectory('css')
copyDirectory('icons')
copyDirectory('scripts')
end
@@ -264,18 +288,12 @@
# The directory needs to be in the same directory as the HTML report.
auxDstDir = File.dirname((@name[0] == '/' ? '' : @project.outputDir) +
@name) + '/'
# Find the data directory that came with the TaskJuggler installation.
auxSrcDir = AppConfig.dataDirs("data/#{dirName}")[0]
- if auxSrcDir.nil? || !File.exists?(auxSrcDir)
- raise TjException.new, <<"EOT"
-Cannot find the #{dirName} directory. This is usually
-the result of an improper TaskJuggler installation. If you know the directory,
-you can use the TASKJUGGLER_DATA_PATH environment variable to specify the
-location.
-EOT
- end
+ # Raise an error if we haven't found the data directory
+ dataDirError(dirName) if auxSrcDir.nil? || !File.exists?(auxSrcDir)
# Don't copy directory if all files are up-to-date.
return if directoryUpToDate?(auxSrcDir, auxDstDir + dirName)
# Recursively copy the directory and all content.
FileUtils.cp_r(auxSrcDir, auxDstDir)
@@ -291,9 +309,19 @@
dstFile = (auxDstDir + '/' + file).untaint
return false if !File.exist?(dstFile) ||
File.mtime(srcFile) > File.mtime(dstFile)
end
true
+ end
+
+ def dataDirError(dirName)
+ raise TjException.new, <<"EOT"
+Cannot find the #{dirName} directory. This is usually the result of an
+improper TaskJuggler installation. If you know the directory, you can use the
+TASKJUGGLER_DATA_PATH environment variable to specify the location. The
+variable should be set to the path without the /data at the end. Multiple
+directories must be separated by colons.
+EOT
end
def error(id, message)
@project.messageHandler.send(Message.new(id, 'error', message, nil, nil,
@sourceFileInfo))