diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 108d236..b388ed1 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -15,11 +15,11 @@ class Kernel extends ConsoleKernel */ protected function schedule(Schedule $schedule): void { - $schedule->command('sitemap:generate')->daily(); + $schedule->command('sitemap:generate')->daily()->name('sitemap-generate-daily'); $schedule->call(function () { BrowseAndWriteWithAIJob::dispatch()->onQueue('default')->onConnection('default'); - })->dailyAt('00:00'); + })->everySixHours()->name('write-a-job-6hrs'); $schedule->call(function () { $future_post = Post::whereNotNull('published_at')->where('status', 'future')->where('published_at', '>=', now())->orderBy('published_at', 'ASC')->first(); @@ -28,7 +28,7 @@ protected function schedule(Schedule $schedule): void PublishIndexPostJob::dispatch($future_post->id)->onQueue('default')->onConnection('default'); } - })->everyMinute(); + })->everyMinute()->name('schedule-future-post'); } diff --git a/app/Helpers/FirstParty/ImageGen/ImageGen.php b/app/Helpers/FirstParty/ImageGen/ImageGen.php new file mode 100644 index 0000000..6353b27 --- /dev/null +++ b/app/Helpers/FirstParty/ImageGen/ImageGen.php @@ -0,0 +1,171 @@ +height() - 145; // Position for the title at one-third the height + $description_position_y = $canvas->height() - 30; + $website_position_y = $canvas->height() - 30; + +// Title - wrapped to 2 lines if necessary, with ellipsis if there is excess text +$wrappedTitle = wordwrap($title, 35, "\n", true); // Wrap the title +$lines = explode("\n", $wrappedTitle); // Split the title into lines + +// Adjust these variables as needed +$lineHeight = 65; // The height of a line of text, adjust as needed for line spacing +$titleStartPositionY = $title_position_y; // Starting Y position for the title, adjust if needed + +// Check if there are more than 2 lines after wrapping +if (count($lines) > 2) { + $lines = array_slice($lines, 0, 2); // Keep only the first two lines + $secondLine = &$lines[1]; // Reference to the second line + // Check if the second line can fit an ellipsis; if not, trim the text + if (strlen($secondLine) > 32) { + $secondLine = substr($secondLine, 0, 32) . '...'; // Trim and add ellipsis + } else { + // Add ellipsis directly if there's enough space + $secondLine .= '...'; + } +} + +// Now, render each line individually with adjusted line spacing +foreach ($lines as $index => $line) { + $currentLineY = $titleStartPositionY + ($index * $lineHeight); + $canvas->text($line, 30, $currentLineY, function($font) use ($bold_font, $font_color, $font_size_title) { + $font->file($bold_font); + $font->size($font_size_title); + $font->color($font_color); + $font->align('left'); // Align text to the left + $font->valign('bottom'); // Align text to the top of the current line position + }); +} + + // Description - justified to the left, below the title + $canvas->text($description, 30, $description_position_y, function($font) use ($bold_font, $font_color, $font_size_description) { + $font->file($bold_font); + $font->size($font_size_description); + $font->color($font_color); + $font->align('left'); // Align text to the left + $font->valign('bottom'); // Align text to the top (as it is below the title) + }); + + // Website - justified to the right, at the bottom of the image + $canvas->text($website, $canvas->width() - 30, $website_position_y, function($font) use ($bold_font, $font_color, $font_size_website) { + $font->file($bold_font); + $font->size($font_size_website); + $font->color($font_color); + $font->align('right'); // Align text to the right + $font->valign('bottom'); // Align text to the bottom + }); + + return $canvas; +} + + + + private static function setOgTint($canvas, $width, $height) + { + + $og_tint = Image::make(resource_path("images/tints/caption-bg.png")); + + // Stretch the image to the given width and height + $og_tint->resize($width, $height); + + $canvas->insert($og_tint, 'top-left', 0, 0); + + return $canvas; + } + + private static function setImageTint($canvas, $width, $height) + { + /// ADD TINT + // Define the directory path + $directoryPath = resource_path('images/tints'); + + // Search for files starting with 'tint-' and count them + $tintFilesCount = count(glob($directoryPath . '/tint-*')); + + $tint_image = Image::make(resource_path("images/tints/tint-" . rand(1, $tintFilesCount) . ".png")); + + // Stretch the image to the given width and height + $tint_image->resize($width, $height); + + $canvas->insert($tint_image, 'top-left', 0, 0); + + return $canvas; + } + + private static function getBaseImage($url, $scale = 1.8, $width = 1007, $height = 567) + { + $original_image = Image::make($url); + + // Determine which dimension (width or height) is larger + if ($original_image->width() > $original_image->height()) { + // Width is larger, resize by width + $original_image->resize($width, null, function ($constraint) { + $constraint->aspectRatio(); + $constraint->upsize(); // Prevent upscaling + }); + } else { + // Height is larger or equal, resize by height + $original_image->resize(null, $height, function ($constraint) { + $constraint->aspectRatio(); + $constraint->upsize(); // Prevent upscaling + }); + } + + // Scale the image by 1.5x + $scaled_width = $original_image->width() * $scale; + $scaled_height = $original_image->height() * $scale; + $original_image->resize($scaled_width, $scaled_height); + + // Create an empty canvas + $canvas = Image::canvas($width, $height); + + // Calculate the position to center the scaled image + $x = ($canvas->width() - $scaled_width) / 2; + $y = ($canvas->height() - $scaled_height) / 2; + + // Paste the scaled image onto the canvas at the center position + + $canvas->insert($original_image, 'top-left', (int) $x, (int) $y); + + return $canvas; + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Front/FrontPostController.php b/app/Http/Controllers/Front/FrontPostController.php index b69d84d..b58881e 100644 --- a/app/Http/Controllers/Front/FrontPostController.php +++ b/app/Http/Controllers/Front/FrontPostController.php @@ -78,14 +78,14 @@ public function index(Request $request, $category_slug, $slug) OpenGraph::setUrl(url()->current()); OpenGraph::addProperty('type', 'article'); OpenGraph::addProperty('locale', 'en_US'); - OpenGraph::addImage($post->featured_image_cdn); + OpenGraph::addImage($post->featured_og_image); $jsonld_multi = JsonLdMulti::newJsonLd(); $jsonld_multi->setTitle($post->title) ->setDescription($post_description) ->setType('Article') ->addValue('headline', $post->title) - ->addImage($post->featured_image_cdn) + ->addImage($post->featured_og_image) ->addValue('author', [ 'type' => 'Person', 'name' => 'FutureWalker', @@ -96,7 +96,7 @@ public function index(Request $request, $category_slug, $slug) 'name' => 'FutureWalker', 'logo' => [ 'type' => 'ImageObject', - 'url' => asset('FutureWalker-logo-512x512.png'), + 'url' => asset('images/icons/icon-512x512.png'), ], ]) ->addValue('datePublished', $post->published_at->format('Y-m-d')) diff --git a/app/Http/Controllers/Tests/TestController.php b/app/Http/Controllers/Tests/TestController.php index 01ec29b..f37f5ac 100644 --- a/app/Http/Controllers/Tests/TestController.php +++ b/app/Http/Controllers/Tests/TestController.php @@ -6,9 +6,21 @@ use Illuminate\Http\Request; use LaravelFreelancerNL\LaravelIndexNow\Facades\IndexNow; use LaravelGoogleIndexing; +use App\Helpers\FirstParty\ImageGen\ImageGen; + class TestController extends Controller { + public function imageGen(Request $request) + { + $image_url = 'https://cdn.futurewalker.co/post_images_2/whats-next-for-openai-after-ceo-sam-altmans-ouster-1700439234754.jpg'; + + $canvas = ImageGen::getOpenGraphImage($image_url, 'What’s Next for OpenAI After CEO Sam Altman’s Ouster What’s Next for OpenAI After CEO Sam Altman’s Ouster', '20 NOV • OPENAI • SAM ALTMAN • 3 min read '); + + return response($canvas->encode('jpeg')) + ->header('Content-Type', 'image/jpeg'); + } + public function indexing(Request $request) { $url = $request->input('url'); diff --git a/app/Jobs/Tasks/FillPostMetadataTask.php b/app/Jobs/Tasks/FillPostMetadataTask.php index d94f704..84416cb 100644 --- a/app/Jobs/Tasks/FillPostMetadataTask.php +++ b/app/Jobs/Tasks/FillPostMetadataTask.php @@ -2,6 +2,7 @@ namespace App\Jobs\Tasks; +use App\Helpers\FirstParty\ImageGen\ImageGen; use App\Helpers\FirstParty\OpenAI\OpenAI; use App\Helpers\FirstParty\OSSUploader\OSSUploader; use App\Jobs\SchedulePublishPost; @@ -184,6 +185,7 @@ private static function setPostImage($post) $image_content = $image_response->body(); + // Get the size of the image content in KB $imageSizeInKb = strlen($image_response->body()) / 1024; @@ -192,49 +194,20 @@ private static function setPostImage($post) continue; } - $canvas_width = 1080; - $canvas_height = 608; + $post_description = strtoupper(now()->format('j M')) . " • " . $post->main_keyword . " • " . markdown_min_read($post->body); - $thumb_width = 540; - $thumb_height = 78; + $image = ImageGen::getMainImage($image_content, 1007, 567); + $og_image = ImageGen::getOpenGraphImage($image_content, 1007, 567, $post->title, $post_description); - // Create an image from the fetched content - $image = Image::make($image_content); - // Check if the image is wider than it is tall (landscape orientation) - if ($image->width() > $image->height()) { - // Resize the image to fill the canvas width while maintaining aspect ratio - $image->resize($canvas_width, null, function ($constraint) { - $constraint->aspectRatio(); - }); - } else { - // Resize the image to fill the canvas height while maintaining aspect ratio - $image->resize(null, $canvas_height, function ($constraint) { - $constraint->aspectRatio(); - }); - } - - // Fit the image to the canvas size, without gaps - $image->fit($canvas_width, $canvas_height, function ($constraint) { - $constraint->upsize(); - }); - - // Create a thumbnail by cloning the original image and resizing it - $thumb = clone $image; - $thumb->resize($thumb_width, $thumb_height, function ($constraint) { - $constraint->aspectRatio(); - $constraint->upsize(); - }); - - // Create a image filename $epoch_now_timestamp = epoch_now_timestamp(); $filename = $post->slug.'-'.$epoch_now_timestamp.'.jpg'; - $thumb_filename = $post->slug.'-'.$epoch_now_timestamp.'_thumb.jpg'; + $og_filename = $post->slug.'-'.$epoch_now_timestamp.'_og.jpg'; - OSSUploader::uploadFile('r2', 'post_images_2/', $filename, (string) $image->stream('jpeg', 75)); - OSSUploader::uploadFile('r2', 'post_images_2/', $thumb_filename, (string) $thumb->stream('jpeg', 50)); + OSSUploader::uploadFile('r2', 'post_images/', $filename, (string) $image->stream('jpeg', 75)); + OSSUploader::uploadFile('r2', 'post_images/', $og_filename, (string) $og_image->stream('jpeg', 75)); - $post->featured_image = 'post_images_2/'.$filename; + $post->featured_image = 'post_images/'.$filename; $post->image_ref_url = $image_ref_url; $image->destroy(); diff --git a/app/Jobs/Tasks/ParseDFSNewsTask.php b/app/Jobs/Tasks/ParseDFSNewsTask.php index babb682..e4c0305 100644 --- a/app/Jobs/Tasks/ParseDFSNewsTask.php +++ b/app/Jobs/Tasks/ParseDFSNewsTask.php @@ -49,12 +49,24 @@ public static function handle(NewsSerpResult $news_serp_result, $serp_counts = 1 continue; } + // check timestamp + $serp_timestamp = Carbon::parse($serp_item->timestamp); + if(!$serp_timestamp->isBetween(now()->subHours(6), now())) + { + continue; + } + + ///// + $blacklist_keywords = config('platform.global.blacklist_keywords_serp'); $blacklist_domains = config('platform.global.blacklist_domains_serp'); $skipItem = false; + + + foreach ($blacklist_domains as $domain) { if (str_contains($serp_item->domain, $domain)) { $skipItem = true; diff --git a/app/Models/Post.php b/app/Models/Post.php index 2906deb..4a1ea31 100644 --- a/app/Models/Post.php +++ b/app/Models/Post.php @@ -81,7 +81,7 @@ protected function featuredImage(): Attribute ); } - protected function getFeaturedThumbImageAttribute() + protected function getFeaturedOgImageAttribute() { $value = $this->featured_image; @@ -91,10 +91,9 @@ protected function getFeaturedThumbImageAttribute() // Extract the file extension $extension = pathinfo($value, PATHINFO_EXTENSION); - // Construct the thumbnail filename by appending '_thumb' before the extension - $thumbnail = str_replace(".{$extension}", "_thumb.{$extension}", $value); + $og = str_replace(".{$extension}", "_og.{$extension}", $value); - return $thumbnail; + return $og; // Return the full URL to the thumbnail image //return Storage::disk('r2')->url($thumbnail); diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index 4ae7c90..5f63637 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -29,6 +29,9 @@ public function boot(): void }); $this->routes(function () { + Route::middleware('web') + ->prefix('tests') + ->group(base_path('routes/tests.php')); Route::middleware('api') ->prefix('api') ->group(base_path('routes/api.php')); @@ -36,9 +39,6 @@ public function boot(): void Route::middleware('web') ->group(base_path('routes/web.php')); - Route::middleware('web') - ->prefix('tests') - ->group(base_path('routes/tests.php')); }); } } diff --git a/resources/.DS_Store b/resources/.DS_Store new file mode 100644 index 0000000..a87a429 Binary files /dev/null and b/resources/.DS_Store differ diff --git a/resources/fonts/.DS_Store b/resources/fonts/.DS_Store new file mode 100644 index 0000000..a09b312 Binary files /dev/null and b/resources/fonts/.DS_Store differ diff --git a/resources/fonts/RobotoCondensed/RobotoCondensed-Black.ttf b/resources/fonts/RobotoCondensed/RobotoCondensed-Black.ttf new file mode 100644 index 0000000..d1586a8 Binary files /dev/null and b/resources/fonts/RobotoCondensed/RobotoCondensed-Black.ttf differ diff --git a/resources/fonts/RobotoCondensed/RobotoCondensed-BlackItalic.ttf b/resources/fonts/RobotoCondensed/RobotoCondensed-BlackItalic.ttf new file mode 100644 index 0000000..5b1a3b7 Binary files /dev/null and b/resources/fonts/RobotoCondensed/RobotoCondensed-BlackItalic.ttf differ diff --git a/resources/fonts/RobotoCondensed/RobotoCondensed-Bold.ttf b/resources/fonts/RobotoCondensed/RobotoCondensed-Bold.ttf new file mode 100644 index 0000000..647c3e3 Binary files /dev/null and b/resources/fonts/RobotoCondensed/RobotoCondensed-Bold.ttf differ diff --git a/resources/fonts/RobotoCondensed/RobotoCondensed-BoldItalic.ttf b/resources/fonts/RobotoCondensed/RobotoCondensed-BoldItalic.ttf new file mode 100644 index 0000000..852e599 Binary files /dev/null and b/resources/fonts/RobotoCondensed/RobotoCondensed-BoldItalic.ttf differ diff --git a/resources/fonts/RobotoCondensed/RobotoCondensed-ExtraBold.ttf b/resources/fonts/RobotoCondensed/RobotoCondensed-ExtraBold.ttf new file mode 100644 index 0000000..17db86e Binary files /dev/null and b/resources/fonts/RobotoCondensed/RobotoCondensed-ExtraBold.ttf differ diff --git a/resources/fonts/RobotoCondensed/RobotoCondensed-ExtraBoldItalic.ttf b/resources/fonts/RobotoCondensed/RobotoCondensed-ExtraBoldItalic.ttf new file mode 100644 index 0000000..0e70c65 Binary files /dev/null and b/resources/fonts/RobotoCondensed/RobotoCondensed-ExtraBoldItalic.ttf differ diff --git a/resources/fonts/RobotoCondensed/RobotoCondensed-ExtraLight.ttf b/resources/fonts/RobotoCondensed/RobotoCondensed-ExtraLight.ttf new file mode 100644 index 0000000..96cbc95 Binary files /dev/null and b/resources/fonts/RobotoCondensed/RobotoCondensed-ExtraLight.ttf differ diff --git a/resources/fonts/RobotoCondensed/RobotoCondensed-ExtraLightItalic.ttf b/resources/fonts/RobotoCondensed/RobotoCondensed-ExtraLightItalic.ttf new file mode 100644 index 0000000..13b4316 Binary files /dev/null and b/resources/fonts/RobotoCondensed/RobotoCondensed-ExtraLightItalic.ttf differ diff --git a/resources/fonts/RobotoCondensed/RobotoCondensed-Italic.ttf b/resources/fonts/RobotoCondensed/RobotoCondensed-Italic.ttf new file mode 100644 index 0000000..d507564 Binary files /dev/null and b/resources/fonts/RobotoCondensed/RobotoCondensed-Italic.ttf differ diff --git a/resources/fonts/RobotoCondensed/RobotoCondensed-Light.ttf b/resources/fonts/RobotoCondensed/RobotoCondensed-Light.ttf new file mode 100644 index 0000000..1d963ad Binary files /dev/null and b/resources/fonts/RobotoCondensed/RobotoCondensed-Light.ttf differ diff --git a/resources/fonts/RobotoCondensed/RobotoCondensed-LightItalic.ttf b/resources/fonts/RobotoCondensed/RobotoCondensed-LightItalic.ttf new file mode 100644 index 0000000..bbe91f5 Binary files /dev/null and b/resources/fonts/RobotoCondensed/RobotoCondensed-LightItalic.ttf differ diff --git a/resources/fonts/RobotoCondensed/RobotoCondensed-Medium.ttf b/resources/fonts/RobotoCondensed/RobotoCondensed-Medium.ttf new file mode 100644 index 0000000..4dfbac9 Binary files /dev/null and b/resources/fonts/RobotoCondensed/RobotoCondensed-Medium.ttf differ diff --git a/resources/fonts/RobotoCondensed/RobotoCondensed-MediumItalic.ttf b/resources/fonts/RobotoCondensed/RobotoCondensed-MediumItalic.ttf new file mode 100644 index 0000000..707606e Binary files /dev/null and b/resources/fonts/RobotoCondensed/RobotoCondensed-MediumItalic.ttf differ diff --git a/resources/fonts/RobotoCondensed/RobotoCondensed-Regular.ttf b/resources/fonts/RobotoCondensed/RobotoCondensed-Regular.ttf new file mode 100644 index 0000000..74f029c Binary files /dev/null and b/resources/fonts/RobotoCondensed/RobotoCondensed-Regular.ttf differ diff --git a/resources/fonts/RobotoCondensed/RobotoCondensed-SemiBold.ttf b/resources/fonts/RobotoCondensed/RobotoCondensed-SemiBold.ttf new file mode 100644 index 0000000..d936493 Binary files /dev/null and b/resources/fonts/RobotoCondensed/RobotoCondensed-SemiBold.ttf differ diff --git a/resources/fonts/RobotoCondensed/RobotoCondensed-SemiBoldItalic.ttf b/resources/fonts/RobotoCondensed/RobotoCondensed-SemiBoldItalic.ttf new file mode 100644 index 0000000..f698ac1 Binary files /dev/null and b/resources/fonts/RobotoCondensed/RobotoCondensed-SemiBoldItalic.ttf differ diff --git a/resources/fonts/RobotoCondensed/RobotoCondensed-Thin.ttf b/resources/fonts/RobotoCondensed/RobotoCondensed-Thin.ttf new file mode 100644 index 0000000..74f3c18 Binary files /dev/null and b/resources/fonts/RobotoCondensed/RobotoCondensed-Thin.ttf differ diff --git a/resources/fonts/RobotoCondensed/RobotoCondensed-ThinItalic.ttf b/resources/fonts/RobotoCondensed/RobotoCondensed-ThinItalic.ttf new file mode 100644 index 0000000..1938663 Binary files /dev/null and b/resources/fonts/RobotoCondensed/RobotoCondensed-ThinItalic.ttf differ diff --git a/resources/images/.DS_Store b/resources/images/.DS_Store new file mode 100644 index 0000000..3017b7f Binary files /dev/null and b/resources/images/.DS_Store differ diff --git a/resources/images/tints/.DS_Store b/resources/images/tints/.DS_Store new file mode 100644 index 0000000..5008ddf Binary files /dev/null and b/resources/images/tints/.DS_Store differ diff --git a/resources/images/tints/caption-bg.png b/resources/images/tints/caption-bg.png new file mode 100644 index 0000000..f1091ae Binary files /dev/null and b/resources/images/tints/caption-bg.png differ diff --git a/resources/images/tints/tint-1.png b/resources/images/tints/tint-1.png new file mode 100644 index 0000000..97c8e74 Binary files /dev/null and b/resources/images/tints/tint-1.png differ diff --git a/resources/images/tints/tint-10.png b/resources/images/tints/tint-10.png new file mode 100644 index 0000000..6fe63c7 Binary files /dev/null and b/resources/images/tints/tint-10.png differ diff --git a/resources/images/tints/tint-11.png b/resources/images/tints/tint-11.png new file mode 100644 index 0000000..54c8424 Binary files /dev/null and b/resources/images/tints/tint-11.png differ diff --git a/resources/images/tints/tint-12.png b/resources/images/tints/tint-12.png new file mode 100644 index 0000000..3806a57 Binary files /dev/null and b/resources/images/tints/tint-12.png differ diff --git a/resources/images/tints/tint-2.png b/resources/images/tints/tint-2.png new file mode 100644 index 0000000..e939816 Binary files /dev/null and b/resources/images/tints/tint-2.png differ diff --git a/resources/images/tints/tint-3.png b/resources/images/tints/tint-3.png new file mode 100644 index 0000000..51cb886 Binary files /dev/null and b/resources/images/tints/tint-3.png differ diff --git a/resources/images/tints/tint-4.png b/resources/images/tints/tint-4.png new file mode 100644 index 0000000..cbb9b07 Binary files /dev/null and b/resources/images/tints/tint-4.png differ diff --git a/resources/images/tints/tint-5.png b/resources/images/tints/tint-5.png new file mode 100644 index 0000000..dd0b331 Binary files /dev/null and b/resources/images/tints/tint-5.png differ diff --git a/resources/images/tints/tint-6.png b/resources/images/tints/tint-6.png new file mode 100644 index 0000000..eb579cb Binary files /dev/null and b/resources/images/tints/tint-6.png differ diff --git a/resources/images/tints/tint-7.png b/resources/images/tints/tint-7.png new file mode 100644 index 0000000..0a9b5af Binary files /dev/null and b/resources/images/tints/tint-7.png differ diff --git a/resources/images/tints/tint-8.png b/resources/images/tints/tint-8.png new file mode 100644 index 0000000..4a011ee Binary files /dev/null and b/resources/images/tints/tint-8.png differ diff --git a/resources/images/tints/tint-9.png b/resources/images/tints/tint-9.png new file mode 100644 index 0000000..63b67f8 Binary files /dev/null and b/resources/images/tints/tint-9.png differ diff --git a/resources/views/front/layouts/partials/nav.blade.php b/resources/views/front/layouts/partials/nav.blade.php index 69ec3ce..a331380 100644 --- a/resources/views/front/layouts/partials/nav.blade.php +++ b/resources/views/front/layouts/partials/nav.blade.php @@ -60,7 +60,7 @@ Home @foreach ($categories as $category) - {{ $category->name }} @endforeach diff --git a/resources/views/front/post_list.blade.php b/resources/views/front/post_list.blade.php index 3e698ef..cf66614 100644 --- a/resources/views/front/post_list.blade.php +++ b/resources/views/front/post_list.blade.php @@ -38,7 +38,7 @@