#38: Modified the way the metadata upgrade page works - which now does a "re-analyse" the same way as it does an "analyse"

This commit is contained in:
Andy Heathershaw 2017-09-17 16:04:07 +01:00
parent 010e847835
commit 150f0a4966
8 changed files with 124 additions and 53 deletions

View File

@ -194,39 +194,14 @@ class AlbumController extends Controller
/** @var Album $album */ /** @var Album $album */
$album = $this->loadAlbum($id); $album = $this->loadAlbum($id);
return Theme::render('admin.album_metadata', ['album' => $album, 'current_metadata' => PhotoService::METADATA_VERSION]);
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function metadataPost(Request $request, $id)
{
$this->authorizeAccessToAdminPanel('admin:manage-albums');
/** @var Album $album */
$album = $this->loadAlbum($id);
$photosNeededToUpdate = $album->photos()->where('metadata_version', '<', PhotoService::METADATA_VERSION)->get(); $photosNeededToUpdate = $album->photos()->where('metadata_version', '<', PhotoService::METADATA_VERSION)->get();
$queueToken = MiscHelper::randomString();
// First download the original of each photo that needs updating and mark it as needing analysis return Theme::render('admin.album_metadata', [
foreach ($photosNeededToUpdate as $photo) 'album' => $album,
{ 'current_metadata' => PhotoService::METADATA_VERSION,
/** @var Photo $photo */ 'photos' => $photosNeededToUpdate,
$photo->is_analysed = false; 'queue_token' => MiscHelper::randomString()
]);
$photoService = new PhotoService($photo);
$photoService->downloadOriginalToFolder(FileHelper::getQueuePath($queueToken));
$photo->save();
}
// Now redirect to the analysis page
return response()->redirectToRoute('albums.analyse', ['id' => $id, 'queue_token' => $queueToken]);
} }
public function setGroupPermissions(Request $request, $id) public function setGroupPermissions(Request $request, $id)

View File

@ -60,11 +60,8 @@ class PhotoController extends Controller
$result['message'] = $ex->getMessage(); $result['message'] = $ex->getMessage();
// Remove the photo if it cannot be analysed (only if there isn't currently a version of metadata) // Remove the photo if it cannot be analysed (only if there isn't currently a version of metadata)
if (is_null($photo->metadata_version))
{
$photo->delete(); $photo->delete();
} }
}
return response()->json($result); return response()->json($result);
} }
@ -147,6 +144,33 @@ class PhotoController extends Controller
} }
} }
public function reAnalyse($id, $queue_token)
{
$this->authorizeAccessToAdminPanel();
/** @var Photo $photo */
$photo = $this->loadPhoto($id);
$result = ['is_successful' => false, 'message' => ''];
try
{
$photoService = new PhotoService($photo);
$photoService->downloadOriginalToFolder(FileHelper::getQueuePath($queue_token));
$photoService->analyse($queue_token);
$result['is_successful'] = true;
}
catch (\Exception $ex)
{
$result['is_successful'] = false;
$result['message'] = $ex->getMessage();
// Unlike the analyse method, we don't remove the photo if it cannot be analysed
}
return response()->json($result);
}
public function regenerateThumbnails($photoId) public function regenerateThumbnails($photoId)
{ {
$this->authorizeAccessToAdminPanel(); $this->authorizeAccessToAdminPanel();

View File

@ -19,6 +19,7 @@ class CheckMaxPostSizeExceeded
protected $exclude = [ protected $exclude = [
'/admin/photos/analyse/*', '/admin/photos/analyse/*',
'/admin/photos/flip/*', '/admin/photos/flip/*',
'/admin/photos/reanalyse/*',
'/admin/photos/regenerate-thumbnails/*', '/admin/photos/regenerate-thumbnails/*',
'/admin/photos/rotate/*' '/admin/photos/rotate/*'
]; ];

View File

@ -50,7 +50,7 @@ class PhotoService
$this->themeHelper = new ThemeHelper(); $this->themeHelper = new ThemeHelper();
} }
public function analyse($queueToken) public function analyse($queueToken, $isReanalyse = false)
{ {
$queuePath = FileHelper::getQueuePath($queueToken); $queuePath = FileHelper::getQueuePath($queueToken);
$photoFile = join(DIRECTORY_SEPARATOR, [$queuePath, $this->photo->storage_file_name]); $photoFile = join(DIRECTORY_SEPARATOR, [$queuePath, $this->photo->storage_file_name]);
@ -85,7 +85,7 @@ class PhotoService
// If Exif data contains an Orientation, ensure we rotate the original image as such (providing we don't // If Exif data contains an Orientation, ensure we rotate the original image as such (providing we don't
// currently have a metadata version - i.e. it hasn't been read and rotated already before) // currently have a metadata version - i.e. it hasn't been read and rotated already before)
if ($isExifDataFound && isset($exifData['Orientation']) && is_null($this->photo->metadata_version)) if ($isExifDataFound && isset($exifData['Orientation']) && !$isReanalyse)
{ {
switch ($exifData['Orientation']) switch ($exifData['Orientation'])
{ {

View File

@ -2,7 +2,7 @@
return [ return [
// Version number of Blue Twilight // Version number of Blue Twilight
'version' => '2.1.0-beta.2', 'version' => '2.1.0-beta.3',
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------

View File

@ -114,6 +114,16 @@ php artisan clear-compiled
return false; return false;
} }
ob_start();
system('php artisan config:clear', $rc);
$result = ob_get_clean();
echo nl2br($result);
if ($rc != 0)
{
$this->echoError('config:clear command failed');
return false;
}
ob_start(); ob_start();
system('php artisan view:clear', $rc); system('php artisan view:clear', $rc);
$result = ob_get_clean(); $result = ob_get_clean();

View File

@ -12,21 +12,69 @@
@section('content') @section('content')
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<div class="col-md-8 ml-md-auto mr-md-auto"> <div class="col-md-8 ml-md-auto mr-md-auto" id="analyse-album">
<div class="card bg-primary"> <div v-if="!isCompleted">
<div class="card" id="analysis-card" style="display: none;">
<div class="card-header">Analysing...</div>
<div class="card-body">
<p>Your photos are now being analysed.</p>
<div class="progress">
<div class="progress-bar bg-success" v-bind:style="{ width: successfulPercentage }">
</div>
<div class="progress-bar bg-danger" v-bind:style="{ width: failedPercentage }">
</div>
</div>
{{-- We display a queue of 3 recently completed items, and 5 up-next items, as well as a counter saying "... and XYZ more" --}}
{{-- That's what the 3's and 5's are in the next couple of blocks --}}
<div v-for="image in latestCompletedImages" style="margin-top: 20px;">
<p class="text-success"><span v-text="image.name"></span> ... <i class="fa fa-fw fa-check"></i></p>
</div>
<div v-for="image in imagesInProgress.slice(0, 5)" style="margin-top: 20px;">
<p><span v-text="image.name"></span> ... <i class="fa fa-fw fa-refresh"></i></p>
</div>
<div v-if="imagesInProgress.length > 5">
<p>@lang('admin.analyse_and_more.and') <span v-text="imagesInProgress.length - 5"></span> @lang('admin.analyse_and_more.others')</p>
</div>
<div v-for="image in imagesFailed" style="margin-top: 20px;">
<p class="text-danger"><span v-text="image.name"></span> ... <i class="fa fa-fw fa-times"></i></p>
</div>
</div>
</div>
<div class="card bg-primary" id="confirm-card">
<div class="card-header text-white">@yield('title')</div> <div class="card-header text-white">@yield('title')</div>
<div class="card-body bg-light"> <div class="card-body bg-light">
<p>@lang('admin.metadata_upgrade.confirm', ['name' => $album->name])</p> <p>@lang('admin.metadata_upgrade.confirm', ['name' => $album->name])</p>
<p class="text-danger"><b>@lang('admin.metadata_upgrade.warning')</b></p> <p class="text-danger"><b>@lang('admin.metadata_upgrade.warning')</b></p>
<div class="text-right"> <div class="text-right">
<form action="{{ route('albums.metadataPost', [$album->id]) }}" method="POST">
{{ csrf_field() }}
<a href="{{ route('admin.metadataUpgrade', ['id' => $album->id]) }}" class="btn btn-link">@lang('forms.cancel_action')</a> <a href="{{ route('admin.metadataUpgrade', ['id' => $album->id]) }}" class="btn btn-link">@lang('forms.cancel_action')</a>
<button id="submit-button" type="submit" class="btn btn-primary"><i class="fa fa-fw fa-check"></i> @lang('forms.continue_action')</button> <button id="submit-button" type="submit" class="btn btn-primary"><i class="fa fa-fw fa-check"></i> @lang('forms.continue_action')</button>
</form>
</div> </div>
</pdiv> </div>
</div>
</div>
<div class="card" v-if="isCompleted">
<div class="card-header">Analysis completed</div>
<div class="card-body">
<p>Your analysis has completed.</p>
<div v-if="numberFailed > 0">
<p class="text-danger">@lang('admin.analyse_photos_failed')</p>
<ul class="text-danger" v-for="image in imagesFailed">
<li><span v-text="image.name"></span>: <span v-text="image.reason"></span></li>
</ul>
</div>
<div class="text-right">
<a class="btn btn-link" href="{{ $album->url() }}">View album</a>
<a class="btn btn-primary" href="{{ route('admin.metadataUpgrade') }}"><i class="fa fa-fw fa-chevron-left"></i> Back to metadata upgrade</a>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -35,10 +83,23 @@
@push('scripts') @push('scripts')
<script type="text/javascript"> <script type="text/javascript">
var viewModel = new AnalyseAlbumViewModel();
var app = new Vue(viewModel);
$(document).ready(function() { $(document).ready(function() {
$('#submit-button').click(function() { $('#submit-button').click(function()
$(this).prop('disabled', true); {
$(this).closest('form').submit(); $('#analysis-card').show();
$('#confirm-card').hide();
{{-- For each photo to analyse, push an instance of AnalyseImageViewModel to our master view model --}}
@foreach ($photos as $photo)
app.analyseImage(new AnalyseImageViewModel({
'id': '{{ $photo->id }}',
'name': '{!! addslashes($photo->name) !!}',
'url': '{{ route('photos.re-analyse', ['id' => $photo->id, 'queue_token' => $queue_token]) }}'
}));
@endforeach
}); });
}); });
</script> </script>

View File

@ -27,7 +27,6 @@ Route::group(['prefix' => 'admin'], function () {
Route::get('albums/{id}/analyse/{queue_token}', 'Admin\AlbumController@analyse')->name('albums.analyse'); Route::get('albums/{id}/analyse/{queue_token}', 'Admin\AlbumController@analyse')->name('albums.analyse');
Route::get('albums/{id}/delete', 'Admin\AlbumController@delete')->name('albums.delete'); Route::get('albums/{id}/delete', 'Admin\AlbumController@delete')->name('albums.delete');
Route::get('/albums/{id}/metadata', 'Admin\AlbumController@metadata')->name('albums.metadata'); Route::get('/albums/{id}/metadata', 'Admin\AlbumController@metadata')->name('albums.metadata');
Route::post('/albums/{id}/metadata', 'Admin\AlbumController@metadataPost')->name('albums.metadataPost');
Route::post('albums/{id}/set-group-permissions', 'Admin\AlbumController@setGroupPermissions')->name('albums.set_group_permissions'); Route::post('albums/{id}/set-group-permissions', 'Admin\AlbumController@setGroupPermissions')->name('albums.set_group_permissions');
Route::post('albums/{id}/set-user-permissions', 'Admin\AlbumController@setUserPermissions')->name('albums.set_user_permissions'); Route::post('albums/{id}/set-user-permissions', 'Admin\AlbumController@setUserPermissions')->name('albums.set_user_permissions');
Route::delete('albums/{id}/delete-redirect/{redirectId}', 'Admin\AlbumController@deleteRedirect')->name('albums.delete_redirect'); Route::delete('albums/{id}/delete-redirect/{redirectId}', 'Admin\AlbumController@deleteRedirect')->name('albums.delete_redirect');
@ -38,6 +37,7 @@ Route::group(['prefix' => 'admin'], function () {
Route::post('photos/analyse/{id}/{queue_token}', 'Admin\PhotoController@analyse')->name('photos.analyse'); Route::post('photos/analyse/{id}/{queue_token}', 'Admin\PhotoController@analyse')->name('photos.analyse');
Route::post('photos/flip/{photoId}/{horizontal}/{vertical}', 'Admin\PhotoController@flip')->name('photos.flip'); Route::post('photos/flip/{photoId}/{horizontal}/{vertical}', 'Admin\PhotoController@flip')->name('photos.flip');
Route::post('photos/move/{photoId}', 'Admin\PhotoController@move')->name('photos.move'); Route::post('photos/move/{photoId}', 'Admin\PhotoController@move')->name('photos.move');
Route::post('photos/reanalyse/{id}/{queue_token}', 'Admin\PhotoController@reAnalyse')->name('photos.re-analyse');
Route::post('photos/regenerate-thumbnails/{photoId}', 'Admin\PhotoController@regenerateThumbnails')->name('photos.regenerateThumbnails'); Route::post('photos/regenerate-thumbnails/{photoId}', 'Admin\PhotoController@regenerateThumbnails')->name('photos.regenerateThumbnails');
Route::post('photos/rotate/{photoId}/{angle}', 'Admin\PhotoController@rotate')->name('photos.rotate'); Route::post('photos/rotate/{photoId}/{angle}', 'Admin\PhotoController@rotate')->name('photos.rotate');
Route::post('photos/store-bulk', 'Admin\PhotoController@storeBulk')->name('photos.storeBulk'); Route::post('photos/store-bulk', 'Admin\PhotoController@storeBulk')->name('photos.storeBulk');