Commit 214d3b46 authored by Dainis Abols's avatar Dainis Abols
Browse files

Added `LU Tools` section and Logo generation endpoint

v3.1.0
parent 63cdba43
......@@ -4,6 +4,7 @@ namespace Lu\LuApi\Controller;
use Lu\LuApi\DataSources\FileDownloader;
use Lu\LuApi\Generators\QRCodeGenerator;
use Lu\LuApi\Generators\LogoGenerator;
use Lu\LuApi\Helpers\ReturnPretty;
use Lu\LuApi\Models\Courses;
use Lu\LuApi\Models\CoursesContinue;
......@@ -114,6 +115,7 @@ class ExchangeController extends ActionController
/* SELF ENDING ROUTES */
case "download": FileDownloader::fetch(); break; // Direct file download from type and id
case "qrcode": QRCodeGenerator::create(); break; // QR Code generator from URL
case "logo": LogoGenerator::create(); break; // QR Code generator from URL
/* BASIC ROUTES */
case "course": $data = Courses::fetch(); break; // Study catalogue course
......
<?php
namespace Lu\LuApi\Generators;
use Lu\LuApi\Types\LogoFile;
use TYPO3\CMS\Core\Core\Environment;
/**
* Class LogoGenerator
* Generates current LU logos
*
* @author Dainis Abols <dainis.abols@lu.lv>
* @since 22.03.2022
*
* @package Lu\LuApi\Generators
*/
class LogoGenerator
{
/**
* Max qrcode image size
*
* @var string
*/
static private string $size = '300';
/**
* Return logo by rerquested data
*
* request: {type}_{weight}_{width}_{height}.{extension}
* example: full_light_w150_h50.png
* example: small_dark.svg (minimal request params)
*
* @param string $url
*/
static public function create($return = false)
{
// Fetch request values
$file = explode('.', explode('/', $_REQUEST['r'])[1]);
$request = explode('_', $file[0]);
// Set initial values
$myLogoFile = new LogoFile($file[1], $request);
// Check return type
$logo = 'lu_logo_'.$myLogoFile->getWeight()->toString().'_'.$myLogoFile->getOption()->toString().'.'.$myLogoFile->getExtension()->toString();
$logoPath = Environment::getPublicPath().'/typo3conf/ext/lu_api/Resources/Public/Logos/'.$logo;
switch ($myLogoFile->getExtension()->toString()) {
case "svg":
header('Content-type: image/svg+xml');
print file_get_contents($logoPath);
break;
case "png":
// Set a maximum height and width
$width = $myLogoFile->getWidth()->toInt();
$height = $myLogoFile->getHeight()->toInt();
// Get original dimensions and ration
[$width_orig, $height_orig] = getimagesize($logoPath);
$ratio_orig = $width_orig / $height_orig;
// Set default, if no size provided
if ($height == 0 && $width == 0) {
$width = self::$size;
}
// Calculate new dimensions
if ($height == 0) {
$height = $width / $ratio_orig;
} else {
if ($width == 0) {
$width = $height * $ratio_orig;
} else {
$height = $width / $ratio_orig;
}
}
// Content type
header('Content-Type: image/png');
// Fetch original image
$img = imagecreatefrompng($logoPath);
// Create blank image
$blank_img = imagecreatetruecolor($width, $height);
// Set image transparency
$transparent = imagecolorallocatealpha($blank_img, 0, 0, 0, 127);
// Add transparency to blank image
imagefill($blank_img, 0, 0, $transparent);
imagecolortransparent($blank_img, $transparent);
// Fill blank image with original image
imagecopyresampled($blank_img, $img, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);
// Print image
imagepng($blank_img);
break;
}
exit;
}
}
......@@ -86,6 +86,29 @@ class NabaLive implements RestModel
'programme' => $playModel->getCurrentProgramme(),
'songString' => $playModel->getCurrentSong(true),
];
// @TODO: add json output request in Naba/Play as $playModel->getCurrentJson();
// @TODO: add sending to LR in cron request call inside Naba extension!
/**
[
{
"station": 6,
"id": 3456,
"status": "playing",
"type": "song",
"airtime_utc": "2022-03-23T13:00:00.0006237Z",
"endtime_utc": "2022-03-23T13:02:40.0006237Z",
"artist": [
{
"name": "ŠŅK"
}
],
"title": "Nevajadzīgs",
"length": "160"
}
]
*/
}
return $data;
......
<?php
namespace Lu\LuApi\Types;
/**
* Extension type
*
* @author Dainis Abols <dainis.abols@lu.lv>
* @owner University of Latvia
* @since 22.03.2022
*/
class Extension extends TypeClass
{
use TypeMethods;
const SVG = 'svg';
const PNG = 'png';
/**
* Validates value
*
* @param $value
* @return
*/
public function validate($value)
{
if (!(strlen($value) > 0)) {
$bt = debug_backtrace()[1];
unset($bt['object']); unset($bt['args']); unset($bt['type']);
$this->logger->info(TypeErrors::EXTENSION_EMPTY . ": " . print_r($bt, true));
return null;
}
$value = trim($value, '.');
if (!in_array($value, [self::SVG, self::PNG])) {
$bt = debug_backtrace()[1];
unset($bt['object']); unset($bt['args']); unset($bt['type']);
$this->logger->info(printf(TypeErrors::EXTENSION_INVALID, $value) . ": " . print_r($bt, true));
return null;
}
return $value;
}
}
<?php
namespace Lu\LuApi\Types;
/**
* Height type
*
* @author Dainis Abols <dainis.abols@lu.lv>
* @owner University of Latvia
* @since 22.03.2022
*/
class Height extends TypeClass
{
use TypeMethods;
/**
* Validates value
*
* @param $value
* @return
*/
public function validate($value)
{
return $value;
}
}
<?php
namespace Lu\LuApi\Types;
/**
* Logo File type
*
* @author Dainis Abols <dainis.abols@lu.lv>
* @owner University of Latvia
* @since 22.03.2022
*/
class LogoFile
{
/**
* SVG or PNG etc
*
* @var \Lu\LuApi\Types\Extension
*/
private Extension $extension;
/**
* Small or Full etc
*
* @var \Lu\LuApi\Types\Option
*/
private Option $option;
/**
* Dark or light etc
*
* @var \Lu\LuApi\Types\Weight
*/
private Weight $weight;
/**
* Image width
*
* @var \Lu\LuApi\Types\Width
*/
private Width $width;
/**
* Image height
*
* @var \Lu\LuApi\Types\Height
*/
private Height $height;
/**
* Create object
*
* @param $extension
* @param $request
*/
public function __construct($extension = null, $request = null)
{
if ($extension == null || $request == null) {
exit;
}
// Set defaults
$this->setExtension(new Extension($extension));
$this->setOption(new Option(Option::FULL));
$this->setWeight(new Weight(Weight::DARK));
$this->setWidth(new Width(0));
$this->setHeight(new Height(0));
// Set midifications
foreach ($request as $item) {
switch ($item) {
case "full":
case "small":
$this->setOption(new Option($item));
break;
case "dark":
case "light":
$this->setWeight(new Weight($item));
break;
default:
switch (substr($item, 0, 1)) {
case "w":
if (substr($item, 1) == substr($item, 1) * 1) {
$this->setWidth(new Width(substr($item, 1)));
}
break;
case "h":
if (substr($item, 1) == substr($item, 1) * 1) {
$this->setHeight(new Height(substr($item, 1)));
}
break;
}
}
}
}
/**
* @return \Lu\LuApi\Types\Extension
*/
public function getExtension(): Extension
{
return $this->extension;
}
/**
* @param \Lu\LuApi\Types\Extension $extension
*/
public function setExtension(Extension $extension): void
{
$this->extension = $extension;
}
/**
* @return \Lu\LuApi\Types\Option
*/
public function getOption(): Option
{
return $this->option;
}
/**
* @param \Lu\LuApi\Types\Option $option
*/
public function setOption(Option $option): void
{
$this->option = $option;
}
/**
* @return \Lu\LuApi\Types\Weight
*/
public function getWeight(): Weight
{
return $this->weight;
}
/**
* @param \Lu\LuApi\Types\Weight $weight
*/
public function setWeight(Weight $weight): void
{
$this->weight = $weight;
}
/**
* @return \Lu\LuApi\Types\Width
*/
public function getWidth(): Width
{
return $this->width;
}
/**
* @param \Lu\LuApi\Types\Width $width
*/
public function setWidth(Width $width): void
{
$this->width = $width;
}
/**
* @return \Lu\LuApi\Types\Height
*/
public function getHeight(): Height
{
return $this->height;
}
/**
* @param \Lu\LuApi\Types\Height $height
*/
public function setHeight(Height $height): void
{
$this->height = $height;
}
}
<?php
namespace Lu\LuApi\Types;
/**
* Option type
*
* @author Dainis Abols <dainis.abols@lu.lv>
* @owner University of Latvia
* @since 22.03.2022
*/
class Option extends TypeClass
{
use TypeMethods;
const FULL = 'full';
const SMALL = 'small';
/**
* Validates value
*
* @param $value
* @return
*/
public function validate($value)
{
if (!(strlen($value) > 0)) {
$bt = debug_backtrace()[1];
unset($bt['object']); unset($bt['args']); unset($bt['type']);
$this->logger->info(TypeErrors::OPTION_EMPTY . ": " . print_r($bt, true));
return null;
}
if (!in_array($value, [self::FULL, self::SMALL])) {
$bt = debug_backtrace()[1];
unset($bt['object']); unset($bt['args']); unset($bt['type']);
$this->logger->info(printf(TypeErrors::OPTION_INVALID, $value) . ": " . print_r($bt, true));
return null;
}
return $value;
}
}
......@@ -15,4 +15,10 @@ class TypeErrors
const TABLE_NAME_EMPTY = "Empty database table provided";
const REQUEST_TYPE_EMPTY = "Empty request type provided";
const REQUEST_TYPE_INVALID = "Invalid request type provided [%s]";
const EXTENSION_EMPTY = "Empty extension provided";
const EXTENSION_INVALID = "Invalid extension provided [%s]";
const OPTION_EMPTY = "Empty option provided";
const OPTION_INVALID = "Invalid option provided [%s]";
const WEIGHT_EMPTY = "Empty weight provided";
const WEIGHT_INVALID = "Invalid weight provided [%s]";
}
\ No newline at end of file
<?php
namespace Lu\LuApi\Types;
/**
* Weight type
*
* @author Dainis Abols <dainis.abols@lu.lv>
* @owner University of Latvia
* @since 22.03.2022
*/
class Weight extends TypeClass
{
use TypeMethods;
const LIGHT = 'light';
const DARK = 'dark';
/**
* Validates value
*
* @param $value
* @return
*/
public function validate($value)
{
if (!(strlen($value) > 0)) {
$bt = debug_backtrace()[1];
unset($bt['object']); unset($bt['args']); unset($bt['type']);
$this->logger->info(TypeErrors::WEIGHT_EMPTY . ": " . print_r($bt, true));
return null;
}
if (!in_array($value, [self::LIGHT, self::DARK])) {
$bt = debug_backtrace()[1];
unset($bt['object']); unset($bt['args']); unset($bt['type']);
$this->logger->info(printf(TypeErrors::WEIGHT_INVALID, $value) . ": " . print_r($bt, true));
return null;
}
return $value;
}
}
<?php
namespace Lu\LuApi\Types;
/**
* Width type
*
* @author Dainis Abols <dainis.abols@lu.lv>
* @owner University of Latvia
* @since 22.03.2022
*/
class Width extends TypeClass
{
use TypeMethods;
/**
* Validates value
*
* @param $value
* @return
*/
public function validate($value)
{
return $value;
}
}
......@@ -14,6 +14,12 @@
<trans-unit id="plugin.title">
<source><![CDATA[API]]></source>
</trans-unit>
</body>
<trans-unit id="mlang_labels_tablabel">
<source>LU Tools administration</source>
</trans-unit>
<trans-unit id="mlang_tabs_tab">
<source>LU Tools</source>
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -17,6 +17,15 @@
<source><![CDATA[API]]></source>
<target><![CDATA[API]]></target>
</trans-unit>
</body>
<trans-unit id="mlang_labels_tablabel">
<source>LU Tools administration</source>
<target>LU Tools administration</target>
</trans-unit>
<trans-unit id="mlang_tabs_tab">
<source>LU Tools</source>
<target>LU Tools</target>
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 337 108" style="enable-background:new 0 0 337 108;" xml:space="preserve">
<style type="text/css">
.st0{fill:#1B5089;}
.st1{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
</style>
<g>
<path class="st0" d="M56.5,1c-29.3,0-53,23.7-53,52.9s23.7,52.9,52.9,52.9s52.9-23.7,52.9-52.9C109.4,24.7,85.7,1,56.5,1"/>
<path class="st1" d="M62.3,73.3c0.4-0.1,1-0.6,1.4-0.5c0.1,0,0.1,0.1,0.2,0.3c0,0.1,0,0.1,0,0.2s0,0.2,0,0.3c0,1.2,0,2.3,0,3.5
c0,0.5,0.1,1,0.1,1.6c0,0.3,0.1,0.6,0.1,0.9c0,0.2,0.1,0.4,0.1,0.6c0,0.1,0.1,0.2,0.2,0.3l0.1,0.1c0.3,0.3,0.7,0.5,1,0.7l0.1,0.1
c0.4,0.4,0.7,0.7,1.1,1.1c0.4,0.5,0.8,1,1.1,1.5c0.3,0.4,0.5,0.8,0.7,1.3c0,0.1,0,0.2,0,0.2c0,0.1-0.1,0.2-0.3,0.2h-0.1L67.5,86
c-0.2,0-0.3,0.1-0.4,0.1s-0.1,0-0.2,0c-0.4-0.1-0.7-0.2-1-0.4l-3.6-1.5c-0.8-0.3-1-0.2-1.2-1.1c-0.1-0.3-0.2-0.7-0.3-1
c-0.1-0.6-0.2-1.3-0.4-2c0-0.2-0.1-0.6-0.3-0.7l0,0H60c-0.2,0.1-0.2,0.5-0.2,0.7c-0.2,1-0.2,1.7-0.5,2.9c-0.1,0.4-0.3,0.8-0.5,1.1
c-0.3,0.6-0.8,1.1-1.2,1.6c-0.1,0.1-0.8,0.6-0.9,0.6c-0.4,0.1-0.8,0-1.1-0.4l-0.9-1.4c-0.2-0.3-0.4-0.6-0.6-0.9
c-0.1-0.1-0.2-0.3-0.2-0.5s0-0.4,0-0.6c0.1-1.1,0.2-2.2,0.3-3.4c0-0.9,0.1-1.8,0-2.8c0-0.2,0-0.4,0-0.6v-0.1
c-0.1-0.6-0.1-0.8-0.3-0.8c-0.1,0-0.1,0-0.2,0c-0.1,0.1-0.2,1.1-0.2,1.3c-0.3,2.2-0.4,5-1.8,6.8c-0.4,0.5-0.8,0.9-1.2,0.9h-1h-0.3
L48,84.4c-0.1,0.1-0.2,0.1-0.3,0.1c-0.7,0.3-1.5,0.5-2.2,0.3c-0.1,0-0.1,0-0.2,0c-0.3-0.1-0.5-0.2-0.3-0.5c0.2-0.4,0.4-0.7,0.6-1.1
c0.3-0.6,0.9-1.6,1.4-2.1c0.7-0.6,2.2-1.7,2.5-2.6c0-0.1,0.1-0.1,0.1-0.2c0.3-1.5,0.2-5.4,0.1-7.1c0-0.2,0-0.3-0.1-0.5
c0-0.2-0.1-0.4-0.2-0.6c-0.4-1-0.8-2.1-1.1-3.1c-0.1-0.3-0.1-0.5-0.2-0.8c-0.1-0.2-0.2-0.3-0.3-0.5s-0.3-0.2-0.5-0.3
c-0.9-0.4-2-0.8-2.9-1.3c-0.5-0.3-1-0.5-1.5-0.8c-0.2-0.1-0.3-0.3-0.4-0.4c-0.2-0.3-0.3-0.7-0.2-1c0.2-0.4,0.7-0.3,1-0.2
c0.1,0,0.2,0.1,0.3,0.1c0.7,0.3,1.8,0.6,2.1,0.6c0.2,0,0.3-0.1,0.2-0.4c0-0.1-0.1-0.2-0.1-0.3s-0.1-0.2-0.1-0.2
c-0.1-0.1-0.1-0.2-0.2-0.3c-0.5-0.8-0.8-1.4-1.2-2.4c0-0.1-0.1-0.2-0.1-0.3c-0.2-0.7,0.5-0.9,0.9-0.6c0.2,0.1,0.4,0.4,0.5,0.6
c0.7,1,1.2,2.2,2,3.3c0.4,0.5,0.5,0.6,1,0.9c0.6,0.3,1.1,0.6,1.7,1c0.4,0.3,0.9,1.5,1.1,1.9c0.3,0.7,0.7,1.5,1,2.2
c0.4,1.1,0.7,2,0.9,3c0.1,0.5,0.2,0.9,0.3,1.4c0,0.2,0.1,0.3,0.3,0.3s0.2-0.5,0.3-0.8c0-0.1,0-0.3,0-0.3c0-0.1,0-0.2,0-0.3
c0-0.2,0-0.3,0-0.6c0-0.4,0-0.8-0.1-1.2c0-0.3,0-0.6-0.1-0.9c-0.2-1.1-1.3-3-1.9-4c-0.6-1.1-1.8-3-2.5-3.9
c-0.2-0.3-1.7-1.1-2.3-1.8c-0.2-0.2-0.2-0.5-0.1-0.7c0.1-0.2,0.1-0.3,0.3-0.3c0.1-0.1,0.2-0.1,0.4-0.1s0.8,0.3,1.3,0.5
c0.2,0.1,0.5,0.3,0.7,0.2s0.3-0.2,0.3-0.4s0-0.6,0-0.9c0-0.3,0-0.3,0-0.5c0.1-0.3,0.3-0.4,0.4-0.3c0.4,0.1,0.6,0.7,0.6,1.1
c0,0.4,0,1.2,0.3,2c0.1,0.5,0.4,1.1,0.9,1.5c0.9,0.9,1.4,1.5,2,2.3c0.3,0.5,0.4,1.1,0.4,1.7c0,0.1,0,0.4,0.1,0.5
c0,0.1,0.2,0.2,0.2,0.2c0.2,0,0.4-0.1,0.4-0.3c0-0.2,0-0.4,0-0.6s0-0.4,0-0.5c0-0.2,0-0.3,0-0.5c0-0.3,0-0.6-0.1-0.8
c0-0.1,0-0.2-0.1-0.3s-0.1-0.2-0.2-0.4c-0.6-0.8-1.3-1.7-1.8-2.6c-0.4-0.8-0.7-1.7-1-2.5c-0.6-1.3-2-3.4-3.1-4.1
c-0.2-0.1-0.8-0.4-1.1-0.6c0,0-0.1,0-0.1-0.1c-0.1-0.1-0.2-0.1-0.2-0.2c-0.2-0.2,0-0.6,0.3-0.7c0.1,0,0.1,0,0.2,0
c0.4,0.1,0.8,0.3,1.2,0.3c0.1,0,0.1,0,0.2-0.1c0.1-0.1,0.1-0.1,0.1-0.2c0-0.2,0-0.4,0-0.6c-0.1-0.6-0.4-1.3-0.5-2
c0-0.3,0-0.4,0-0.6c0.1-0.3,0.2-0.5,0.5-0.6c0.4-0.1,0.7,0.5,0.8,0.8c0,0.1,0.1,0.2,0.1,0.3c0.4,1.9,0.8,3.2,1.8,4.4
c0.6,0.8,1.5,1.5,2.3,2.1c0.2,0.2,0.4,0.4,0.5,0.4s0.1,0.1,0.1,0.1c0.2,0.1,0.2,0.1,0.3,0c0.1-0.2,0-0.6-0.1-0.7
c-0.1-0.1-0.3-0.4-0.4-0.6c-0.3-0.5-0.6-1-0.7-1.4c0-0.1,0-0.2,0-0.3s0-0.2,0-0.3c0.1-0.4,0.1-0.7,0.2-1c0-0.1,0-0.3,0-0.5
c0-0.1,0-0.2,0-0.3c0-0.5-0.3-1.9-0.1-2.3c0-0.1,0.1-0.1,0.2-0.2c0.1-0.1,0.1-0.1,0.2-0.1c0.2-0.1,0.4-0.2,0.6-0.3
c0.2-0.1,0.4-0.1,0.6,0c0.1,0,0.2,0,0.2,0.1c0.1,0,0.2,0.2,0.3,0.3c0.5,0.7,0.6,1.8,1,2.7c0,0.1,0.1,0.3,0.2,0.4
c0.1,0.2,0.3,0.5,0.4,0.6c0.1,0.1,0.2,0.1,0.4,0c0.1-0.1,0.1-0.1,0.1-0.2c0-0.1,0-0.4-0.1-0.6c0-0.1,0-0.1,0-0.2c0-0.1,0-0.2,0-0.3
s0-0.2,0-0.3s0-0.1,0.1-0.2c0.6-1,0.9-2.6,1.1-3.8c0.1-0.5,0.4-0.6,0.7-0.7h0.1c0.1,0,0.3,0,0.4,0c0.1,0,0.1,0,0.2,0
c0.6,0.1,0.6,0.5,0.6,1.1c0,0.1,0,0.1,0,0.2c-0.1,1.1-0.1,2.2-0.2,3.3c0,0.2,0,0.3,0,0.5c0.1,1-0.5,1-1,1c-0.8,0.1-1.3,0.4-1.5,1.1
c0,0.1-0.1,0.3-0.2,0.4c0,0.1-0.1,0.3-0.1,0.4c-0.1,0.2-0.1,0.4-0.2,0.6c-0.1,0.4-0.3,0.9,0,1.4c0.1,0.2,0.2,0.4,0.2,0.6
c0.1,0.4-0.2,0.8-0.5,1.1c-0.6,0.6-1.1,0.6-1.2,2c-0.1,0.9,0.5,2.1,1.4,2.5c0.2,0.1,0.5,0.1,0.7,0.1c0.1,0,0.4-0.1,0.5-0.1h0.1
c0.4-0.1,0.4,0,0.7,0.2c1.1,0.7,2.2,0.1,2.7-0.6c0.2-0.2,0.3-0.5,0.6-0.6c0,0,0,0,0.1,0c0.2,0,0.4,0,0.5,0.2
c0.1,0.1-0.2,1.3-0.3,1.8c0,0,0,0.1-0.1,0.1c-0.3,0.4-0.7,0.8-1,1.2c-0.2,0.2-0.4,0.4-0.5,0.7c-0.1,0.1-0.2,0.3-0.3,0.4