[tools 2/3] testbot/web: Use SimpleCollectionPage for the job details page.

Francois Gouget fgouget at codeweavers.com
Thu Mar 31 09:52:53 CDT 2022


Signed-off-by: Francois Gouget <fgouget at codeweavers.com>
---
 testbot/web/JobDetails.pl | 378 +++++++++++++++++++++-----------------
 1 file changed, 205 insertions(+), 173 deletions(-)

diff --git a/testbot/web/JobDetails.pl b/testbot/web/JobDetails.pl
index 5b8b7013a..c4d6b1a1b 100644
--- a/testbot/web/JobDetails.pl
+++ b/testbot/web/JobDetails.pl
@@ -2,7 +2,7 @@
 # Job details page
 #
 # Copyright 2009 Ge van Geldorp
-# Copyright 2012-2014,2017-2020 Francois Gouget
+# Copyright 2012-2014,2017-2022 Francois Gouget
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -20,73 +20,35 @@
 
 use strict;
 
-package JobDetailsPage;
+package StepsTasksBlock;
 
-use ObjectModel::CGI::CollectionPage;
-our @ISA = qw(ObjectModel::CGI::CollectionPage);
+use ObjectModel::CGI::CollectionBlock;
+our @ISA = qw(ObjectModel::CGI::CollectionBlock);
 
-use File::Basename;
-use POSIX qw(strftime);
 use URI::Escape;
+use POSIX qw(strftime);
 
-use WineTestBot::Config;
-use WineTestBot::Jobs;
-use WineTestBot::Log; # For Elapsed()
-use WineTestBot::LogUtils;
-use WineTestBot::Missions;
-use WineTestBot::StepsTasks;
 use WineTestBot::Utils;
+use WineTestBot::Missions;
 use WineTestBot::Engine::Notify;
 
 
-sub _initialize($$$)
+sub Create($$)
 {
-  my ($self, $Request, $RequiredRole) = @_;
-  $self->{start} = Time();
+  my ($Collection, $EnclosingPage) = @_;
 
-  my $JobId = $self->GetParam("Key");
-  if (! defined($JobId))
-  {
-    $JobId = $self->GetParam("JobId");
-  }
-  $self->{Job} = CreateJobs()->GetItem($JobId);
-  if (!defined $self->{Job})
-  {
-    exit($self->Redirect("/"));
-  }
-  $self->{JobId} = $JobId;
-
-  $self->SUPER::_initialize($Request, $RequiredRole, CreateStepsTasks(undef, $self->{Job}));
-  if ($self->{Job}->Status =~ /^(?:queued|running)$/)
-  {
-    $self->SetRefreshInterval(30);
-  }
-}
-
-sub GetPageTitle($)
-{
-  my ($self) = @_;
-
-  my $PageTitle = $self->{Job}->Remarks;
-  $PageTitle =~ s/^[[]\Q$PatchesMailingList\E[]] //;
-  $PageTitle = "Job " . $self->{JobId} if ($PageTitle eq "");
-  $PageTitle .= " - ${ProjectName} Test Bot";
-  return $PageTitle;
+  return StepsTasksBlock->new($Collection, $EnclosingPage);
 }
 
-sub GetTitle($)
-{
-  my ($self) = @_;
-
-  return "Job " . $self->{JobId} . " - " . $self->{Job}->Remarks;
-}
+#
+# Individual item property support
+#
 
-sub DisplayProperty($$$)
+sub DisplayProperty($$)
 {
-  my ($self, $CollectionBlock, $PropertyDescriptor) = @_;
+  my ($self, $PropertyDescriptor) = @_;
 
   my $PropertyName = $PropertyDescriptor->GetName();
-
   return $PropertyName eq "StepNo" || $PropertyName eq "TaskNo" ||
          $PropertyName eq "Status" || $PropertyName eq "VM" ||
          $PropertyName eq "Timeout" || $PropertyName eq "FileName" ||
@@ -94,9 +56,22 @@ sub DisplayProperty($$$)
          $PropertyName eq "Ended" || $PropertyName eq "TestFailures";
 }
 
-sub GenerateHeaderCell($$$)
+sub SortKeys($$)
 {
-  my ($self, $CollectionBlock, $PropertyDescriptor) = @_;
+  my ($self, $Keys) = @_;
+
+  my @SortedKeys = sort { $a <=> $b } @$Keys;
+  return \@SortedKeys;
+}
+
+
+#
+# Item cell generation
+#
+
+sub GenerateHeaderCell($$)
+{
+  my ($self, $PropertyDescriptor) = @_;
 
   my $PropertyName = $PropertyDescriptor->GetName();
   if ($PropertyName eq "CmdLineArg")
@@ -109,13 +84,104 @@ sub GenerateHeaderCell($$$)
   }
   else
   {
-    return $self->SUPER::GenerateHeaderCell($CollectionBlock, $PropertyDescriptor);
+    return $self->SUPER::GenerateHeaderCell($PropertyDescriptor);
+  }
+}
+
+sub GenerateDataCell($$$$)
+{
+  my ($self, $StepTask, $PropertyDescriptor, $DetailsPage) = @_;
+
+  my $PropertyName = $PropertyDescriptor->GetName();
+  if ($PropertyName eq "VM")
+  {
+    print "<td><a href='#k", $self->escapeHTML($StepTask->GetKey()), "'>";
+    print $self->escapeHTML($self->GetDisplayValue($StepTask, $PropertyDescriptor));
+    print "</a></td>\n";
+  }
+  elsif ($PropertyName eq "FileName")
+  {
+    my $FileName = $StepTask->GetFullFileName();
+    if ($FileName and -r $FileName)
+    {
+      my $JobId = $self->{EnclosingPage}->GetJob()->Id;
+      my $URI = "/GetFile.pl?JobKey=" . uri_escape($JobId) .
+                  "&StepKey=" . uri_escape($StepTask->StepNo);
+      print "<td><a href='" . $self->escapeHTML($URI) . "'>";
+      print $self->escapeHTML($self->GetDisplayValue($StepTask, $PropertyDescriptor));
+      print "</a></td>\n";
+    }
+    else
+    {
+      $self->SUPER::GenerateDataCell($StepTask, $PropertyDescriptor, $DetailsPage);
+    }
+  }
+  elsif ($PropertyName eq "CmdLineArg")
+  {
+    my $Args = $self->escapeHTML($StepTask->CmdLineArg);
+    if ($Args eq "" or $StepTask->VM->Type eq "wine")
+    {
+      $Args .= "<br>" if ($Args ne "");
+      my ($ErrMessage, $Missions) = ParseMissionStatement($StepTask->Missions);
+      if (defined $ErrMessage)
+      {
+        $Args .= "<span class='Mission'>$ErrMessage</span>";
+      }
+      else
+      {
+        $Args .= "<span class='Mission'>". $self->escapeHTML(GetTaskMissionDescription($Missions->[0], $StepTask->Type)) ."</span>";
+      }
+    }
+    print "<td>$Args</td>\n";
+  }
+  elsif ($PropertyName eq "Ended")
+  {
+    if (defined $StepTask->Ended)
+    {
+      my $Duration = $StepTask->Ended - $StepTask->Started;
+      my $TagId = "E". $StepTask->Id;
+      print "<td><a id='$TagId' class='title' title='",
+            strftime("%Y-%m-%d %H:%M:%S", localtime($StepTask->Ended)),
+            "'>", DurationToString($Duration), "</a>\n";
+      print "<script type='text/javascript'><!--\n";
+      print "  ShowDateTime(", $StepTask->Ended, ",'$TagId');\n";
+      print "--></script>\n";
+      print "</td>\n";
+    }
+    else
+    {
+      print "<td> </td>\n";
+    }
+  }
+  else
+  {
+    $self->SUPER::GenerateDataCell($StepTask, $PropertyDescriptor, $DetailsPage);
   }
 }
 
-sub GetItemActions($$)
+
+#
+# Per-item actions handling
+#
+
+sub GetItemActions($)
 {
-  #my ($self, $CollectionBlock) = @_;
+  #my ($self) = @_;
+  return [];
+}
+
+
+#
+# Actions handling
+#
+
+sub GetActions($)
+{
+  my ($self) = @_;
+
+  # These are mutually exclusive
+  return ["Cancel job"] if (!defined $self->CanCancel());
+  return ["Restart job"] if (!defined $self->CanRestart());
   return [];
 }
 
@@ -123,20 +189,21 @@ sub CanCancel($)
 {
   my ($self) = @_;
 
-  my $Status = $self->{Job}->Status;
+  my $Job = $self->{EnclosingPage}->GetJob();
+  my $Status = $Job->Status;
   if ($Status ne "queued" && $Status ne "running")
   {
-    return "Job already $Status"; 
+    return "Job already $Status";
   }
 
-  my $Session = $self->GetCurrentSession();
+  my $Session = $self->{EnclosingPage}->GetCurrentSession();
   if (! defined($Session))
   {
     return "You are not authorized to cancel this job";
   }
   my $CurrentUser = $Session->User;
   if (! $CurrentUser->HasRole("admin") &&
-      $self->{Job}->User->GetKey() ne $CurrentUser->GetKey())
+      $Job->User->GetKey() ne $CurrentUser->GetKey())
   {
     return "You are not authorized to cancel this job";
   }
@@ -148,20 +215,21 @@ sub CanRestart($)
 {
   my ($self) = @_;
 
-  my $Status = $self->{Job}->Status;
+  my $Job = $self->{EnclosingPage}->GetJob();
+  my $Status = $Job->Status;
   if ($Status ne "boterror" && $Status ne "canceled")
   {
     return "Not a failed / canceled Job";
   }
 
-  my $Session = $self->GetCurrentSession();
+  my $Session = $self->{EnclosingPage}->GetCurrentSession();
   if (! defined($Session))
   {
     return "You are not authorized to restart this job";
   }
   my $CurrentUser = $Session->User;
   if (! $CurrentUser->HasRole("admin") &&
-      $self->{Job}->User->GetKey() ne $CurrentUser->GetKey()) # FIXME: Admin only?
+      $Job->User->GetKey() ne $CurrentUser->GetKey()) # FIXME: Admin only?
   {
     return "You are not authorized to restart this job";
   }
@@ -169,35 +237,26 @@ sub CanRestart($)
   return undef;
 }
 
-sub GetActions($$)
-{
-  my ($self, $CollectionBlock) = @_;
-
-  # These are mutually exclusive
-  return ["Cancel job"] if (!defined $self->CanCancel());
-  return ["Restart job"] if (!defined $self->CanRestart());
-  return [];
-}
-
 sub OnCancel($)
 {
   my ($self) = @_;
 
   my $ErrMessage = $self->CanCancel();
-  if (defined($ErrMessage))
+  if (defined $ErrMessage)
   {
-    $self->{ErrMessage} = $ErrMessage;
+    $self->{EnclosingPage}->SetError(undef, $ErrMessage);
     return !1;
   }
 
-  $ErrMessage = JobCancel($self->{JobId});
-  if (defined($ErrMessage))
+  my $JobId = $self->{EnclosingPage}->GetJob()->Id;
+  $ErrMessage = JobCancel($JobId);
+  if (defined $ErrMessage)
   {
-    $self->{ErrMessage} = $ErrMessage;
+    $self->{EnclosingPage}->SetError(undef, $ErrMessage);
     return !1;
   }
 
-  exit($self->Redirect("/JobDetails.pl?Key=" . $self->{JobId}));
+  exit($self->{EnclosingPage}->Redirect("/JobDetails.pl?Key=$JobId"));
 }
 
 sub OnRestart($)
@@ -205,44 +264,89 @@ sub OnRestart($)
   my ($self) = @_;
 
   my $ErrMessage = $self->CanRestart();
-  if (defined($ErrMessage))
+  if (defined $ErrMessage)
   {
-    $self->{ErrMessage} = $ErrMessage;
+    $self->{EnclosingPage}->SetError(undef, $ErrMessage);
     return !1;
   }
 
-  $ErrMessage = JobRestart($self->{JobId});
-  if (defined($ErrMessage))
+  my $JobId = $self->{EnclosingPage}->GetJob()->Id;
+  $ErrMessage = JobRestart($JobId);
+  if (defined $ErrMessage)
   {
-    $self->{ErrMessage} = $ErrMessage;
+    $self->{EnclosingPage}->SetError(undef, $ErrMessage);
     return !1;
   }
 
-  exit($self->Redirect("/JobDetails.pl?Key=" . $self->{JobId}));
+  exit($self->{EnclosingPage}->Redirect("/JobDetails.pl?Key=$JobId"));
 }
 
-sub OnAction($$$)
+sub OnAction($$)
 {
-  my ($self, $CollectionBlock, $Action) = @_;
+  my ($self, $Action) = @_;
 
-  if ($Action eq "Cancel job")
-  {
-    return $self->OnCancel();
-  }
-  elsif ($Action eq "Restart job")
+  return $Action eq "Cancel job" ? $self->OnCancel() :
+         $Action eq "Restart job" ? $self->OnRestart() :
+         $self->SUPER::OnAction($Action);
+}
+
+
+package JobDetailsPage;
+
+use ObjectModel::CGI::SimpleCollectionPage;
+our @ISA = qw(ObjectModel::CGI::SimpleCollectionPage);
+
+use URI::Escape;
+
+use WineTestBot::Config;
+use WineTestBot::Jobs;
+use WineTestBot::Log; # For Elapsed()
+use WineTestBot::LogUtils;
+use WineTestBot::StepsTasks;
+
+
+sub _initialize($$$)
+{
+  my ($self, $Request, $RequiredRole) = @_;
+  $self->{start} = Time();
+
+  $self->{JobId} = $self->GetParam("Key");
+  $self->{JobId} = $self->GetParam("JobId") if (!defined $self->{JobId});
+
+  $self->{Job} = CreateJobs()->GetItem($self->{JobId});
+  exit($self->Redirect("/")) if (!defined $self->{Job});
+
+  my $Collection = CreateStepsTasks(undef, $self->{Job});
+  $self->SUPER::_initialize($Request, $RequiredRole, $Collection, \&StepsTasksBlock::Create);
+  if ($self->{Job}->Status =~ /^(?:queued|running)$/)
   {
-    return $self->OnRestart();
+    $self->SetRefreshInterval(30);
   }
+}
+
+sub GetJob($)
+{
+  my ($self) = @_;
 
-  return $self->SUPER::OnAction($CollectionBlock, $Action);
+  return $self->{Job};
 }
 
-sub SortKeys($$$)
+sub GetPageTitle($)
 {
-  my ($self, $CollectionBlock, $Keys) = @_;
+  my ($self) = @_;
 
-  my @SortedKeys = sort { $a <=> $b } @$Keys;
-  return \@SortedKeys;
+  my $PageTitle = $self->{Job}->Remarks;
+  $PageTitle =~ s/^[[]\Q$PatchesMailingList\E[]] //;
+  $PageTitle = "Job " . $self->{JobId} if ($PageTitle eq "");
+  $PageTitle .= " - ${ProjectName} Test Bot";
+  return $PageTitle;
+}
+
+sub GetTitle($)
+{
+  my ($self) = @_;
+
+  return "Job $self->{JobId} - ". $self->{Job}->Remarks;
 }
 
 sub InitMoreInfo($)
@@ -250,7 +354,7 @@ sub InitMoreInfo($)
   my ($self) = @_;
 
   my $More = $self->{More} = {};
-  my $Keys = $self->SortKeys(undef, $self->{Collection}->GetKeys());
+  my $Keys = $self->{CollectionBlock}->SortKeys($self->{Collection}->GetKeys());
   foreach my $Key (@$Keys)
   {
     my $StepTask = $self->{Collection}->GetItem($Key);
@@ -458,7 +562,7 @@ function HideLog(event, url)
 EOF
 
   print "<div class='Content'>\n";
-  my $Keys = $self->SortKeys(undef, $self->{Collection}->GetKeys());
+  my $Keys = $self->{CollectionBlock}->SortKeys($self->{Collection}->GetKeys());
   my $KeyIndex = 0;
   foreach my $Key (@$Keys)
   {
@@ -627,78 +731,6 @@ EOF
   print "</div>\n";
 }
 
-sub GenerateDataCell($$$$$)
-{
-  my ($self, $CollectionBlock, $StepTask, $PropertyDescriptor, $DetailsPage) = @_;
-
-  my $PropertyName = $PropertyDescriptor->GetName();
-  if ($PropertyName eq "VM")
-  {
-    print "<td><a href='#k", $self->escapeHTML($StepTask->GetKey()), "'>";
-    print $self->escapeHTML($self->GetDisplayValue($CollectionBlock, $StepTask,
-                                                   $PropertyDescriptor));
-    print "</a></td>\n";
-  }
-  elsif ($PropertyName eq "FileName")
-  {
-    my $FileName = $StepTask->GetFullFileName();
-    if ($FileName and -r $FileName)
-    {
-      my $URI = "/GetFile.pl?JobKey=" . uri_escape($self->{JobId}) .
-                  "&StepKey=" . uri_escape($StepTask->StepNo);
-      print "<td><a href='" . $self->escapeHTML($URI) . "'>";
-      print $self->escapeHTML($self->GetDisplayValue($CollectionBlock, $StepTask,
-                                                     $PropertyDescriptor));
-      print "</a></td>\n";
-    }
-    else
-    {
-      $self->SUPER::GenerateDataCell($CollectionBlock, $StepTask, $PropertyDescriptor, $DetailsPage);
-    }
-  }
-  elsif ($PropertyName eq "CmdLineArg")
-  {
-    my $Args = $self->escapeHTML($StepTask->CmdLineArg);
-    if ($Args eq "" or $StepTask->VM->Type eq "wine")
-    {
-      $Args .= "<br>" if ($Args ne "");
-      my ($ErrMessage, $Missions) = ParseMissionStatement($StepTask->Missions);
-      if (defined $ErrMessage)
-      {
-        $Args .= "<span class='Mission'>$ErrMessage</span>";
-      }
-      else
-      {
-        $Args .= "<span class='Mission'>". $self->escapeHTML(GetTaskMissionDescription($Missions->[0], $StepTask->Type)) ."</span>";
-      }
-    }
-    print "<td>$Args</td>\n";
-  }
-  elsif ($PropertyName eq "Ended")
-  {
-    if (defined $StepTask->Ended)
-    {
-      my $Duration = $StepTask->Ended - $StepTask->Started;
-      my $TagId = "E". $StepTask->Id;
-      print "<td><a id='$TagId' class='title' title='",
-            strftime("%Y-%m-%d %H:%M:%S", localtime($StepTask->Ended)),
-            "'>", DurationToString($Duration), "</a>\n";
-      print "<script type='text/javascript'><!--\n";
-      print "  ShowDateTime(", $StepTask->Ended, ",'$TagId');\n";
-      print "--></script>\n";
-      print "</td>\n";
-    }
-    else
-    {
-      print "<td> </td>\n";
-    }
-  }
-  else
-  {
-    $self->SUPER::GenerateDataCell($CollectionBlock, $StepTask, $PropertyDescriptor, $DetailsPage);
-  }
-}
-
 sub GenerateFooter($)
 {
   my ($self) = @_;
-- 
2.30.2




More information about the wine-devel mailing list