Add attachments, more pages
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Book;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class BookController extends Controller {
|
||||
@ -40,7 +41,13 @@ class BookController extends Controller {
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($id) {
|
||||
//
|
||||
$book = Book::find($id);
|
||||
|
||||
if (!$book) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
return view('books.show', [ 'book' => $book ]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -71,6 +78,16 @@ class BookController extends Controller {
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy($id) {
|
||||
//
|
||||
$book = Book::find($id);
|
||||
|
||||
if (!$book) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
$book->delete();
|
||||
|
||||
return response()->json([
|
||||
'success' => true
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ class LocationController extends Controller {
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index() {
|
||||
//
|
||||
return view('locations.index', [ 'locations' => Location::paginate(15) ]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -47,7 +47,7 @@ class LocationController extends Controller {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
return view('location', [ 'location' => $location ]);
|
||||
return view('locations.show', [ 'location' => $location, 'rows' => $location->books()->paginate(15) ]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2,20 +2,31 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Book;
|
||||
use App\Services\BookInformation\BookLookupService;
|
||||
use Cache;
|
||||
use App\Services\BookInformation\GoogleBooks;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
|
||||
class LookupController {
|
||||
public function lookup($isbn) {
|
||||
if (!preg_match('/^(\d+)$/', $isbn)) {
|
||||
throw new HttpException(400);
|
||||
public function lookup(BookLookupService $service, $isbn) {
|
||||
$result = $service->lookup($isbn);
|
||||
|
||||
$arr = [
|
||||
'success' => false
|
||||
];
|
||||
|
||||
if ($result) {
|
||||
$arr = array_merge($arr, [
|
||||
'success' => true,
|
||||
'data' => $result
|
||||
]);
|
||||
}
|
||||
|
||||
return Cache::remember('isbn_' . $isbn, 86400, function() use ($isbn) {
|
||||
$google_books = new GoogleBooks();
|
||||
$book = Book::where('barcode', $isbn)->first();
|
||||
|
||||
return $google_books->lookup($isbn);
|
||||
});
|
||||
if ($book) {
|
||||
$arr['warning'] = 'Item already exists.<br />Location: ' . $book->location->name;
|
||||
}
|
||||
|
||||
return response()->json($arr);
|
||||
}
|
||||
}
|
@ -5,6 +5,9 @@ namespace App\Http\Controllers;
|
||||
use App\Models\Author;
|
||||
use App\Models\Book;
|
||||
use App\Models\Location;
|
||||
use App\Services\BookInformation\BookLookupService;
|
||||
use App\Services\BookInformation\GoogleBooks;
|
||||
use GuzzleHttp\Client;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
@ -16,24 +19,21 @@ class MainController extends Controller {
|
||||
}
|
||||
|
||||
public function search(Request $request) {
|
||||
$this->validate($request, [
|
||||
'query' => [ 'required' ]
|
||||
]);
|
||||
|
||||
$rows = Book::where('name', 'LIKE', '%' . $request->get('query') . '%')->paginate(15);
|
||||
$rows = Book::search($request->get('query'))->paginate(15);
|
||||
|
||||
return view('index', [ 'rows' => $rows ]);
|
||||
}
|
||||
|
||||
public function add(Request $request) {
|
||||
return view('add', [
|
||||
'locations' => Location::get(),
|
||||
'old' => array_filter($request->old('books', []), function($item) {
|
||||
return !empty($item['barcode']);
|
||||
})
|
||||
]);
|
||||
}
|
||||
|
||||
public function save(Request $request) {
|
||||
public function save(Request $request, BookLookupService $service) {
|
||||
$this->validate($request, [
|
||||
'location' => [ 'required' ]
|
||||
]);
|
||||
@ -69,6 +69,39 @@ class MainController extends Controller {
|
||||
$authors = array_map(function($author) { return $author->id; }, $authors);
|
||||
|
||||
$book->authors()->attach($authors);
|
||||
|
||||
// Lookup info from cache
|
||||
$res = $service->lookup($item['barcode']);
|
||||
|
||||
if (!empty($res)) {
|
||||
if ($thumbnail = data_get('images.thumbnail', $res)) {
|
||||
$file = $this->downloadFile($thumbnail);
|
||||
|
||||
$book->attach('thumbnail', $file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Download a file and return the local temp path.
|
||||
*
|
||||
* @param $url
|
||||
* @return string|null
|
||||
*/
|
||||
private function downloadFile($url) {
|
||||
$client = new Client();
|
||||
|
||||
$path = tempnam(storage_path('app/temp'), 'image');
|
||||
|
||||
$res = $client->get($url, [
|
||||
'sink' => $path
|
||||
]);
|
||||
|
||||
if ($res->getStatusCode() != 200) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
}
|
||||
|
@ -3,12 +3,13 @@
|
||||
namespace App\Models;
|
||||
|
||||
use App\Services\Search\BookConfigurator;
|
||||
use Bnb\Laravel\Attachments\HasAttachment;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use ScoutElastic\Searchable;
|
||||
|
||||
class Book extends Model {
|
||||
|
||||
use Searchable;
|
||||
use Searchable, HasAttachment;
|
||||
|
||||
protected $indexConfigurator = BookConfigurator::class;
|
||||
|
||||
|
@ -14,4 +14,8 @@ class Location extends Model {
|
||||
protected $fillable = [
|
||||
'name',
|
||||
];
|
||||
|
||||
public function books() {
|
||||
return $this->hasMany(Book::class);
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,9 @@
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Services\BookInformation\BookLookupService;
|
||||
use App\Services\BookInformation\CachedService;
|
||||
use App\Services\BookInformation\GoogleBooks;
|
||||
use Illuminate\Pagination\Paginator;
|
||||
use Schema;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
@ -23,6 +26,8 @@ class AppServiceProvider extends ServiceProvider {
|
||||
* @return void
|
||||
*/
|
||||
public function register() {
|
||||
//
|
||||
$this->app->singleton(BookLookupService::class, function() {
|
||||
return new CachedService(new GoogleBooks());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
19
app/Services/BookInformation/CachedService.php
Normal file
19
app/Services/BookInformation/CachedService.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\BookInformation;
|
||||
|
||||
use Cache;
|
||||
|
||||
class CachedService implements BookLookupService {
|
||||
private $service;
|
||||
|
||||
public function __construct($service) {
|
||||
$this->service = $service;
|
||||
}
|
||||
|
||||
public function lookup($isbn) {
|
||||
return Cache::remember('isbn_' . $isbn, 86400, function() use ($isbn) {
|
||||
return $this->service->lookup($isbn);
|
||||
});
|
||||
}
|
||||
}
|
@ -22,9 +22,10 @@ class GoogleBooks implements BookLookupService {
|
||||
*/
|
||||
$volume = Arr::first($results->getItems())->getVolumeInfo();
|
||||
|
||||
return [
|
||||
return (object) [
|
||||
'title' => $volume->getTitle(),
|
||||
'authors' => $volume->getAuthors()
|
||||
'authors' => $volume->getAuthors(),
|
||||
'images' => $volume->getImageLinks(),
|
||||
];
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user