Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feauture/import #24

Merged
merged 1 commit into from
Jan 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ DB_PASSWORD=
BROADCAST_DRIVER=log
CACHE_DRIVER=file
FILESYSTEM_DISK=local
QUEUE_CONNECTION=sync
QUEUE_CONNECTION=database
SESSION_DRIVER=file
SESSION_LIFETIME=120

Expand Down
8 changes: 8 additions & 0 deletions src/app/Enums/Imports/ImportSources.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace App\Enums\Imports;

enum ImportSources: string
{
case OPEN_LIBRARY = 'openlibrary';
}
3 changes: 3 additions & 0 deletions src/app/Http/Controllers/IndexController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@

use Illuminate\Http\Request;
use Inertia\Inertia;
use App\Traits\Imports\OpenLibraryTrait;

class IndexController extends Controller
{
use OpenLibraryTrait;
public function index() {
$this->importOpenLibrary();
return Inertia::render('index');
}
}
47 changes: 47 additions & 0 deletions src/app/Jobs/ImportFromApiJob.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

Timtendo12 marked this conversation as resolved.
Show resolved Hide resolved
namespace App\Jobs;

use App\Enums\Imports\ImportSources;
use Exception;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Traits\Imports\OpenLibraryTrait;

class ImportFromApiJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
use OpenLibraryTrait;

/**
* Create a new job instance.
*/
public function __construct(
private ImportSources $source = ImportSources::OPEN_LIBRARY,
private array $query = ['first_publish_year:[0 TO 2024]'],
)
{}

/**
* Execute the job.
* @throws Exception
*/
public function handle(): void
{
// validate if query array is key only and not key-value pair
foreach ($this->query as $key => $value) {
if (is_string($key)) {
throw new Exception('Query array must not be key-value pair');
}
}

// replace with switch statement once more sources are added
if ($this->source == ImportSources::OPEN_LIBRARY) {
$this->importOpenLibrary($this->query);
}
}
}
22 changes: 22 additions & 0 deletions src/app/Traits/CommonLibraryTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\Traits;

use App\Models\Item;
use App\Models\LibraryPass;
use Illuminate\Support\Env;

Expand Down Expand Up @@ -49,5 +50,26 @@ private function isLibraryPassBarCodeAlreadyInUse($barcode): bool
{
return LibraryPass::where('barcode', $barcode)->exists();
}


public function generateValidItemIdentifier(): string
{
$identifier = $this->generateItemIdentifier();
while($this->isItemIdentifierAlreadyInUse($identifier)) {
$identifier = $this->generateItemIdentifier();
}
return $identifier;
}

private function generateItemIdentifier(): string
{
$prefix = "ITM";
return $prefix . $this->generateRandomNumber(16);
}

private function isItemIdentifierAlreadyInUse($identifier): bool
{
return Item::where('identifier', $identifier)->exists();
}
}

63 changes: 63 additions & 0 deletions src/app/Traits/Imports/OpenLibraryTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

namespace App\Traits\Imports;

use App\Models\Item;
use App\Models\User;
use App\Traits\CommonLibraryTrait;

trait OpenLibraryTrait
{
use CommonLibraryTrait;
public function importOpenLibrary($tries = 3) {
if ($tries < 1) $tries = 3;

$maxOffset = (int) ceil(100 * $tries / 100) * 100;
$offset = 100;
$loop = (int) ceil($offset / 100);

for ($i = 0; $i < $loop; $i++) {
$this->import($offset);
if ($offset >= $maxOffset) {
break;
}
$offset += 100;
};
}

private function import($offset) {
$books = $this->getData($offset);

foreach ($books as $book) {
$this->importBook($book);
}
}

private function importBook($book) {
Item::create([
'identifier' => $this->generateValidItemIdentifier(),
'type' => 'book',
'name' => $book['title'],
'description' => "Dit boek is geschreven door {$book['author_name'][0]} en is uitgegeven in {$book['first_publish_year']}.",
'category' => 1,
'ISBN' => $book['isbn'][0],
'rating' => 1,
'borrowing_time' => 30,
'modified_kind' => 'I',
'modified_user' => User::where('email', '[email protected]')->first()->id,
]);
}

private function getData($offset)
{
$baseUrl = "https://openlibrary.org/search.json?q=language%3Adut&sort=new&lang=nl&offset=" . $offset;
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $baseUrl);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($curl);
curl_close($curl);

$response = json_decode($response, true);
return $response['docs'];
}
}
4 changes: 3 additions & 1 deletion src/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
"laravel/framework": "^10.10",
"laravel/sanctum": "^3.3",
"laravel/tinker": "^2.8",
"spatie/laravel-permission": "^6.1"
"mxl/laravel-job": "^1.5",
"spatie/laravel-permission": "^6.1",
"ext-curl": "*"
},
"require-dev": {
"fakerphp/faker": "^1.9.1",
Expand Down
61 changes: 60 additions & 1 deletion src/composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 32 additions & 0 deletions src/database/migrations/2023_12_20_101128_create_jobs_table.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('jobs', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('queue')->index();
$table->longText('payload');
$table->unsignedTinyInteger('attempts');
$table->unsignedInteger('reserved_at')->nullable();
$table->unsignedInteger('available_at');
$table->unsignedInteger('created_at');
});
}

/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('jobs');
}
};
29 changes: 29 additions & 0 deletions src/database/migrations/2023_12_21_105625_add_author_to_items.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('items', function (Blueprint $table) {
$table->string('author')->nullable()->after('name');
$table->string('publisher')->nullable()->after('author');
});
}

/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('items', function (Blueprint $table) {
//
});
}
};
Loading