taskjuggler 3.1.0 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +44 -0
- data/bin/tj3webd +4 -0
- data/data/css/tjreport.css +14 -5
- data/data/tjp.vim +22 -7
- data/examples/Fedora-20/reports.tji +2 -4
- data/examples/Scrum/Product Burndown.csv +26 -0
- data/examples/Scrum/Sprint 1 Burndown.csv +26 -0
- data/examples/Scrum/Sprint 2 Burndown.csv +26 -0
- data/examples/Scrum/Sprint 3 Burndown.csv +26 -0
- data/examples/Scrum/scrum.tjp +141 -0
- data/examples/Tutorial/tutorial.tjp +13 -7
- data/lib/taskjuggler/Attributes.rb +2 -3
- data/lib/taskjuggler/HTMLDocument.rb +25 -18
- data/lib/taskjuggler/Journal.rb +85 -65
- data/lib/taskjuggler/KeywordDocumentation.rb +25 -13
- data/lib/taskjuggler/LeaveList.rb +1 -1
- data/lib/taskjuggler/Limits.rb +3 -5
- data/lib/taskjuggler/MessageHandler.rb +173 -19
- data/lib/taskjuggler/Painter.rb +75 -0
- data/lib/taskjuggler/Painter/BasicShapes.rb +76 -0
- data/lib/taskjuggler/Painter/Color.rb +273 -0
- data/lib/taskjuggler/Painter/Element.rb +56 -0
- data/lib/taskjuggler/Painter/FontData.rb +221 -0
- data/lib/taskjuggler/Painter/FontMetrics.rb +125 -0
- data/lib/taskjuggler/Painter/FontMetricsData.rb +151 -0
- data/lib/taskjuggler/Painter/Group.rb +77 -0
- data/lib/taskjuggler/Painter/Points.rb +47 -0
- data/lib/taskjuggler/Painter/Primitives.rb +100 -0
- data/lib/taskjuggler/Painter/SVGSupport.rb +36 -0
- data/lib/taskjuggler/Painter/Text.rb +36 -0
- data/lib/taskjuggler/Project.rb +46 -29
- data/lib/taskjuggler/ProjectFileParser.rb +24 -22
- data/lib/taskjuggler/ProjectFileScanner.rb +2 -2
- data/lib/taskjuggler/PropertyTreeNode.rb +26 -34
- data/lib/taskjuggler/Query.rb +8 -5
- data/lib/taskjuggler/RealFormat.rb +3 -0
- data/lib/taskjuggler/Resource.rb +3 -5
- data/lib/taskjuggler/ResourceScenario.rb +19 -7
- data/lib/taskjuggler/RichText.rb +4 -6
- data/lib/taskjuggler/RichText/FunctionExample.rb +1 -1
- data/lib/taskjuggler/RichText/FunctionHandler.rb +5 -6
- data/lib/taskjuggler/RichText/Parser.rb +4 -6
- data/lib/taskjuggler/RichText/RTFNavigator.rb +1 -1
- data/lib/taskjuggler/RichText/RTFQuery.rb +2 -3
- data/lib/taskjuggler/RichText/RTFReport.rb +1 -1
- data/lib/taskjuggler/RichText/RTFReportLink.rb +1 -2
- data/lib/taskjuggler/RichText/RTFWithQuerySupport.rb +1 -1
- data/lib/taskjuggler/RichText/Scanner.rb +6 -6
- data/lib/taskjuggler/RichText/Snip.rb +1 -2
- data/lib/taskjuggler/RuntimeConfig.rb +9 -6
- data/lib/taskjuggler/ScenarioData.rb +4 -3
- data/lib/taskjuggler/Scoreboard.rb +6 -0
- data/lib/taskjuggler/SheetHandlerBase.rb +25 -8
- data/lib/taskjuggler/SimpleQueryExpander.rb +14 -5
- data/lib/taskjuggler/SyntaxReference.rb +1 -2
- data/lib/taskjuggler/TableColumnSorter.rb +84 -0
- data/lib/taskjuggler/Task.rb +3 -5
- data/lib/taskjuggler/TaskJuggler.rb +36 -29
- data/lib/taskjuggler/TaskScenario.rb +154 -66
- data/lib/taskjuggler/TextParser.rb +24 -17
- data/lib/taskjuggler/TextParser/Scanner.rb +16 -11
- data/lib/taskjuggler/TextParser/SourceFileInfo.rb +20 -15
- data/lib/taskjuggler/TimeSheets.rb +6 -12
- data/lib/taskjuggler/Tj3AppBase.rb +35 -16
- data/lib/taskjuggler/Tj3Config.rb +1 -1
- data/lib/taskjuggler/TjpSyntaxRules.rb +239 -49
- data/lib/taskjuggler/XMLElement.rb +9 -2
- data/lib/taskjuggler/apps/Tj3.rb +43 -37
- data/lib/taskjuggler/apps/Tj3Client.rb +62 -112
- data/lib/taskjuggler/apps/Tj3Daemon.rb +66 -29
- data/lib/taskjuggler/apps/Tj3Man.rb +5 -5
- data/lib/taskjuggler/apps/Tj3SsReceiver.rb +10 -13
- data/lib/taskjuggler/apps/Tj3SsSender.rb +13 -16
- data/lib/taskjuggler/apps/Tj3TsReceiver.rb +10 -13
- data/lib/taskjuggler/apps/Tj3TsSender.rb +12 -15
- data/lib/taskjuggler/apps/Tj3TsSummary.rb +12 -15
- data/lib/taskjuggler/apps/Tj3WebD.rb +99 -0
- data/lib/taskjuggler/daemon/Daemon.rb +50 -10
- data/lib/taskjuggler/daemon/DaemonConnector.rb +127 -0
- data/lib/taskjuggler/daemon/ProcessIntercom.rb +36 -21
- data/lib/taskjuggler/daemon/ProjectBroker.rb +122 -112
- data/lib/taskjuggler/daemon/ProjectServer.rb +78 -46
- data/lib/taskjuggler/daemon/ReportServer.rb +52 -28
- data/lib/taskjuggler/daemon/ReportServlet.rb +92 -21
- data/lib/taskjuggler/daemon/WebServer.rb +75 -22
- data/lib/taskjuggler/daemon/WelcomePage.rb +1 -0
- data/lib/taskjuggler/reports/AccountListRE.rb +3 -3
- data/lib/taskjuggler/reports/CSVFile.rb +9 -2
- data/lib/taskjuggler/reports/ChartPlotter.rb +453 -0
- data/lib/taskjuggler/reports/Navigator.rb +1 -0
- data/lib/taskjuggler/reports/NikuReport.rb +4 -4
- data/lib/taskjuggler/reports/Report.rb +6 -18
- data/lib/taskjuggler/reports/ReportBase.rb +9 -9
- data/lib/taskjuggler/reports/ReportContext.rb +2 -2
- data/lib/taskjuggler/reports/StatusSheetReport.rb +6 -6
- data/lib/taskjuggler/reports/TableReport.rb +24 -15
- data/lib/taskjuggler/reports/TimeSheetReport.rb +5 -5
- data/lib/taskjuggler/reports/TraceReport.rb +251 -0
- data/lib/tj3webd.rb +17 -0
- data/manual/Day_To_Day_Juggling +10 -3
- data/manual/Installation +38 -19
- data/manual/Software +25 -19
- data/manual/Tutorial +119 -110
- data/manual/html/Day_To_Day_Juggling.html +7 -5
- data/manual/html/Getting_Started.html +4 -4
- data/manual/html/How_To_Contribute.html +4 -4
- data/manual/html/Installation.html +19 -11
- data/manual/html/Intro.html +4 -4
- data/manual/html/Reporting_Bugs.html +4 -4
- data/manual/html/Rich_Text_Attributes.html +4 -4
- data/manual/html/Software.html +15 -11
- data/manual/html/TaskJuggler_2x_Migration.html +4 -4
- data/manual/html/TaskJuggler_Internals.html +4 -4
- data/manual/html/The_TaskJuggler_Syntax.html +4 -4
- data/manual/html/Tutorial.html +41 -32
- data/manual/html/account.html +4 -4
- data/manual/html/account.task.html +4 -4
- data/manual/html/accountprefix.html +4 -4
- data/manual/html/accountreport.html +27 -9
- data/manual/html/accountroot.html +5 -5
- data/manual/html/active.html +4 -4
- data/manual/html/adopt.task.html +4 -4
- data/manual/html/aggregate.html +4 -4
- data/manual/html/alert.html +4 -4
- data/manual/html/alertlevels.html +4 -4
- data/manual/html/allocate.html +5 -5
- data/manual/html/alphabet.html +4 -4
- data/manual/html/alternative.html +4 -4
- data/manual/html/author.html +4 -4
- data/manual/html/balance.html +5 -5
- data/manual/html/booking.resource.html +4 -4
- data/manual/html/booking.task.html +4 -4
- data/manual/html/caption.html +5 -5
- data/manual/html/cellcolor.column.html +43 -8
- data/manual/html/celltext.column.html +4 -4
- data/manual/html/center.html +5 -5
- data/manual/html/charge.html +4 -4
- data/manual/html/chargeset.html +4 -4
- data/manual/html/columnid.html +27 -15
- data/manual/html/columns.html +5 -5
- data/manual/html/complete.html +4 -4
- data/manual/html/copyright.html +4 -4
- data/manual/html/credits.html +4 -4
- data/manual/html/css/tjreport.css +14 -5
- data/manual/html/currency.html +4 -4
- data/manual/html/currencyformat.html +5 -5
- data/manual/html/dailymax.html +5 -5
- data/manual/html/dailymin.html +5 -5
- data/manual/html/dailyworkinghours.html +4 -4
- data/manual/html/date.extend.html +4 -4
- data/manual/html/date.html +5 -5
- data/manual/html/definitions.html +4 -4
- data/manual/html/depends.html +4 -4
- data/manual/html/details.html +4 -4
- data/manual/html/disabled.html +4 -4
- data/manual/html/duration.html +4 -4
- data/manual/html/efficiency.html +4 -4
- data/manual/html/effort.html +4 -4
- data/manual/html/email.html +4 -4
- data/manual/html/enabled.html +4 -4
- data/manual/html/end.column.html +4 -4
- data/manual/html/end.html +4 -4
- data/manual/html/end.limit.html +4 -4
- data/manual/html/end.report.html +5 -5
- data/manual/html/end.timesheet.html +4 -4
- data/manual/html/endcredit.html +4 -4
- data/manual/html/epilog.html +5 -5
- data/manual/html/export.html +4 -4
- data/manual/html/extend.html +4 -4
- data/manual/html/fail.html +43 -8
- data/manual/html/fdl.html +4 -4
- data/manual/html/flags.account.html +4 -4
- data/manual/html/flags.html +4 -4
- data/manual/html/flags.journalentry.html +4 -4
- data/manual/html/flags.report.html +5 -5
- data/manual/html/flags.resource.html +4 -4
- data/manual/html/flags.statussheet.html +4 -4
- data/manual/html/flags.task.html +4 -4
- data/manual/html/flags.timesheet.html +4 -4
- data/manual/html/fontcolor.column.html +43 -8
- data/manual/html/footer.html +5 -5
- data/manual/html/formats.html +5 -5
- data/manual/html/functions.html +4 -4
- data/manual/html/gapduration.html +4 -4
- data/manual/html/gaplength.html +4 -4
- data/manual/html/halign.center.html +4 -4
- data/manual/html/halign.column.html +43 -8
- data/manual/html/halign.left.html +4 -4
- data/manual/html/halign.right.html +4 -4
- data/manual/html/hasalert.html +4 -4
- data/manual/html/header.html +5 -5
- data/manual/html/headline.html +7 -7
- data/manual/html/height.html +72 -0
- data/manual/html/hideaccount.html +46 -11
- data/manual/html/hidejournalentry.html +5 -5
- data/manual/html/hidereport.html +43 -8
- data/manual/html/hideresource.html +44 -9
- data/manual/html/hidetask.html +44 -9
- data/manual/html/icalreport.html +4 -4
- data/manual/html/include.macro.html +4 -4
- data/manual/html/include.project.html +4 -4
- data/manual/html/include.properties.html +4 -4
- data/manual/html/index.html +2 -1
- data/manual/html/inherit.extend.html +4 -4
- data/manual/html/interval1.html +4 -4
- data/manual/html/interval2.html +4 -4
- data/manual/html/interval3.html +4 -4
- data/manual/html/interval4.html +4 -4
- data/manual/html/isactive.html +4 -4
- data/manual/html/ischildof.html +4 -4
- data/manual/html/isdependencyof.html +4 -4
- data/manual/html/isdutyof.html +4 -4
- data/manual/html/isfeatureof.html +4 -4
- data/manual/html/isleaf.html +4 -4
- data/manual/html/ismilestone.html +4 -4
- data/manual/html/isongoing.html +4 -4
- data/manual/html/isresource.html +4 -4
- data/manual/html/isresponsibilityof.html +4 -4
- data/manual/html/istask.html +4 -4
- data/manual/html/journalattributes.html +11 -7
- data/manual/html/journalentry.html +4 -4
- data/manual/html/journalmode.html +5 -5
- data/manual/html/leaveallowance.html +5 -5
- data/manual/html/leaves.html +5 -6
- data/manual/html/left.html +5 -5
- data/manual/html/length.html +4 -4
- data/manual/html/limits.allocate.html +4 -4
- data/manual/html/limits.html +4 -4
- data/manual/html/limits.resource.html +4 -4
- data/manual/html/limits.task.html +4 -4
- data/manual/html/listitem.column.html +4 -4
- data/manual/html/listtype.column.html +4 -4
- data/manual/html/loadunit.html +5 -5
- data/manual/html/logicalexpression.html +8 -44
- data/manual/html/logicalflagexpression.html +4 -4
- data/manual/html/macro.html +4 -4
- data/manual/html/managers.html +4 -4
- data/manual/html/mandatory.html +4 -4
- data/manual/html/maxend.html +4 -4
- data/manual/html/maximum.html +5 -5
- data/manual/html/maxstart.html +4 -4
- data/manual/html/milestone.html +4 -4
- data/manual/html/minend.html +4 -4
- data/manual/html/minimum.html +5 -5
- data/manual/html/minstart.html +4 -4
- data/manual/html/monthlymax.html +5 -5
- data/manual/html/monthlymin.html +5 -5
- data/manual/html/navbar.html +10 -4
- data/manual/html/navigator.html +4 -4
- data/manual/html/newtask.html +4 -4
- data/manual/html/nikureport.html +4 -4
- data/manual/html/note.task.html +4 -4
- data/manual/html/now.html +4 -4
- data/manual/html/numberformat.html +5 -5
- data/manual/html/onend.html +4 -4
- data/manual/html/onstart.html +4 -4
- data/manual/html/opennodes.html +5 -5
- data/manual/html/overtime.booking.html +4 -4
- data/manual/html/period.column.html +4 -4
- data/manual/html/period.limit.html +4 -4
- data/manual/html/period.report.html +5 -5
- data/manual/html/period.task.html +4 -4
- data/manual/html/persistent.html +4 -4
- data/manual/html/precedes.html +4 -4
- data/manual/html/priority.html +4 -4
- data/manual/html/priority.timesheet.html +4 -4
- data/manual/html/project.html +4 -4
- data/manual/html/projectid.html +4 -4
- data/manual/html/projectid.task.html +4 -4
- data/manual/html/projectids.html +4 -4
- data/manual/html/projection.html +5 -7
- data/manual/html/prolog.html +5 -5
- data/manual/html/properties.html +11 -5
- data/manual/html/purge.html +5 -5
- data/manual/html/rate.html +4 -4
- data/manual/html/rate.resource.html +4 -4
- data/manual/html/reference.extend.html +4 -4
- data/manual/html/remaining.html +4 -4
- data/manual/html/replace.html +4 -4
- data/manual/html/reportprefix.html +4 -4
- data/manual/html/resource.html +4 -10
- data/manual/html/resourceattributes.html +4 -4
- data/manual/html/resourceprefix.html +4 -4
- data/manual/html/resourcereport.html +28 -10
- data/manual/html/resourceroot.html +5 -5
- data/manual/html/resources.limit.html +4 -4
- data/manual/html/responsible.html +4 -4
- data/manual/html/richtext.extend.html +4 -4
- data/manual/html/right.html +5 -5
- data/manual/html/rollupaccount.html +44 -9
- data/manual/html/rollupresource.html +44 -9
- data/manual/html/rolluptask.html +44 -9
- data/manual/html/scale.column.html +4 -4
- data/manual/html/scenario.html +4 -22
- data/manual/html/scenario.ical.html +4 -4
- data/manual/html/scenarios.export.html +4 -4
- data/manual/html/scenarios.html +5 -5
- data/manual/html/scenariospecific.extend.html +4 -4
- data/manual/html/scheduled.html +4 -4
- data/manual/html/scheduling.html +4 -4
- data/manual/html/select.html +4 -4
- data/manual/html/selfcontained.html +5 -5
- data/manual/html/shift.allocate.html +4 -4
- data/manual/html/shift.html +4 -4
- data/manual/html/shift.resource.html +5 -5
- data/manual/html/shift.task.html +4 -4
- data/manual/html/shift.timesheet.html +4 -4
- data/manual/html/shifts.allocate.html +4 -4
- data/manual/html/shifts.resource.html +4 -4
- data/manual/html/shifts.task.html +4 -4
- data/manual/html/shorttimeformat.html +4 -4
- data/manual/html/sloppy.booking.html +4 -4
- data/manual/html/sloppy.projection.html +5 -5
- data/manual/html/sortaccounts.html +5 -5
- data/manual/html/sortjournalentries.html +5 -5
- data/manual/html/sortresources.html +5 -5
- data/manual/html/sorttasks.html +5 -5
- data/manual/html/start.column.html +4 -4
- data/manual/html/start.html +4 -4
- data/manual/html/start.limit.html +4 -4
- data/manual/html/start.report.html +5 -5
- data/manual/html/startcredit.html +4 -4
- data/manual/html/status.statussheet.html +4 -4
- data/manual/html/status.timesheet.html +4 -4
- data/manual/html/statussheet.html +4 -4
- data/manual/html/statussheetreport.html +4 -4
- data/manual/html/strict.projection.html +5 -5
- data/manual/html/summary.html +4 -4
- data/manual/html/supplement.html +4 -4
- data/manual/html/supplement.resource.html +4 -10
- data/manual/html/supplement.task.html +4 -28
- data/manual/html/tagfile.html +4 -4
- data/manual/html/task.html +4 -28
- data/manual/html/task.statussheet.html +4 -4
- data/manual/html/task.timesheet.html +4 -4
- data/manual/html/taskattributes.html +4 -4
- data/manual/html/taskprefix.html +4 -4
- data/manual/html/taskreport.html +28 -10
- data/manual/html/taskroot.html +5 -5
- data/manual/html/text.extend.html +4 -4
- data/manual/html/textreport.html +27 -9
- data/manual/html/timeformat.html +5 -5
- data/manual/html/timeoff.nikureport.html +4 -4
- data/manual/html/timesheet.html +4 -4
- data/manual/html/timesheetreport.html +23 -5
- data/manual/html/timezone.export.html +4 -4
- data/manual/html/timezone.html +4 -4
- data/manual/html/timezone.report.html +5 -5
- data/manual/html/timezone.shift.html +4 -4
- data/manual/html/timingresolution.html +4 -4
- data/manual/html/title.column.html +4 -4
- data/manual/html/title.html +5 -5
- data/manual/html/toc.html +207 -179
- data/manual/html/tooltip.column.html +45 -10
- data/manual/html/tracereport.html +405 -0
- data/manual/html/trackingscenario.html +6 -6
- data/manual/html/treelevel.html +4 -4
- data/manual/html/vacation.html +4 -4
- data/manual/html/vacation.resource.html +4 -4
- data/manual/html/vacation.shift.html +4 -4
- data/manual/html/warn.html +43 -8
- data/manual/html/weeklymax.html +5 -5
- data/manual/html/weeklymin.html +5 -5
- data/manual/html/weekstartsmonday.html +4 -4
- data/manual/html/weekstartssunday.html +6 -6
- data/manual/html/width.column.html +6 -6
- data/manual/html/width.html +72 -0
- data/manual/html/work.html +4 -4
- data/manual/html/workinghours.project.html +4 -4
- data/manual/html/workinghours.resource.html +4 -4
- data/manual/html/workinghours.shift.html +4 -4
- data/manual/html/yearlyworkingdays.html +4 -4
- data/spec/Color_spec.rb +60 -0
- data/spec/ProjectBroker_spec.rb +3 -2
- data/spec/StatusSheets_spec.rb +5 -4
- data/spec/TableColumnSorter_spec.rb +78 -0
- data/spec/TimeSheets_spec.rb +6 -2
- data/spec/Tj3Daemon_spec.rb +2 -2
- data/spec/TraceReport_spec.rb +117 -0
- data/taskjuggler.gemspec +1 -1
- data/test/MessageChecker.rb +3 -1
- data/test/ReferenceGenerator.rb +1 -1
- data/test/TestSuite/CSV-Reports/Leave.tjp +1 -1
- data/test/TestSuite/CSV-Reports/refs/resourcereport_with_tasks.csv +3 -0
- data/test/TestSuite/CSV-Reports/refs/taskcounter.csv +9 -0
- data/test/TestSuite/CSV-Reports/refs/taskreport_with_resources.csv +19 -16
- data/test/TestSuite/CSV-Reports/refs/weekly.csv +1 -0
- data/test/TestSuite/Export-Reports/refs/LogicalExpression.tjp +14 -2
- data/test/TestSuite/Export-Reports/refs/tutorial.tjp +98 -86
- data/test/TestSuite/Scheduler/Correct/Leaves.tjp +25 -0
- data/test/TestSuite/Syntax/Correct/Leave.tjp +1 -1
- data/test/TestSuite/Syntax/Correct/LogicalExpression.tjp +9 -1
- data/test/TestSuite/Syntax/Correct/TraceReport.tjp +10 -0
- data/test/TestSuite/Syntax/Correct/tutorial.tjp +10 -4
- data/test/test_CSV-Reports.rb +3 -3
- data/test/test_Export-Reports.rb +91 -86
- data/test/test_Journal.rb +15 -12
- data/test/test_Limits.rb +3 -3
- data/test/test_Project.rb +1 -2
- data/test/test_ProjectFileScanner.rb +1 -1
- data/test/test_PropertySet.rb +1 -1
- data/test/test_Query.rb +5 -6
- data/test/test_ReportGenerator.rb +15 -7
- data/test/test_RichText.rb +4 -3
- data/test/test_Scheduler.rb +19 -7
- data/test/test_ShiftAssignments.rb +2 -2
- data/test/test_SimpleQueryExpander.rb +29 -2
- data/test/test_Syntax.rb +14 -5
- metadata +49 -10
- data/lib/taskjuggler/LogFile.rb +0 -73
@@ -16,9 +16,8 @@ require 'drb/acl'
|
|
16
16
|
require 'monitor'
|
17
17
|
require 'taskjuggler/daemon/ProcessIntercom'
|
18
18
|
require 'taskjuggler/daemon/ReportServer'
|
19
|
-
require 'taskjuggler/
|
19
|
+
require 'taskjuggler/MessageHandler'
|
20
20
|
require 'taskjuggler/TaskJuggler'
|
21
|
-
require 'taskjuggler/Log'
|
22
21
|
require 'taskjuggler/TjTime'
|
23
22
|
|
24
23
|
class TaskJuggler
|
@@ -79,7 +78,7 @@ class TaskJuggler
|
|
79
78
|
rd, wr = IO.pipe
|
80
79
|
|
81
80
|
if (@pid = fork) == -1
|
82
|
-
|
81
|
+
fatal('ps_fork_failed', 'ProjectServer fork failed')
|
83
82
|
elsif @pid.nil?
|
84
83
|
# This is the child
|
85
84
|
if @logConsole
|
@@ -91,13 +90,12 @@ class TaskJuggler
|
|
91
90
|
begin
|
92
91
|
$SAFE = 1
|
93
92
|
DRb.install_acl(ACL.new(%w[ deny all allow 127.0.0.1 ]))
|
94
|
-
DRb.start_service
|
95
93
|
iFace = ProjectServerIface.new(self)
|
96
94
|
begin
|
97
95
|
@uri = DRb.start_service('druby://127.0.0.1:0', iFace).uri
|
98
|
-
|
96
|
+
debug('', "Project server is listening on #{@uri}")
|
99
97
|
rescue
|
100
|
-
|
98
|
+
error('ps_cannot_start_drb', "ProjectServer can't start DRb: #{$!}")
|
101
99
|
end
|
102
100
|
|
103
101
|
# Send the URI of the newly started DRb server to the parent process.
|
@@ -114,12 +112,15 @@ class TaskJuggler
|
|
114
112
|
|
115
113
|
# Cleanup the DRb threads
|
116
114
|
DRb.thread.join
|
117
|
-
|
115
|
+
debug('', 'Project server terminated')
|
118
116
|
exit 0
|
119
|
-
rescue
|
120
|
-
|
121
|
-
|
122
|
-
|
117
|
+
rescue => exception
|
118
|
+
# TjRuntimeError exceptions are simply passed through.
|
119
|
+
if exception.is_a?(TjRuntimeError)
|
120
|
+
raise TjRuntimeError, $!
|
121
|
+
end
|
122
|
+
|
123
|
+
error('ps_cannot_start_drb', "ProjectServer can't start DRb: #{$!}")
|
123
124
|
end
|
124
125
|
else
|
125
126
|
# This is the parent
|
@@ -144,28 +145,37 @@ class TaskJuggler
|
|
144
145
|
@modifiedCheck = TjTime.new
|
145
146
|
|
146
147
|
updateState(:loading, dirAndFiles, false)
|
147
|
-
|
148
|
+
begin
|
149
|
+
@tj = TaskJuggler.new
|
150
|
+
# Make sure that trace reports get CSV formats included so there
|
151
|
+
# reports can be generated on request.
|
152
|
+
@tj.generateTraces = true
|
153
|
+
|
154
|
+
# Parse all project files
|
155
|
+
unless @tj.parse(args, true)
|
156
|
+
warning('parse_failed', "Parsing of #{args.join(' ')} failed")
|
157
|
+
updateState(:failed, nil, false)
|
158
|
+
@terminate = true
|
159
|
+
return false
|
160
|
+
end
|
148
161
|
|
149
|
-
|
150
|
-
|
151
|
-
|
162
|
+
# Then schedule the project
|
163
|
+
unless @tj.schedule
|
164
|
+
warning('schedule_failed',
|
165
|
+
"Scheduling of project #{@tj.projectId} failed")
|
166
|
+
updateState(:failed, @tj.projectId, false)
|
167
|
+
@terminate = true
|
168
|
+
return false
|
169
|
+
end
|
170
|
+
rescue TjRuntimeError
|
152
171
|
updateState(:failed, nil, false)
|
153
172
|
@terminate = true
|
154
173
|
return false
|
155
174
|
end
|
156
175
|
|
157
|
-
# Then schedule the project
|
158
|
-
unless @tj.schedule
|
159
|
-
@log.error("Scheduling of project #{@tj.projectId} failed")
|
160
|
-
updateState(:failed, @tj.projectId, false)
|
161
|
-
Log.exit('scheduler')
|
162
|
-
@terminate = true
|
163
|
-
return false
|
164
|
-
end
|
165
|
-
|
166
176
|
# Great, everything went fine. We've got a project to work with.
|
167
177
|
updateState(:ready, @tj.projectId, false)
|
168
|
-
|
178
|
+
debug('', "Project #{@tj.projectId} loaded")
|
169
179
|
restartTimer
|
170
180
|
true
|
171
181
|
end
|
@@ -201,7 +211,7 @@ class TaskJuggler
|
|
201
211
|
# find it in the @reportServers list, we create a unique tag to identify
|
202
212
|
# it.
|
203
213
|
tag = rand(99999999999999)
|
204
|
-
|
214
|
+
debug('', "Pushing #{tag} onto report server request queue")
|
205
215
|
@reportServerRequests.push(tag)
|
206
216
|
|
207
217
|
# Now wait until the new ReportServer shows up in the list.
|
@@ -216,8 +226,8 @@ class TaskJuggler
|
|
216
226
|
sleep 0.1 if reportServer.nil?
|
217
227
|
end
|
218
228
|
|
219
|
-
|
220
|
-
|
229
|
+
debug('', "Got report server with URI #{reportServer.uri} for " +
|
230
|
+
"tag #{tag}")
|
221
231
|
restartTimer
|
222
232
|
[ reportServer.uri, reportServer.authKey ]
|
223
233
|
end
|
@@ -249,9 +259,16 @@ class TaskJuggler
|
|
249
259
|
def updateState(state, filesOrId, modified)
|
250
260
|
begin
|
251
261
|
@daemon = DRbObject.new(nil, @daemonURI) unless @daemon
|
252
|
-
@daemon.updateState(@daemonAuthKey, @authKey, filesOrId, state,
|
253
|
-
|
254
|
-
|
262
|
+
@daemon.updateState(@daemonAuthKey, @authKey, filesOrId, state,
|
263
|
+
modified)
|
264
|
+
rescue => exception
|
265
|
+
# TjRuntimeError exceptions are simply passed through.
|
266
|
+
if exception.is_a?(TjRuntimeError)
|
267
|
+
raise TjRuntimeError, $!
|
268
|
+
end
|
269
|
+
|
270
|
+
error('cannot_update_daemon_state',
|
271
|
+
"Can't update state with daemon: #{$!}")
|
255
272
|
end
|
256
273
|
@stateLock.synchronize do
|
257
274
|
@state = state
|
@@ -265,6 +282,9 @@ class TaskJuggler
|
|
265
282
|
Thread.new do
|
266
283
|
begin
|
267
284
|
loop do
|
285
|
+
# Exit this thread if the @terminate flag is set.
|
286
|
+
break if @terminate
|
287
|
+
|
268
288
|
# Was the project data provided during object creation?
|
269
289
|
# Then we load the data here.
|
270
290
|
if @projectData
|
@@ -280,7 +300,7 @@ class TaskJuggler
|
|
280
300
|
@stateLock.synchronize { @modifiedCheck = TjTime.new }
|
281
301
|
|
282
302
|
if @tj.project.inputFiles.modified?
|
283
|
-
|
303
|
+
debug('', "Project #{@tj.projectId} has been modified")
|
284
304
|
updateState(:ready, @tj.projectId, true)
|
285
305
|
end
|
286
306
|
end
|
@@ -288,17 +308,17 @@ class TaskJuggler
|
|
288
308
|
# Check for pending requests for new ReportServers.
|
289
309
|
unless @reportServerRequests.empty?
|
290
310
|
tag = @reportServerRequests.pop
|
291
|
-
|
311
|
+
debug('', "Popped #{tag}")
|
292
312
|
# Create an new entry for the @reportServers list.
|
293
313
|
rsr = ReportServerRecord.new(tag)
|
294
|
-
|
314
|
+
debug('', "RSR created")
|
295
315
|
# Create a new ReportServer object that runs as a separate
|
296
316
|
# process. The constructor will tell us the URI and authentication
|
297
317
|
# key of the new ReportServer.
|
298
318
|
rs = ReportServer.new(@tj, @logConsole)
|
299
319
|
rsr.uri = rs.uri
|
300
320
|
rsr.authKey = rs.authKey
|
301
|
-
|
321
|
+
debug('', "Adding ReportServer with URI #{rsr.uri} to list")
|
302
322
|
# Add the new ReportServer to our list.
|
303
323
|
@reportServers.synchronize do
|
304
324
|
@reportServers << rsr
|
@@ -309,25 +329,31 @@ class TaskJuggler
|
|
309
329
|
# can die during the transaction, the server might hang in some
|
310
330
|
# states. Here we define timeout for each state. If the timeout is
|
311
331
|
# not 0 and exceeded, we immediately terminate the process.
|
312
|
-
timeouts = { :new =>
|
332
|
+
timeouts = { :new => 30, :loading => 15 * 60, :failed => 60,
|
313
333
|
:ready => 0 }
|
314
334
|
if timeouts[@state] > 0 &&
|
315
335
|
TjTime.new - @stateUpdated > timeouts[@state]
|
316
|
-
|
336
|
+
error('state_timeout',
|
337
|
+
"Reached timeout for state #{@state}. Terminating.")
|
317
338
|
end
|
318
339
|
|
319
340
|
# If we have not received a ping from the ProjectBroker for 2
|
320
341
|
# minutes, we assume it has died and terminate as well.
|
321
342
|
if TjTime.new - @lastPing > 180
|
322
|
-
|
343
|
+
error('daemon_heartbeat_lost',
|
344
|
+
'Heartbeat from daemon lost. Terminating.')
|
323
345
|
end
|
324
346
|
sleep 1
|
325
347
|
end
|
326
|
-
rescue
|
348
|
+
rescue => exception
|
349
|
+
# TjRuntimeError exceptions are simply passed through.
|
350
|
+
if exception.is_a?(TjRuntimeError)
|
351
|
+
raise TjRuntimeError, $!
|
352
|
+
end
|
353
|
+
|
327
354
|
# Make sure we get a backtrace for this thread.
|
328
|
-
|
329
|
-
|
330
|
-
@log.fatal("ProjectServer housekeeping error: #{$!}")
|
355
|
+
fatal('ps_housekeeping_error',
|
356
|
+
"ProjectServer housekeeping error: #{$!}")
|
331
357
|
end
|
332
358
|
end
|
333
359
|
end
|
@@ -381,6 +407,8 @@ class TaskJuggler
|
|
381
407
|
# the ProjectServer.
|
382
408
|
class ReportServerRecord
|
383
409
|
|
410
|
+
include MessageHandler
|
411
|
+
|
384
412
|
attr_reader :tag
|
385
413
|
attr_accessor :uri, :authKey
|
386
414
|
|
@@ -393,7 +421,6 @@ class TaskJuggler
|
|
393
421
|
@authKey = nil
|
394
422
|
# The DRbObject of the ReportServer.
|
395
423
|
@reportServer = nil
|
396
|
-
@log = LogFile.instance
|
397
424
|
end
|
398
425
|
|
399
426
|
# Send a ping to the ReportServer process to check that it is still
|
@@ -402,14 +429,19 @@ class TaskJuggler
|
|
402
429
|
def ping
|
403
430
|
return true unless @uri
|
404
431
|
|
405
|
-
|
432
|
+
debug('', "Sending ping to ReportServer #{@uri}")
|
406
433
|
begin
|
407
434
|
@reportServer = DRbObject.new(nil, @uri) unless @reportServer
|
408
435
|
@reportServer.ping(@authKey)
|
409
|
-
rescue
|
436
|
+
rescue => exception
|
437
|
+
# TjRuntimeError exceptions are simply passed through.
|
438
|
+
if exception.is_a?(TjRuntimeError)
|
439
|
+
raise TjRuntimeError, $!
|
440
|
+
end
|
441
|
+
|
410
442
|
# ReportServer processes terminate on request of their clients. Not
|
411
443
|
# responding to a ping is a normal event.
|
412
|
-
|
444
|
+
debug('', "ReportServer (#{@uri}) has terminated")
|
413
445
|
return false
|
414
446
|
end
|
415
447
|
true
|
@@ -43,7 +43,7 @@ class TaskJuggler
|
|
43
43
|
rd, wr = IO.pipe
|
44
44
|
|
45
45
|
if (@pid = fork) == -1
|
46
|
-
|
46
|
+
fatal('rs_fork_failed', 'ReportServer fork failed')
|
47
47
|
elsif @pid.nil?
|
48
48
|
if logConsole
|
49
49
|
# If the Broker wasn't daemonized, log stdout and stderr to PID
|
@@ -56,13 +56,13 @@ class TaskJuggler
|
|
56
56
|
$SAFE = 1
|
57
57
|
DRb.install_acl(ACL.new(%w[ deny all
|
58
58
|
allow 127.0.0.1 ]))
|
59
|
-
DRb.start_service
|
60
59
|
iFace = ReportServerIface.new(self)
|
61
60
|
begin
|
62
61
|
uri = DRb.start_service('druby://127.0.0.1:0', iFace).uri
|
63
|
-
|
62
|
+
debug('', "Report server is listening on #{uri}")
|
64
63
|
rescue
|
65
|
-
|
64
|
+
error('rs_cannot_start_drb',
|
65
|
+
"ReportServer can't start DRb: #{$!}")
|
66
66
|
end
|
67
67
|
|
68
68
|
# Send the URI of the newly started DRb server to the parent process.
|
@@ -77,12 +77,16 @@ class TaskJuggler
|
|
77
77
|
|
78
78
|
# Cleanup the DRb threads
|
79
79
|
DRb.thread.join
|
80
|
-
|
80
|
+
debug('', 'Report server terminated')
|
81
81
|
exit 0
|
82
|
-
rescue
|
83
|
-
|
84
|
-
|
85
|
-
|
82
|
+
rescue => exception
|
83
|
+
# TjRuntimeError exceptions are simply passed through.
|
84
|
+
if exception.is_a?(TjRuntimeError)
|
85
|
+
raise TjRuntimeError, $!
|
86
|
+
end
|
87
|
+
|
88
|
+
error('rs_unexp_excp',
|
89
|
+
"ReportServer caught unexpected exception: #{$!}")
|
86
90
|
end
|
87
91
|
else
|
88
92
|
Process.detach(@pid)
|
@@ -100,7 +104,7 @@ class TaskJuggler
|
|
100
104
|
def addFile(file)
|
101
105
|
begin
|
102
106
|
@tj.parseFile(file, :reportPropertiesFile)
|
103
|
-
rescue
|
107
|
+
rescue TjRuntimeError
|
104
108
|
return false
|
105
109
|
end
|
106
110
|
restartTimer
|
@@ -108,40 +112,58 @@ class TaskJuggler
|
|
108
112
|
end
|
109
113
|
|
110
114
|
def generateReport(id, regExpMode, formats, dynamicAttributes)
|
111
|
-
|
115
|
+
info('generating_report', "Generating report #{id}")
|
112
116
|
startTime = Time.now
|
113
|
-
|
114
|
-
@
|
115
|
-
|
116
|
-
|
117
|
+
begin
|
118
|
+
if (ok = @tj.generateReport(id, regExpMode, formats, dynamicAttributes))
|
119
|
+
info('report_id_generated',
|
120
|
+
"Report #{id} generated in #{Time.now - startTime} seconds")
|
121
|
+
else
|
122
|
+
error('report_generation_failed', "Report generation of #{id} failed")
|
123
|
+
end
|
124
|
+
rescue TjRuntimeError
|
125
|
+
return false
|
117
126
|
end
|
118
127
|
restartTimer
|
119
128
|
ok
|
120
129
|
end
|
121
130
|
|
122
131
|
def listReports(id, regExpMode)
|
123
|
-
|
124
|
-
|
125
|
-
@
|
126
|
-
|
127
|
-
|
132
|
+
info('listing_report_id', "Listing report #{id}")
|
133
|
+
begin
|
134
|
+
if (ok = @tj.listReports(id, regExpMode))
|
135
|
+
debug('', "Report list for #{id} generated")
|
136
|
+
else
|
137
|
+
error('repor_list_comp_failed',
|
138
|
+
"Report list compilation of #{id} failed")
|
139
|
+
end
|
140
|
+
rescue TjRuntimeError
|
141
|
+
return false
|
128
142
|
end
|
129
143
|
restartTimer
|
130
144
|
ok
|
131
145
|
end
|
132
146
|
|
133
147
|
def checkTimeSheet(sheet)
|
134
|
-
|
135
|
-
|
136
|
-
|
148
|
+
info('check_time_sheet', "Checking time sheet #{sheet}")
|
149
|
+
begin
|
150
|
+
ok = @tj.checkTimeSheet(sheet)
|
151
|
+
debug('', "Time sheet #{sheet} is #{ok ? '' : 'not '}ok")
|
152
|
+
rescue TjRuntimeError
|
153
|
+
return false
|
154
|
+
end
|
137
155
|
restartTimer
|
138
156
|
ok
|
139
157
|
end
|
140
158
|
|
141
159
|
def checkStatusSheet(sheet)
|
142
|
-
|
143
|
-
|
144
|
-
|
160
|
+
info('check_status_sheet', "Checking status sheet #{sheet}")
|
161
|
+
begin
|
162
|
+
ok = @tj.checkStatusSheet(sheet)
|
163
|
+
debug('', "Status sheet #{sheet} is #{ok ? '' : 'not '}ok")
|
164
|
+
rescue TjRuntimeError
|
165
|
+
return false
|
166
|
+
end
|
145
167
|
restartTimer
|
146
168
|
ok
|
147
169
|
end
|
@@ -152,7 +174,8 @@ class TaskJuggler
|
|
152
174
|
Thread.new do
|
153
175
|
loop do
|
154
176
|
if TjTime.new - @lastPing > 120
|
155
|
-
|
177
|
+
error('ps_heartbeat_lost',
|
178
|
+
'Heartbeat from ProjectServer lost. Terminating.')
|
156
179
|
end
|
157
180
|
sleep 30
|
158
181
|
end
|
@@ -181,7 +204,8 @@ class TaskJuggler
|
|
181
204
|
trap { @server.addFile(file) }
|
182
205
|
end
|
183
206
|
|
184
|
-
def generateReport(authKey, reportId, regExpMode, formats,
|
207
|
+
def generateReport(authKey, reportId, regExpMode, formats,
|
208
|
+
dynamicAttributes)
|
185
209
|
return false unless @server.checkKey(authKey, 'generateReport')
|
186
210
|
|
187
211
|
trap do
|
@@ -12,29 +12,43 @@
|
|
12
12
|
#
|
13
13
|
|
14
14
|
require 'webrick'
|
15
|
+
require 'taskjuggler/MessageHandler'
|
16
|
+
require 'taskjuggler/RichText'
|
17
|
+
require 'taskjuggler/HTMLDocument'
|
18
|
+
require 'taskjuggler/daemon/DaemonConnector'
|
15
19
|
|
16
20
|
class TaskJuggler
|
17
21
|
|
18
22
|
class ReportServlet < WEBrick::HTTPServlet::AbstractServlet
|
19
23
|
|
20
|
-
def initialize(config,
|
24
|
+
def initialize(config, options)
|
21
25
|
super
|
22
|
-
@
|
26
|
+
@authKey = options[0]
|
27
|
+
@host = options[1]
|
28
|
+
@port = options[2]
|
29
|
+
@uri = options[3]
|
23
30
|
end
|
24
31
|
|
25
32
|
def self.get_instance(config, options)
|
26
|
-
self.new(config,
|
33
|
+
self.new(config, options)
|
27
34
|
end
|
28
35
|
|
29
36
|
def do_GET(req, res)
|
37
|
+
debug('', "Serving URL #{req}")
|
30
38
|
@req = req
|
31
39
|
@res = res
|
32
40
|
begin
|
33
|
-
|
34
|
-
|
35
|
-
|
41
|
+
# WEBrick is returning the query elements as FormData objects. We must
|
42
|
+
# use to_s to explicitely convert them to String objects.
|
43
|
+
projectId = req.query['project'].to_s
|
44
|
+
debug('', "Project ID: #{projectId}")
|
45
|
+
reportId = req.query['report'].to_s
|
46
|
+
debug('', "Report ID: #{reportId}")
|
47
|
+
if projectId.empty? || reportId.empty?
|
48
|
+
debug('', "Project welcome page requested")
|
36
49
|
generateWelcomePage(projectId)
|
37
50
|
else
|
51
|
+
debug('', "Report #{reportId} of project #{projectId} requested")
|
38
52
|
attributes = req.query['attributes'] || ''
|
39
53
|
attributes = URLParameter.decode(attributes) unless attributes.empty?
|
40
54
|
generateReport(projectId, reportId, attributes)
|
@@ -45,11 +59,32 @@ class TaskJuggler
|
|
45
59
|
|
46
60
|
private
|
47
61
|
|
62
|
+
def connectToBroker
|
63
|
+
begin
|
64
|
+
broker = DaemonConnector.new(@authKey, @host, @port, @uri)
|
65
|
+
rescue
|
66
|
+
error('cannot_connect_broker',
|
67
|
+
"Cannot connect to the TaskJuggler daemon: #{$!}\n" +
|
68
|
+
"Please make sure you have tj3d running and listening " +
|
69
|
+
"on port #{@port} or URI '#{@uri}'.")
|
70
|
+
end
|
71
|
+
|
72
|
+
broker
|
73
|
+
end
|
74
|
+
|
48
75
|
def generateReport(projectId, reportId, attributes)
|
76
|
+
broker = connectToBroker
|
77
|
+
|
49
78
|
# Request the Project credentials from the ProbjectBroker.
|
50
|
-
|
79
|
+
begin
|
80
|
+
@ps_uri, @ps_authKey = broker.getProject(projectId)
|
81
|
+
rescue
|
82
|
+
error('cannot_get_project_server',
|
83
|
+
"Cannot get project server for ID #{projectId}: #{$!}")
|
84
|
+
end
|
85
|
+
|
51
86
|
if @ps_uri.nil?
|
52
|
-
error("No project with ID #{projectId} loaded")
|
87
|
+
error('ps_uri_nil', "No project with ID #{projectId} loaded")
|
53
88
|
end
|
54
89
|
# Get the responsible ReportServer that can generate the report.
|
55
90
|
begin
|
@@ -57,7 +92,8 @@ class TaskJuggler
|
|
57
92
|
@rs_uri, @rs_authKey = @projectServer.getReportServer(@ps_authKey)
|
58
93
|
@reportServer = DRbObject.new(nil, @rs_uri)
|
59
94
|
rescue
|
60
|
-
error(
|
95
|
+
error('cannot_get_report_server',
|
96
|
+
"Cannot get report server: #{$!}")
|
61
97
|
end
|
62
98
|
# Create two StringIO buffers that will receive the $stdout and $stderr
|
63
99
|
# text from the report server. This buffer will contain the generated
|
@@ -70,8 +106,13 @@ class TaskJuggler
|
|
70
106
|
|
71
107
|
begin
|
72
108
|
@reportServer.connect(@rs_authKey, stdOut, stdErr, $stdin, true)
|
73
|
-
rescue
|
74
|
-
|
109
|
+
rescue => exception
|
110
|
+
# TjRuntimeError exceptions are simply passed through.
|
111
|
+
if exception.is_a?(TjRuntimeError)
|
112
|
+
raise TjRuntimeError, $!
|
113
|
+
end
|
114
|
+
|
115
|
+
error('rs_io_connect_failed', "Can't connect IO: #{$!}")
|
75
116
|
end
|
76
117
|
|
77
118
|
# Ask the ReportServer to generate the reports with the provided ID.
|
@@ -81,21 +122,24 @@ class TaskJuggler
|
|
81
122
|
rescue
|
82
123
|
stdOut.rewind
|
83
124
|
stdErr.rewind
|
84
|
-
error(
|
125
|
+
error('rs_generate_report_failed',
|
126
|
+
"Report server crashed: #{$!}\n#{stdErr.read}\n#{stdOut.read}")
|
85
127
|
end
|
86
128
|
# Disconnect the ReportServer
|
87
129
|
begin
|
88
130
|
@reportServer.disconnect(@rs_authKey)
|
89
131
|
rescue
|
90
|
-
error("Can't disconnect IO: #{$!}")
|
132
|
+
error('rs_io_disconnect_failed', "Can't disconnect IO: #{$!}")
|
91
133
|
end
|
92
134
|
# And send a termination request.
|
93
135
|
begin
|
94
136
|
@reportServer.terminate(@rs_authKey)
|
95
137
|
rescue
|
96
|
-
error(
|
138
|
+
error('report_server_term_failed',
|
139
|
+
"Report server termination failed: #{$!}")
|
97
140
|
end
|
98
141
|
@reportServer = nil
|
142
|
+
broker.disconnect
|
99
143
|
|
100
144
|
@res['content-type'] = 'text/html'
|
101
145
|
stdErr.rewind
|
@@ -107,7 +151,14 @@ class TaskJuggler
|
|
107
151
|
end
|
108
152
|
|
109
153
|
def generateWelcomePage(projectId)
|
110
|
-
|
154
|
+
broker = connectToBroker
|
155
|
+
|
156
|
+
begin
|
157
|
+
projects = broker.getProjectList
|
158
|
+
rescue
|
159
|
+
error('cannot_get_project_list',
|
160
|
+
"Cannot get project list from daemon: #{$!}")
|
161
|
+
end
|
111
162
|
|
112
163
|
text = "== Welcome to the TaskJuggler Project Server ==\n----\n"
|
113
164
|
projects.each do |id|
|
@@ -128,6 +179,10 @@ class TaskJuggler
|
|
128
179
|
text << "* [/taskjuggler?project=#{id} #{getProjectName(id)}]\n"
|
129
180
|
end
|
130
181
|
end
|
182
|
+
|
183
|
+
# We no longer need the broker.
|
184
|
+
broker.disconnect
|
185
|
+
|
131
186
|
rt = RichText.new(text)
|
132
187
|
rti = rt.generateIntermediateFormat
|
133
188
|
rti.sectionNumbers = false
|
@@ -139,26 +194,42 @@ class TaskJuggler
|
|
139
194
|
end
|
140
195
|
|
141
196
|
def getProjectName(id)
|
142
|
-
|
197
|
+
broker = connectToBroker
|
198
|
+
|
199
|
+
uri, authKey = broker.getProject(id)
|
143
200
|
return nil unless uri
|
144
201
|
projectServer = DRbObject.new(nil, uri)
|
145
202
|
return nil unless projectServer
|
146
|
-
projectServer.getProjectName(authKey)
|
203
|
+
res = projectServer.getProjectName(authKey)
|
204
|
+
|
205
|
+
broker.disconnect
|
206
|
+
|
207
|
+
res
|
147
208
|
end
|
148
209
|
|
149
210
|
def getReportList(id)
|
150
|
-
|
211
|
+
broker = connectToBroker
|
212
|
+
|
213
|
+
uri, authKey = broker.getProject(id)
|
151
214
|
return [] unless uri
|
152
215
|
projectServer = DRbObject.new(nil, uri)
|
153
216
|
return [] unless projectServer
|
154
|
-
projectServer.getReportList(authKey)
|
217
|
+
res = projectServer.getReportList(authKey)
|
218
|
+
|
219
|
+
broker.disconnect
|
220
|
+
|
221
|
+
res
|
155
222
|
end
|
156
223
|
|
157
|
-
def error(message)
|
224
|
+
def error(id, message)
|
158
225
|
@res.status = 412
|
159
226
|
@res.body = "ERROR: #{message}"
|
160
227
|
@res['content-type'] = 'text/plain'
|
161
|
-
|
228
|
+
MessageHandlerInstance.instance.error(id, message)
|
229
|
+
end
|
230
|
+
|
231
|
+
def debug(id, message)
|
232
|
+
MessageHandlerInstance.instance.debug(id, message)
|
162
233
|
end
|
163
234
|
|
164
235
|
end
|