taskjuggler 3.1.0 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (410) hide show
  1. data/CHANGELOG +44 -0
  2. data/bin/tj3webd +4 -0
  3. data/data/css/tjreport.css +14 -5
  4. data/data/tjp.vim +22 -7
  5. data/examples/Fedora-20/reports.tji +2 -4
  6. data/examples/Scrum/Product Burndown.csv +26 -0
  7. data/examples/Scrum/Sprint 1 Burndown.csv +26 -0
  8. data/examples/Scrum/Sprint 2 Burndown.csv +26 -0
  9. data/examples/Scrum/Sprint 3 Burndown.csv +26 -0
  10. data/examples/Scrum/scrum.tjp +141 -0
  11. data/examples/Tutorial/tutorial.tjp +13 -7
  12. data/lib/taskjuggler/Attributes.rb +2 -3
  13. data/lib/taskjuggler/HTMLDocument.rb +25 -18
  14. data/lib/taskjuggler/Journal.rb +85 -65
  15. data/lib/taskjuggler/KeywordDocumentation.rb +25 -13
  16. data/lib/taskjuggler/LeaveList.rb +1 -1
  17. data/lib/taskjuggler/Limits.rb +3 -5
  18. data/lib/taskjuggler/MessageHandler.rb +173 -19
  19. data/lib/taskjuggler/Painter.rb +75 -0
  20. data/lib/taskjuggler/Painter/BasicShapes.rb +76 -0
  21. data/lib/taskjuggler/Painter/Color.rb +273 -0
  22. data/lib/taskjuggler/Painter/Element.rb +56 -0
  23. data/lib/taskjuggler/Painter/FontData.rb +221 -0
  24. data/lib/taskjuggler/Painter/FontMetrics.rb +125 -0
  25. data/lib/taskjuggler/Painter/FontMetricsData.rb +151 -0
  26. data/lib/taskjuggler/Painter/Group.rb +77 -0
  27. data/lib/taskjuggler/Painter/Points.rb +47 -0
  28. data/lib/taskjuggler/Painter/Primitives.rb +100 -0
  29. data/lib/taskjuggler/Painter/SVGSupport.rb +36 -0
  30. data/lib/taskjuggler/Painter/Text.rb +36 -0
  31. data/lib/taskjuggler/Project.rb +46 -29
  32. data/lib/taskjuggler/ProjectFileParser.rb +24 -22
  33. data/lib/taskjuggler/ProjectFileScanner.rb +2 -2
  34. data/lib/taskjuggler/PropertyTreeNode.rb +26 -34
  35. data/lib/taskjuggler/Query.rb +8 -5
  36. data/lib/taskjuggler/RealFormat.rb +3 -0
  37. data/lib/taskjuggler/Resource.rb +3 -5
  38. data/lib/taskjuggler/ResourceScenario.rb +19 -7
  39. data/lib/taskjuggler/RichText.rb +4 -6
  40. data/lib/taskjuggler/RichText/FunctionExample.rb +1 -1
  41. data/lib/taskjuggler/RichText/FunctionHandler.rb +5 -6
  42. data/lib/taskjuggler/RichText/Parser.rb +4 -6
  43. data/lib/taskjuggler/RichText/RTFNavigator.rb +1 -1
  44. data/lib/taskjuggler/RichText/RTFQuery.rb +2 -3
  45. data/lib/taskjuggler/RichText/RTFReport.rb +1 -1
  46. data/lib/taskjuggler/RichText/RTFReportLink.rb +1 -2
  47. data/lib/taskjuggler/RichText/RTFWithQuerySupport.rb +1 -1
  48. data/lib/taskjuggler/RichText/Scanner.rb +6 -6
  49. data/lib/taskjuggler/RichText/Snip.rb +1 -2
  50. data/lib/taskjuggler/RuntimeConfig.rb +9 -6
  51. data/lib/taskjuggler/ScenarioData.rb +4 -3
  52. data/lib/taskjuggler/Scoreboard.rb +6 -0
  53. data/lib/taskjuggler/SheetHandlerBase.rb +25 -8
  54. data/lib/taskjuggler/SimpleQueryExpander.rb +14 -5
  55. data/lib/taskjuggler/SyntaxReference.rb +1 -2
  56. data/lib/taskjuggler/TableColumnSorter.rb +84 -0
  57. data/lib/taskjuggler/Task.rb +3 -5
  58. data/lib/taskjuggler/TaskJuggler.rb +36 -29
  59. data/lib/taskjuggler/TaskScenario.rb +154 -66
  60. data/lib/taskjuggler/TextParser.rb +24 -17
  61. data/lib/taskjuggler/TextParser/Scanner.rb +16 -11
  62. data/lib/taskjuggler/TextParser/SourceFileInfo.rb +20 -15
  63. data/lib/taskjuggler/TimeSheets.rb +6 -12
  64. data/lib/taskjuggler/Tj3AppBase.rb +35 -16
  65. data/lib/taskjuggler/Tj3Config.rb +1 -1
  66. data/lib/taskjuggler/TjpSyntaxRules.rb +239 -49
  67. data/lib/taskjuggler/XMLElement.rb +9 -2
  68. data/lib/taskjuggler/apps/Tj3.rb +43 -37
  69. data/lib/taskjuggler/apps/Tj3Client.rb +62 -112
  70. data/lib/taskjuggler/apps/Tj3Daemon.rb +66 -29
  71. data/lib/taskjuggler/apps/Tj3Man.rb +5 -5
  72. data/lib/taskjuggler/apps/Tj3SsReceiver.rb +10 -13
  73. data/lib/taskjuggler/apps/Tj3SsSender.rb +13 -16
  74. data/lib/taskjuggler/apps/Tj3TsReceiver.rb +10 -13
  75. data/lib/taskjuggler/apps/Tj3TsSender.rb +12 -15
  76. data/lib/taskjuggler/apps/Tj3TsSummary.rb +12 -15
  77. data/lib/taskjuggler/apps/Tj3WebD.rb +99 -0
  78. data/lib/taskjuggler/daemon/Daemon.rb +50 -10
  79. data/lib/taskjuggler/daemon/DaemonConnector.rb +127 -0
  80. data/lib/taskjuggler/daemon/ProcessIntercom.rb +36 -21
  81. data/lib/taskjuggler/daemon/ProjectBroker.rb +122 -112
  82. data/lib/taskjuggler/daemon/ProjectServer.rb +78 -46
  83. data/lib/taskjuggler/daemon/ReportServer.rb +52 -28
  84. data/lib/taskjuggler/daemon/ReportServlet.rb +92 -21
  85. data/lib/taskjuggler/daemon/WebServer.rb +75 -22
  86. data/lib/taskjuggler/daemon/WelcomePage.rb +1 -0
  87. data/lib/taskjuggler/reports/AccountListRE.rb +3 -3
  88. data/lib/taskjuggler/reports/CSVFile.rb +9 -2
  89. data/lib/taskjuggler/reports/ChartPlotter.rb +453 -0
  90. data/lib/taskjuggler/reports/Navigator.rb +1 -0
  91. data/lib/taskjuggler/reports/NikuReport.rb +4 -4
  92. data/lib/taskjuggler/reports/Report.rb +6 -18
  93. data/lib/taskjuggler/reports/ReportBase.rb +9 -9
  94. data/lib/taskjuggler/reports/ReportContext.rb +2 -2
  95. data/lib/taskjuggler/reports/StatusSheetReport.rb +6 -6
  96. data/lib/taskjuggler/reports/TableReport.rb +24 -15
  97. data/lib/taskjuggler/reports/TimeSheetReport.rb +5 -5
  98. data/lib/taskjuggler/reports/TraceReport.rb +251 -0
  99. data/lib/tj3webd.rb +17 -0
  100. data/manual/Day_To_Day_Juggling +10 -3
  101. data/manual/Installation +38 -19
  102. data/manual/Software +25 -19
  103. data/manual/Tutorial +119 -110
  104. data/manual/html/Day_To_Day_Juggling.html +7 -5
  105. data/manual/html/Getting_Started.html +4 -4
  106. data/manual/html/How_To_Contribute.html +4 -4
  107. data/manual/html/Installation.html +19 -11
  108. data/manual/html/Intro.html +4 -4
  109. data/manual/html/Reporting_Bugs.html +4 -4
  110. data/manual/html/Rich_Text_Attributes.html +4 -4
  111. data/manual/html/Software.html +15 -11
  112. data/manual/html/TaskJuggler_2x_Migration.html +4 -4
  113. data/manual/html/TaskJuggler_Internals.html +4 -4
  114. data/manual/html/The_TaskJuggler_Syntax.html +4 -4
  115. data/manual/html/Tutorial.html +41 -32
  116. data/manual/html/account.html +4 -4
  117. data/manual/html/account.task.html +4 -4
  118. data/manual/html/accountprefix.html +4 -4
  119. data/manual/html/accountreport.html +27 -9
  120. data/manual/html/accountroot.html +5 -5
  121. data/manual/html/active.html +4 -4
  122. data/manual/html/adopt.task.html +4 -4
  123. data/manual/html/aggregate.html +4 -4
  124. data/manual/html/alert.html +4 -4
  125. data/manual/html/alertlevels.html +4 -4
  126. data/manual/html/allocate.html +5 -5
  127. data/manual/html/alphabet.html +4 -4
  128. data/manual/html/alternative.html +4 -4
  129. data/manual/html/author.html +4 -4
  130. data/manual/html/balance.html +5 -5
  131. data/manual/html/booking.resource.html +4 -4
  132. data/manual/html/booking.task.html +4 -4
  133. data/manual/html/caption.html +5 -5
  134. data/manual/html/cellcolor.column.html +43 -8
  135. data/manual/html/celltext.column.html +4 -4
  136. data/manual/html/center.html +5 -5
  137. data/manual/html/charge.html +4 -4
  138. data/manual/html/chargeset.html +4 -4
  139. data/manual/html/columnid.html +27 -15
  140. data/manual/html/columns.html +5 -5
  141. data/manual/html/complete.html +4 -4
  142. data/manual/html/copyright.html +4 -4
  143. data/manual/html/credits.html +4 -4
  144. data/manual/html/css/tjreport.css +14 -5
  145. data/manual/html/currency.html +4 -4
  146. data/manual/html/currencyformat.html +5 -5
  147. data/manual/html/dailymax.html +5 -5
  148. data/manual/html/dailymin.html +5 -5
  149. data/manual/html/dailyworkinghours.html +4 -4
  150. data/manual/html/date.extend.html +4 -4
  151. data/manual/html/date.html +5 -5
  152. data/manual/html/definitions.html +4 -4
  153. data/manual/html/depends.html +4 -4
  154. data/manual/html/details.html +4 -4
  155. data/manual/html/disabled.html +4 -4
  156. data/manual/html/duration.html +4 -4
  157. data/manual/html/efficiency.html +4 -4
  158. data/manual/html/effort.html +4 -4
  159. data/manual/html/email.html +4 -4
  160. data/manual/html/enabled.html +4 -4
  161. data/manual/html/end.column.html +4 -4
  162. data/manual/html/end.html +4 -4
  163. data/manual/html/end.limit.html +4 -4
  164. data/manual/html/end.report.html +5 -5
  165. data/manual/html/end.timesheet.html +4 -4
  166. data/manual/html/endcredit.html +4 -4
  167. data/manual/html/epilog.html +5 -5
  168. data/manual/html/export.html +4 -4
  169. data/manual/html/extend.html +4 -4
  170. data/manual/html/fail.html +43 -8
  171. data/manual/html/fdl.html +4 -4
  172. data/manual/html/flags.account.html +4 -4
  173. data/manual/html/flags.html +4 -4
  174. data/manual/html/flags.journalentry.html +4 -4
  175. data/manual/html/flags.report.html +5 -5
  176. data/manual/html/flags.resource.html +4 -4
  177. data/manual/html/flags.statussheet.html +4 -4
  178. data/manual/html/flags.task.html +4 -4
  179. data/manual/html/flags.timesheet.html +4 -4
  180. data/manual/html/fontcolor.column.html +43 -8
  181. data/manual/html/footer.html +5 -5
  182. data/manual/html/formats.html +5 -5
  183. data/manual/html/functions.html +4 -4
  184. data/manual/html/gapduration.html +4 -4
  185. data/manual/html/gaplength.html +4 -4
  186. data/manual/html/halign.center.html +4 -4
  187. data/manual/html/halign.column.html +43 -8
  188. data/manual/html/halign.left.html +4 -4
  189. data/manual/html/halign.right.html +4 -4
  190. data/manual/html/hasalert.html +4 -4
  191. data/manual/html/header.html +5 -5
  192. data/manual/html/headline.html +7 -7
  193. data/manual/html/height.html +72 -0
  194. data/manual/html/hideaccount.html +46 -11
  195. data/manual/html/hidejournalentry.html +5 -5
  196. data/manual/html/hidereport.html +43 -8
  197. data/manual/html/hideresource.html +44 -9
  198. data/manual/html/hidetask.html +44 -9
  199. data/manual/html/icalreport.html +4 -4
  200. data/manual/html/include.macro.html +4 -4
  201. data/manual/html/include.project.html +4 -4
  202. data/manual/html/include.properties.html +4 -4
  203. data/manual/html/index.html +2 -1
  204. data/manual/html/inherit.extend.html +4 -4
  205. data/manual/html/interval1.html +4 -4
  206. data/manual/html/interval2.html +4 -4
  207. data/manual/html/interval3.html +4 -4
  208. data/manual/html/interval4.html +4 -4
  209. data/manual/html/isactive.html +4 -4
  210. data/manual/html/ischildof.html +4 -4
  211. data/manual/html/isdependencyof.html +4 -4
  212. data/manual/html/isdutyof.html +4 -4
  213. data/manual/html/isfeatureof.html +4 -4
  214. data/manual/html/isleaf.html +4 -4
  215. data/manual/html/ismilestone.html +4 -4
  216. data/manual/html/isongoing.html +4 -4
  217. data/manual/html/isresource.html +4 -4
  218. data/manual/html/isresponsibilityof.html +4 -4
  219. data/manual/html/istask.html +4 -4
  220. data/manual/html/journalattributes.html +11 -7
  221. data/manual/html/journalentry.html +4 -4
  222. data/manual/html/journalmode.html +5 -5
  223. data/manual/html/leaveallowance.html +5 -5
  224. data/manual/html/leaves.html +5 -6
  225. data/manual/html/left.html +5 -5
  226. data/manual/html/length.html +4 -4
  227. data/manual/html/limits.allocate.html +4 -4
  228. data/manual/html/limits.html +4 -4
  229. data/manual/html/limits.resource.html +4 -4
  230. data/manual/html/limits.task.html +4 -4
  231. data/manual/html/listitem.column.html +4 -4
  232. data/manual/html/listtype.column.html +4 -4
  233. data/manual/html/loadunit.html +5 -5
  234. data/manual/html/logicalexpression.html +8 -44
  235. data/manual/html/logicalflagexpression.html +4 -4
  236. data/manual/html/macro.html +4 -4
  237. data/manual/html/managers.html +4 -4
  238. data/manual/html/mandatory.html +4 -4
  239. data/manual/html/maxend.html +4 -4
  240. data/manual/html/maximum.html +5 -5
  241. data/manual/html/maxstart.html +4 -4
  242. data/manual/html/milestone.html +4 -4
  243. data/manual/html/minend.html +4 -4
  244. data/manual/html/minimum.html +5 -5
  245. data/manual/html/minstart.html +4 -4
  246. data/manual/html/monthlymax.html +5 -5
  247. data/manual/html/monthlymin.html +5 -5
  248. data/manual/html/navbar.html +10 -4
  249. data/manual/html/navigator.html +4 -4
  250. data/manual/html/newtask.html +4 -4
  251. data/manual/html/nikureport.html +4 -4
  252. data/manual/html/note.task.html +4 -4
  253. data/manual/html/now.html +4 -4
  254. data/manual/html/numberformat.html +5 -5
  255. data/manual/html/onend.html +4 -4
  256. data/manual/html/onstart.html +4 -4
  257. data/manual/html/opennodes.html +5 -5
  258. data/manual/html/overtime.booking.html +4 -4
  259. data/manual/html/period.column.html +4 -4
  260. data/manual/html/period.limit.html +4 -4
  261. data/manual/html/period.report.html +5 -5
  262. data/manual/html/period.task.html +4 -4
  263. data/manual/html/persistent.html +4 -4
  264. data/manual/html/precedes.html +4 -4
  265. data/manual/html/priority.html +4 -4
  266. data/manual/html/priority.timesheet.html +4 -4
  267. data/manual/html/project.html +4 -4
  268. data/manual/html/projectid.html +4 -4
  269. data/manual/html/projectid.task.html +4 -4
  270. data/manual/html/projectids.html +4 -4
  271. data/manual/html/projection.html +5 -7
  272. data/manual/html/prolog.html +5 -5
  273. data/manual/html/properties.html +11 -5
  274. data/manual/html/purge.html +5 -5
  275. data/manual/html/rate.html +4 -4
  276. data/manual/html/rate.resource.html +4 -4
  277. data/manual/html/reference.extend.html +4 -4
  278. data/manual/html/remaining.html +4 -4
  279. data/manual/html/replace.html +4 -4
  280. data/manual/html/reportprefix.html +4 -4
  281. data/manual/html/resource.html +4 -10
  282. data/manual/html/resourceattributes.html +4 -4
  283. data/manual/html/resourceprefix.html +4 -4
  284. data/manual/html/resourcereport.html +28 -10
  285. data/manual/html/resourceroot.html +5 -5
  286. data/manual/html/resources.limit.html +4 -4
  287. data/manual/html/responsible.html +4 -4
  288. data/manual/html/richtext.extend.html +4 -4
  289. data/manual/html/right.html +5 -5
  290. data/manual/html/rollupaccount.html +44 -9
  291. data/manual/html/rollupresource.html +44 -9
  292. data/manual/html/rolluptask.html +44 -9
  293. data/manual/html/scale.column.html +4 -4
  294. data/manual/html/scenario.html +4 -22
  295. data/manual/html/scenario.ical.html +4 -4
  296. data/manual/html/scenarios.export.html +4 -4
  297. data/manual/html/scenarios.html +5 -5
  298. data/manual/html/scenariospecific.extend.html +4 -4
  299. data/manual/html/scheduled.html +4 -4
  300. data/manual/html/scheduling.html +4 -4
  301. data/manual/html/select.html +4 -4
  302. data/manual/html/selfcontained.html +5 -5
  303. data/manual/html/shift.allocate.html +4 -4
  304. data/manual/html/shift.html +4 -4
  305. data/manual/html/shift.resource.html +5 -5
  306. data/manual/html/shift.task.html +4 -4
  307. data/manual/html/shift.timesheet.html +4 -4
  308. data/manual/html/shifts.allocate.html +4 -4
  309. data/manual/html/shifts.resource.html +4 -4
  310. data/manual/html/shifts.task.html +4 -4
  311. data/manual/html/shorttimeformat.html +4 -4
  312. data/manual/html/sloppy.booking.html +4 -4
  313. data/manual/html/sloppy.projection.html +5 -5
  314. data/manual/html/sortaccounts.html +5 -5
  315. data/manual/html/sortjournalentries.html +5 -5
  316. data/manual/html/sortresources.html +5 -5
  317. data/manual/html/sorttasks.html +5 -5
  318. data/manual/html/start.column.html +4 -4
  319. data/manual/html/start.html +4 -4
  320. data/manual/html/start.limit.html +4 -4
  321. data/manual/html/start.report.html +5 -5
  322. data/manual/html/startcredit.html +4 -4
  323. data/manual/html/status.statussheet.html +4 -4
  324. data/manual/html/status.timesheet.html +4 -4
  325. data/manual/html/statussheet.html +4 -4
  326. data/manual/html/statussheetreport.html +4 -4
  327. data/manual/html/strict.projection.html +5 -5
  328. data/manual/html/summary.html +4 -4
  329. data/manual/html/supplement.html +4 -4
  330. data/manual/html/supplement.resource.html +4 -10
  331. data/manual/html/supplement.task.html +4 -28
  332. data/manual/html/tagfile.html +4 -4
  333. data/manual/html/task.html +4 -28
  334. data/manual/html/task.statussheet.html +4 -4
  335. data/manual/html/task.timesheet.html +4 -4
  336. data/manual/html/taskattributes.html +4 -4
  337. data/manual/html/taskprefix.html +4 -4
  338. data/manual/html/taskreport.html +28 -10
  339. data/manual/html/taskroot.html +5 -5
  340. data/manual/html/text.extend.html +4 -4
  341. data/manual/html/textreport.html +27 -9
  342. data/manual/html/timeformat.html +5 -5
  343. data/manual/html/timeoff.nikureport.html +4 -4
  344. data/manual/html/timesheet.html +4 -4
  345. data/manual/html/timesheetreport.html +23 -5
  346. data/manual/html/timezone.export.html +4 -4
  347. data/manual/html/timezone.html +4 -4
  348. data/manual/html/timezone.report.html +5 -5
  349. data/manual/html/timezone.shift.html +4 -4
  350. data/manual/html/timingresolution.html +4 -4
  351. data/manual/html/title.column.html +4 -4
  352. data/manual/html/title.html +5 -5
  353. data/manual/html/toc.html +207 -179
  354. data/manual/html/tooltip.column.html +45 -10
  355. data/manual/html/tracereport.html +405 -0
  356. data/manual/html/trackingscenario.html +6 -6
  357. data/manual/html/treelevel.html +4 -4
  358. data/manual/html/vacation.html +4 -4
  359. data/manual/html/vacation.resource.html +4 -4
  360. data/manual/html/vacation.shift.html +4 -4
  361. data/manual/html/warn.html +43 -8
  362. data/manual/html/weeklymax.html +5 -5
  363. data/manual/html/weeklymin.html +5 -5
  364. data/manual/html/weekstartsmonday.html +4 -4
  365. data/manual/html/weekstartssunday.html +6 -6
  366. data/manual/html/width.column.html +6 -6
  367. data/manual/html/width.html +72 -0
  368. data/manual/html/work.html +4 -4
  369. data/manual/html/workinghours.project.html +4 -4
  370. data/manual/html/workinghours.resource.html +4 -4
  371. data/manual/html/workinghours.shift.html +4 -4
  372. data/manual/html/yearlyworkingdays.html +4 -4
  373. data/spec/Color_spec.rb +60 -0
  374. data/spec/ProjectBroker_spec.rb +3 -2
  375. data/spec/StatusSheets_spec.rb +5 -4
  376. data/spec/TableColumnSorter_spec.rb +78 -0
  377. data/spec/TimeSheets_spec.rb +6 -2
  378. data/spec/Tj3Daemon_spec.rb +2 -2
  379. data/spec/TraceReport_spec.rb +117 -0
  380. data/taskjuggler.gemspec +1 -1
  381. data/test/MessageChecker.rb +3 -1
  382. data/test/ReferenceGenerator.rb +1 -1
  383. data/test/TestSuite/CSV-Reports/Leave.tjp +1 -1
  384. data/test/TestSuite/CSV-Reports/refs/resourcereport_with_tasks.csv +3 -0
  385. data/test/TestSuite/CSV-Reports/refs/taskcounter.csv +9 -0
  386. data/test/TestSuite/CSV-Reports/refs/taskreport_with_resources.csv +19 -16
  387. data/test/TestSuite/CSV-Reports/refs/weekly.csv +1 -0
  388. data/test/TestSuite/Export-Reports/refs/LogicalExpression.tjp +14 -2
  389. data/test/TestSuite/Export-Reports/refs/tutorial.tjp +98 -86
  390. data/test/TestSuite/Scheduler/Correct/Leaves.tjp +25 -0
  391. data/test/TestSuite/Syntax/Correct/Leave.tjp +1 -1
  392. data/test/TestSuite/Syntax/Correct/LogicalExpression.tjp +9 -1
  393. data/test/TestSuite/Syntax/Correct/TraceReport.tjp +10 -0
  394. data/test/TestSuite/Syntax/Correct/tutorial.tjp +10 -4
  395. data/test/test_CSV-Reports.rb +3 -3
  396. data/test/test_Export-Reports.rb +91 -86
  397. data/test/test_Journal.rb +15 -12
  398. data/test/test_Limits.rb +3 -3
  399. data/test/test_Project.rb +1 -2
  400. data/test/test_ProjectFileScanner.rb +1 -1
  401. data/test/test_PropertySet.rb +1 -1
  402. data/test/test_Query.rb +5 -6
  403. data/test/test_ReportGenerator.rb +15 -7
  404. data/test/test_RichText.rb +4 -3
  405. data/test/test_Scheduler.rb +19 -7
  406. data/test/test_ShiftAssignments.rb +2 -2
  407. data/test/test_SimpleQueryExpander.rb +29 -2
  408. data/test/test_Syntax.rb +14 -5
  409. metadata +49 -10
  410. data/lib/taskjuggler/LogFile.rb +0 -73
@@ -71,17 +71,17 @@ EOT
71
71
  else
72
72
  requestedKeywords.each do |keyword|
73
73
  if (kws = @keywords[keyword, true]).nil?
74
- $stderr.puts "No matches found for '#{keyword}'"
75
- exit 1
74
+ error('tj3man_no_matches', "No matches found for '#{keyword}'")
76
75
  elsif kws.length == 1 || kws.include?(keyword)
77
76
  showManual(keyword)
78
77
  else
79
- $stderr.puts "Multiple matches found for '#{keyword}':\n" +
80
- "#{kws.join(', ')}"
81
- return 1
78
+ warning('tj3man_multi_match',
79
+ "Multiple matches found for '#{keyword}':\n" +
80
+ "#{kws.join(', ')}")
82
81
  end
83
82
  end
84
83
  end
84
+
85
85
  0
86
86
  end
87
87
 
@@ -38,19 +38,16 @@ EOT
38
38
  end
39
39
 
40
40
  def appMain(argv)
41
- begin
42
- ts = TaskJuggler::StatusSheetReceiver.new('tj3ss_receiver')
43
- @rc.configure(ts, 'global')
44
- @rc.configure(ts, 'statussheets')
45
- @rc.configure(ts, 'statussheets.receiver')
46
- ts.workingDir = @workingDir if @workingDir
47
- ts.dryRun = @dryRun
48
-
49
- ts.processEmail
50
- return 0
51
- rescue TjRuntimeError
52
- return 1
53
- end
41
+ ts = TaskJuggler::StatusSheetReceiver.new('tj3ss_receiver')
42
+ @rc.configure(ts, 'global')
43
+ @rc.configure(ts, 'statussheets')
44
+ @rc.configure(ts, 'statussheets.receiver')
45
+ ts.workingDir = @workingDir if @workingDir
46
+ ts.dryRun = @dryRun
47
+
48
+ ts.processEmail
49
+
50
+ 0
54
51
  end
55
52
 
56
53
  end
@@ -68,23 +68,20 @@ EOT
68
68
  end
69
69
 
70
70
  def appMain(argv)
71
- begin
72
- ts = StatusSheetSender.new('tj3ss_sender')
73
- @rc.configure(ts, 'global')
74
- @rc.configure(ts, 'statussheets')
75
- @rc.configure(ts, 'statussheets.sender')
76
- ts.workingDir = @workingDir if @workingDir
77
- ts.dryRun = @dryRun
78
- ts.force = @force
79
- ts.intervalDuration = @intervalDuration if @intervalDuration
80
- ts.date = @date if @date
81
- ts.hideResource = @hideResource if @hideResource
71
+ ts = StatusSheetSender.new('tj3ss_sender')
72
+ @rc.configure(ts, 'global')
73
+ @rc.configure(ts, 'statussheets')
74
+ @rc.configure(ts, 'statussheets.sender')
75
+ ts.workingDir = @workingDir if @workingDir
76
+ ts.dryRun = @dryRun
77
+ ts.force = @force
78
+ ts.intervalDuration = @intervalDuration if @intervalDuration
79
+ ts.date = @date if @date
80
+ ts.hideResource = @hideResource if @hideResource
82
81
 
83
- ts.sendTemplates(@resourceList)
84
- return 0
85
- rescue TjRuntimeError
86
- return 1
87
- end
82
+ ts.sendTemplates(@resourceList)
83
+
84
+ 0
88
85
  end
89
86
 
90
87
  end
@@ -41,19 +41,16 @@ EOT
41
41
  end
42
42
 
43
43
  def appMain(argv)
44
- begin
45
- ts = TimeSheetReceiver.new('tj3ts_receiver')
46
- @rc.configure(ts, 'global')
47
- @rc.configure(ts, 'timesheets')
48
- @rc.configure(ts, 'timesheets.receiver')
49
- ts.workingDir = @workingDir if @workingDir
50
- ts.dryRun = @dryRun
51
-
52
- ts.processEmail
53
- return 0
54
- rescue TjRuntimeError
55
- return 1
56
- end
44
+ ts = TimeSheetReceiver.new('tj3ts_receiver')
45
+ @rc.configure(ts, 'global')
46
+ @rc.configure(ts, 'timesheets')
47
+ @rc.configure(ts, 'timesheets.receiver')
48
+ ts.workingDir = @workingDir if @workingDir
49
+ ts.dryRun = @dryRun
50
+
51
+ ts.processEmail
52
+
53
+ 0
57
54
  end
58
55
 
59
56
  end
@@ -56,22 +56,19 @@ EOT
56
56
  end
57
57
 
58
58
  def appMain(argv)
59
- begin
60
- ts = TimeSheetSender.new('tj3ts_sender')
61
- @rc.configure(ts, 'global')
62
- @rc.configure(ts, 'timesheets')
63
- @rc.configure(ts, 'timesheets.sender')
64
- ts.workingDir = @workingDir if @workingDir
65
- ts.dryRun = @dryRun
66
- ts.force = @force
67
- ts.intervalDuration = @intervalDuration if @intervalDuration
68
- ts.date = @date if @date
59
+ ts = TimeSheetSender.new('tj3ts_sender')
60
+ @rc.configure(ts, 'global')
61
+ @rc.configure(ts, 'timesheets')
62
+ @rc.configure(ts, 'timesheets.sender')
63
+ ts.workingDir = @workingDir if @workingDir
64
+ ts.dryRun = @dryRun
65
+ ts.force = @force
66
+ ts.intervalDuration = @intervalDuration if @intervalDuration
67
+ ts.date = @date if @date
69
68
 
70
- ts.sendTemplates(@resourceList)
71
- return 0
72
- rescue
73
- return 1
74
- end
69
+ ts.sendTemplates(@resourceList)
70
+
71
+ 0
75
72
  end
76
73
 
77
74
  end
@@ -65,22 +65,19 @@ EOT
65
65
  end
66
66
 
67
67
  def appMain(argv)
68
- begin
69
- ts = TimeSheetSummary.new
70
- @rc.configure(ts, 'global')
71
- @rc.configure(ts, 'timesheets')
72
- @rc.configure(ts, 'timesheets.summary')
73
- ts.workingDir = @workingDir if @workingDir
74
- ts.dryRun = @dryRun
75
- ts.date = @date if @date
76
- ts.sheetRecipients += @sheetRecipients
77
- ts.digestRecipients += @digestRecipients
68
+ ts = TimeSheetSummary.new
69
+ @rc.configure(ts, 'global')
70
+ @rc.configure(ts, 'timesheets')
71
+ @rc.configure(ts, 'timesheets.summary')
72
+ ts.workingDir = @workingDir if @workingDir
73
+ ts.dryRun = @dryRun
74
+ ts.date = @date if @date
75
+ ts.sheetRecipients += @sheetRecipients
76
+ ts.digestRecipients += @digestRecipients
78
77
 
79
- ts.sendSummary(@resourceList)
80
- return 0
81
- rescue TjRuntimeError
82
- return 1
83
- end
78
+ ts.sendSummary(@resourceList)
79
+
80
+ 0
84
81
  end
85
82
 
86
83
  end
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env ruby -w
2
+ # encoding: UTF-8
3
+ #
4
+ # = Tj3Daemon.rb -- The TaskJuggler III Project Management Software
5
+ #
6
+ # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012
7
+ # by Chris Schlaeger <chris@linux.com>
8
+ #
9
+ # This program is free software; you can redistribute it and/or modify
10
+ # it under the terms of version 2 of the GNU General Public License as
11
+ # published by the Free Software Foundation.
12
+ #
13
+
14
+ require 'drb'
15
+ require 'taskjuggler/Tj3AppBase'
16
+ require 'taskjuggler/MessageHandler'
17
+ require 'taskjuggler/daemon/WebServer'
18
+
19
+ # Name of the application
20
+ AppConfig.appName = 'tj3webd'
21
+
22
+ class TaskJuggler
23
+
24
+ class Tj3WebD < Tj3AppBase
25
+
26
+ def initialize
27
+ super
28
+
29
+ @mhi = MessageHandlerInstance.instance
30
+ @mhi.logFile = File.join(Dir.getwd, "/#{AppConfig.appName}.log")
31
+ @mhi.appName = AppConfig.appName
32
+ # By default show only warnings and more serious messages.
33
+ @mhi.outputLevel = :warning
34
+ @daemonize = true
35
+ @uriFile = File.join(Dir.getwd, '.tj3d.uri')
36
+ @port = nil
37
+ @webServerPort = nil
38
+ @pidFile = nil
39
+ end
40
+
41
+ def processArguments(argv)
42
+ super do
43
+ @opts.banner += <<'EOT'
44
+ The TaskJuggler web server can be used to serve the HTTP reports of
45
+ TaskJuggler projects to be viewed by any HTML5 compliant web browser. It uses
46
+ the TaskJuggler daemon (tj3d) for data hosting and report generation.
47
+ EOT
48
+ @opts.on('-d', '--dont-daemonize',
49
+ format("Don't put program into daemon mode. Keep it " +
50
+ 'connected to the terminal and show debug output.')) do
51
+ @daemonize = false
52
+ end
53
+ @opts.on('-p', '--port <NUMBER>', Integer,
54
+ format('Use the specified TCP/IP port to connect to the ' +
55
+ 'TaskJuggler daemon (Default: 8474).')) do |arg|
56
+ @port = arg
57
+ end
58
+ @opts.on('--pidfile <FILE NAME>', String,
59
+ format('Write the process ID of the daemon to the ' +
60
+ 'specified file.')) do |arg|
61
+ @pidFile = arg
62
+ end
63
+ @opts.on('--urifile', String,
64
+ format('If the port is 0, use this file to read the URI ' +
65
+ 'of the TaskJuggler daemon.')) do |arg|
66
+ @uriFile = arg
67
+ end
68
+ @opts.on('--webserver-port <NUMBER>', Integer,
69
+ format('Use the specified TCP/IP port to serve web browser ' +
70
+ 'requests (Default: 8080).')) do |arg|
71
+ @webServerPort = arg
72
+ end
73
+ end
74
+ end
75
+
76
+ def appMain(files)
77
+ @rc.configure(self, 'global')
78
+ @rc.configure(@mhi, 'global.log')
79
+ webServer = WebServer.new
80
+ @rc.configure(webServer, 'global')
81
+ @rc.configure(webServer, 'webd')
82
+
83
+ # Set some config variables if corresponding data was provided via the
84
+ # command line.
85
+ webServer.port = @port if @port
86
+ webServer.uriFile = @uriFile.untaint
87
+ webServer.webServerPort = @webServerPort if @webServerPort
88
+ webServer.daemonize = @daemonize
89
+ webServer.pidFile = @pidFile
90
+ debug('', "pidFile 1: #{@pidFile}")
91
+
92
+ webServer.start
93
+ 0
94
+ end
95
+
96
+ end
97
+
98
+ end
99
+
@@ -11,7 +11,7 @@
11
11
  # published by the Free Software Foundation.
12
12
  #
13
13
 
14
- require 'taskjuggler/LogFile'
14
+ require 'taskjuggler/MessageHandler'
15
15
 
16
16
  class TaskJuggler
17
17
 
@@ -20,27 +20,29 @@ class TaskJuggler
20
20
  # this class and call the start() method.
21
21
  class Daemon
22
22
 
23
- attr_accessor :daemonize
24
- attr_reader :log
23
+ include MessageHandler
24
+
25
+ attr_accessor :pidFile, :daemonize
25
26
 
26
27
  def initialize
27
28
  # You can set this flag to false to prevent the program from
28
29
  # disconnecting from the current terminal. This is useful for debugging
29
30
  # purposes.
30
31
  @daemonize = true
31
- @log = LogFile.instance
32
+ # Save the PID of the running daemon as number into this file.
33
+ @pidFile = nil
32
34
  end
33
35
 
34
36
  # Call this method to turn the process into a background process.
35
37
  def start
36
- return unless @daemonize
38
+ return 0 unless @daemonize
37
39
 
38
40
  # Fork and have the parent exit
39
41
  if (pid = fork) == -1
40
- @log.fatal('First fork failed')
42
+ fatal('first_fork_failed', 'First fork failed')
41
43
  elsif !pid.nil?
42
44
  # This is the parent. We can exit now.
43
- @log.debug("Forked a child process with PID #{pid}")
45
+ debug('', "Forked a child process with PID #{pid}")
44
46
  exit! 0
45
47
  end
46
48
 
@@ -48,15 +50,17 @@ class TaskJuggler
48
50
  Process.setsid
49
51
  # Fork again to make sure we lose the controlling terminal
50
52
  if (pid = fork) == -1
51
- @log.fatal('Second fork failed')
53
+ fatal('second_fork_failed', 'Second fork failed')
52
54
  elsif !pid.nil?
53
55
  # This is the parent. We can exit now.
54
- @log.debug("Forked a child process with PID #{pid}")
56
+ debug('', "Forked a child process with PID #{pid}")
55
57
  exit! 0
56
58
  end
57
59
 
58
60
  @pid = Process.pid
59
61
 
62
+ writePidFile
63
+
60
64
  # Change current working directory to the file system root
61
65
  Dir.chdir '/'
62
66
  # Make sure we can create files with any permission
@@ -67,13 +71,49 @@ class TaskJuggler
67
71
  $stdout.reopen('/dev/null', 'a')
68
72
  $stderr.reopen($stdout)
69
73
 
70
- @log.info("The process is running as daemon now with PID #{@pid}")
74
+ info('daemon_pid',
75
+ "The process is running as daemon now with PID #{@pid}")
76
+
71
77
  0
72
78
  end
73
79
 
74
80
  # This method may provide some cleanup functionality in the future. You
75
81
  # better call it before you exit.
76
82
  def stop
83
+ if @pidFile
84
+ begin
85
+ File.delete(@pidFile)
86
+ rescue
87
+ warning('cannot_delete_pidfile',
88
+ "Cannote delete the PID file (#{@pidFile}): #{$!}")
89
+ end
90
+ info('daemon_deleted_pidfile', "PID file #{@pidFile} deleted")
91
+ end
92
+ end
93
+
94
+ private
95
+
96
+ def writePidFile
97
+ if @pidFile
98
+ # Prepend the current working dir to @pidFile unless it's already an
99
+ # absolute path. The working dir is changed to '/' later. We need the
100
+ # absolute name to be able to delete it on exit again.
101
+ if @pidFile[0] != '/'
102
+ @pidFile = File.join(Dir.getwd, @pidFile)
103
+ end
104
+
105
+ # If requested, write the PID of the daemon to the specified file.
106
+ begin
107
+ File.open(@pidFile, 'w') do |f|
108
+ f.puts @pid
109
+ end
110
+ rescue
111
+ warning('cannot_save_pidfile', "Cannot write PID to #{@pidFile}")
112
+ end
113
+ info('daemon_wrote_pidfile',
114
+ "PID file #{@pidFile} written with PID #{@pid}")
115
+ end
116
+
77
117
  end
78
118
 
79
119
  end
@@ -0,0 +1,127 @@
1
+ #!/usr/bin/env ruby -w
2
+ # encoding: UTF-8
3
+ #
4
+ # = DaemonConnector.rb -- The TaskJuggler III Project Management Software
5
+ #
6
+ # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012
7
+ # by Chris Schlaeger <chris@linux.com>
8
+ #
9
+ # This program is free software; you can redistribute it and/or modify
10
+ # it under the terms of version 2 of the GNU General Public License as
11
+ # published by the Free Software Foundation.
12
+ #
13
+
14
+ require 'drb'
15
+ require 'drb/acl'
16
+ require 'taskjuggler/MessageHandler'
17
+
18
+ class TaskJuggler
19
+
20
+ module DaemonConnectorMixin
21
+
22
+ include MessageHandler
23
+
24
+ def connectDaemon
25
+ unless @authKey
26
+ error('missing_auth_key', <<'EOT'
27
+ You must set an authentication key in the configuration file. Create a file
28
+ named .taskjugglerrc or taskjuggler.rc that contains at least the following
29
+ lines. Replace 'your_secret_key' with some random character sequence.
30
+
31
+ _global:
32
+ authKey: your_secret_key
33
+ EOT
34
+ )
35
+ end
36
+
37
+ uri = "druby://#{@host}:#{@port}"
38
+ if @port == 0
39
+ # If the @port is configured to 0, we need to read the URI to connect
40
+ # to the server from the .tj3d.uri file that has been generated by the
41
+ # server.
42
+ begin
43
+ uri = File.read(@uriFile).chomp
44
+ rescue
45
+ error('tjc_port_0',
46
+ 'The server port is configured to be 0, but no ' +
47
+ ".tj3d.uri file can be found: #{$!}")
48
+ end
49
+ end
50
+ debug('', "DRb URI determined as #{uri}")
51
+
52
+ # We try to play it safe here. The client also starts a DRb server, so
53
+ # we need to make sure it's constricted to localhost only. We require
54
+ # the DRb server for the standard IO redirection to work.
55
+ $SAFE = 1 unless @unsafeMode
56
+ DRb.install_acl(ACL.new(%w[ deny all
57
+ allow 127.0.0.1 ]))
58
+ DRb.start_service('druby://127.0.0.1:0')
59
+ debug('', 'DRb service started')
60
+
61
+ broker = nil
62
+ begin
63
+ # Get the ProjectBroker object from the tj3d.
64
+ broker = DRbObject.new_with_uri(uri)
65
+ # Client and server should always come from the same Gem. Since we
66
+ # restict communication to localhost, that's probably not a problem.
67
+ if (check = broker.apiVersion(@authKey, 1)) < 0
68
+ error('tjc_too_old',
69
+ 'This client is too old for the server. Please ' +
70
+ 'upgrade to a more recent version of the software.')
71
+ elsif check == 0
72
+ error('tjc_auth_fail',
73
+ 'Authentication failed. Please check your authentication ' +
74
+ 'key to match the server key.')
75
+ end
76
+ debug('', "Connection with report broker on #{uri} established")
77
+ rescue => e
78
+ # If we ended up here due to a previously reported TjRuntimeError, we
79
+ # just pass it through.
80
+ if e.is_a?(TjRuntimeError)
81
+ raise TjRuntimeError, $!
82
+ end
83
+ error('tjc_srv_not_responding',
84
+ "TaskJuggler server (tj3d) on URI '#{uri}' is not " +
85
+ "responding:\n#{$!}")
86
+ end
87
+
88
+ broker
89
+ end
90
+
91
+ def disconnectDaemon
92
+ DRb.stop_service
93
+ end
94
+
95
+ end
96
+
97
+ class DaemonConnector
98
+
99
+ include DaemonConnectorMixin
100
+
101
+ def initialize(authKey, host, port, uri)
102
+ @authKey = authKey
103
+ @host = host
104
+ @port = port
105
+ @uri = uri
106
+ @unsafeMode = true
107
+
108
+ @broker = connectDaemon
109
+ end
110
+
111
+ def disconnect
112
+ disconnectDaemon
113
+ @broker = nil
114
+ end
115
+
116
+ def getProject(projectId)
117
+ @broker.getProject(@authKey, projectId)
118
+ end
119
+
120
+ def getProjectList
121
+ @broker.getProjectList(@authKey)
122
+ end
123
+
124
+ end
125
+
126
+ end
127
+