lib/TaskJuggler.rb in taskjuggler-0.0.4 vs lib/TaskJuggler.rb in taskjuggler-0.0.5
- old
+ new
@@ -11,28 +11,28 @@
#
require 'drb'
require 'Project'
require 'MessageHandler'
-require 'RemoteServiceManager'
require 'Log'
# The TaskJuggler class models the object that provides access to the
# fundamental features of the TaskJuggler software. It can read project
# files, schedule them and generate the reports.
class TaskJuggler
attr_reader :messageHandler
- attr_accessor :maxCpuCores
+ attr_accessor :maxCpuCores, :warnTsDeltas
# Create a new TaskJuggler object. _console_ is a boolean that determines
# whether or not messsages can be written to $stderr.
def initialize(console)
@project = nil
@parser = nil
@messageHandler = MessageHandler.new(console)
@maxCpuCores = 1
+ @warnTsDeltas = false
end
# Read in the files passed as file names in _files_, parse them and
# construct a Project object. In case of success true is returned.
# Otherwise false.
@@ -62,18 +62,32 @@
# For the report server mode we may need to keep the parser. Otherwise,
# destroy it.
@parser = nil unless keepParser
Log.exit('parser')
- @messageHandler.messages.empty?
+ @messageHandler.errors == 0
end
+ # Parse a file and add the content to the existing project. _fileName_ is
+ # the name of the file. _rule_ is the TextParser::Rule to start with.
+ def parseFile(fileName, rule)
+ @parser.open(fileName, false)
+ @parser.setGlobalMacros
+ return nil if (res = @parser.parse(rule)).nil?
+ # Make sure that _rule_ described the full content of the file. There
+ # should be no more content left.
+ @parser.checkForEnd
+ @parser.close
+ res
+ end
+
# Schedule all scenarios in the project. Return true if no error was
# detected, false otherwise.
def schedule
Log.enter('scheduler', 'Scheduling project ...')
#puts @project.to_s
+ @project.warnTsDeltas = @warnTsDeltas
res = @project.schedule
Log.exit('scheduler')
res
end
@@ -86,18 +100,106 @@
res = @project.generateReports(@maxCpuCores)
Log.exit('reports')
res
end
- def serveReports
- $SAFE = 1
- Log.enter('reportserver', 'Starting Server Mode ...')
- Log.status("Report Server is now active!")
- serviceManager = RemoteServiceManager.new(@parser, @project)
- DRb.start_service('druby://localhost:8474', serviceManager)
- DRb.thread.join
- # We'll probably never get here. The DRb threads may call exit().
- Log.exit('reportserver')
+ # Generate the report with the ID _reportId_.
+ def generateReport(reportId, regExpMode)
+ begin
+ Log.enter('generateReport', 'Generating report #{reportId} ...')
+ @project.generateReport(reportId, regExpMode)
+ rescue TjException
+ Log.exit('generateReport')
+ return false
+ end
+ Log.exit('generateReport')
+ true
+ end
+
+ # Generate the report with the ID _reportId_.
+ def listReports(reportId, regExpMode)
+ begin
+ Log.enter('listReports', 'Generating report list for #{reportId} ...')
+ @project.listReports(reportId, regExpMode)
+ rescue TjException
+ Log.exit('listReports')
+ return false
+ end
+ Log.exit('listReports')
+ true
+ end
+
+ # Check the content of the file _fileName_ and interpret it as a time sheet.
+ # If the sheet is syntaxtically correct and matches the loaded project, true
+ # is returned. Otherwise false.
+ def checkTimeSheet(fileName)
+ begin
+ Log.enter('checkTimeSheet', 'Parsing #{fileName} ...')
+ # Make sure we don't use data from old time sheets or Journal entries.
+ @project.timeSheets.clear
+ @project['journal'] = Journal.new
+ return false unless (ts = parseFile(fileName, 'timeSheet'))
+ return false unless @project.checkTimeSheets
+ queryAttrs = { 'project' => @project,
+ 'property' => ts.resource,
+ 'scopeProperty' => nil,
+ 'scenarioIdx' => @project['trackingScenarioIdx'],
+ 'start' => ts.interval.start,
+ 'end' => ts.interval.end,
+ 'timeFormat' => '%Y-%m-%d' }
+ query = Query.new(queryAttrs)
+ rti = ts.resource.query_journal(query)
+ rti.lineWidth = 72
+ rti.indent = 2
+ rti.titleIndent = 0
+ rti.listIndent = 2
+ rti.parIndent = 2
+ rti.preIndent = 4
+ puts rti.to_s
+ rescue TjException
+ Log.exit('checkTimeSheet')
+ return false
+ end
+ Log.exit('checkTimeSheet')
+ true
+ end
+
+ # Check the content of the file _fileName_ and interpret it as a status
+ # sheet. If the sheet is syntaxtically correct and matches the loaded
+ # project, true is returned. Otherwise false.
+ def checkStatusSheet(fileName)
+ begin
+ Log.enter('checkStatusSheet', 'Parsing #{fileName} ...')
+ return false unless (ss = parseFile(fileName, 'statusSheet'))
+ queryAttrs = { 'project' => @project,
+ 'property' => ss[0],
+ 'scopeProperty' => nil,
+ 'scenarioIdx' => @project['trackingScenarioIdx'],
+ 'timeFormat' => '%Y-%m-%d',
+ 'start' => ss[1],
+ 'end' => ss[2],
+ 'timeFormat' => '%Y-%m-%d' }
+ query = Query.new(queryAttrs)
+ rti = ss[0].query_dashboard(query)
+ rti.lineWidth = 72
+ rti.indent = 2
+ rti.titleIndent = 0
+ rti.listIndent = 2
+ rti.parIndent = 2
+ rti.preIndent = 4
+ puts rti.to_s
+ rescue TjException
+ Log.exit('checkStatusSheet')
+ return false
+ end
+ Log.exit('checkStatusSheet')
+ true
+ end
+
+ # Return the ID of the project or nil if no project has been loaded yet.
+ def projectId
+ return nil if @project.nil?
+ @project['projectid']
end
# Return the number of errors that had been reported during processing.
def errors
@project.messageHandler.errors