Compare commits

...

5 Commits
1.1 ... master

Author SHA1 Message Date
Rev
35b8d4676a update frontend 2021-10-27 00:40:14 +09:00
Rev
98e00c6427 add docstring to method 2021-10-27 00:39:47 +09:00
Rev
33da8354db set execution time and memory when refreshing the data 2021-10-26 11:37:51 +09:00
Rev
a269395b9e fix getLocales method 2021-10-25 23:51:28 +09:00
Rev
3a5849d91a refactor itemCollection class 2021-10-25 21:02:05 +09:00
6 changed files with 72 additions and 39 deletions

View File

@ -3,43 +3,56 @@
namespace App\Data; namespace App\Data;
use App\Exceptions\ItemNotFoundException; use App\Exceptions\ItemNotFoundException;
use Exception;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use App\Config\GiteaConfig; use App\Config\GiteaConfig;
class ItemsCollection class ItemsCollection
{ {
protected Collection $items; protected array $items;
protected Collection $locales; protected array $locales;
private string $items_cache_key = 'items'; private string $items_file_key = 'items.json';
private string $locales_cache_key = 'locales'; private string $locales_file_key = 'locales.json';
/**
* @throws Exception
*/
public function __construct() public function __construct()
{ {
if (!Cache::has($this->items_cache_key)) { if (!File::exists(storage_path($this->items_file_key))) {
$this->refreshItemsCache(); $this->refreshItemsCache();
} else { } else {
$this->items = Cache::get($this->items_cache_key); $content = file_get_contents(storage_path($this->items_file_key));
$this->items = json_decode($content, true);
} }
if (!Cache::has($this->locales_cache_key)) { if (!File::exists(storage_path($this->locales_file_key ))) {
$this->refreshLocalesCache(); $this->refreshLocalesCache();
} else { } else {
$this->locales = Cache::get($this->locales_cache_key); $content = file_get_contents(storage_path($this->locales_file_key ));
$this->locales = json_decode($content, true);
} }
} }
/**
* @return void
* @throws Exception
*/
public function refreshLocalesCache(): void public function refreshLocalesCache(): void
{ {
$this->locales = collect(); $time_limit = ini_get('max_execution_time');
$memory_limit = ini_get('memory_limit');
set_time_limit(180);
ini_set('memory_limit', '256M');
$this->locales = [];
$rawLocalesGlobalBaseUrl = GiteaConfig::RAW_LOCALES_GLOBAL_BASE_URL; $rawLocalesGlobalBaseUrl = GiteaConfig::RAW_LOCALES_GLOBAL_BASE_URL;
// Getting all locales in project/assets/database/locales/global from the Server development branch repository // Getting all locales in project/assets/database/locales/global from the Server development branch repository
$localesList = Http::withOptions(['verify' => false])->get(GiteaConfig::LOCALES_GLOBAL_URL)->json();
$localesList = collect(Http::withOptions(['verify' => false])->get(GiteaConfig::LOCALES_GLOBAL_URL)->json());
foreach ($localesList as $item) { foreach ($localesList as $item) {
// Extract the json name for the locale // Extract the json name for the locale
preg_match('/([a-z]{2}(-[a-z]{2})?).json/', $item['name'], $currentLocaleName, PREG_OFFSET_CAPTURE); preg_match('/([a-z]{2}(-[a-z]{2})?).json/', $item['name'], $currentLocaleName, PREG_OFFSET_CAPTURE);
@ -49,35 +62,53 @@ class ItemsCollection
$trimmedCurrentLocaleName = trim($currentLocaleName[1][0]); $trimmedCurrentLocaleName = trim($currentLocaleName[1][0]);
$currentLocaleJson = Http::withOptions(['verify' => false]) $currentLocaleJson = Http::withOptions(['verify' => false])
->get("${rawLocalesGlobalBaseUrl}/${trimmedCurrentLocaleName}.json")->json(); ->get("$rawLocalesGlobalBaseUrl/$trimmedCurrentLocaleName.json")->json();
$templateLocale = collect($currentLocaleJson['templates']); $templateLocale = $currentLocaleJson['templates'];
$customizationLocale = collect($currentLocaleJson['customization']); $customizationLocale = $currentLocaleJson['customization'];
$this->locales = $this->locales->merge([$trimmedCurrentLocaleName => $templateLocale->concat($customizationLocale)]); $this->locales[$trimmedCurrentLocaleName] = array_merge($templateLocale, $customizationLocale);
} }
Cache::put($this->locales_cache_key, $this->locales); if (!$handle = fopen(storage_path($this->locales_file_key ), 'w')) {
throw new Exception('Cannot open the file');
}
fwrite($handle, json_encode($this->locales));
fclose($handle);
set_time_limit($time_limit);
ini_set('memory_limit', $memory_limit);
} }
/** /**
* @return void * @return void
* @throws Exception
*/ */
public function refreshItemsCache(): void public function refreshItemsCache(): void
{ {
$this->items = collect(Http::withOptions(['verify' => false])->get(GiteaConfig::RAW_ITEMS_URL)->json()); $time_limit = ini_get('max_execution_time');
$this->items = $this->items->merge(collect(Http::withOptions(['verify' => false]) $memory_limit = ini_get('memory_limit');
->get(GiteaConfig::RAW_CUSTOMIZATION_URL)->json())); set_time_limit(180);
Cache::put($this->items_cache_key, $this->items); ini_set('memory_limit', '256M');
$items = Http::withOptions(['verify' => false])->get(GiteaConfig::RAW_ITEMS_URL)->json();
$customization = Http::withOptions(['verify' => false])->get(GiteaConfig::RAW_CUSTOMIZATION_URL)->json();
$this->items = array_merge($items, $customization);
if (!$handle = fopen(storage_path($this->items_file_key ), 'w')) {
throw new Exception('Cannot open the file');
}
fwrite($handle, json_encode($this->items));
fclose($handle);
set_time_limit($time_limit);
ini_set('memory_limit', $memory_limit);
} }
/** /**
* @return Collection * @return array
*/ */
public function getLocales(): Collection public function getLocales(): array
{ {
return $this->locales->keys(); return array_keys($this->locales);
} }
/** /**
* @return void * @return void
* @throws Exception
*/ */
public function refreshAllCache(): void public function refreshAllCache(): void
{ {
@ -106,7 +137,8 @@ class ItemsCollection
*/ */
public function findItem(string $query, string $locale): Collection public function findItem(string $query, string $locale): Collection
{ {
return $this->items->filter(function ($val, $key) use ($query, $locale) { $items = collect($this->items);
return $items->filter(function ($val, $key) use ($query, $locale) {
return $this->contains($val['_id'], $query) return $this->contains($val['_id'], $query)
|| $this->contains($val['_name'], $query) || $this->contains($val['_name'], $query)
|| $this->contains($val['_parent'], $query) || $this->contains($val['_parent'], $query)
@ -118,7 +150,7 @@ class ItemsCollection
'item' => [ 'item' => [
'_id' => $item['_id'], '_id' => $item['_id'],
'_name' => $item['_name'], '_name' => $item['_name'],
], ],
'locale' => $this->locales[$locale][$item['_id']] ?? '' 'locale' => $this->locales[$locale][$item['_id']] ?? ''
]; ];
})->values(); })->values();
@ -132,20 +164,21 @@ class ItemsCollection
*/ */
public function getItemById(string $id, string $locale): array public function getItemById(string $id, string $locale): array
{ {
$item = $this->items[$id] ?? throw new ItemNotFoundException('Item not found'); $item = $this->items[$id] ?? throw new ItemNotFoundException('Item not found');
return [ return [
'item' => $item, 'item' => $item,
'locale' => $this->locales[$locale][$id] ?? '' 'locale' => $this->locales[$locale][$id] ?? ''
]; ];
} }
public function getHierarchy(string $id, string $locale = 'en'): Collection { public function getHierarchy(string $id, string $locale = 'en'): Collection
{
// Return 404 if the item does not exist // Return 404 if the item does not exist
$itemData = $this->items[$id] ?? throw new ItemNotFoundException('Item not found'); $itemData = $this->items[$id] ?? throw new ItemNotFoundException('Item not found');
// Initialize the hierarchy with the current item // Initialize the hierarchy with the current item
$item = [ $item = [
'item'=> [ 'item' => [
'_id' => $itemData['_id'], '_id' => $itemData['_id'],
'_name' => $itemData['_name'], '_name' => $itemData['_name'],
'_parent' => $itemData['_parent'] '_parent' => $itemData['_parent']
@ -157,9 +190,9 @@ class ItemsCollection
// Check the whole hierarchy and merge into the return variable // Check the whole hierarchy and merge into the return variable
while (!empty($item['item']['_parent'] ?? '')) { while (!empty($item['item']['_parent'] ?? '')) {
$itemtId = $item['item']['_parent']; $itemtId = $item['item']['_parent'];
$itemData = $this->items[$itemtId] ?? null; $itemData = $this->items[$itemtId] ?? null;
$item = [ $item = [
'item'=> [ 'item' => [
'_id' => $itemData['_id'], '_id' => $itemData['_id'],
'_name' => $itemData['_name'], '_name' => $itemData['_name'],
'_parent' => $itemData['_parent'] '_parent' => $itemData['_parent']

View File

@ -1,7 +1,7 @@
{ {
"files": { "files": {
"main.js": "/static/js/main.e49801bc.chunk.js", "main.js": "/static/js/main.33101a6f.chunk.js",
"main.js.map": "/static/js/main.e49801bc.chunk.js.map", "main.js.map": "/static/js/main.33101a6f.chunk.js.map",
"runtime-main.js": "/static/js/runtime-main.45092312.js", "runtime-main.js": "/static/js/runtime-main.45092312.js",
"runtime-main.js.map": "/static/js/runtime-main.45092312.js.map", "runtime-main.js.map": "/static/js/runtime-main.45092312.js.map",
"static/js/2.c9c7c886.chunk.js": "/static/js/2.c9c7c886.chunk.js", "static/js/2.c9c7c886.chunk.js": "/static/js/2.c9c7c886.chunk.js",
@ -14,6 +14,6 @@
"entrypoints": [ "entrypoints": [
"static/js/runtime-main.45092312.js", "static/js/runtime-main.45092312.js",
"static/js/2.c9c7c886.chunk.js", "static/js/2.c9c7c886.chunk.js",
"static/js/main.e49801bc.chunk.js" "static/js/main.33101a6f.chunk.js"
] ]
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -17,7 +17,7 @@
<div id="root"></div> <div id="root"></div>
<script>!function (e) { function t(t) { for (var n, u, a = t[0], c = t[1], f = t[2], s = 0, p = []; s < a.length; s++)u = a[s], Object.prototype.hasOwnProperty.call(o, u) && o[u] && p.push(o[u][0]), o[u] = 0; for (n in c) Object.prototype.hasOwnProperty.call(c, n) && (e[n] = c[n]); for (l && l(t); p.length;)p.shift()(); return i.push.apply(i, f || []), r() } function r() { for (var e, t = 0; t < i.length; t++) { for (var r = i[t], n = !0, a = 1; a < r.length; a++) { var c = r[a]; 0 !== o[c] && (n = !1) } n && (i.splice(t--, 1), e = u(u.s = r[0])) } return e } var n = {}, o = { 1: 0 }, i = []; function u(t) { if (n[t]) return n[t].exports; var r = n[t] = { i: t, l: !1, exports: {} }; return e[t].call(r.exports, r, r.exports, u), r.l = !0, r.exports } u.e = function (e) { var t = [], r = o[e]; if (0 !== r) if (r) t.push(r[2]); else { var n = new Promise((function (t, n) { r = o[e] = [t, n] })); t.push(r[2] = n); var i, a = document.createElement("script"); a.charset = "utf-8", a.timeout = 120, u.nc && a.setAttribute("nonce", u.nc), a.src = function (e) { return u.p + "static/js/" + ({}[e] || e) + "." + { 3: "ff1076df" }[e] + ".chunk.js" }(e); var c = new Error; i = function (t) { a.onerror = a.onload = null, clearTimeout(f); var r = o[e]; if (0 !== r) { if (r) { var n = t && ("load" === t.type ? "missing" : t.type), i = t && t.target && t.target.src; c.message = "Loading chunk " + e + " failed.\n(" + n + ": " + i + ")", c.name = "ChunkLoadError", c.type = n, c.request = i, r[1](c) } o[e] = void 0 } }; var f = setTimeout((function () { i({ type: "timeout", target: a }) }), 12e4); a.onerror = a.onload = i, document.head.appendChild(a) } return Promise.all(t) }, u.m = e, u.c = n, u.d = function (e, t, r) { u.o(e, t) || Object.defineProperty(e, t, { enumerable: !0, get: r }) }, u.r = function (e) { "undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, { value: "Module" }), Object.defineProperty(e, "__esModule", { value: !0 }) }, u.t = function (e, t) { if (1 & t && (e = u(e)), 8 & t) return e; if (4 & t && "object" == typeof e && e && e.__esModule) return e; var r = Object.create(null); if (u.r(r), Object.defineProperty(r, "default", { enumerable: !0, value: e }), 2 & t && "string" != typeof e) for (var n in e) u.d(r, n, function (t) { return e[t] }.bind(null, n)); return r }, u.n = function (e) { var t = e && e.__esModule ? function () { return e.default } : function () { return e }; return u.d(t, "a", t), t }, u.o = function (e, t) { return Object.prototype.hasOwnProperty.call(e, t) }, u.p = "/", u.oe = function (e) { throw console.error(e), e }; var a = this["webpackJsonpnew-item-finder-website"] = this["webpackJsonpnew-item-finder-website"] || [], c = a.push.bind(a); a.push = t, a = a.slice(); for (var f = 0; f < a.length; f++)t(a[f]); var l = c; r() }([])</script> <script>!function (e) { function t(t) { for (var n, u, a = t[0], c = t[1], f = t[2], s = 0, p = []; s < a.length; s++)u = a[s], Object.prototype.hasOwnProperty.call(o, u) && o[u] && p.push(o[u][0]), o[u] = 0; for (n in c) Object.prototype.hasOwnProperty.call(c, n) && (e[n] = c[n]); for (l && l(t); p.length;)p.shift()(); return i.push.apply(i, f || []), r() } function r() { for (var e, t = 0; t < i.length; t++) { for (var r = i[t], n = !0, a = 1; a < r.length; a++) { var c = r[a]; 0 !== o[c] && (n = !1) } n && (i.splice(t--, 1), e = u(u.s = r[0])) } return e } var n = {}, o = { 1: 0 }, i = []; function u(t) { if (n[t]) return n[t].exports; var r = n[t] = { i: t, l: !1, exports: {} }; return e[t].call(r.exports, r, r.exports, u), r.l = !0, r.exports } u.e = function (e) { var t = [], r = o[e]; if (0 !== r) if (r) t.push(r[2]); else { var n = new Promise((function (t, n) { r = o[e] = [t, n] })); t.push(r[2] = n); var i, a = document.createElement("script"); a.charset = "utf-8", a.timeout = 120, u.nc && a.setAttribute("nonce", u.nc), a.src = function (e) { return u.p + "static/js/" + ({}[e] || e) + "." + { 3: "ff1076df" }[e] + ".chunk.js" }(e); var c = new Error; i = function (t) { a.onerror = a.onload = null, clearTimeout(f); var r = o[e]; if (0 !== r) { if (r) { var n = t && ("load" === t.type ? "missing" : t.type), i = t && t.target && t.target.src; c.message = "Loading chunk " + e + " failed.\n(" + n + ": " + i + ")", c.name = "ChunkLoadError", c.type = n, c.request = i, r[1](c) } o[e] = void 0 } }; var f = setTimeout((function () { i({ type: "timeout", target: a }) }), 12e4); a.onerror = a.onload = i, document.head.appendChild(a) } return Promise.all(t) }, u.m = e, u.c = n, u.d = function (e, t, r) { u.o(e, t) || Object.defineProperty(e, t, { enumerable: !0, get: r }) }, u.r = function (e) { "undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, { value: "Module" }), Object.defineProperty(e, "__esModule", { value: !0 }) }, u.t = function (e, t) { if (1 & t && (e = u(e)), 8 & t) return e; if (4 & t && "object" == typeof e && e && e.__esModule) return e; var r = Object.create(null); if (u.r(r), Object.defineProperty(r, "default", { enumerable: !0, value: e }), 2 & t && "string" != typeof e) for (var n in e) u.d(r, n, function (t) { return e[t] }.bind(null, n)); return r }, u.n = function (e) { var t = e && e.__esModule ? function () { return e.default } : function () { return e }; return u.d(t, "a", t), t }, u.o = function (e, t) { return Object.prototype.hasOwnProperty.call(e, t) }, u.p = "/", u.oe = function (e) { throw console.error(e), e }; var a = this["webpackJsonpnew-item-finder-website"] = this["webpackJsonpnew-item-finder-website"] || [], c = a.push.bind(a); a.push = t, a = a.slice(); for (var f = 0; f < a.length; f++)t(a[f]); var l = c; r() }([])</script>
<script src="/static/js/2.c9c7c886.chunk.js"></script> <script src="/static/js/2.c9c7c886.chunk.js"></script>
<script src="/static/js/main.e49801bc.chunk.js"></script> <script src="/static/js/main.33101a6f.chunk.js"></script>
</body> </body>
</html> </html>