diff --git a/lib/Project.php b/lib/Project.php index 86693117..36c0e4bb 100644 --- a/lib/Project.php +++ b/lib/Project.php @@ -1,5 +1,12 @@ Validate(); + try{ + $this->FetchLatestCommit(); + } + catch(Exceptions\AppException){ + // Pass; it's OK if this fails during creation. + } + + // Don't let the started date be later than the first commit date. This can happen if the producer starts to commit before their project is approved on the mailing list. + if($this->LastCommitTimestamp !== null && $this->LastCommitTimestamp > $this->Started){ + $this->Started = $this->LastCommitTimestamp; + } + // Is this ebook already released? if(!$this->Ebook->IsPlaceholder()){ throw new Exceptions\EbookIsNotAPlaceholderException(); @@ -233,6 +252,65 @@ class Project{ $this->PropertyFromHttp('ReviewerUserId'); } + /** + * @throws Exceptions\AppException If the operation faile.d + */ + public function FetchLatestCommit(?string $apiKey = null): void{ + $headers = [ + 'Accept: application/vnd.github+json', + 'X-GitHub-Api-Version: 2022-11-28', + 'User-Agent: Standard Ebooks' // Required by GitHub. + ]; + + if($apiKey !== null){ + $headers[] = 'Authorization: Bearer ' . $apiKey; + } + + // First, we check if the repo has been renamed. If so, update the repo now. + $curl = curl_init($this->VcsUrl); + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, Enums\HttpMethod::Head->value); // Only perform HTTP HEAD. + curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); + curl_exec($curl); + + /** @var string $finalUrl */ + $finalUrl = curl_getinfo($curl, CURLINFO_EFFECTIVE_URL); + // Were we redirected? + if($finalUrl != $this->VcsUrl){ + $this->VcsUrl = $finalUrl; + } + + // Now check the actual commits. + $url = preg_replace('|^https://github.com/|iu', 'https://api.github.com/repos/', $this->VcsUrl . '/commits'); + + $curl = curl_init($url); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + + try{ + $response = curl_exec($curl); + /** @var int $httpCode */ + $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); + + if(!is_string($response)){ + throw new Exceptions\AppException('Response from GitHub was not a string: ' . $response); + } + + if($httpCode != Enums\HttpCode::Ok->value){ + throw new Exception('HTTP code from GitHub was: ' . $httpCode); + } + + /** @var array $commits */ + $commits = json_decode($response); + + if(sizeof($commits) > 0){ + $this->LastCommitTimestamp = new DateTimeImmutable($commits[0]->commit->committer->date); + } + } + catch(Exception $ex){ + throw new Exceptions\AppException('Error in update-project-commits for URL <' . $url . '>: ' . $ex->getMessage(), 0, $ex); + } + } + // *********** // ORM METHODS diff --git a/scripts/update-project-commits b/scripts/update-project-commits index 76e33e34..9de2936e 100755 --- a/scripts/update-project-commits +++ b/scripts/update-project-commits @@ -2,87 +2,55 @@ VcsUrl); - curl_setopt($curl, CURLOPT_CUSTOMREQUEST, Enums\HttpMethod::Head->value); // Only perform HTTP HEAD. - curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); - curl_exec($curl); - - $finalUrl = curl_getinfo($curl, CURLINFO_EFFECTIVE_URL); - // Were we redirected? - if($finalUrl != $project->VcsUrl){ - $project->VcsUrl = $finalUrl; - $project->Save(); - } - - // Now check the actual commits. - $url = preg_replace('|^https://github.com/|iu', 'https://api.github.com/repos/', $project->VcsUrl . '/commits'); - - $curl = curl_init($url); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); - curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); - try{ - $response = curl_exec($curl); - /** @var int $httpCode */ - $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); + $project->FetchLatestCommit($apiKey); - if(!is_string($response)){ - throw new Exception('Response from GitHub was not a string: ' . $response); - } - - if($httpCode != Enums\HttpCode::Ok->value){ - throw new Exception('HTTP code from GitHub was: ' . $httpCode); - } - - /** @var array $commits */ - $commits = json_decode($response); - - if(sizeof($commits) > 0){ - $project->LastCommitTimestamp = new DateTimeImmutable($commits[0]->commit->committer->date); - } - - if($project->LastCommitTimestamp !== null && $project->LastCommitTimestamp < new DateTimeImmutable('30 days ago')){ + if( + $project->Status == Enums\ProjectStatusType::InProgress + && + $project->LastCommitTimestamp !== null + && + $project->LastCommitTimestamp < $oldestAllowedCommitTimestamp + ){ + // An active `Project` has stalled. $project->Status = Enums\ProjectStatusType::Stalled; } - else{ + elseif( + $project->Status == Enums\ProjectStatusType::Stalled + && + $project->LastCommitTimestamp !== null + && + $project->LastCommitTimestamp >= $oldestAllowedCommitTimestamp + ){ // Revive previously-stalled `Project`s. $project->Status = Enums\ProjectStatusType::InProgress; } $project->Save(); } - catch(Exception $ex){ - Log::WriteErrorLogEntry('Error in update-project-commits for URL <' . $url . '>: ' . $ex->getMessage()); + catch(Exceptions\AppException $ex){ + Log::WriteErrorLogEntry($ex->getMessage()); } sleep(1); diff --git a/templates/ProjectsTable.php b/templates/ProjectsTable.php index f11a6469..f83406cf 100644 --- a/templates/ProjectsTable.php +++ b/templates/ProjectsTable.php @@ -20,6 +20,7 @@ $includeStatus = $includeStatus ?? true; Status + @@ -38,10 +39,10 @@ $includeStatus = $includeStatus ?? true; - LastCommitTimestamp?->format(Enums\DateTimeFormat::ShortDate->value) ?> + Started->format(Enums\DateTimeFormat::ShortDate->value) ?> - Started->format(Enums\DateTimeFormat::ShortDate->value) ?> + LastCommitTimestamp?->format(Enums\DateTimeFormat::ShortDate->value) ?> @@ -51,6 +52,11 @@ $includeStatus = $includeStatus ?? true; GitHub + + DiscussionUrl !== null){ ?> + Discussion + +