Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"php": "^8.1",
"laravel/framework": "^10.0",
"maatwebsite/excel": "^3.1.45",
"eveseat/eseye": "^3.2",
"eveseat/eseye": "^3.2.1",
"eveseat/services": "^5.1",
"guzzlehttp/guzzle": "^7.0",
"doctrine/dbal": "^3.0",
Expand Down
4 changes: 4 additions & 0 deletions src/Bus/Corporation.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
use Seat\Eveapi\Jobs\Corporation\Starbases;
use Seat\Eveapi\Jobs\Corporation\Structures;
use Seat\Eveapi\Jobs\Corporation\Titles;
use Seat\Eveapi\Jobs\CorporationProjects\Projects;
use Seat\Eveapi\Jobs\Industry\Corporation\Jobs;
use Seat\Eveapi\Jobs\Industry\Corporation\Mining\Extractions;
use Seat\Eveapi\Jobs\Industry\Corporation\Mining\ObserverDetails;
Expand Down Expand Up @@ -205,5 +206,8 @@ protected function addAuthenticatedJobs()
$this->addAuthenticatedJob(new ContainerLogs($this->corporation_id, $this->token));
$this->addAuthenticatedJob(new Locations($this->corporation_id, $this->token));
$this->addAuthenticatedJob(new Names($this->corporation_id, $this->token));

// projects
$this->addAuthenticatedJob(new Projects($this->corporation_id, $this->token));
}
}
1 change: 1 addition & 0 deletions src/Config/eveapi.scopes.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,5 @@
'esi-universe.read_structures.v1',
'esi-wallet.read_character_wallet.v1',
'esi-wallet.read_corporation_wallets.v1',
'esi-corporations.read_projects.v1',
];
149 changes: 149 additions & 0 deletions src/Jobs/CorporationProjects/Contributors.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
<?php

/*
* This file is part of SeAT
*
* Copyright (C) 2015 to present Leon Jacobs
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

namespace Seat\Eveapi\Jobs\CorporationProjects;

use Seat\Eveapi\Jobs\AbstractAuthCorporationJob;
use Seat\Eveapi\Models\CorporationProjects\CorporationProject;
use Seat\Eveapi\Models\CorporationProjects\CorporationProjectContributor;
use Seat\Eveapi\Models\RefreshToken;

/**
* Class Projects.
*
* @package Seat\Eveapi\Jobs\CorporationProjects
*/
class Contributors extends AbstractAuthCorporationJob
{
/**
* @var string
*/
protected $method = 'get';

/**
* @var string
*/
protected $endpoint = '/corporations/{corporation_id}/projects/{project_id}/contributors';

/**
* @var string
*/
protected $scope = 'esi-corporations.read_projects.v1';

/**
* @var array
*/
protected $roles = ['Project Manager']; // TODO: TBC
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Has this todo been resolved? If so, we should remove it, else we should resolve it.


/**
* When this job was written, so ESI can try to serve a response compatible with the behaviour of the endpoint at that time.
*
* @var string
*/
protected string $compatibility_date = '2025-12-16';

/**
* @var array
*/
protected $tags = ['corporation', 'project'];

/**
* @var string
*/
protected $version = '';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this can be dropped, see the recent commits on other jobs


private $project_id;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason we don't have a type hint?


public function __construct(int $corporation_id, RefreshToken $token, string $project_id)
{
$this->project_id = $project_id;

parent::__construct($corporation_id, $token);
}

/**
* Execute the job.
*
* @return void
*
* @throws \Throwable
*/
public function handle()
{
parent::handle();

$this->query_string['limit'] = '100';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't really looked into all the ESI changes, but is this for the new cursor pagination thing? I wonder if we don't better push this into the esi request logic instead of having it in the job.


$before = '0';

$proj = CorporationProject::findOrFail($this->project_id);

$contriblist = collect();

while (true) {

$this->query_string['before'] = $before;

$response = $this->retrieve([
'corporation_id' => $this->getCorporationId(),
'project_id' => $this->project_id,
]);

$contribs = $response->getBody();
if (isset($contribs->cursor) && isset($contribs->cursor->before)) {
$before = $contribs->cursor->before;
} else {
break; // empty cursor
}
if (isset($contribs->contributors)) {
$contriblist = $contriblist->concat($contribs->contributors);
} else {
// We have reached the end of the dataset
break;
}
}

// Clear out list if necessary. Disabled under assumption contributors cant leave list
// CorporationProjectContributor::where('project_id', $this->project_id)->delete();

$rows = $contriblist->map(function ($item) use ($proj) {
// handle object or array item
$id = is_object($item) ? ($item->id ?? null) : ($item['id'] ?? null);
$contributed = is_object($item) ? ($item->contributed ?? 0) : ($item['contributed'] ?? 0);

return [
'project_id' => $proj->id,
'character_id' => $id,
'contributed' => $contributed,
];
})->toArray();

// Perform upsert: unique by project_id + character_id, update contributed on conflict
// Timestamps are auto updated
CorporationProjectContributor::upsert(
$rows,
uniqueBy: ['project_id', 'character_id'],
update: ['contributed']
);

}
}
147 changes: 147 additions & 0 deletions src/Jobs/CorporationProjects/Details.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
<?php

/*
* This file is part of SeAT
*
* Copyright (C) 2015 to present Leon Jacobs
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

namespace Seat\Eveapi\Jobs\CorporationProjects;

use Carbon\Carbon;
use Seat\Eveapi\Jobs\AbstractAuthCorporationJob;
use Seat\Eveapi\Mapping\CorporationProjects\ProjectsMapping;
use Seat\Eveapi\Models\CorporationProjects\CorporationProject;
use Seat\Eveapi\Models\RefreshToken;

/**
* Class Projects.
*
* @package Seat\Eveapi\Jobs\CorporationProjects
*/
class Details extends AbstractAuthCorporationJob
{
/**
* @var string
*/
protected $method = 'get';

/**
* @var string
*/
protected $endpoint = '/corporations/{corporation_id}/projects/{project_id}';

/**
* @var string
*/
protected $scope = 'esi-corporations.read_projects.v1';

/**
* When this job was written, so ESI can try to serve a response compatible with the behaviour of the endpoint at that time.
*
* @var string
*/
protected string $compatibility_date = '2025-12-16';

/**
* @var array
*/
protected $tags = ['corporation', 'project'];

/**
* @var string
*/
private $project_id;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can also add a type hint


/**
* @var string
*/
protected $version = '';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above, I don't think this is required anymore


public function __construct(int $corporation_id, RefreshToken $token, string $project_id)
{
$this->project_id = $project_id;

parent::__construct($corporation_id, $token);
}

/**
* Execute the job.
*
* @return void
*
* @throws \Throwable
*/
public function handle()
{
parent::handle();

$cid = $this->getCorporationId(); // Extract it here early as we use it a log

$response = $this->retrieve([
'project_id' => $this->project_id,
'corporation_id' => $cid,
]);

$details = $response->getBody();

$lm = Carbon::parse($details->last_modified);

// Weird early projects, bad data
$thresholdDate = Carbon::parse('2025-01-01');
if ($lm->isBefore($thresholdDate)){
logger()->warning('early project detected', ['body' => $details]); // TODO investigate
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

another TODO


return;
}

$proj = CorporationProject::firstOrNew([
'id' => $this->project_id,
'corporation_id' => $cid,
]);

ProjectsMapping::make($proj, $details, [
'last_modified' => function () use ($lm) {
return $lm->format('Y-m-d H:i:s');
},
'corporation_id' => function () use ($cid) {
return $cid;
},
'created' => function () use ($details) {
return Carbon::parse($details->details->created)->format('Y-m-d H:i:s');
},
'finished' => function () use ($details) {
if (! isset($details->details->finished)){
return;
}

return Carbon::parse($details->details->finished)->format('Y-m-d H:i:s');
},
'expires' => function () use ($details) {
if (! isset($details->details->expires)){
return;
}

return Carbon::parse($details->details->expires)->format('Y-m-d H:i:s');
},
'configuration' => function () use ($details) {
return json_encode($details->configuration);
},
])->save();

}
}
Loading