Commit 8daa71a7 by Vladislav

#20443 Загрузка и синхронизация изображений

1 parent 42787f19
<?php
namespace App\Console\Commands;
use App\Models\Pivots\GoalAdImage;
use App\Models\Tokens;
use App\Service\Requests\Direct\AddAdImages;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\Relations\HasMany;
class AdImagesAdd extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'adimages:add';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Добавление не созданных изображений с целевого аккаунта';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
* @throws \Exception
*/
public function handle()
{
$tokens = Tokens::whereHas('goalAdImagesForNotExternalForNotReserveCreate.adImage')
->where('type', '!=', Tokens::MAIN)
->get();
foreach ($tokens as $token) {
$token->load([
'goalAdImagesForNotExternalForNotReserveCreate' => function (HasMany $query) {
return $query->has('adImage');
},
'goalAdImagesForNotExternalForNotReserveCreate.adImage',
]);
$goalAdImages = $token->goalAdImagesForNotExternalForNotReserveCreate;
foreach (array_chunk($goalAdImages->pluck('id')->toArray(), 1000) as $items) {
GoalAdImage::whereIn('id', $items)
->update([
'reserve_create_at' => Carbon::now(),
]);
}
$request = new AddAdImages();
$request->setToken($token)
->call([
'goalAdImages' => $goalAdImages,
]);
}
return 0;
}
}
<?php
namespace App\Console\Commands;
use App\Models\Advertisement;
use App\Models\Tokens;
use App\Service\Requests\Direct\GetAdImages;
use App\Service\Requests\Direct\GetSitelinks;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
class AdImagesLoad extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'adimages:load';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Загрузка изображений';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
* @throws \Exception
*/
public function handle()
{
$token = Tokens::where('type', Tokens::MAIN)->first();
if (!$token) {
throw new \Exception('Не найден токен блин');
}
$request = new GetAdImages();
$request->setToken($token)
->call();
return 0;
}
}
......@@ -110,6 +110,16 @@ class DictionaryCampaignsSyncByCampaign extends Command
");
}
//грузим изображения которых по какой то причне нет в целевых.
DB::insert("
INSERT INTO goal_ad_images(ad_image_id, token_id, created_at, updated_at)
SELECT ai.id, t.id, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP
FROM ad_images ai
INNER JOIN tokens t on t.type != '" . Tokens::MAIN . "'
LEFT JOIN goal_ad_images gai on ai.id = gai.ad_image_id and t.id = gai.token_id
WHERE gai.id is null and gai.deleted_at is null
");
//грузим наборы минус-фраз которых по какой то причне нет в целевых.
DB::insert("
INSERT INTO goal_negative_keyword_shared_sets(negative_keyword_shared_set_id, token_id, created_at, updated_at)
......
<?php
namespace App\Models;
use App\Models\Pivots\GoalAdImage;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Http;
class AdImage extends Model
{
use SoftDeletes;
const TYPE_SMALL = 'SMALL';
const TYPE_REGULAR = 'REGULAR';
const TYPE_WIDE = 'WIDE';
const TYPE_FIXED_IMAGE = 'FIXED_IMAGE';
const TYPE_UNFIT = 'UNFIT';
const SUBTYPE_IMG_240_400 = 'IMG_240_400';
const SUBTYPE_IMG_300_250 = 'IMG_300_250';
const SUBTYPE_IMG_300_500 = 'IMG_300_500';
const SUBTYPE_IMG_300_600 = 'IMG_300_600';
const SUBTYPE_IMG_336_280 = 'IMG_336_280';
const SUBTYPE_IMG_640_100 = 'IMG_640_100';
const SUBTYPE_IMG_640_200 = 'IMG_640_200';
const SUBTYPE_IMG_640_960 = 'IMG_640_960';
const SUBTYPE_IMG_728_90 = 'IMG_728_90';
const SUBTYPE_IMG_960_640 = 'IMG_960_640';
const SUBTYPE_IMG_970_250 = 'IMG_970_250';
const SUBTYPE_NONE = 'NONE';
protected $fillable = [
'hash',
'name',
'type',
'subtype',
'original_url',
'preview_url',
];
public function getImageDataAttribute()
{
return Http::get($this->original_url);
}
public function goalAdImages()
{
return $this->hasMany(GoalAdImage::class, 'ad_image_id');
}
}
<?php
namespace App\Models\Pivots;
use App\Models\AdImage;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\Pivot;
use Illuminate\Database\Eloquent\SoftDeletes;
class GoalAdImage extends Pivot
{
use SoftDeletes;
protected $table = 'goal_ad_images';
protected $fillable = [
'hash',
'ad_image_id',
'token_id',
'external_upload_at',
'reserve_create_at',
];
protected $casts = [
'external_upload_at' => 'datetime',
'reserve_create_at' => 'datetime',
];
public $incrementing = true;
static public function getWithPivot()
{
return [
'id',
'hash',
'ad_image_id',
'token_id',
'external_upload_at',
'reserve_create_at',
];
}
/**
* @param Builder $query
* @return Builder
*/
public function scopeForExternal($query)
{
return $query->whereNotNull('hash');
}
/**
* @param Builder $query
* @return Builder
*/
public function scopeForNotExternal($query)
{
return $query->whereNull('hash');
}
/**
* @param Builder $query
* @return Builder
*/
public function scopeForNotReserveCreate($query)
{
return $query->whereNull('reserve_create_at');
}
public function adImage()
{
return $this->belongsTo(AdImage::class, 'ad_image_id');
}
}
......@@ -4,6 +4,7 @@ namespace App\Models;
use App\Models\Pivots\DictionaryCampaign;
use App\Models\Pivots\GoalAdExtension;
use App\Models\Pivots\GoalAdImage;
use App\Models\Pivots\GoalNegativeKeywordSharedSet;
use App\Models\Pivots\GoalRetargetinglist;
use App\Models\Pivots\GoalSitelink;
......@@ -309,4 +310,14 @@ class Tokens extends Model
return $this->goalRetargetinglists()->forNotExternal()->forNotReserveCreate();
}
public function goalAdImages()
{
return $this->hasMany(GoalAdImage::class, 'token_id');
}
public function goalAdImagesForNotExternalForNotReserveCreate()
{
return $this->goalAdImages()->forNotExternal()->forNotReserveCreate();
}
}
<?php
namespace App\Service\Requests\Direct;
use App\Jobs\ProcessCallLimitedAPI;
use App\Models\Pivots\GoalAdImage;
use App\Service\Contract\APIRequest;
use App\Service\Requests\DirectRequest;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\Log;
class AddAdImages extends DirectRequest
{
protected $max_count = 1000;
protected $timestamp;
/* @var Collection|GoalAdImage[] */
protected $goalAdImages;
public function call($params = null)
{
$this->requestPrepare($params);
$process = new ProcessCallLimitedAPI($this);
dispatch($process)->onQueue('limits');
}
public function getObjectsCount()
{
return count($this->getParams()['AdImages']);
}
public function slice($maxObjects): ?APIRequest
{
$splinter = $this->sliceByKey($maxObjects, 'AdImages');
$splinter->putParams([
'goalAdImages' => $this->goalAdImages->slice($maxObjects)->values(),
]);
$this->putParams([
'goalAdImages' => $this->goalAdImages->slice(0, $maxObjects),
]);
return $splinter;
}
public function handle($response)
{
try {
if (!isset($response['result']['AddResults'])) {
return;
}
foreach ($response['result']['AddResults'] as $key => $add_result) {
$goalAdImage = $this->goalAdImages->get($key);
if (!isset($add_result['AdImageHash'])) {
Log::debug("AddAdImage, empty AdImageHash");
Log::debug($add_result);
Log::debug($this->getParams()['AdImages'][$key]);
$goalAdImage->update([
'reserve_create_at' => null,
]);
continue;
}
$hash = (string)$add_result['AdImageHash'];
$goalAdImage->update([
'hash' => $hash,
'external_upload_at' => Carbon::now(),
'reserve_create_at' => null,
]);
}
} catch (\Exception $e) {
Log::debug($e);
throw $e;
}
}
public function failed()
{
GoalAdImage::whereIn('id', $this->goalAdImages->pluck('id')->toArray())
->update([
'reserve_create_at' => null,
]);
}
public function putParams($params)
{
$this->goalAdImages = $params['goalAdImages'];
}
private function requestPrepare($params)
{
$this->setService('AdImages');
$this->setMethod('add');
$this->putParams($params);
$this->setParams([
'AdImages' => $this->goalAdImages->map(function (GoalAdImage $goalAdImage) {
return [
'Name' => $goalAdImage->adImage->name,
'ImageData' => $goalAdImage->adImage->imageData,
];
})->toArray(),
]);
}
}
<?php
namespace App\Service\Requests\Direct;
use App\Jobs\ProcessCallLimitedAPI;
use App\Models\AdImage;
use App\Service\Contract\APIRequest;
use App\Service\Requests\DirectRequest;
use Illuminate\Support\Facades\Log;
class GetAdImages extends DirectRequest
{
protected $max_count = -1;
protected $max_count_AdImageHashes = 10000;
function call($params = null)
{
$this->requestPrepare($params);
$process = new ProcessCallLimitedAPI($this);
dispatch($process)->onQueue('limits');
}
public function getObjectsCount()
{
$params = $this->getParams();
if (isset($params['SelectionCriteria']['AdImageHashes'])) {
return count($params['SelectionCriteria']['AdImageHashes']);
}
return -1;
}
public function slice($maxObjects): ?APIRequest
{
$params = $this->getParams();
if (isset($params['SelectionCriteria']['AdImageHashes'])) {
return $this->sliceByKey($maxObjects, ['SelectionCriteria', 'AdImageHashes']);
}
return null;
}
function handle($response)
{
try {
if (isset($response['result']['AdImages'])) {
foreach ($response['result']['AdImages'] as $ad_image) {
$hash = (string)$ad_image['AdImageHash'];
$original_url = $ad_image['OriginalUrl'];
if ($this->getToken()->isMain()) {
if (!$original_url) {
Log::debug("GetAdImage, empty OriginalUrl");
Log::debug($ad_image);
continue;
}
$data = [
'hash' => $hash,
'name' => $ad_image['Name'],
'type' => $ad_image['Type'],
'subtype' => $ad_image['Subtype'],
'original_url' => $original_url,
'preview_url' => $ad_image['PreviewUrl'],
];
$adImage = AdImage::updateOrCreate([
'hash' => $hash
], $data);
} else {
//
}
}
}
} catch (\Exception $e) {
Log::debug($e);
throw $e;
}
}
private function requestPrepare($filter)
{
$this->setService('AdImages');
$this->setMethod('get');
$params = [
"SelectionCriteria" => [
'Associated' => 'YES',
],
"FieldNames" => [
"AdImageHash", "OriginalUrl", "PreviewUrl",
"Name", "Type", "Subtype"
],
];
if (isset($filter['Ids'])) {
$this->max_count = $this->max_count_AdImageHashes;
$params['SelectionCriteria']['AdImageHashes'] = $filter['AdImageHashes'];
}
$this->setParams($params);
}
}
<?php
use App\Models\AdImage;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateAdImagesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('ad_images', function (Blueprint $table) {
$table->id();
$table->string('hash');
$table->string('name');
$table->enum('type', [
AdImage::TYPE_SMALL,
AdImage::TYPE_REGULAR,
AdImage::TYPE_WIDE,
AdImage::TYPE_FIXED_IMAGE,
AdImage::TYPE_UNFIT,
]);
$table->enum('subtype', [
AdImage::SUBTYPE_NONE,
AdImage::SUBTYPE_IMG_240_400,
AdImage::SUBTYPE_IMG_300_250,
AdImage::SUBTYPE_IMG_300_500,
AdImage::SUBTYPE_IMG_300_600,
AdImage::SUBTYPE_IMG_336_280,
AdImage::SUBTYPE_IMG_640_100,
AdImage::SUBTYPE_IMG_640_200,
AdImage::SUBTYPE_IMG_640_960,
AdImage::SUBTYPE_IMG_728_90,
AdImage::SUBTYPE_IMG_960_640,
AdImage::SUBTYPE_IMG_970_250,
]);
$table->text('original_url');
$table->text('preview_url');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('ad_images');
}
}
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateGoalAdImagesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('goal_ad_images', function (Blueprint $table) {
$table->id();
$table->string('hash')->nullable();
$table->bigInteger('ad_image_id')->unsigned();
$table->bigInteger('token_id')->unsigned();
$table->timestamp('external_upload_at')->nullable();
$table->timestamp('reserve_create_at')->nullable();
$table->foreign('ad_image_id')->references('id')->on('ad_images')
->cascadeOnDelete();
$table->foreign('token_id')->references('id')->on('tokens')
->cascadeOnDelete();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('goal_ad_images');
}
}
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!