Merge branch 'danielbrendel:main' into main

This commit is contained in:
2024-04-09 04:56:04 -07:00
committed by GitHub
13 changed files with 420 additions and 40 deletions

6
app/config/cache.php Normal file
View File

@ -0,0 +1,6 @@
<?php
return [
'driver' => env('CACHE_DRIVER', null),
'duration' => env('CACHE_DURATION', 123)
];

View File

@ -26,7 +26,7 @@ class ApiController extends BaseController {
$appid = $request->params()->query('appid', null);
$language = $request->params()->query('lang', 'english');
$data = SteamApp::querySteamData($appid, $language);
$data = SteamCache::cachedSteamApp($appid, $language);
HitsModel::addHit(HitsModel::HITTYPE_MODULE_APP);
@ -47,7 +47,7 @@ class ApiController extends BaseController {
try {
$addr = $request->params()->query('addr', null);
$data = SteamServer::querySteamData(env('STEAM_API_KEY'), $addr);
$data = SteamCache::cachedSteamServer(env('STEAM_API_KEY'), $addr);
HitsModel::addHit(HitsModel::HITTYPE_MODULE_SERVER);
@ -68,7 +68,7 @@ class ApiController extends BaseController {
try {
$steamid = $request->params()->query('steamid', null);
$data = SteamUser::querySteamData(env('STEAM_API_KEY'), $steamid);
$data = SteamCache::cachedSteamUser(env('STEAM_API_KEY'), $steamid);
HitsModel::addHit(HitsModel::HITTYPE_MODULE_USER);
@ -89,7 +89,7 @@ class ApiController extends BaseController {
try {
$itemid = $request->params()->query('itemid', null);
$data = SteamWorkshop::querySteamData($itemid);
$data = SteamCache::cachedSteamWorkshop($itemid);
HitsModel::addHit(HitsModel::HITTYPE_MODULE_WORKSHOP);
@ -110,7 +110,7 @@ class ApiController extends BaseController {
try {
$group = $request->params()->query('group', null);
$data = SteamGroup::querySteamData($group);
$data = SteamCache::cachedSteamGroup($group);
HitsModel::addHit(HitsModel::HITTYPE_MODULE_GROUP);

View File

@ -0,0 +1,49 @@
<?php
/*
Asatru PHP - Migration vor Caching
*/
class CacheModel_Migration {
private $database = null;
private $connection = null;
/**
* Construct class and store PDO connection handle
*
* @param \PDO $pdo
* @return void
*/
public function __construct($pdo)
{
$this->connection = $pdo;
}
/**
* Called when the table shall be created or modified
*
* @return void
*/
public function up()
{
$this->database = new Asatru\Database\Migration('CacheModel', $this->connection);
$this->database->drop();
$this->database->add('id INT NOT NULL AUTO_INCREMENT PRIMARY KEY');
$this->database->add('ident VARCHAR(260) NOT NULL');
$this->database->add('value BLOB NULL');
$this->database->add('updated_at TIMESTAMP');
$this->database->add('created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP');
$this->database->create();
}
/**
* Called when the table shall be dropped
*
* @return void
*/
public function down()
{
$this->database = new Asatru\Database\Migration('Cache', $this->connection);
$this->database->drop();
}
}

View File

@ -1 +1,4 @@
47f3d3306fbd25715600db55b33b1542293ab5eb593205d6f5884bcaafa5d9a4627c76af04b684962c99a9518ef6b3d10e983203f6b5a8576912445d8f285fb7
cd19e5ec4a12d40d8d3ecdf267ef890e80fdd94ab28f81fddeb0c12b6f6b88773157e469c2d693abd4583e18b9b5a126c3fcecd6c07f4374c6c6e2837166b2ec

206
app/models/CacheModel.php Normal file
View File

@ -0,0 +1,206 @@
<?php
/*
Asatru PHP - Model for Caching
*/
class CacheModel extends \Asatru\Database\Model {
/**
* Obtain value either from cache or from closure
*
* @param string $ident The cache item identifier
* @param int $timeInSeconds Amount of seconds the item shall be cached
* @param $closure Function to be called for the actual value
* @return mixed
*/
public static function remember($ident, $timeInSeconds, $closure)
{
$item = CacheModel::find($ident, 'ident');
if ($item->count() == 0) {
$value = $closure();
$data = array(
'ident' => $ident,
'value' => $value,
'updated_at' => date('Y-m-d H:i:s')
);
foreach ($data as $key => $val) {
CacheModel::insert($key, $val);
}
CacheModel::go();
return $value;
} else {
$data = $item->get(0);
$dtLast = new DateTime(date('Y-m-d H:i:s', strtotime($data->get('updated_at'))));
$dtLast->add(new DateInterval('PT' . $timeInSeconds . 'S'));
$dtNow = new DateTime('now');
if ($dtNow < $dtLast) {
return $data->get('value');
} else {
$value = $closure();
$updData = array(
'value' => $value,
'updated_at' => date('Y-m-d H:i:s')
);
foreach ($updData as $key => $val) {
CacheModel::update($key, $val);
}
CacheModel::where('id', '=', $data->get('id'));
CacheModel::go();
return $value;
}
}
return null;
}
/**
* Query an entire item
*
* @param $ident
* @param $default
* @return mixed
*/
public static function query($ident, $default = null)
{
$what = null;
if (strpos($ident, '.') !== false) {
$what = explode('.', $ident);
}
$result = CacheModel::where('ident', '=', (((is_array($what)) && (count($what) > 0)) ? $what[0] : $ident))->first();
if (!$result) {
return $default;
}
if ((is_array($what)) && (count($what) > 1)) {
return $result->get($what[1]);
}
return $result->get('value');
}
/**
* Check for item existence
*
* @param $ident
* @return bool
*/
public static function has($ident)
{
$item = CacheModel::find($ident, 'ident');
if ($item->count() > 0) {
return true;
}
return false;
}
/**
* Check if item cache time is elapsed
*
* @param $ident
* @param $timeInSeconds
* @return bool
*/
public static function elapsed($ident, $timeInSeconds)
{
if (!CacheModel::has($ident)) {
return false;
}
$data = CacheModel::where('ident', '=', $ident)->first();
$dtLast = new DateTime(date('Y-m-d H:i:s', strtotime($data->get('updated_at'))));
$dtLast->add(new DateInterval('PT' . $timeInSeconds . 'S'));
$dtNow = new DateTime('now');
return ($dtNow >= $dtLast);
}
/**
* Get item and then delete it
*
* @param $ident
* @return mixed
*/
public static function pull($ident)
{
$item = CacheModel::find($ident, 'ident');
if ($item->count() > 0) {
$data = $item->get(0);
CacheModel::where('id', '=', $item->get(0)->get('id'))->delete();
return $data->get('value');
}
return null;
}
/**
* Write item to table
*
* @param $ident
* @param $value
* @return bool
*/
public static function put($ident, $value)
{
if (CacheModel::has($ident)) {
return false;
}
$data = array(
'ident' => $ident,
'value' => $value,
'updated_at' => date('Y-m-d H:i:s')
);
foreach ($data as $key => $val) {
CacheModel::insert($key, $val);
}
CacheModel::go();
return true;
}
/**
* Forget cache item
*
* @param string $ident The item identifier
* @return bool
*/
public static function forget($ident)
{
$item = CacheModel::find($ident, 'ident');
if ($item->count() > 0) {
CacheModel::where('id', '=', $item->get(0)->get('id'))->delete();
return true;
}
return false;
}
/**
* Return the associated table name of the migration
*
* @return string
*/
public static function tableName()
{
return 'CacheModel';
}
}

106
app/modules/SteamCache.php Normal file
View File

@ -0,0 +1,106 @@
<?php
/**
* Class SteamCache
*
* Cached gateway to Steam Web API queries
*/
class SteamCache {
/**
* @param $appid
* @param $lang
* @return mixed
*/
public static function cachedSteamApp($appid, $lang)
{
$cache = config('cache');
if ($cache->driver === 'db') {
return json_decode(CacheModel::remember('steam_app_' . $appid . '_' . $lang, $cache->duration, function() use ($appid, $lang) {
return json_encode(SteamApp::querySteamData($appid, $lang));
}));
} else if ($cache->driver === 'redis') {
throw new \Exception('Not implemented yet.');
} else {
return SteamApp::querySteamData($appid, $lang);
}
}
/**
* @param $key
* @param $steamid
* @return mixed
*/
public static function cachedSteamUser($key, $steamid)
{
$cache = config('cache');
if ($cache->driver === 'db') {
return json_decode(CacheModel::remember('steam_user_' . $steamid, $cache->duration, function() use ($key, $steamid) {
return json_encode(SteamUser::querySteamData($key, $steamid));
}));
} else if ($cache->driver === 'redis') {
throw new \Exception('Not implemented yet.');
} else {
return SteamUser::querySteamData($key, $steamid);
}
}
/**
* @param $itemid
* @return mixed
*/
public static function cachedSteamWorkshop($itemid)
{
$cache = config('cache');
if ($cache->driver === 'db') {
return json_decode(CacheModel::remember('steam_workshop_' . $itemid, $cache->duration, function() use ($itemid) {
return json_encode(SteamWorkshop::querySteamData($itemid));
}));
} else if ($cache->driver === 'redis') {
throw new \Exception('Not implemented yet.');
} else {
return SteamWorkshop::querySteamData($itemid);
}
}
/**
* @param $group
* @return mixed
*/
public static function cachedSteamGroup($group)
{
$cache = config('cache');
if ($cache->driver === 'db') {
return json_decode(CacheModel::remember('steam_group_' . $group, $cache->duration, function() use ($group) {
return json_encode(SteamGroup::querySteamData($group));
}));
} else if ($cache->driver === 'redis') {
throw new \Exception('Not implemented yet.');
} else {
return SteamGroup::querySteamData($group);
}
}
/**
* @param $key
* @param $addr
* @return mixed
*/
public static function cachedSteamServer($key, $addr)
{
$cache = config('cache');
if ($cache->driver === 'db') {
return json_decode(CacheModel::remember('steam_server_' . $addr, $cache->duration, function() use ($key, $addr) {
return json_encode(SteamServer::querySteamData($key, $addr));
}));
} else if ($cache->driver === 'redis') {
throw new \Exception('Not implemented yet.');
} else {
return SteamServer::querySteamData($key, $addr);
}
}
}

View File

@ -97,6 +97,12 @@ a.navbar-burger:hover {
height: 100%;
}
.header-centered {
@media screen and (min-width: 1089px) {
transform: translateX(9.5%);
}
}
.header-content {
position: relative;
top: 50%;

View File

@ -653,7 +653,7 @@ document.addEventListener('DOMContentLoaded', function() {
</pre>
<br/><br/>
This renders the following widget:<br/>
This renders the following widget:<br/><br/>
<steam-workshop itemid="{{ env('APP_EXAMPLE_WORKSHOP') }}"></steam-workshop>
</p>
@ -842,7 +842,7 @@ document.addEventListener('DOMContentLoaded', function() {
</pre>
<br/><br/>
This renders the following widget:<br/>
This renders the following widget:<br/><br/>
<steam-group group="{{ env('APP_EXAMPLE_GROUP') }}"></steam-group>
</p>

View File

@ -2,7 +2,7 @@
<div class="header">
<div class="header-overlay">
<div class="container">
<div class="columns">
<div class="columns header-centered">
<div class="column is-half">
<div class="header-content">
<h1 class="header-gradient">{{ env('APP_NAME') }}</h1>