home *** CD-ROM | disk | FTP | other *** search
/ Lighthouse Design Suite / LIGHTHOUSE.mdf / Quantrix_1.2 / Application / FilterServicer.service / mpx2tm < prev    next >
Text File  |  1995-05-02  |  14KB  |  560 lines

  1. #
  2. #  mpx2tm 
  3. #
  4. #  This file when used as input to perl will take a file in the MPX file 
  5. #  format as described in the Microsoft Project Reference book and translate
  6. #  it into TaskMaster format.
  7. #
  8. #  Copyright (C) 1993 Lighthouse Design Ltd.
  9. #
  10. #  You may freely copy, distribute, and reuse the code in
  11. #  this example provided this copyright legend and disclaimer
  12. #  are preserved in all copies and derivative work.
  13. #
  14. #  Lighthouse Design disclaims any warranty of any kind,
  15. #  expressed or implied, as to this code's fitness
  16. #  for any particular use.
  17. #
  18. #
  19. #
  20.  
  21.  
  22. if($ARGV[0] eq "-t"){
  23.     require "timelocal.pl";
  24.     require "writetm.pl";
  25.     shift(@ARGV);
  26.     foreach $file (@ARGV) {
  27.     print "Trying $file...\n";
  28.     print STDERR "HELLOOOOO!\n\n";
  29.     sleep (1);
  30.     
  31.     if (!open(TEXTFILE,"cat \"$ARGV[0]\" | tr \'\\015\' \'\\012\' |")) {
  32.         printf(STDERR "$ARGV[0] not readable. Skipping $ARGV[0]\n");
  33.         exit 0;
  34.     }
  35.         
  36.     $dirName = ".";
  37.     if ($file =~ /\//) {
  38.         $dirName = $file;
  39.         $dirName =~ s/\/[^\/]$//;
  40.     }
  41.  
  42.     $tmFilename = "/tmp/TEST.taskmaster";
  43.     $interfaceFilename = "";
  44.  
  45.     &doFile();
  46.     close(TEXTFILE);
  47.     }                   
  48. }else{            
  49.     require "$ARGV[2]/timelocal.pl";
  50.     require "$ARGV[2]/writetm.pl";
  51.     
  52.  
  53.     if (!open(TEXTFILE,"cat \"$ARGV[0]\" | tr \'\\015\' \'\\012\' |")) {
  54.     printf(STDERR "$ARGV[0] not readable. Skipping $ARGV[0]\n");
  55.     exit 0;
  56.     }
  57.  
  58.     $tmFilename = $ARGV[1];
  59.     $interfaceFilename = "$ARGV[2]/ObjectArchive.tmoa";
  60.     
  61.     &doFile();
  62.     close(TEXTFILE);
  63. }
  64.  
  65.  
  66. sub doFile  {
  67.  
  68.     select((select(STDERR), $| = 0)[0]);
  69.     $| = 1;
  70.  
  71.     $currentOutlineNumber = "0.";
  72.     $currentOutlineLevel = 1;
  73.     
  74.     #
  75.     # Initialize variables
  76.     #
  77.     # calendar stuff
  78.     $currentCalendarName = "";
  79.     $firstLine = 0;
  80.     @currentCalendarWeek = (0,0,0,0,0,0,0);
  81.  
  82.     while(<TEXTFILE>){
  83.  
  84.     # firstLine
  85.     !$firstLine && do {
  86.         if(!/^MPX(.)/){
  87.         print STDERR "This isn't an MPX type file.\n\n";
  88.         sleep(1);
  89.         exit 0;
  90.         }
  91.         $fieldSeparator = $1;
  92.         $firstLine = 1;
  93.     };
  94.  
  95.     # comments
  96.     /^0/ && do { 
  97.         next;
  98.     };
  99.    
  100.     # currency settings
  101.     /^10/ && do { 
  102.         # doesn't have meaning in TM
  103.         next;
  104.     };   
  105.  
  106.     # Date and Time settings
  107.     /^12/ && do { 
  108.         # PENDING
  109.         next;
  110.     };   
  111.  
  112.     # Base Calendar Definition
  113.     /^20/ && do { 
  114.         if($inCalendar){
  115.         &addCalendar($currentCalendarName, @currentCalendarWeek, @currentCalendarHolidays);
  116.         if($currentCalendarName eq "Standard"){
  117.             &setDefaultCalendar($currentCalendarName);
  118.         }
  119.         print "Reading Base Calendar...\n\n" if !$baseCalendarNotified;
  120.         $baseCalendarNotified = 1;
  121.         }
  122.         ($recordNum, $currentCalendarName, @currentCalendarWeek)  = &breakUpLine($_);
  123.          @currentCalendarHolidays = ();
  124.          $inCalendar = 1;
  125.         next;
  126.     };   
  127.  
  128.     # Base Calendar Hours
  129.     /^25/ && do { 
  130.         ($recordNum, $dayOfWeek, @fromToArray) = &breakUpLine($_);
  131.         $dayOfWeek--;
  132.         if($currentCalendarWeek[$dayOfWeek]){
  133.         $currentCalendarWeek[$dayOfWeek] = &sumHours(@fromToArray);
  134.         }
  135.         next;
  136.     };   
  137.  
  138.     # Base Calendar Exeptions (Holidays?)
  139.     /^26/ && do { 
  140.         ($recordNum, $startDate, $endDate, $working) = &breakUpLine($_);
  141.         if(!$working || !$endDate){
  142.         if(!$endDate){
  143.             $endDate = $startDate;
  144.         }
  145.         @holidayDates = &daysBetween($startDate, $endDate);
  146.         @currentCalendarHolidays = (@currentCalendarHolidays, @holidayDates);
  147.         }
  148.         next;
  149.     };   
  150.  
  151.     # Project Header
  152.     /^30/ && do { 
  153.         ($recordNum, $projectName, $projectCompany, $projectManager, $projectCalendar, $projectStart, $projectEnd, $isEndOn) = &breakUpLine($_);
  154.         if($inCalendar){
  155.         &addCalendar($currentCalendarName, @currentCalendarWeek, @currentCalendarHolidays);
  156.         if($currentCalendarName eq "Standard"){
  157.             &setDefaultCalendar($currentCalendarName);
  158.         }
  159.         print "Reading Calendars...\n\n" if !$calendarsNotified;
  160.         $calendarsNotified = 1;
  161.         }
  162.         if($projectName){
  163.         &setProjectName($projectName);
  164.         }
  165.         if($projectManager){
  166.         $projectManager .= ":$projectCompany" unless !$projectCompany;
  167.         &setProjectManager($projectManager);
  168.         }
  169.         if($isEndOn){
  170.         &setProjectEndDate($projectEnd);
  171.         }else{
  172.         &setProjectStartDate($projectStart);
  173.         }
  174.         next;
  175.     };   
  176.  
  177.     # Text Resource Table Definition
  178.     /^40/ && do { 
  179.         next;
  180.     };   
  181.  
  182.     # Numeric Resource Table Definition
  183.     /^41/ && do { 
  184.         ®isterColumnHeadings($_);
  185.         next;
  186.     };   
  187.  
  188.     # Resource
  189.     /^50/ && do { 
  190.         ®isterCurrentLine($_);
  191.         # 40 -> ID
  192.         # 1 -> Name
  193.         # 41 -> MaxUnits
  194.         # 42 -> StandardRate
  195.         # 44 -> Per Use Cost
  196.         # 48 -> Base Calendar
  197.         $resourceID = ¤tValue(40);
  198.         die "Lacking Resource ID" if ($resourceID eq "");
  199.         $resourceName = ¤tValue(1) || do {
  200.         $resourceName = "Resource $resourceID";
  201.         };
  202.         $resourceUnits = ¤tValue(41) || do {
  203.         $resourceUnits = 1;
  204.         };
  205.         $resourceRate = ¤tValue(42);
  206.         if($resourceRate){
  207.         if($resourceRate =~ /\$([\d\.]+)\/w/){
  208.             $resourceRate = $1/5;
  209.         }elsif($resourceRate =~ /\$([\d\.]+)\/d/){
  210.             $resourceRate = $1;
  211.         }elsif($resourceRate =~ /\$([\d\.]+)\/h/){
  212.             $resourceRate = $1 * 8;
  213.         }else{
  214.             $resourceRate = 0;
  215.         };
  216.         }else{
  217.         $resourceRate = 0;
  218.         }
  219.         $resourcePerUse = ¤tValue(44) || do {
  220.         $resourcePerUse = 0;
  221.         };
  222.         if($resourcePerUse =~ /\$([\d\.\,]+)/ ){
  223.         $resourcePerUse = $1;
  224.         $resourcePerUse =~ s/\,//g;
  225.         }                  
  226.         $resourceBaseCalendar = ¤tValue(48) || do{
  227.         $resourceBaseCalendar = "Standard";
  228.         };
  229.         $currentResourceCalendar = "CalendarOf:".$resourceID;
  230.         &addResource($resourceID, $resourceName, $resourceUnits, $resourceRate, $resourcePerUse, $currentResourceCalendar);
  231.         &addCalendarCopyOf($currentResourceCalendar, $resourceBaseCalendar);
  232.         print "Reading Resources...\n\n" if !$resourcesNotified;
  233.         $resourcesNotified = 1;
  234.         next;
  235.     };  
  236.  
  237.     # Resource Notes
  238.     /^51/ && do { 
  239.         next;
  240.     };   
  241.  
  242.     # Resource Calendar Definition
  243.     /^55/ && do { 
  244.         ($recordNum, $baseCalendarName, @currentCalendarWeek)  = &breakUpLine($_);
  245.         $ct = 1;
  246.         foreach $day (@currentCalendarWeek){
  247.         if($day == 0){
  248.             &setCalendarHoursForDay($currentResourceCalendar, $ct, 0);
  249.         }
  250.         $ct++;
  251.         }
  252.         next;
  253.     };   
  254.  
  255.     # Resource Calendar Hours
  256.     /^56/ && do { 
  257.         ($recordNum, $dayOfWeek, @fromToArray) = &breakUpLine($_);
  258.         &setCalendarHoursForDay($currentResourceCalendar, $dayOfWeek, &sumHours(@fromToArray));
  259.         next;
  260.     };
  261.  
  262.     # Resource Calendar Exceptions
  263.     /^57/ && do { 
  264.         ($recordNum, $startDate, $endDate, $working) = &breakUpLine($_);
  265.         if(!$working || !$endDate){
  266.         if(!$endDate) {
  267.             $endDate = $startDate;
  268.         }
  269.         @holidayDates = &daysBetween($startDate, $endDate);
  270.         &addCalendarHolidays($currentResourceCalendar, @holidayDates);
  271.         }
  272.         next;
  273.     };   
  274.  
  275.     # Text Task Table Definition
  276.     /^60/ && do { 
  277.         next;
  278.     };   
  279.  
  280.     # Numeric Task Tabel Definition
  281.     /^61/ && do { 
  282.         ®isterColumnHeadings($_);
  283.         next;
  284.     };  
  285.  
  286.     # Task
  287.     /^70/ && do { 
  288.         ®isterCurrentLine($_);
  289.         # 90 -> ID
  290.         # 1 -> Name
  291.         # Assume type task?
  292.         # 3 -> outline level (used to get outline #)
  293.         # 50 -> scheduledStart 
  294.         # 20 -> planned work
  295.         # 91 -> constraint type
  296.         # 68 -> constraint date
  297.         # 0 expenses
  298.         # 95 -> priority
  299.         # 4 -> Text 1 = Subtitle
  300.         # 5 -> Text 2 = Notes
  301.         # 
  302.  
  303.         $taskID = ¤tValue(90);
  304.         die "Task ID Missing" if ($taskID eq "");
  305.         $currentTaskID = $taskID;
  306.         $taskName = ¤tValue(1) || do {
  307.         $taskName = "Task $taskID";
  308.         };
  309.         #figure type
  310.         $taskType = "Task";
  311.         if(¤tValue(80) eq "No" && ¤tValue(40) =~ /[0-9.]+e./){
  312.         $taskType = "Group";
  313.         }
  314.         # figure outline number
  315.         $outlineLevel = ¤tValue(3) || do {
  316.         $currentOutlineNumber = "";
  317.         $currentOutlineLevel = -30;
  318.         };
  319.         if($outlineLevel == $currentOutlineLevel){
  320.         $currentOutlineNumber = &nextSibling($currentOutlineNumber);
  321.         }elsif($outlineLevel == $currentOutlineLevel+1){
  322.         $currentOutlineLevel++;
  323.         $currentOutlineNumber = &firstChild($currentOutlineNumber);
  324.         }elsif($outlineLevel == $currentOutlineLevel-1){
  325.         $currentOutlineLevel--;
  326.         $currentOutlineNumber = &nextAunt($currentOutlineNumber);
  327.         }else{
  328.         $currentOutlineNumber = "";
  329.         $currentOutlineLevel = -30;
  330.         }
  331.         $taskStartDate = ¤tValue(50) || do {
  332.         $taskStartDate = "";
  333.         };
  334.         $taskDuration = ¤tValue(40) || do {
  335.         $taskDuration = "1d";
  336.         };
  337.         if($taskDuration =~ /([1-9.]+)e(.)/){
  338.         $taskDuration = "$1$2";
  339.         }
  340.         # figure constraint
  341.         $taskConstraint = ¤tValue(91) || do {
  342.         $taskConstraint = "As Soon As Possible";
  343.         };
  344.         if($taskConstraint eq "Must Start On"){
  345.         $taskConstraint = "StartOn";
  346.         }elsif($taskConstraint eq "Start No Earlier Than"){
  347.         $taskConstraint = "StartEarliestAfter";
  348.         }elsif($taskConstraint eq "Start No Later Than"){
  349.         $taskConstraint = "StartOn";
  350.         }elsif($taskConstraint eq "As Soon As Possible"){
  351.         $taskConstraint = "Earliest";
  352.         }elsif($taskConstraint eq "Must Finish On"){
  353.         $taskConstraint = "EndOn";
  354.         }elsif($taskConstraint eq "Finish No Earlier Than"){
  355.         $taskConstraint = "EndOn";
  356.         }elsif($taskConstraint eq "Finish No Later Than"){
  357.         $taskConstraint = "EndEarliestBefore";
  358.         }elsif($taskConstraint eq "As Late As Possible"){
  359.         $taskConstraint = "Latest";
  360.         }else{
  361.         $taskConstraint = "Earliest";
  362.         }
  363.         $taskConstraintDate = ¤tValue(68) || do {
  364.         $taskConstraintDate = "1/1/1970 0:00:00";
  365.         };
  366.         $taskExpenses = 0;
  367.         #figure priority
  368.         $taskPriority = ¤tValue(95) || do {
  369.         $taskPriority = "Medium";
  370.         };
  371.         if($taskPriority eq "Highest"){
  372.         $taskPriority = 10;
  373.         }elsif($taskPriority eq "High"){
  374.         $taskPriority = 20;
  375.         }elsif($taskPriority eq "Medium"){
  376.         $taskPriority = 30;
  377.         }elsif($taskPriority eq "Low"){
  378.         $taskPriority = 40;
  379.         }elsif($taskPriority eq "Lowest"){
  380.         $taskPriority = 50;
  381.         }else{
  382.         $taskPriority = 30;
  383.         }
  384.         $taskSubtitle = ¤tValue(4);
  385.         $taskNotes = ¤tValue(5);
  386.         &addTask($taskID, $taskName, $taskType, $currentOutlineNumber, $taskStartDate, $taskDuration, $taskConstraint, $taskConstraintDate, $taskExpenses, $taskPriority, $taskSubtitle, $taskNotes);
  387.         print "Reading Tasks...\n\n" if !$tasksNotified;
  388.         $tasksNotified = 1;
  389.         $taskPreds = ¤tValue(70);
  390.         if($taskPreds){
  391.         @predList = split(/\,/, $taskPreds);
  392.         foreach $pred (@predList){
  393.             $pred =~ s/^(\d+).*/$1/;
  394.             &addDependency($pred, $taskID);
  395.         }
  396.         };
  397.         next;
  398.     };   
  399.  
  400.     # Task Notes
  401.     /^71/ && do { 
  402.         next;
  403.     };   
  404.  
  405.     # Resource Assignment
  406.     /^75/ && do { 
  407.         ($recordNum, $assignmentResID, $assignmentUnits, $assignmentWork) = &breakUpLine($_);
  408.         &addAssignment($currentTaskID, $assignmentResID, $assignmentWork, $assignmentUnits, 1.00);
  409.         next;
  410.     };   
  411.  
  412.  
  413.     }    
  414.     print "Writing...\n\n";
  415.     &outputToFile($tmFilename, $interfaceFilename);
  416.     print "Done.\n\n";
  417.     sleep 1;
  418.     `echo 'Done $ARGV[0] $tmFilename' >> /tmp/log`
  419. }
  420.  
  421. sub breakUpLine {  # oneLineFromInput -> array of fields
  422.     local(@tempArray) = split(/$fieldSeparator/, $_[0]);
  423.     local($element, $currentField);
  424.  
  425.     @ret = ();
  426.     $inQuote = 0;
  427.     foreach $element (@tempArray){
  428.     $element =~ s/\n//;
  429.     if($inQuote){
  430.         $currentField .= ",".$element;
  431.     }else{
  432.         $currentField = $element;
  433.     }
  434.     $numQuotes = ($currentField =~ s/\"/\"/g);
  435.     if($numQuotes % 2 == 0){ # good field
  436.         if($inQuote && $currentField =~ /^\"(.*)\"$/){
  437.         $currentField = $1;
  438.         }
  439.         $currentField =~ s/\"\"/\\\"/g;
  440.         push(ret, $currentField);
  441.         $currentField = 0;
  442.         $inQuote = 0;
  443.     }else{
  444.         $inQuote = 1;
  445.     }
  446.     }
  447.     return @ret;
  448. }
  449.  
  450. sub sumHours { #fromToArray of times
  451.     local(@fromTo) = @_;
  452.     local($ct, $total);
  453.  
  454.     $total = 0;
  455.     for($ct = 0; $ct <= $#fromTo; $ct += 2){
  456.     $total += &hoursBetween($fromTo[$ct], $fromTo[$ct+1]);
  457.     }
  458.     return $total;
  459. }
  460.  
  461. sub hoursBetween { # from to
  462.     local($from, $to) = @_;
  463.  
  464.     return 0 unless $from && $to;
  465.  
  466.     local(@fromSegs) = split(/:/,$from);
  467.     local(@toSegs) = split(/:/,$to);
  468.  
  469.     # assumes HH:MM:SS
  470.     $from = ($from =~ /[\d:]+\s+pm/ && $fromSegs[0] < 12 ? $fromSegs[0]+12 : $fromSegs[0]);
  471.     $from += $fromSegs[1]/60;
  472.     $from += $fromSegs[2]/60;
  473.     $to = ($to =~ /[\d:]+\s+pm/ && $toSegs[0] < 12 ? $toSegs[0]+12 : $toSegs[0]);
  474.     $to += $toSegs[1]/60;    
  475.     $to += $toSegs[2]/60;    
  476.  
  477.     return ($to-$from);
  478. }
  479.     
  480. sub daysBetween  {  #startDate, endDate
  481.     local($sM,$sD,$sY) = split(/\//,$_[0]);
  482.     local($eM,$eD,$eY) = split(/\//,$_[1]);
  483.     local($fromTime) = &timelocal(0,0,0,$sD,$sM-1,$sY);
  484.     local($toTime) = &timelocal(0,0,0,$eD,$eM-1,$eY);
  485.     local(@returnList) = ();
  486.     while($fromTime <= $toTime){
  487.     ($s, $m, $h, $sD, $sM, $sY) = localtime($fromTime);
  488.     $aDate = "$sM/$sD/$sY";
  489.     push(@returnList, $aDate);
  490.     $fromTime += 86400;
  491.     }
  492.     return @returnList;
  493. }
  494.  
  495.  
  496. #
  497. #  outline manipulation
  498. #
  499. sub nextSibling{
  500.     local($outlineNumber) = @_;
  501.     local(@temp);
  502.     if($outlineNumber){
  503.     @temp = split(/\./, $outlineNumber);
  504.     $temp[$#temp]++;
  505.     $ret = join('.',@temp);
  506.     $ret .= '.';
  507.     }else{
  508.     return ("");
  509.     }
  510. }
  511.  
  512. sub firstChild{
  513.     local($outlineNumber) = @_;
  514.     if($outlineNumber){
  515.     $outlineNumber .= "1.";
  516.     }else{
  517.     return ("");
  518.     }
  519.  
  520. }
  521.  
  522. sub nextAunt{
  523.     local($outlineNumber) = @_;
  524.     local(@temp);
  525.     if($outlineNumber){
  526.     @temp = split(/\./, $outlineNumber);
  527.     pop(@temp);
  528.     $temp[$#temp]++;
  529.     $ret = join('.',@temp);
  530.     $ret .= '.';
  531.     }else{
  532.     return ("");
  533.     }
  534. }
  535.  
  536.  
  537. #
  538. # line headings stuff
  539. #
  540. sub registerColumnHeadings{
  541.     local(@lineDefinition) = &breakUpLine($_[0]);
  542.     foreach $i (0..$#lineDefinition){
  543.     $column{$lineDefinition[$i]} = $i;
  544.     }
  545. }
  546.  
  547. sub registerCurrentLine{
  548.     @currentLine = &breakUpLine($_[0]);
  549. }
  550.  
  551. sub currentValue{
  552.     local($flag) = $_[0];
  553.     
  554.     if($column{$flag}){
  555.     return $currentLine[$column{$flag}];
  556.     }else{
  557.     return "";
  558.     }
  559. }
  560.