* tsp-info endpoint added
* different collector services are now implemented
This commit is contained in:
parent
88527e4ff1
commit
efc6e7b0c4
@ -11,7 +11,9 @@
|
||||
"require": {
|
||||
"php": "^7.1",
|
||||
"doctrine/common": "^2.8",
|
||||
"league/csv": "^9.0",
|
||||
"los/basepath": "^1.0",
|
||||
"meyfa/php-svg": "^0.6.0",
|
||||
"roave/security-advisories": "dev-master",
|
||||
"symfony/console": "^3.3",
|
||||
"symfony/css-selector": "^3.3",
|
||||
|
||||
109
composer.lock
generated
109
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "58819bed1efddc237ebfcd76754b3380",
|
||||
"content-hash": "2c35a874f4da183a1aef96abfbd4ee59",
|
||||
"packages": [
|
||||
{
|
||||
"name": "container-interop/container-interop",
|
||||
@ -542,6 +542,70 @@
|
||||
],
|
||||
"time": "2017-01-14T15:23:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/csv",
|
||||
"version": "9.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/csv.git",
|
||||
"reference": "5dc305e7958190bcab0cc2778888a4f658d29aa1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/csv/zipball/5dc305e7958190bcab0cc2778888a4f658d29aa1",
|
||||
"reference": "5dc305e7958190bcab0cc2778888a4f658d29aa1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"php": ">=7.0.10"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-curl": "*",
|
||||
"friendsofphp/php-cs-fixer": "^2.0",
|
||||
"phpunit/phpunit": "^6.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-iconv": "Needed to ease transcoding CSV using iconv stream filters"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "9.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"League\\Csv\\": "src"
|
||||
},
|
||||
"files": [
|
||||
"src/functions_include.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ignace Nyamagana Butera",
|
||||
"email": "nyamsprod@gmail.com",
|
||||
"homepage": "https://github.com/nyamsprod/",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Csv data manipulation made easy in PHP",
|
||||
"homepage": "http://csv.thephpleague.com",
|
||||
"keywords": [
|
||||
"csv",
|
||||
"export",
|
||||
"filter",
|
||||
"import",
|
||||
"read",
|
||||
"write"
|
||||
],
|
||||
"time": "2017-08-21T13:42:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "los/basepath",
|
||||
"version": "1.0.1",
|
||||
@ -585,6 +649,49 @@
|
||||
"homepage": "https://github.com/lansoweb/basepath",
|
||||
"time": "2016-08-27T20:56:32+00:00"
|
||||
},
|
||||
{
|
||||
"name": "meyfa/php-svg",
|
||||
"version": "v0.6.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/meyfa/php-svg.git",
|
||||
"reference": "cde475bf2566d8414fb6d11f55653180203d4e01"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/meyfa/php-svg/zipball/cde475bf2566d8414fb6d11f55653180203d4e01",
|
||||
"reference": "cde475bf2566d8414fb6d11f55653180203d4e01",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.5"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"SVG\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabian Meyer",
|
||||
"homepage": "http://meyfa.net"
|
||||
}
|
||||
],
|
||||
"description": "Read, edit, write, and render SVG files with PHP",
|
||||
"homepage": "https://github.com/meyfa/php-svg",
|
||||
"keywords": [
|
||||
"svg"
|
||||
],
|
||||
"time": "2017-07-29T11:10:57+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nikic/fast-route",
|
||||
"version": "v1.2.0",
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
use \App\Service\TrInfoCollectorService as TrInfo;
|
||||
/**
|
||||
* Local configuration.
|
||||
*
|
||||
@ -11,6 +12,33 @@ return [
|
||||
'app.config' => [
|
||||
'jira.user' => '...',
|
||||
'jira.password' => '...',
|
||||
'mhweb.user' => '...',
|
||||
'mhweb.password' => '...',
|
||||
|
||||
'pra.baseData' => [
|
||||
'A' => [
|
||||
TrInfo::UNIT_CORE => 0,
|
||||
TrInfo::UNIT_SIG => 0,
|
||||
TrInfo::UNIT_TADE => 0,
|
||||
],
|
||||
'B' => [
|
||||
TrInfo::UNIT_CORE => 27,
|
||||
TrInfo::UNIT_SIG => 3,
|
||||
TrInfo::UNIT_TADE => 0,
|
||||
],
|
||||
'C' => [
|
||||
TrInfo::UNIT_CORE => 212,
|
||||
TrInfo::UNIT_SIG => 56,
|
||||
TrInfo::UNIT_TADE => 9,
|
||||
],
|
||||
],
|
||||
'url.jiraTspExpedites' => [
|
||||
"baseUrl" => "https://jirapducc.mo.ca.am.ericsson.se/rest/api/2/search?jql=filter=%s",
|
||||
"filters" => [
|
||||
"unassigned" => 12768,
|
||||
"all" => 12502,
|
||||
]
|
||||
],
|
||||
'url.jiraKanbanBoard' => [
|
||||
'baseUrl' => 'https://jirapducc.mo.ca.am.ericsson.se/rest/api/2/search?jql=filter=%s&maxResults=1000&fields=%s',
|
||||
'filterId' => 14229,
|
||||
@ -35,7 +63,15 @@ return [
|
||||
'customfield_11692',
|
||||
],
|
||||
],
|
||||
'url.mhWebPraGoals' => 'https://mhweb.ericsson.se:443/SearchWeb/faces/search/query/resultPage.xhtml?&v=3&queryKey=74023&output=CSV&csvDelimiter=COMMA',
|
||||
'url.mhWebTrProgress' => 'https://mhweb.ericsson.se:443/SearchWeb/faces/search/query/resultPage.xhtml?&v=3&queryKey=68655&output=CSV&csvDelimiter=COMMA',
|
||||
'url.mhWebTrEdit' => 'https://mhweb.ericsson.se/TREditWeb/faces/tredit/tredit.xhtml?eriref=%s',
|
||||
'url.labTemperatureUrl' => 'https://159.107.194.61/public/mapshow_simple.htm?id=3381&mapid=884B46A7-AE59-4523-9981-8E9FEB7C1FCF',
|
||||
'url.vacation' => 'https://rhp.common.hu.eld.ericsson.se/vacation.php?action=groupview&dm_h=2&dm_v=1&group_id=478',
|
||||
'url.jcatTrFlow' => "http://jcat.tsp.eth.ericsson.se:8080/Trweb/trflow/reader.php?query=SELECT+*+FROM+trinfo+where+validationerrors+!=+''",
|
||||
|
||||
'url.eurestCamera2' => 'https://auto:auto@91.82.89.112:8443/mjpg/video.mjpg',
|
||||
|
||||
'http.proxy.enabled' => false,
|
||||
'http.proxy.type' => CURLPROXY_SOCKS5,
|
||||
'http.proxy.url' => "localhost:1080",
|
||||
|
||||
@ -31,3 +31,5 @@ $app->get('/api/ping', App\Action\PingAction::class, 'api.ping');
|
||||
|
||||
$app->get('/api/kanban', App\Action\KanbanAction::class, 'api.kanban');
|
||||
$app->get('/avatars/{signum}', App\Action\AvatarAction::class, 'user.avatar');
|
||||
|
||||
$app->get('/api/tsp-info', App\Action\TspInfoAction::class, 'api.tsp-info');
|
||||
|
||||
73
src/App/Action/TspInfoAction.php
Normal file
73
src/App/Action/TspInfoAction.php
Normal file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace App\Action;
|
||||
|
||||
use App\Response\JsonCorsResponse;
|
||||
use App\Service\JcatInfoCollectorService;
|
||||
use App\Service\JiraCollectorService;
|
||||
use App\Service\LabInfoCollectorService;
|
||||
use App\Service\TrInfoCollectorService;
|
||||
use App\Service\VacationInfoCollectorService;
|
||||
use Interop\Http\ServerMiddleware\DelegateInterface;
|
||||
use Interop\Http\ServerMiddleware\MiddlewareInterface as ServerMiddlewareInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
class TspInfoAction implements ServerMiddlewareInterface
|
||||
{
|
||||
/**
|
||||
* @var VacationInfoCollectorService
|
||||
*/
|
||||
private $vacationInfoCollectorService;
|
||||
|
||||
/**
|
||||
* @var TrInfoCollectorService
|
||||
*/
|
||||
private $trInfoCollectorService;
|
||||
|
||||
/**
|
||||
* @var JcatInfoCollectorService
|
||||
*/
|
||||
private $jcatInfoCollectorService;
|
||||
|
||||
/**
|
||||
* @var LabInfoCollectorService
|
||||
*/
|
||||
private $labInfoCollectorService;
|
||||
|
||||
/**
|
||||
* @var JiraCollectorService
|
||||
*/
|
||||
private $jiraCollectorService;
|
||||
|
||||
public function __construct(VacationInfoCollectorService $vacationInfoCollectorService,
|
||||
TrInfoCollectorService $trInfoCollectorService,
|
||||
JcatInfoCollectorService $jcatInfoCollectorService,
|
||||
LabInfoCollectorService $labInfoCollectorService,
|
||||
JiraCollectorService $jiraCollectorService)
|
||||
{
|
||||
$this->vacationInfoCollectorService = $vacationInfoCollectorService;
|
||||
$this->trInfoCollectorService = $trInfoCollectorService;
|
||||
$this->jcatInfoCollectorService = $jcatInfoCollectorService;
|
||||
$this->labInfoCollectorService = $labInfoCollectorService;
|
||||
$this->jiraCollectorService = $jiraCollectorService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ServerRequestInterface $request
|
||||
* @param DelegateInterface $delegate
|
||||
* @return JsonCorsResponse
|
||||
* @todo lab temperature data
|
||||
*/
|
||||
public function process(ServerRequestInterface $request, DelegateInterface $delegate)
|
||||
{
|
||||
return new JsonCorsResponse([
|
||||
'animGifs' => [],
|
||||
'praGoals' => $this->trInfoCollectorService->getPraGoals(),
|
||||
'trProgress' => $this->trInfoCollectorService->getProgressInfo(),
|
||||
'trFlow' => $this->jcatInfoCollectorService->getTrFlow(),
|
||||
'expedites' => $this->jiraCollectorService->getExpedites(),
|
||||
'vacationInfo' => $this->vacationInfoCollectorService->isVacationSoon(),
|
||||
'labTemperature' => $this->labInfoCollectorService->getLabTemperatureData(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
30
src/App/Action/TspInfoFactory.php
Normal file
30
src/App/Action/TspInfoFactory.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Action;
|
||||
|
||||
use App\Service\JcatInfoCollectorService;
|
||||
use App\Service\JiraCollectorService;
|
||||
use App\Service\LabInfoCollectorService;
|
||||
use App\Service\TrInfoCollectorService;
|
||||
use App\Service\VacationInfoCollectorService;
|
||||
use Interop\Container\ContainerInterface;
|
||||
|
||||
class TspInfoFactory
|
||||
{
|
||||
public function __invoke(ContainerInterface $container)
|
||||
{
|
||||
$dataCollectorService = $container->get(VacationInfoCollectorService::class);
|
||||
$trInfoCollectorService = $container->get(TrInfoCollectorService::class);
|
||||
$jcatInfoCollectorService = $container->get(JcatInfoCollectorService::class);
|
||||
$labInfoCollectorService = $container->get(LabInfoCollectorService::class);
|
||||
$jiraInfoCollectorService = $container->get(JiraCollectorService::class);
|
||||
|
||||
return new TspInfoAction(
|
||||
$dataCollectorService,
|
||||
$trInfoCollectorService,
|
||||
$jcatInfoCollectorService,
|
||||
$labInfoCollectorService,
|
||||
$jiraInfoCollectorService
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -46,10 +46,14 @@ class ConfigProvider
|
||||
Action\AvatarAction::class => Action\AvatarFactory::class,
|
||||
Action\HomePageAction::class => Action\HomePageFactory::class,
|
||||
Action\KanbanAction::class => Action\KanbanFactory::class,
|
||||
Action\TspInfoAction::class => Action\TspInfoFactory::class,
|
||||
|
||||
Service\AvatarService::class => Service\AvatarServiceFactory::class,
|
||||
Service\JiraCollectorService::class => Service\JiraCollectorServiceFactory::class,
|
||||
Service\LabInfoCollectorService::class => Service\LabInfoCollectorServiceFactory::class,
|
||||
Service\VacationInfoCollectorService::class => Service\VacationInfoCollectorServiceFactory::class,
|
||||
Service\TrInfoCollectorService::class => Service\TrInfoCollectorServiceFactory::class,
|
||||
Service\JcatInfoCollectorService::class => Service\JcatInfoCollectorServiceFactory::class,
|
||||
|
||||
'service.avatarCache' => function(ContainerInterface $container): StorageInterface {
|
||||
$cache = new FilesytemCache();
|
||||
|
||||
@ -234,6 +234,9 @@ class KanbanBoard implements \JsonSerializable
|
||||
*/
|
||||
private function updatedAtReverseSort(array $toSort): array
|
||||
{
|
||||
$toSort = array_filter($toSort, function(KanbanEntry $item){
|
||||
return $item->getAssignee() != null;
|
||||
});
|
||||
usort($toSort, function(KanbanEntry $a, KanbanEntry $b){
|
||||
return $b->getUpdatedAt() <=> $a->getUpdatedAt();
|
||||
});
|
||||
|
||||
114
src/App/Entity/TrProgress.php
Normal file
114
src/App/Entity/TrProgress.php
Normal file
@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
class TrProgress implements \JsonSerializable
|
||||
{
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $eriref;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $heading;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $prio;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $lastProgress;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getEriref(): string
|
||||
{
|
||||
return $this->eriref;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $eriref
|
||||
* @return TrProgress
|
||||
*/
|
||||
public function setEriref(string $eriref): TrProgress
|
||||
{
|
||||
$this->eriref = $eriref;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getHeading(): string
|
||||
{
|
||||
return $this->heading;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $heading
|
||||
* @return TrProgress
|
||||
*/
|
||||
public function setHeading(string $heading): TrProgress
|
||||
{
|
||||
$this->heading = $heading;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPrio(): string
|
||||
{
|
||||
return $this->prio;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $prio
|
||||
* @return TrProgress
|
||||
*/
|
||||
public function setPrio(string $prio): TrProgress
|
||||
{
|
||||
$this->prio = $prio;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getLastProgress(): int
|
||||
{
|
||||
return $this->lastProgress;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $lastProgress
|
||||
* @return TrProgress
|
||||
*/
|
||||
public function setLastProgress(int $lastProgress): TrProgress
|
||||
{
|
||||
$this->lastProgress = $lastProgress;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
function jsonSerialize()
|
||||
{
|
||||
return [
|
||||
'eriref' => $this->getEriref(),
|
||||
'heading' => $this->getHeading(),
|
||||
'prio' => $this->getPrio(),
|
||||
'lastProgress' => $this->getLastProgress(),
|
||||
];
|
||||
}
|
||||
}
|
||||
94
src/App/Entity/VacationDay.php
Normal file
94
src/App/Entity/VacationDay.php
Normal file
@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
|
||||
class VacationDay implements \JsonSerializable
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $day;
|
||||
|
||||
/**
|
||||
* @var string[]|ArrayCollection
|
||||
*/
|
||||
private $signums;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->signums = new ArrayCollection();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getDay(): int
|
||||
{
|
||||
return $this->day;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $day
|
||||
* @return VacationDay
|
||||
*/
|
||||
public function setDay(int $day): VacationDay
|
||||
{
|
||||
$this->day = $day;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ArrayCollection|string[]
|
||||
*/
|
||||
public function getSignums()
|
||||
{
|
||||
return $this->signums;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ArrayCollection|string[] $signums
|
||||
* @return VacationDay
|
||||
*/
|
||||
public function setSignums($signums): VacationDay
|
||||
{
|
||||
$this->signums = $signums;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $signum
|
||||
* @return VacationDay
|
||||
*/
|
||||
public function addSignum(string $signum): VacationDay
|
||||
{
|
||||
if(!$this->signums->contains($signum)) {
|
||||
$this->signums->add($signum);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $signum
|
||||
* @return VacationDay
|
||||
*/
|
||||
public function removeSignum(string $signum): VacationDay
|
||||
{
|
||||
if($this->signums->contains($signum)) {
|
||||
$this->signums->removeElement($signum);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
function jsonSerialize()
|
||||
{
|
||||
return [
|
||||
'day' => $this->getDay(),
|
||||
'signums' => $this->getSignums()->getValues(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -4,6 +4,8 @@ namespace App\Service;
|
||||
|
||||
use Zend\Cache\Storage\StorageInterface;
|
||||
use Zend\Config\Config;
|
||||
use Zend\Diactoros\Response;
|
||||
use Zend\Diactoros\Response\TextResponse;
|
||||
use Zend\Expressive\Router\RouterInterface;
|
||||
use Zend\Http\Client;
|
||||
|
||||
@ -72,6 +74,8 @@ class AvatarService
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns avatar image data as string
|
||||
*
|
||||
* @param string $signum
|
||||
* @return string
|
||||
*/
|
||||
@ -83,4 +87,18 @@ class AvatarService
|
||||
|
||||
return $this->cache->getItem($signum);
|
||||
}
|
||||
|
||||
public function getUserAvatarResponse(string $signum)
|
||||
{
|
||||
$localAvatarFile = "public/avatars/$signum";
|
||||
if(file_exists($localAvatarFile)) {
|
||||
$fp = fopen($localAvatarFile,"r+");
|
||||
$response = new Response($fp);
|
||||
} else {
|
||||
$response = new TextResponse($this->getAvatarData($signum));
|
||||
}
|
||||
|
||||
return $response
|
||||
->withHeader('Content-type', 'image/png');
|
||||
}
|
||||
}
|
||||
|
||||
70
src/App/Service/JcatInfoCollectorService.php
Normal file
70
src/App/Service/JcatInfoCollectorService.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use League\Csv\Reader;
|
||||
use League\Csv\Statement;
|
||||
use Zend\Config\Config;
|
||||
use Zend\Http\Client;
|
||||
|
||||
class JcatInfoCollectorService
|
||||
{
|
||||
/**
|
||||
* @var Config
|
||||
*/
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* @var Client
|
||||
*/
|
||||
private $httpClient;
|
||||
|
||||
|
||||
/**
|
||||
* JiraClientService constructor.
|
||||
* @param Client $client
|
||||
* @param Config $config
|
||||
*/
|
||||
public function __construct(Client $client, Config $config)
|
||||
{
|
||||
$this->httpClient = $client;
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
public function getTrFlow()
|
||||
{
|
||||
/** @var Config $kanbanBoardUriParams */
|
||||
$trFlowUri = $this->config->get('url.jcatTrFlow');
|
||||
|
||||
$response = $this->httpClient
|
||||
->setUri($trFlowUri)
|
||||
->send();
|
||||
|
||||
if (!$response->isSuccess()) {
|
||||
throw new \UnexpectedValueException("Bad JCAT result", $response->getStatusCode());
|
||||
}
|
||||
|
||||
return $this->parseFlowHtmlResult($response->getBody());
|
||||
}
|
||||
|
||||
private function parseFlowHtmlResult(string $html)
|
||||
{
|
||||
$xmlErrorHandling = libxml_use_internal_errors(TRUE);
|
||||
$domDocument = new \DOMDocument();
|
||||
$domDocument->loadHTML($html);
|
||||
libxml_clear_errors();
|
||||
libxml_use_internal_errors($xmlErrorHandling);
|
||||
|
||||
$documentXpath = new \DOMXPath($domDocument);
|
||||
/** @var \DOMNodeList $elements */
|
||||
$elements = $documentXpath->query('//tr/td[1]');
|
||||
|
||||
$result = [];
|
||||
/** @var \DOMElement $element */
|
||||
foreach ($elements as $element) {
|
||||
$result[] = trim($element->nodeValue);
|
||||
}
|
||||
|
||||
return array_count_values($result);
|
||||
}
|
||||
}
|
||||
18
src/App/Service/JcatInfoCollectorServiceFactory.php
Normal file
18
src/App/Service/JcatInfoCollectorServiceFactory.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use Interop\Container\ContainerInterface;
|
||||
use Zend\Config\Config;
|
||||
use Zend\Http\Client;
|
||||
|
||||
class JcatInfoCollectorServiceFactory
|
||||
{
|
||||
public function __invoke(ContainerInterface $container)
|
||||
{
|
||||
$configArray = $container->get('config');
|
||||
$httpClient = $container->get(Client::class);
|
||||
$config = new Config($configArray['app.config']);
|
||||
return new JcatInfoCollectorService($httpClient, $config);
|
||||
}
|
||||
}
|
||||
@ -41,6 +41,45 @@ class JiraCollectorService
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getExpedites(): array
|
||||
{
|
||||
$user = $this->config->get('jira.user');
|
||||
$password = $this->config->get('jira.password');
|
||||
/** @var Config $expediteUriParams */
|
||||
$expediteUriParams = $this->config->get('url.jiraTspExpedites');
|
||||
|
||||
$result = [];
|
||||
foreach ($expediteUriParams['filters'] as $type => $filterId) {
|
||||
|
||||
$jiraResultUri = sprintf(
|
||||
$expediteUriParams['baseUrl'],
|
||||
$filterId
|
||||
);
|
||||
|
||||
$response = $this->httpClient
|
||||
->setUri($jiraResultUri)
|
||||
->setAuth($user, $password)
|
||||
->send();
|
||||
|
||||
if(!$response->isSuccess()) {
|
||||
throw new \UnexpectedValueException(
|
||||
sprintf("Bad JIRA result when trying to load: %s\n%s",
|
||||
$jiraResultUri,
|
||||
$response->getBody()
|
||||
),
|
||||
$response->getStatusCode()
|
||||
);
|
||||
}
|
||||
|
||||
$parsedJsonData = Decoder::decode($response->getBody(), Json::TYPE_OBJECT);
|
||||
$result[$type] = $parsedJsonData->total;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return KanbanBoard
|
||||
*/
|
||||
@ -58,8 +97,8 @@ class JiraCollectorService
|
||||
);
|
||||
|
||||
$response = $this->httpClient
|
||||
->setAuth($user, $password)
|
||||
->setUri($kanbanBoardUri)
|
||||
->setAuth($user, $password)
|
||||
->send();
|
||||
|
||||
if(!$response->isSuccess()) {
|
||||
|
||||
@ -2,12 +2,27 @@
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use Symfony\Component\CssSelector\CssSelectorConverter;
|
||||
use App\Entity\TrProgress;
|
||||
use League\Csv\Reader;
|
||||
use League\Csv\Statement;
|
||||
use Zend\Config\Config;
|
||||
use Zend\Http\Client;
|
||||
|
||||
class TrInfoCollectorService
|
||||
{
|
||||
const UNIT_CORE = 'core';
|
||||
const UNIT_SIG = 'sig';
|
||||
const UNIT_TADE = 'tade';
|
||||
|
||||
const MHO_MAP = [
|
||||
'ETH-TSPCW-D' => self::UNIT_CORE,
|
||||
'ETH-TSPCORE' => self::UNIT_CORE,
|
||||
'XTS-TSP-SIG' => self::UNIT_SIG,
|
||||
'XTS-TSPSIGD' => self::UNIT_SIG,
|
||||
'ETH-TADE-DE' => self::UNIT_TADE,
|
||||
'ETH-TADE-MA' => self::UNIT_TADE,
|
||||
];
|
||||
|
||||
/**
|
||||
* @var Config
|
||||
*/
|
||||
@ -18,15 +33,6 @@ class TrInfoCollectorService
|
||||
*/
|
||||
private $httpClient;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $tempSensors = [
|
||||
'Temp 5' => 'back_left',
|
||||
'Temp 4' => 'back_middle',
|
||||
'Temp 3' => 'back_right',
|
||||
];
|
||||
|
||||
/**
|
||||
* JiraClientService constructor.
|
||||
* @param Client $client
|
||||
@ -38,49 +44,139 @@ class TrInfoCollectorService
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
public function getLabTemperatureData()
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getProgressInfo()
|
||||
{
|
||||
/** @var Config $labTemperatureUrl */
|
||||
$labTemperatureUrl = $this->config->get('url.labTemperatureUrl');
|
||||
$user = $this->config->get('mhweb.user');
|
||||
$password = $this->config->get('mhweb.password');
|
||||
/** @var string $trProgressUri */
|
||||
$trProgressUri = $this->config->get('url.mhWebTrProgress');
|
||||
|
||||
$response = $this->httpClient
|
||||
->setUri($labTemperatureUrl)
|
||||
->setAuth($user, $password)
|
||||
->setUri($trProgressUri)
|
||||
->send();
|
||||
|
||||
if(!$response->isSuccess()) {
|
||||
throw new \UnexpectedValueException("Bad LAB result", $response->getStatusCode());
|
||||
if (!$response->isSuccess()) {
|
||||
throw new \UnexpectedValueException("Bad MHWEB result", $response->getStatusCode());
|
||||
}
|
||||
|
||||
return $this->parseHtml($response->getBody());
|
||||
$csvResponse = $response->getBody();
|
||||
$csvReader = Reader::createFromString($csvResponse);
|
||||
$csvReader->setHeaderOffset(0);
|
||||
|
||||
return $this->parseProgressCsvRecords($csvReader);
|
||||
}
|
||||
|
||||
private function parseHtml($html): array
|
||||
public function getPraGoals()
|
||||
{
|
||||
$cssToXpathConverter = new CssSelectorConverter();
|
||||
$xpathLabelQuery = $cssToXpathConverter->toXPath('a.sensormenu.isnotpaused');
|
||||
$xpathValueQuery = $cssToXpathConverter->toXPath('div.graphlabel2');
|
||||
$user = $this->config->get('mhweb.user');
|
||||
$password = $this->config->get('mhweb.password');
|
||||
/** @var string $trProgressUri */
|
||||
$trProgressUri = $this->config->get('url.mhWebPraGoals');
|
||||
|
||||
$xmlErrorHandling = libxml_use_internal_errors(TRUE);
|
||||
$domDocument = new \DOMDocument();
|
||||
$domDocument->loadHTML($html);
|
||||
libxml_clear_errors();
|
||||
libxml_use_internal_errors($xmlErrorHandling);
|
||||
$response = $this->httpClient
|
||||
->setAuth($user, $password)
|
||||
->setUri($trProgressUri)
|
||||
->send();
|
||||
|
||||
$documentXpath = new \DOMXPath($domDocument);
|
||||
/** @var \DOMNodeList $element */
|
||||
$element = $documentXpath->query($xpathLabelQuery);
|
||||
if (!$response->isSuccess()) {
|
||||
throw new \UnexpectedValueException("Bad MHWEB result", $response->getStatusCode());
|
||||
}
|
||||
|
||||
$thing = [];
|
||||
/** @var \DOMElement $item */
|
||||
foreach($element as $item) {
|
||||
$sensorName = trim($item->nodeValue);
|
||||
if( in_array($sensorName, array_keys($this->tempSensors)) ){
|
||||
/** @var \DOMNodeList $element */
|
||||
$valueElement = $documentXpath->query($xpathValueQuery, $item->parentNode->parentNode);
|
||||
$thing[$this->tempSensors[$sensorName]] = $valueElement->item(0)->nodeValue;
|
||||
$csvResponse = $response->getBody();
|
||||
$csvReader = Reader::createFromString($csvResponse);
|
||||
$csvReader->setHeaderOffset(0);
|
||||
|
||||
$statement = new Statement();
|
||||
$csvRecords = $statement
|
||||
->process($csvReader);
|
||||
|
||||
$goalCounter = $this->initGoalCounter();
|
||||
|
||||
foreach ($csvRecords as $record) {
|
||||
$goalCounter[self::MHO_MAP[$record["mho"]]][$record["prio"]]++;
|
||||
}
|
||||
|
||||
return $this->caltulatePraBaseDiff($goalCounter);
|
||||
}
|
||||
|
||||
private function caltulatePraBaseDiff($goalCounter): array
|
||||
{
|
||||
$praBaseData = $this->config->get('pra.baseData');
|
||||
foreach ($goalCounter as $mho => &$counters) {
|
||||
foreach (['A', 'B', 'C'] as $prio) {
|
||||
$counters[$prio] = $counters[$prio] - $praBaseData[$mho][$prio];
|
||||
}
|
||||
}
|
||||
return $goalCounter;
|
||||
}
|
||||
|
||||
private function parseProgressCsvRecords(Reader $csvReader)
|
||||
{
|
||||
$statement = new Statement();
|
||||
$csvRecords = $statement
|
||||
->process($csvReader);
|
||||
|
||||
$trProgressList = [];
|
||||
|
||||
foreach ($csvRecords as $csvRecord) {
|
||||
$trProgress = new TrProgress();
|
||||
$trProgress->setEriref($csvRecord["eriref"])
|
||||
->setHeading($csvRecord["heading"])
|
||||
->setPrio($csvRecord["prio"])
|
||||
->setLastProgress($this->getLastProgressInDay($csvRecord))
|
||||
;
|
||||
|
||||
$trProgressList[] = $trProgress;
|
||||
}
|
||||
|
||||
usort($trProgressList, function(TrProgress $a, TrProgress $b){
|
||||
return $b->getLastProgress() <=> $a->getLastProgress();
|
||||
});
|
||||
|
||||
return $trProgressList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $csvRecord
|
||||
* @return int
|
||||
* @todo fix the BS with tuesday or whatever
|
||||
*/
|
||||
private function getLastProgressInDay(array $csvRecord): int
|
||||
{
|
||||
$lastProgressDate = null;
|
||||
$hasNoProgressDate = false;
|
||||
try {
|
||||
$lastProgressDate = new \DateTime(str_replace(" - "," ", $csvRecord["lastprogressdate"]));
|
||||
} catch(\Exception $e) {
|
||||
$hasNoProgressDate = true;
|
||||
}
|
||||
try {
|
||||
$lastDesignDate = new \DateTime($csvRecord["lastdesigndate"]);
|
||||
if($hasNoProgressDate || $lastDesignDate > $lastProgressDate) {
|
||||
$lastProgressDate = $lastDesignDate;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
if($hasNoProgressDate) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return $thing;
|
||||
$now = new \DateTime();
|
||||
$dateDiff = $now->diff($lastProgressDate);
|
||||
return $dateDiff->days;
|
||||
}
|
||||
|
||||
private function initGoalCounter(): array
|
||||
{
|
||||
$emptyPrios = ['A' => 0, 'B' => 0, 'C' => 0];
|
||||
return [
|
||||
self::UNIT_CORE => $emptyPrios,
|
||||
self::UNIT_SIG => $emptyPrios,
|
||||
self::UNIT_TADE => $emptyPrios,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,11 @@
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use Symfony\Component\CssSelector\CssSelectorConverter;
|
||||
use App\Entity\VacationDay;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use SVG\Nodes\Embedded\SVGImageElement;
|
||||
use SVG\Nodes\Shapes\SVGRect;
|
||||
use SVG\SVGImage;
|
||||
use Zend\Config\Config;
|
||||
use Zend\Http\Client;
|
||||
|
||||
@ -19,13 +23,9 @@ class VacationInfoCollectorService
|
||||
private $httpClient;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* @var VacationDay[]|ArrayCollection
|
||||
*/
|
||||
private $tempSensors = [
|
||||
'Temp 5' => 'back_left',
|
||||
'Temp 4' => 'back_middle',
|
||||
'Temp 3' => 'back_right',
|
||||
];
|
||||
private $vacations;
|
||||
|
||||
/**
|
||||
* JiraClientService constructor.
|
||||
@ -36,29 +36,71 @@ class VacationInfoCollectorService
|
||||
{
|
||||
$this->httpClient = $client;
|
||||
$this->config = $config;
|
||||
$this->vacations = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function getLabTemperatureData()
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isVacationSoon(): bool
|
||||
{
|
||||
/** @var Config $labTemperatureUrl */
|
||||
$labTemperatureUrl = $this->config->get('url.labTemperatureUrl');
|
||||
return count($this->getVacationData()) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function createVacationSvgImage(): string
|
||||
{
|
||||
$vacationData = $this->getVacationData();
|
||||
$svgImage = new SVGImage(1000,400);
|
||||
|
||||
|
||||
$doc = $svgImage->getDocument();
|
||||
|
||||
for ($i = 0; $i<5; $i++) {
|
||||
for($j=0; $j<3; $j++) {
|
||||
$rect = new SVGRect($i*40+5*$i+5, 40*$j+5*$j+5, 40, 40);
|
||||
$rect->setStyle('fill', '#0000FF');
|
||||
|
||||
$img = new SVGImageElement("/avatars/edvidan", $i*40+5*($i+1), 40*$j+5*$j+5, 20,20);
|
||||
|
||||
$doc->addChild($rect)
|
||||
->addChild($img);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// blue 40x40 square at (0, 0)
|
||||
|
||||
return $svgImage;
|
||||
}
|
||||
|
||||
public function getVacationData()
|
||||
{
|
||||
/** @var Config $vacationPageUrl */
|
||||
$vacationPageUrl = $this->config->get('url.vacation');
|
||||
|
||||
$response = $this->httpClient
|
||||
->setUri($labTemperatureUrl)
|
||||
->setUri($vacationPageUrl)
|
||||
->send();
|
||||
|
||||
if(!$response->isSuccess()) {
|
||||
throw new \UnexpectedValueException("Bad LAB result", $response->getStatusCode());
|
||||
throw new \UnexpectedValueException("Bad vacation result", $response->getStatusCode());
|
||||
}
|
||||
|
||||
return $this->parseHtml($response->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $html
|
||||
* @return VacationDay[]
|
||||
*/
|
||||
private function parseHtml($html): array
|
||||
{
|
||||
$cssToXpathConverter = new CssSelectorConverter();
|
||||
$xpathLabelQuery = $cssToXpathConverter->toXPath('a.sensormenu.isnotpaused');
|
||||
$xpathValueQuery = $cssToXpathConverter->toXPath('div.graphlabel2');
|
||||
$peopleQuery = '//table[@class="vacation"]//td[@class="v_user_h"]';
|
||||
|
||||
$xmlErrorHandling = libxml_use_internal_errors(TRUE);
|
||||
$domDocument = new \DOMDocument();
|
||||
@ -68,19 +110,63 @@ class VacationInfoCollectorService
|
||||
|
||||
$documentXpath = new \DOMXPath($domDocument);
|
||||
/** @var \DOMNodeList $element */
|
||||
$element = $documentXpath->query($xpathLabelQuery);
|
||||
$element = $documentXpath->query($peopleQuery);
|
||||
|
||||
$now = new \DateTime();
|
||||
$todaysDayNumber = intval($now->format("d"));
|
||||
$todaysWeekDay = intval($now->format("N"));
|
||||
|
||||
$thisWeekFirstDay = $todaysDayNumber - $todaysWeekDay + 1;
|
||||
$thisWeekLastDay = $thisWeekFirstDay + 4;
|
||||
$nextWeekFirstDay = $thisWeekFirstDay + 7;
|
||||
$nextWeekLastDay = $nextWeekFirstDay + 4;
|
||||
|
||||
$thing = [];
|
||||
/** @var \DOMElement $item */
|
||||
foreach($element as $item) {
|
||||
$sensorName = trim($item->nodeValue);
|
||||
if( in_array($sensorName, array_keys($this->tempSensors)) ){
|
||||
/** @var \DOMNodeList $element */
|
||||
$valueElement = $documentXpath->query($xpathValueQuery, $item->parentNode->parentNode);
|
||||
$thing[$this->tempSensors[$sensorName]] = $valueElement->item(0)->nodeValue;
|
||||
$thisWeekFirstDay = ($thisWeekFirstDay < 1)
|
||||
? 1
|
||||
: $thisWeekFirstDay;
|
||||
$dateCells = $documentXpath->query('..//td', $item);
|
||||
|
||||
// $user = trim($dateCells->item(0)->textContent);
|
||||
$signumHref = $dateCells->item(0)->firstChild->getAttribute('href');
|
||||
preg_match("/id=(.*)$/msi",$signumHref,$matchResult);
|
||||
$signum = $matchResult[1];
|
||||
|
||||
|
||||
for($i = $thisWeekFirstDay; $i < $thisWeekLastDay+1; $i++) {
|
||||
$vacationDay = $this->getVacationDay($i);
|
||||
$isVacation = $documentXpath->query(
|
||||
'.//div[@class="book book_n_v"]',
|
||||
$dateCells->item($i)
|
||||
);
|
||||
if ($isVacation->length) {
|
||||
$vacationDay->addSignum($signum);
|
||||
}
|
||||
}
|
||||
|
||||
for($i=$nextWeekFirstDay; $i<$nextWeekLastDay+1; $i++) {
|
||||
$vacationDay = $this->getVacationDay($i);
|
||||
$isVacation = $documentXpath->query(
|
||||
'.//div[@class="book book_n_v"]',
|
||||
$dateCells->item($i)
|
||||
);
|
||||
if ($isVacation->length) {
|
||||
$vacationDay->addSignum($signum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $thing;
|
||||
return $this->vacations->filter(function(VacationDay $item){
|
||||
return count($item->getSignums());
|
||||
})->getValues();
|
||||
}
|
||||
|
||||
private function getVacationDay(int $day): VacationDay
|
||||
{
|
||||
if(!isset($this->vacations[$day])) {
|
||||
$this->vacations[$day] = (new VacationDay())->setDay($day);
|
||||
}
|
||||
return $this->vacations[$day];
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user