#121: Bulk updates to photos now take place on the queue if enabled (just need to handle album changes)
This commit is contained in:
parent
0cca6eec66
commit
ebbc5ba097
@ -7,6 +7,7 @@ use App\Photo;
|
|||||||
use App\QueueItem;
|
use App\QueueItem;
|
||||||
use App\Services\PhotoService;
|
use App\Services\PhotoService;
|
||||||
use App\Services\RabbitMQService;
|
use App\Services\RabbitMQService;
|
||||||
|
use App\User;
|
||||||
use App\UserActivity;
|
use App\UserActivity;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
@ -84,6 +85,17 @@ class ProcessQueueCommand extends Command
|
|||||||
$this->processPhotoAnalyseMessage($queueItem);
|
$this->processPhotoAnalyseMessage($queueItem);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'photo.bulk_action.change_album':
|
||||||
|
case 'photo.bulk_action.delete':
|
||||||
|
case 'photo.bulk_action.flip_both':
|
||||||
|
case 'photo.bulk_action.flip_horizontal':
|
||||||
|
case 'photo.bulk_action.flip_vertical':
|
||||||
|
case 'photo.bulk_action.refresh_thumbnails':
|
||||||
|
case 'photo.bulk_action.rotate_left':
|
||||||
|
case 'photo.bulk_action.rotate_right':
|
||||||
|
$this->processPhotoBulkActionMessage($queueItem);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
$this->output->writeln(sprintf('Action %s is not recognised, skipping', $queueItem->action_type));
|
$this->output->writeln(sprintf('Action %s is not recognised, skipping', $queueItem->action_type));
|
||||||
return;
|
return;
|
||||||
@ -102,7 +114,7 @@ class ProcessQueueCommand extends Command
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function createActivityRecord(Photo $photo, $type, $activityDateTime = null)
|
private function createActivityRecord(Photo $photo, $type, $userID, $activityDateTime = null)
|
||||||
{
|
{
|
||||||
if (is_null($activityDateTime))
|
if (is_null($activityDateTime))
|
||||||
{
|
{
|
||||||
@ -110,7 +122,7 @@ class ProcessQueueCommand extends Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
$userActivity = new UserActivity();
|
$userActivity = new UserActivity();
|
||||||
$userActivity->user_id = $photo->user_id;
|
$userActivity->user_id = $userID;
|
||||||
$userActivity->activity_at = $activityDateTime;
|
$userActivity->activity_at = $activityDateTime;
|
||||||
$userActivity->type = $type;
|
$userActivity->type = $type;
|
||||||
$userActivity->photo_id = $photo->id;
|
$userActivity->photo_id = $photo->id;
|
||||||
@ -121,11 +133,12 @@ class ProcessQueueCommand extends Command
|
|||||||
{
|
{
|
||||||
$this->output->writeln(sprintf('Analysing photo ID %l (batch: %s)', $queueItem->photo_id, $queueItem->batch_reference));
|
$this->output->writeln(sprintf('Analysing photo ID %l (batch: %s)', $queueItem->photo_id, $queueItem->batch_reference));
|
||||||
|
|
||||||
$photo = Photo::where('id', $queueItem->photo_id)->first();
|
/** @var Photo $photo */
|
||||||
|
$photo = $queueItem->photo;
|
||||||
if (is_null($photo))
|
if (is_null($photo))
|
||||||
{
|
{
|
||||||
$this->output->writeln('Photo does not exist; skipping');
|
$this->output->writeln('Photo does not exist; skipping');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* IF CHANGING THIS LOGIC, ALSO CHECK PhotoController::analyse */
|
/* IF CHANGING THIS LOGIC, ALSO CHECK PhotoController::analyse */
|
||||||
@ -138,7 +151,104 @@ class ProcessQueueCommand extends Command
|
|||||||
if (!is_null($photo->taken_at))
|
if (!is_null($photo->taken_at))
|
||||||
{
|
{
|
||||||
// Log an activity record for the user's feed
|
// Log an activity record for the user's feed
|
||||||
$this->createActivityRecord($photo, 'photo.taken', $photo->taken_at);
|
$this->createActivityRecord($photo, 'photo.taken', $queueItem->user_id, $photo->taken_at);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function processPhotoBulkActionMessage(QueueItem $queueItem)
|
||||||
|
{
|
||||||
|
$action = str_replace('photo.bulk_action.', '', $queueItem->action_type);
|
||||||
|
$this->output->writeln(sprintf('Apply action \'%s\' to photo ID %l (batch: %s)', $action, $queueItem->photo_id, $queueItem->batch_reference));
|
||||||
|
|
||||||
|
/** @var Photo $photo */
|
||||||
|
$photo = $queueItem->photo;
|
||||||
|
if (is_null($photo))
|
||||||
|
{
|
||||||
|
$this->output->writeln('Photo does not exist; skipping');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var User $user */
|
||||||
|
$user = $queueItem->user;
|
||||||
|
if (is_null($user))
|
||||||
|
{
|
||||||
|
$this->output->writeln('User does not exist; skipping');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$photoService = new PhotoService($photo);
|
||||||
|
|
||||||
|
switch (strtolower($action))
|
||||||
|
{
|
||||||
|
/* This needs a bit more work - we need to also store the new album ID in the queue_items table */
|
||||||
|
/*case 'change_album':
|
||||||
|
if ($user->can('change-metadata', $photo))
|
||||||
|
{
|
||||||
|
$newAlbumId = intval($request->get('new-album-id'));
|
||||||
|
if ($newAlbumId == $photo->album_id)
|
||||||
|
{
|
||||||
|
// Photo already belongs to this album, don't move
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$newAlbum = $this->loadAlbum($newAlbumId, 'upload-photos');
|
||||||
|
$photoService->changeAlbum($newAlbum);
|
||||||
|
$changed = true;
|
||||||
|
}
|
||||||
|
break;*/
|
||||||
|
|
||||||
|
case 'delete':
|
||||||
|
if ($user->can('delete', $photo))
|
||||||
|
{
|
||||||
|
$photoService->delete();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'flip_both':
|
||||||
|
if ($user->can('manipulate', $photo))
|
||||||
|
{
|
||||||
|
$photoService->flip(true, true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'flip_horizontal':
|
||||||
|
if ($user->can('manipulate', $photo))
|
||||||
|
{
|
||||||
|
$photoService->flip(true, false);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'flip_vertical':
|
||||||
|
if ($user->can('manipulate', $photo))
|
||||||
|
{
|
||||||
|
$photoService->flip(false, true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'refresh_thumbnails':
|
||||||
|
if ($user->can('change-metadata', $photo))
|
||||||
|
{
|
||||||
|
$photoService->regenerateThumbnails();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'rotate_left':
|
||||||
|
if ($user->can('manipulate', $photo))
|
||||||
|
{
|
||||||
|
$photoService->rotate(90);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'rotate_right':
|
||||||
|
if ($user->can('manipulate', $photo))
|
||||||
|
{
|
||||||
|
$photoService->rotate(270);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
$this->output->writeln(sprintf('Action \'%s\' not recognised; skipping'));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,6 +350,7 @@ class PhotoController extends Controller
|
|||||||
'action_type' => 'photo.analyse',
|
'action_type' => 'photo.analyse',
|
||||||
'album_id' => $photo->album_id,
|
'album_id' => $photo->album_id,
|
||||||
'photo_id' => $photo->id,
|
'photo_id' => $photo->id,
|
||||||
|
'user_id' => $this->getUser()->id,
|
||||||
'queued_at' => new \DateTime()
|
'queued_at' => new \DateTime()
|
||||||
]);
|
]);
|
||||||
$queueItem->save();
|
$queueItem->save();
|
||||||
@ -528,7 +529,14 @@ class PhotoController extends Controller
|
|||||||
$numberChanged = $this->updatePhotoDetails($request, $album);
|
$numberChanged = $this->updatePhotoDetails($request, $album);
|
||||||
}
|
}
|
||||||
|
|
||||||
$request->session()->flash('success', trans_choice('admin.bulk_photos_changed', $numberChanged, ['number' => $numberChanged]));
|
$request->session()->flash(
|
||||||
|
'success',
|
||||||
|
trans_choice(
|
||||||
|
UserConfig::isImageProcessingQueueEnabled() ? 'admin.bulk_photos_changed_queued' : 'admin.bulk_photos_changed',
|
||||||
|
$numberChanged,
|
||||||
|
['number' => $numberChanged]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
return redirect(route('albums.show', array('id' => $albumId, 'page' => $request->get('page', 1))));
|
return redirect(route('albums.show', array('id' => $albumId, 'page' => $request->get('page', 1))));
|
||||||
}
|
}
|
||||||
@ -570,11 +578,37 @@ class PhotoController extends Controller
|
|||||||
$action = $request->get('bulk-action');
|
$action = $request->get('bulk-action');
|
||||||
$numberChanged = 0;
|
$numberChanged = 0;
|
||||||
|
|
||||||
|
if (UserConfig::isImageProcessingQueueEnabled())
|
||||||
|
{
|
||||||
|
$queueUid = MiscHelper::randomString();
|
||||||
|
|
||||||
|
foreach ($photosToProcess as $photo)
|
||||||
|
{
|
||||||
|
$queueItem = new QueueItem([
|
||||||
|
'batch_reference' => $queueUid,
|
||||||
|
'action_type' => sprintf('photo.bulk_action.%s', strtolower($action)),
|
||||||
|
'album_id' => $photo->album_id,
|
||||||
|
'photo_id' => $photo->id,
|
||||||
|
'user_id' => $this->getUser()->id,
|
||||||
|
'queued_at' => new \DateTime()
|
||||||
|
]);
|
||||||
|
$queueItem->save();
|
||||||
|
|
||||||
|
$rabbitmq = new RabbitMQService();
|
||||||
|
$rabbitmq->queueItem($queueItem);
|
||||||
|
|
||||||
|
$numberChanged++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
foreach ($photosToProcess as $photo)
|
foreach ($photosToProcess as $photo)
|
||||||
{
|
{
|
||||||
$changed = false;
|
$changed = false;
|
||||||
$photoService = new PhotoService($photo);
|
$photoService = new PhotoService($photo);
|
||||||
$doNotSave = false;
|
$doNotSave = false;
|
||||||
|
|
||||||
|
/* IF CHANGING THIS LOGIC OR ADDING EXTRA case OPTIONS, ALSO CHECK ProcessQueueCommand::processQueueItem AND ProcessQueueCommand::processPhotoBulkActionMessage */
|
||||||
switch (strtolower($action))
|
switch (strtolower($action))
|
||||||
{
|
{
|
||||||
case 'change_album':
|
case 'change_album':
|
||||||
@ -584,7 +618,7 @@ class PhotoController extends Controller
|
|||||||
if ($newAlbumId == $photo->album_id)
|
if ($newAlbumId == $photo->album_id)
|
||||||
{
|
{
|
||||||
// Photo already belongs to this album, don't move
|
// Photo already belongs to this album, don't move
|
||||||
continue;
|
continue 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
$newAlbum = $this->loadAlbum($newAlbumId, 'upload-photos');
|
$newAlbum = $this->loadAlbum($newAlbumId, 'upload-photos');
|
||||||
@ -667,6 +701,7 @@ class PhotoController extends Controller
|
|||||||
$numberChanged++;
|
$numberChanged++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $numberChanged;
|
return $numberChanged;
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,22 @@ class QueueItem extends Model
|
|||||||
'action_type',
|
'action_type',
|
||||||
'album_id',
|
'album_id',
|
||||||
'photo_id',
|
'photo_id',
|
||||||
'queued_at'
|
'queued_at',
|
||||||
|
'user_id'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
public function album()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Album::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function photo()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Photo::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function user()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(User::class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,14 +15,19 @@ class CreateQueueItemsTable extends Migration
|
|||||||
{
|
{
|
||||||
Schema::create('queue_items', function (Blueprint $table) {
|
Schema::create('queue_items', function (Blueprint $table) {
|
||||||
$table->increments('id');
|
$table->increments('id');
|
||||||
|
$table->unsignedInteger('user_id');
|
||||||
$table->string('batch_reference')->nullable(true);
|
$table->string('batch_reference')->nullable(true);
|
||||||
$table->string('action_type', 20);
|
$table->string('action_type', 50);
|
||||||
$table->unsignedInteger('album_id');
|
$table->unsignedInteger('album_id');
|
||||||
$table->unsignedBigInteger('photo_id');
|
$table->unsignedBigInteger('photo_id');
|
||||||
$table->dateTime('queued_at');
|
$table->dateTime('queued_at');
|
||||||
$table->dateTime('completed_at')->nullable(true);
|
$table->dateTime('completed_at')->nullable(true);
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
|
|
||||||
|
$table->foreign('user_id')
|
||||||
|
->references('id')->on('users')
|
||||||
|
->onDelete('cascade');
|
||||||
|
|
||||||
$table->foreign('album_id')
|
$table->foreign('album_id')
|
||||||
->references('id')->on('albums')
|
->references('id')->on('albums')
|
||||||
->onDelete('cascade');
|
->onDelete('cascade');
|
||||||
|
@ -66,6 +66,7 @@ return [
|
|||||||
'bulk_comments_approved' => ':number comment was approved successfully.|:number comments were approved successfully.',
|
'bulk_comments_approved' => ':number comment was approved successfully.|:number comments were approved successfully.',
|
||||||
'bulk_comments_deleted' => ':number comment was deleted successfully.|:number comments were deleted successfully.',
|
'bulk_comments_deleted' => ':number comment was deleted successfully.|:number comments were deleted successfully.',
|
||||||
'bulk_photos_changed' => ':number photo was updated successfully.|:number photos were updated successfully.',
|
'bulk_photos_changed' => ':number photo was updated successfully.|:number photos were updated successfully.',
|
||||||
|
'bulk_photos_changed_queued' => 'Your requested change has been queued. :number photo will be updated shortly.|Your requested change has been queued. :number photos will be updated shortly.',
|
||||||
'cannot_delete_own_user_account' => 'It is not possible to delete your own user account. Please ask another administrator to delete it for you.',
|
'cannot_delete_own_user_account' => 'It is not possible to delete your own user account. Please ask another administrator to delete it for you.',
|
||||||
'cannot_remove_own_admin' => 'You cannot remove your own administrator permissions. Please ask another administrator to remove the administrator permissions for you.',
|
'cannot_remove_own_admin' => 'You cannot remove your own administrator permissions. Please ask another administrator to remove the administrator permissions for you.',
|
||||||
'change_album_message' => 'Please select the album to move the photo(s) to:',
|
'change_album_message' => 'Please select the album to move the photo(s) to:',
|
||||||
|
Loading…
Reference in New Issue
Block a user