Rebuild
This commit is contained in:
211
web/modules/custom/ufc/src/Controller/DcjsRouteController.php
Normal file
211
web/modules/custom/ufc/src/Controller/DcjsRouteController.php
Normal file
@@ -0,0 +1,211 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\ufc\Controller;
|
||||
|
||||
use Drupal\Core\Controller\ControllerBase;
|
||||
use Drupal\Core\Entity\EntityTypeManager;
|
||||
use Drupal\Core\StreamWrapper\StreamWrapperManager;
|
||||
use Drupal\Core\Render\Renderer;
|
||||
use Drupal\node\NodeInterface;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\media\Entity\Media;
|
||||
use Drupal\file\Entity\File;
|
||||
use Drupal\Core\Cache\CacheableResponse;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
// use Symfony\Component\HttpFoundation\Response;
|
||||
// use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class DcjsRouteController extends ControllerBase {
|
||||
|
||||
/**
|
||||
* The entity type manager service.
|
||||
*
|
||||
* @var Drupal\Core\Entity\EntityTypeManager
|
||||
* The entity type manager service.
|
||||
*/
|
||||
protected $entityTypeManager;
|
||||
|
||||
/**
|
||||
* The renderer service.
|
||||
*
|
||||
* @var \Drupal\Core\Render\Renderer
|
||||
* The renderer service.
|
||||
*/
|
||||
protected $renderer;
|
||||
|
||||
/**
|
||||
* The Stream Wrapper Manager service.
|
||||
*
|
||||
* @var \Drupal\Core\StreamWrapper\StreamWrapperManager
|
||||
* Stream wrapper manager service.
|
||||
*/
|
||||
protected $streamWrapperManager;
|
||||
|
||||
|
||||
/**
|
||||
* Public constructor.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityTypeManager $entityTypeManager
|
||||
* The entity type manager service.
|
||||
*
|
||||
* @var \Drupal\Core\Render\Renderer $renderer
|
||||
* The renderer service.
|
||||
*
|
||||
* @var \Drupal\Core\StreamWrapper\StreamWrapperManager $streamWrapperManager
|
||||
* The stream wrapper manager service.
|
||||
*
|
||||
*/
|
||||
public function __construct(
|
||||
EntityTypeManager $entityTypeManager,
|
||||
Renderer $renderer,
|
||||
StreamWrapperManager $streamWrapperManager
|
||||
) {
|
||||
$this->entityTypeManager = $entityTypeManager;
|
||||
$this->renderer = $renderer;
|
||||
$this->streamWrapperManager = $streamWrapperManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
// Instantiates this form class.
|
||||
return new static(
|
||||
// Load the service required to construct this class.
|
||||
$container->get('entity_type.manager'),
|
||||
$container->get('renderer'),
|
||||
$container->get('stream_wrapper_manager'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Not working right now.
|
||||
*/
|
||||
private function validateDcjsUserAgent(Request $request): bool {
|
||||
$user_agent = $request->headers->get('user-agent');
|
||||
if ($user_agent !== "DCJS Fetcher") {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all fighters to serve via DCJS.
|
||||
*
|
||||
* @return array<string,string>
|
||||
*/
|
||||
public function allFightersForDcjs(): CacheableResponse {
|
||||
$query = $this->entityTypeManager->getStorage('node')->getQuery();
|
||||
$query->accessCheck(TRUE);
|
||||
$query->condition('type', 'fighter')->sort('title', 'ASC');
|
||||
$query->range(0, 200);
|
||||
$nids = $query->execute();
|
||||
$all_fighters = Node::loadMultiple($nids);
|
||||
$fighter_data = [];
|
||||
foreach ($all_fighters as $fighter) {
|
||||
$photo_mid = $fighter->field_player_photo->target_id;
|
||||
$fighter_id = $fighter->id();
|
||||
$link_to_content = "/node/$fighter_id";
|
||||
$fighter_name = $fighter->title->value;
|
||||
$photo_uri = $this->retrievePhotoUri($photo_mid);
|
||||
$fighter_data[] = [
|
||||
'link' => $link_to_content,
|
||||
'name' => $fighter_name,
|
||||
'picUrl' => $photo_uri,
|
||||
];
|
||||
}
|
||||
$build = [
|
||||
'#theme' => 'fighters_dcjs_list',
|
||||
'#fighters' => $fighter_data,
|
||||
];
|
||||
|
||||
return new CacheableResponse($this->renderer->renderPlain($build));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an individual fighter.
|
||||
*/
|
||||
public function fighterForDcjs(NodeInterface $fighter_node): CacheableResponse {
|
||||
$personal_fields = [
|
||||
'age',
|
||||
'division',
|
||||
'height',
|
||||
'weight',
|
||||
'reach',
|
||||
'leg_reach',
|
||||
];
|
||||
$stats_fields = [
|
||||
'knockouts',
|
||||
'striking_accuracy',
|
||||
'strikes_per_minute',
|
||||
'sig_strike_defense',
|
||||
'absorbed_per_min',
|
||||
'standing_strikes',
|
||||
'clinch_strikes',
|
||||
'ground_strikes',
|
||||
'grappling_accuracy',
|
||||
'strikes_to_head',
|
||||
'strikes_to_body',
|
||||
'strikes_to_leg',
|
||||
'knockdown_ratio',
|
||||
'takedowns_per_15',
|
||||
'takedown_defense',
|
||||
'average_fight_time',
|
||||
'first_round_finishes',
|
||||
];
|
||||
|
||||
$fighter_build = [
|
||||
'#theme' => 'fighter_for_dcjs',
|
||||
'#node' => $fighter_node,
|
||||
'#personal_info' => $this->getFieldValuesFromNode($fighter_node, $personal_fields),
|
||||
'#stats' => $this->getFieldValuesFromNode($fighter_node, $stats_fields),
|
||||
];
|
||||
|
||||
$rendered = $this->renderer->renderPlain($fighter_build);
|
||||
|
||||
return new CacheableResponse($rendered);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Extracts target field values from a node.
|
||||
*
|
||||
* @param NodeInterface $node
|
||||
* The node.
|
||||
*
|
||||
* @param array[] $retrieve
|
||||
* The fields to retrieve
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
private function getFieldValuesFromNode(NodeInterface $node, array $retrieve): array {
|
||||
$return_data = [];
|
||||
foreach ($retrieve as $field_name) {
|
||||
$field_name_with_prefix = "field_$field_name";
|
||||
if ($field_name == 'division') {
|
||||
$div_id = $node->get($field_name_with_prefix)->target_id;
|
||||
$term = $this->entityTypeManager->getStorage('taxonomy_term')->load($div_id);
|
||||
$return_data['division'] = $term->getName();
|
||||
}
|
||||
else {
|
||||
$return_data[$field_name] = $node->{$field_name_with_prefix}->value;
|
||||
}
|
||||
}
|
||||
|
||||
return $return_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve URI for a player photo.
|
||||
*/
|
||||
private function retrievePhotoUri(int $media_id): string {
|
||||
$player_fid = Media::load($media_id)->field_media_image->target_id;
|
||||
$file = File::load($player_fid);
|
||||
if ($wrapper = $this->streamWrapperManager->getViaUri($file->getFileUri())) {
|
||||
|
||||
return $wrapper->getExternalUrl();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\ufc\Controller;
|
||||
|
||||
use Drupal\Core\Controller\ControllerBase;
|
||||
use Drupal\Core\Entity\EntityTypeManager;
|
||||
use Drupal\node\NodeInterface;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\media\Entity\Media;
|
||||
use Drupal\file\Entity\File;
|
||||
use Drupal\Core\Cache\CacheableJsonResponse;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class FightTrainingController extends ControllerBase {
|
||||
|
||||
/*
|
||||
* Fields holding fighter data.
|
||||
*/
|
||||
protected $fields = [
|
||||
'age',
|
||||
'height',
|
||||
'reach',
|
||||
'leg_reach',
|
||||
'knockouts',
|
||||
'striking_accuracy',
|
||||
'strikes_per_minute',
|
||||
'sig_strike_defense',
|
||||
'absorbed_per_min',
|
||||
'standing_strikes',
|
||||
'clinch_strikes',
|
||||
'ground_strikes',
|
||||
'grappling_accuracy',
|
||||
'strikes_to_head',
|
||||
'strikes_to_body',
|
||||
'strikes_to_leg',
|
||||
'knockdown_ratio',
|
||||
'takedowns_per_15',
|
||||
'takedown_defense',
|
||||
'average_fight_time',
|
||||
'first_round_finishes',
|
||||
];
|
||||
|
||||
/**
|
||||
* The entity type manager service.
|
||||
*
|
||||
* @var Drupal\Core\Entity\EntityTypeManager
|
||||
* The entity type manager service.
|
||||
*/
|
||||
protected $entityTypeManager;
|
||||
|
||||
/**
|
||||
* Public constructor.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityTypeManager $entityTypeManager
|
||||
* The entity type manager service.
|
||||
*
|
||||
*/
|
||||
public function __construct(
|
||||
EntityTypeManager $entityTypeManager
|
||||
) {
|
||||
$this->entityTypeManager = $entityTypeManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
// Instantiates this form class.
|
||||
return new static(
|
||||
// Load the service required to construct this class.
|
||||
$container->get('entity_type.manager'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates all fighting data for training NN.
|
||||
*/
|
||||
public function generateTrainingData(): CacheableJsonResponse {
|
||||
// Go get all fights.
|
||||
$all_fights = $this->entityTypeManager->getStorage('node')->loadByProperties(['type' => 'fight']);
|
||||
$training_data = [];
|
||||
foreach ($all_fights as $fight) {
|
||||
$train_array = [
|
||||
'input' => [],
|
||||
'output' => [],
|
||||
];
|
||||
// Ensure we have a winner.
|
||||
if (!$fight->field_result->target_id) {
|
||||
continue;
|
||||
}
|
||||
// Extract fighters.
|
||||
$fighter_one_id = $fight->field_fighter_one->target_id;
|
||||
$fighter_two_id = $fight->field_fighter_two->target_id;
|
||||
|
||||
if (!$fighter_one_id || !$fighter_two_id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$fighter_one_data = $this->getFighterData($fighter_one_id);
|
||||
$fighter_two_data = $this->getFighterData($fighter_two_id, FALSE);
|
||||
|
||||
if (empty($fighter_one_data) || empty($fighter_two_data)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$train_array['input'] = array_merge($fighter_one_data, $fighter_two_data);
|
||||
|
||||
if ($fight->field_result->target_id == $fighter_one_id) {
|
||||
$train_array['output'] = [
|
||||
'fighter_one' => 1,
|
||||
'fighter_two' => 0,
|
||||
];
|
||||
$training_data[] = $train_array;
|
||||
}
|
||||
else if ($fight->field_result->target_id == $fighter_two_id) {
|
||||
$train_array['output'] = [
|
||||
'fighter_one' => 0,
|
||||
'fighter_two' => 1,
|
||||
];
|
||||
$training_data[] = $train_array;
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return new CacheableJsonResponse($training_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves data about a specific fight for predictions.
|
||||
*/
|
||||
public function getFightData(NodeInterface $fight): CacheableJsonResponse {
|
||||
$fighter_1_id = $fight->field_fighter_one->target_id;
|
||||
$fighter_2_id = $fight->field_fighter_two->target_id;
|
||||
|
||||
$fight_data = array_merge(
|
||||
$this->getFighterData($fighter_1_id),
|
||||
$this->getFighterData($fighter_2_id, FALSE),
|
||||
);
|
||||
|
||||
return new CacheableJsonResponse($fight_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fighter data.
|
||||
*
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
private function getFighterData(int $id, bool $is_f1 = TRUE): array {
|
||||
if ($is_f1) {
|
||||
$prefix = 'fighter_one_';
|
||||
}
|
||||
else {
|
||||
$prefix = 'fighter_two_';
|
||||
}
|
||||
|
||||
$extracted_values = $this->extractValuesFromFields($id, $this->fields, $prefix);
|
||||
|
||||
return $this->normalizeData($extracted_values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts a value from a given field (cannot be ent reference)
|
||||
*/
|
||||
private function extractValuesFromFields(int $id, array $field_names, string $prefix): mixed {
|
||||
$fighter = Node::load($id);
|
||||
$values = [];
|
||||
|
||||
foreach ($field_names as $field) {
|
||||
$value_key = $prefix . $field;
|
||||
$field_machine_name = 'field_' . $field;
|
||||
$values[$value_key] = $fighter->{$field_machine_name}->value ?? 0;
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize the field value.
|
||||
*
|
||||
* This needs to be between 0-1
|
||||
*/
|
||||
private function normalizeData(array $data): array {
|
||||
$min = min(array_values($data));
|
||||
$max = max(array_values($data));
|
||||
$normalized = [];
|
||||
foreach ($data as $key => $value) {
|
||||
$norm_val = 0;
|
||||
if ($max - $min == 0) {
|
||||
$normalized[$key] = $norm_val;
|
||||
}
|
||||
else {
|
||||
$norm_val = ($value - $min) / ($max - $min);
|
||||
$normalized[$key] = $norm_val;
|
||||
}
|
||||
}
|
||||
|
||||
return $normalized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the trained neural network.
|
||||
*/
|
||||
public function getNeuralNetwork(): CacheableJsonResponse {
|
||||
$build = [];
|
||||
$cur_network = \Drupal::state()->get('neuralNetwork') ?? FALSE;
|
||||
if (!$cur_network) {
|
||||
$build['ERROR'] = "There is no spoon.";
|
||||
}
|
||||
else {
|
||||
$build['data'] = base64_decode($cur_network);
|
||||
}
|
||||
|
||||
return new CacheableJsonResponse($build);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user