sync
This commit is contained in:
@@ -29,17 +29,15 @@ protected function schedule(Schedule $schedule)
|
||||
private function scheduleCategory(Schedule $schedule, $locale, $categoryName, $taskName)
|
||||
{
|
||||
$schedule->call(function () use ($locale, $categoryName) {
|
||||
|
||||
|
||||
$category = Category::where('country_locale_slug', $locale)->where('name', $categoryName)->first();
|
||||
|
||||
if (!is_null($category))
|
||||
{
|
||||
$task = $category->country_locale_slug . "-" . $category->slug;
|
||||
if (! is_null($category)) {
|
||||
$task = $category->country_locale_slug.'-'.$category->slug;
|
||||
|
||||
$nextRun = DailyTaskSchedule::where('task', $task)->first();
|
||||
|
||||
if (!is_null($nextRun))
|
||||
{
|
||||
if (! is_null($nextRun)) {
|
||||
$currentTime = now();
|
||||
|
||||
if ($currentTime->gte($nextRun->next_run_time)) {
|
||||
@@ -57,11 +55,9 @@ private function scheduleCategory(Schedule $schedule, $locale, $categoryName, $t
|
||||
$nextRun->next_run_time = now()->addMinutes(rand(1200, 1440));
|
||||
$nextRun->save();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$nextRun = new DailyTaskSchedule;
|
||||
$nextRun->task = $category->country_locale_slug . "-" . $category->slug;
|
||||
$nextRun->task = $category->country_locale_slug.'-'.$category->slug;
|
||||
$nextRun->next_run_time = now()->addMinutes(rand(0, 1440));
|
||||
$nextRun->save();
|
||||
}
|
||||
|
||||
@@ -37,10 +37,8 @@ public function register()
|
||||
return response()->json([
|
||||
'status' => -1,
|
||||
], 404);
|
||||
}
|
||||
else
|
||||
{
|
||||
return redirect()->route('home', [], 301);
|
||||
} else {
|
||||
return redirect()->route('home', [], 301);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
40
app/FirstParty/DFS/DFSBacklinks.php
Normal file
40
app/FirstParty/DFS/DFSBacklinks.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Helpers\FirstParty\DFS;
|
||||
|
||||
use Exception;
|
||||
use Http;
|
||||
|
||||
class DFSBacklinks
|
||||
{
|
||||
public static function backlinksPaginationLive($target, $search_after_token, $value = 1000)
|
||||
{
|
||||
$api_url = config('dataforseo.url');
|
||||
|
||||
$api_version = config('dataforseo.api_version');
|
||||
|
||||
$api_timeout = config('dataforseo.timeout');
|
||||
|
||||
$query = [
|
||||
'target' => $target,
|
||||
'search_after_token' => $search_after_token,
|
||||
'value' => $value,
|
||||
'mode' => 'as_is',
|
||||
];
|
||||
|
||||
try {
|
||||
$response = Http::timeout($api_timeout)->withBasicAuth(config('dataforseo.login'), config('dataforseo.password'))->withBody(
|
||||
json_encode([(object) $query])
|
||||
)->post("{$api_url}{$api_version}backlinks/backlinks/live");
|
||||
|
||||
if ($response->successful()) {
|
||||
return $response->body();
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
43
app/FirstParty/DFS/DFSSerp.php
Normal file
43
app/FirstParty/DFS/DFSSerp.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Helpers\FirstParty\DFS;
|
||||
|
||||
use Exception;
|
||||
use Http;
|
||||
|
||||
class DFSSerp
|
||||
{
|
||||
public static function liveAdvanced($se, $se_type, $keyword, $location_name, $language_code, $depth, $search_param = null)
|
||||
{
|
||||
$api_url = config('dataforseo.url');
|
||||
|
||||
$api_version = config('dataforseo.api_version');
|
||||
|
||||
$api_timeout = config('dataforseo.timeout');
|
||||
|
||||
$query = [
|
||||
'keyword' => $keyword,
|
||||
'location_name' => $location_name,
|
||||
'language_code' => $language_code,
|
||||
];
|
||||
|
||||
if (! is_empty($search_param)) {
|
||||
$query['search_param'] = $search_param;
|
||||
}
|
||||
|
||||
try {
|
||||
$response = Http::timeout($api_timeout)->withBasicAuth(config('dataforseo.login'), config('dataforseo.password'))->withBody(
|
||||
json_encode([(object) $query])
|
||||
)->post("{$api_url}{$api_version}serp/{$se}/{$se_type}/live/advanced");
|
||||
|
||||
if ($response->successful()) {
|
||||
return $response->body();
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ public static function writeProductArticle($excerpt, $photos, $categories)
|
||||
{
|
||||
//$excerpt = substr($excerpt, 0, 1500);
|
||||
|
||||
$category_str = implode("|", $categories);
|
||||
$category_str = implode('|', $categories);
|
||||
|
||||
$system_prompt = '
|
||||
You are tasked with writing a product introduction & review article using the provided excerpt. Write as if you are reviewing the product by a third party, avoiding pronouns. Emphasize the product\'s performance, features, and notable aspects. Do not mention marketplace-related information. Return the output as a minified JSON in this format:
|
||||
|
||||
@@ -17,7 +17,7 @@ function str_first_sentence($str)
|
||||
|
||||
// Return the first part of the array if available
|
||||
if (isset($sentences[0])) {
|
||||
return trim($sentences[0]) . ".";
|
||||
return trim($sentences[0]).'.';
|
||||
}
|
||||
|
||||
// If no sentence ending found, return the whole string
|
||||
|
||||
@@ -3,214 +3,12 @@
|
||||
namespace App\Http\Controllers\Front;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Category;
|
||||
use App\Models\CountryLocale;
|
||||
use App\Models\Post;
|
||||
use Artesaos\SEOTools\Facades\JsonLdMulti;
|
||||
use Artesaos\SEOTools\Facades\OpenGraph;
|
||||
use Artesaos\SEOTools\Facades\SEOMeta;
|
||||
use Artesaos\SEOTools\Facades\SEOTools;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class HomeController extends Controller
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
|
||||
SEOTools::metatags();
|
||||
SEOTools::twitter();
|
||||
SEOTools::opengraph();
|
||||
SEOTools::jsonLd();
|
||||
SEOTools::setTitle('Top Product Reviews, Deals & New Launches');
|
||||
SEOTools::setDescription('Explore ProductAlert for in-depth product reviews and incredible deals. We cover Beauty, Tech, Home Appliances, Health & Fitness, Parenting, and more.');
|
||||
|
||||
$country = strtolower($request->session()->get('country'));
|
||||
|
||||
return redirect()->route('home.country', ['country' => $country]);
|
||||
}
|
||||
|
||||
public function country(Request $request, $country)
|
||||
{
|
||||
|
||||
$country_locale = CountryLocale::where('slug', $country)->first();
|
||||
|
||||
if (! is_null($country_locale)) {
|
||||
|
||||
$request->session()->put('view_country_locale', $country_locale);
|
||||
|
||||
$featured_posts = Post::select('posts.*')
|
||||
->join('post_categories', 'posts.id', '=', 'post_categories.post_id')
|
||||
->join('categories', 'post_categories.category_id', '=', 'categories.id')
|
||||
->whereNotNull('post_categories.id')
|
||||
->whereNotNull('categories.id')
|
||||
->where('categories.country_locale_slug', $country_locale->slug)
|
||||
->where('posts.status', 'publish')
|
||||
->orderBy('posts.publish_date', 'desc')
|
||||
->take(3)
|
||||
->get();
|
||||
|
||||
$latest_posts = Post::select('posts.*')
|
||||
->join('post_categories', 'posts.id', '=', 'post_categories.post_id')
|
||||
->join('categories', 'post_categories.category_id', '=', 'categories.id')
|
||||
->whereNotNull('post_categories.id')
|
||||
->whereNotNull('categories.id')
|
||||
->where('categories.country_locale_slug', $country_locale->slug)
|
||||
->whereNotIn('posts.id', $featured_posts->pluck('id')->toArray())
|
||||
->where('posts.status', 'publish')
|
||||
->orderBy('posts.publish_date', 'desc')
|
||||
->distinct()
|
||||
->take(10)
|
||||
->get();
|
||||
|
||||
if ($latest_posts->count() <= 0) {
|
||||
SEOMeta::setRobots('noindex');
|
||||
}
|
||||
|
||||
SEOTools::metatags();
|
||||
SEOTools::twitter();
|
||||
SEOTools::opengraph();
|
||||
SEOTools::jsonLd();
|
||||
|
||||
$country_name = get_country_name_by_iso($country_locale->country_iso);
|
||||
|
||||
SEOTools::setTitle("Your {$country_name} Guide to Product Reviews & Top Deals");
|
||||
SEOTools::setDescription("Discover trusted product reviews and unbeatable deals at ProductAlert {$country_name}, your local guide to smart shopping.");
|
||||
|
||||
return view('front.country', compact('country_locale', 'featured_posts', 'latest_posts')
|
||||
);
|
||||
}
|
||||
|
||||
return redirect()->route('home.country', ['country' => config('platform.general.fallback_country_slug')]);
|
||||
}
|
||||
|
||||
public function countryCategory(Request $request, $country, $category)
|
||||
{
|
||||
$country_locale = CountryLocale::where('slug', $country)->first();
|
||||
|
||||
if (is_null($country_locale)) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
$category = Category::where('slug', $category)->where('enabled', true)->first();
|
||||
|
||||
if (is_null($category)) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
$request->session()->put('view_country_locale', $country_locale);
|
||||
|
||||
$latest_posts = Post::with('post_categories')->select('posts.*')
|
||||
->join('post_categories', 'posts.id', '=', 'post_categories.post_id')
|
||||
->join('categories', 'post_categories.category_id', '=', 'categories.id')
|
||||
->whereNotNull('post_categories.id')
|
||||
->whereNotNull('categories.id')
|
||||
->where('categories.country_locale_slug', $country_locale->slug)
|
||||
->where('categories.id', $category->id)
|
||||
->where('posts.status', 'publish')
|
||||
->orderBy('posts.publish_date', 'desc')
|
||||
->distinct()
|
||||
->paginate(15);
|
||||
|
||||
if ($latest_posts->count() <= 0) {
|
||||
SEOMeta::setRobots('noindex');
|
||||
}
|
||||
|
||||
SEOTools::metatags();
|
||||
SEOTools::twitter();
|
||||
SEOTools::opengraph();
|
||||
SEOTools::jsonLd();
|
||||
|
||||
$this_month = now()->format('F Y');
|
||||
|
||||
$country_name = get_country_name_by_iso($country_locale->country_iso);
|
||||
|
||||
//dd($category->type);
|
||||
|
||||
if ($category->type == 'review') {
|
||||
SEOTools::setTitle("Top {$category->name} Reviews for {$this_month} in {$country_name}");
|
||||
} elseif ($category->type == 'deals') {
|
||||
SEOTools::setTitle("{$this_month} Latest Deals, Coupon Codes & Vouchers for {$country_name}");
|
||||
} elseif ($category->type == 'launch') {
|
||||
SEOTools::setTitle("New {$this_month} Product Launches in {$country_name}");
|
||||
}
|
||||
|
||||
$category_name = strtolower($category->name);
|
||||
|
||||
SEOTools::setDescription($category->description);
|
||||
|
||||
return view('front.country_category', compact('country_locale', 'category', 'latest_posts'));
|
||||
}
|
||||
|
||||
public function all(Request $request, $country)
|
||||
{
|
||||
$country_locale = CountryLocale::where('slug', $country)->first();
|
||||
|
||||
$request->session()->put('view_country_locale', $country_locale);
|
||||
|
||||
$latest_posts = Post::with('post_categories')->select('posts.*')
|
||||
->join('post_categories', 'posts.id', '=', 'post_categories.post_id')
|
||||
->join('categories', 'post_categories.category_id', '=', 'categories.id')
|
||||
->whereNotNull('post_categories.id')
|
||||
->whereNotNull('categories.id')
|
||||
->where('categories.country_locale_slug', $country_locale->slug)
|
||||
->where('posts.status', 'publish')
|
||||
->orderBy('posts.publish_date', 'desc')
|
||||
->distinct()
|
||||
->paginate(15);
|
||||
|
||||
if ($latest_posts->count() <= 0) {
|
||||
SEOMeta::setRobots('noindex');
|
||||
}
|
||||
|
||||
SEOTools::metatags();
|
||||
SEOTools::twitter();
|
||||
SEOTools::opengraph();
|
||||
SEOTools::jsonLd();
|
||||
|
||||
$country_name = get_country_name_by_iso($country_locale->country_iso);
|
||||
|
||||
SEOTools::setTitle("Find Product Reviews and Best Deals for {$country_name}");
|
||||
|
||||
SEOTools::setDescription("Discover the latest product reviews and unbeatable deals at ProductAlert, your guide to shopping in {$country_name}. Stay on top of fresh product updates.");
|
||||
|
||||
return view('front.country_all', compact('country_locale', 'latest_posts'));
|
||||
}
|
||||
|
||||
public function post(Request $request, $country, $post_slug)
|
||||
{
|
||||
$post = Post::where('slug', $post_slug)->where('status', 'publish')->first();
|
||||
|
||||
if (! is_null($post)) {
|
||||
|
||||
$request->session()->put('view_country_locale', $post->post_category->category->country_locale);
|
||||
|
||||
SEOMeta::setTitle($post->title);
|
||||
SEOMeta::setDescription($post->excerpt);
|
||||
SEOMeta::addMeta('article:published_time', $post->publish_date, 'property');
|
||||
SEOMeta::addMeta('article:section', $post->post_category->category->name, 'property');
|
||||
|
||||
OpenGraph::setDescription($post->excerpt);
|
||||
OpenGraph::setTitle($post->title);
|
||||
OpenGraph::setUrl(url()->current());
|
||||
OpenGraph::addProperty('type', 'article');
|
||||
OpenGraph::addProperty('locale', $post->post_category->category->country_locale->i18n);
|
||||
OpenGraph::addImage($post->featured_image);
|
||||
|
||||
$jsonld_multi = JsonLdMulti::newJsonLd();
|
||||
$jsonld_multi->setTitle($post->title)
|
||||
->setDescription($post->excerpt)
|
||||
->setType('Article')
|
||||
->addImage($post->featured_image)
|
||||
->addValue('author', $post->author->name)
|
||||
->addValue('datePublished', $post->publish_date->format('Y-m-d'))
|
||||
->addValue('dateCreated', $post->publish_date->format('Y-m-d'))
|
||||
->addValue('dateModified', $post->updated_at->format('Y-m-d'))
|
||||
->addValue('description', $post->excerpt)
|
||||
->addValue('articleBody', trim(preg_replace('/\s\s+/', ' ', strip_tags($post->html_body))));
|
||||
|
||||
return view('front.post', compact('post'));
|
||||
}
|
||||
abort(404);
|
||||
|
||||
return view('front.home');
|
||||
}
|
||||
}
|
||||
|
||||
194
app/Http/Controllers/Front/OldHomeController.php
Normal file
194
app/Http/Controllers/Front/OldHomeController.php
Normal file
@@ -0,0 +1,194 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Front;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Category;
|
||||
use App\Models\CountryLocale;
|
||||
use App\Models\Post;
|
||||
use Artesaos\SEOTools\Facades\JsonLdMulti;
|
||||
use Artesaos\SEOTools\Facades\OpenGraph;
|
||||
use Artesaos\SEOTools\Facades\SEOMeta;
|
||||
use Artesaos\SEOTools\Facades\SEOTools;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class OldHomeController extends Controller
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
|
||||
SEOTools::metatags();
|
||||
SEOTools::twitter();
|
||||
SEOTools::opengraph();
|
||||
SEOTools::jsonLd();
|
||||
SEOTools::setTitle('Top Product Reviews, Deals & New Launches');
|
||||
SEOTools::setDescription('Explore ProductAlert for in-depth product reviews and incredible deals. We cover Beauty, Tech, Home Appliances, Health & Fitness, Parenting, and more.');
|
||||
|
||||
return redirect()->route('home.country', ['country' => 'global']);
|
||||
}
|
||||
|
||||
public function country(Request $request, $country)
|
||||
{
|
||||
|
||||
$country_locale = CountryLocale::where('slug', $country)->first();
|
||||
|
||||
if (! is_null($country_locale)) {
|
||||
|
||||
$request->session()->put('view_country_locale', $country_locale);
|
||||
|
||||
$featured_posts = collect([]);
|
||||
|
||||
$latest_posts = collect([]);
|
||||
|
||||
if ($latest_posts->count() <= 0) {
|
||||
SEOMeta::setRobots('noindex');
|
||||
}
|
||||
|
||||
SEOTools::metatags();
|
||||
SEOTools::twitter();
|
||||
SEOTools::opengraph();
|
||||
SEOTools::jsonLd();
|
||||
|
||||
$country_name = get_country_name_by_iso($country_locale->country_iso);
|
||||
|
||||
SEOTools::setTitle("Your {$country_name} Guide to Product Reviews & Top Deals");
|
||||
SEOTools::setDescription("Discover trusted product reviews and unbeatable deals at ProductAlert {$country_name}, your local guide to smart shopping.");
|
||||
|
||||
return view('front.country', compact('country_locale', 'featured_posts', 'latest_posts')
|
||||
);
|
||||
}
|
||||
|
||||
return redirect()->route('home.country', ['country' => config('platform.general.fallback_country_slug')]);
|
||||
}
|
||||
|
||||
public function countryCategory(Request $request, $country, $category)
|
||||
{
|
||||
$country_locale = CountryLocale::where('slug', $country)->first();
|
||||
|
||||
if (is_null($country_locale)) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
$category = Category::where('slug', $category)->where('enabled', true)->first();
|
||||
|
||||
if (is_null($category)) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
$request->session()->put('view_country_locale', $country_locale);
|
||||
|
||||
$latest_posts = Post::with('post_categories')->select('posts.*')
|
||||
->join('post_categories', 'posts.id', '=', 'post_categories.post_id')
|
||||
->join('categories', 'post_categories.category_id', '=', 'categories.id')
|
||||
->whereNotNull('post_categories.id')
|
||||
->whereNotNull('categories.id')
|
||||
->where('categories.country_locale_slug', $country_locale->slug)
|
||||
->where('categories.id', $category->id)
|
||||
->where('posts.status', 'publish')
|
||||
->orderBy('posts.publish_date', 'desc')
|
||||
->distinct()
|
||||
->paginate(15);
|
||||
|
||||
if ($latest_posts->count() <= 0) {
|
||||
SEOMeta::setRobots('noindex');
|
||||
}
|
||||
|
||||
SEOTools::metatags();
|
||||
SEOTools::twitter();
|
||||
SEOTools::opengraph();
|
||||
SEOTools::jsonLd();
|
||||
|
||||
$this_month = now()->format('F Y');
|
||||
|
||||
$country_name = get_country_name_by_iso($country_locale->country_iso);
|
||||
|
||||
//dd($category->type);
|
||||
|
||||
if ($category->type == 'review') {
|
||||
SEOTools::setTitle("Top {$category->name} Reviews for {$this_month} in {$country_name}");
|
||||
} elseif ($category->type == 'deals') {
|
||||
SEOTools::setTitle("{$this_month} Latest Deals, Coupon Codes & Vouchers for {$country_name}");
|
||||
} elseif ($category->type == 'launch') {
|
||||
SEOTools::setTitle("New {$this_month} Product Launches in {$country_name}");
|
||||
}
|
||||
|
||||
$category_name = strtolower($category->name);
|
||||
|
||||
SEOTools::setDescription($category->description);
|
||||
|
||||
return view('front.country_category', compact('country_locale', 'category', 'latest_posts'));
|
||||
}
|
||||
|
||||
public function all(Request $request, $country)
|
||||
{
|
||||
$country_locale = CountryLocale::where('slug', $country)->first();
|
||||
|
||||
$request->session()->put('view_country_locale', $country_locale);
|
||||
|
||||
$latest_posts = Post::with('post_categories')->select('posts.*')
|
||||
->join('post_categories', 'posts.id', '=', 'post_categories.post_id')
|
||||
->join('categories', 'post_categories.category_id', '=', 'categories.id')
|
||||
->whereNotNull('post_categories.id')
|
||||
->whereNotNull('categories.id')
|
||||
->where('categories.country_locale_slug', $country_locale->slug)
|
||||
->where('posts.status', 'publish')
|
||||
->orderBy('posts.publish_date', 'desc')
|
||||
->distinct()
|
||||
->paginate(15);
|
||||
|
||||
if ($latest_posts->count() <= 0) {
|
||||
SEOMeta::setRobots('noindex');
|
||||
}
|
||||
|
||||
SEOTools::metatags();
|
||||
SEOTools::twitter();
|
||||
SEOTools::opengraph();
|
||||
SEOTools::jsonLd();
|
||||
|
||||
$country_name = get_country_name_by_iso($country_locale->country_iso);
|
||||
|
||||
SEOTools::setTitle("Find Product Reviews and Best Deals for {$country_name}");
|
||||
|
||||
SEOTools::setDescription("Discover the latest product reviews and unbeatable deals at ProductAlert, your guide to shopping in {$country_name}. Stay on top of fresh product updates.");
|
||||
|
||||
return view('front.country_all', compact('country_locale', 'latest_posts'));
|
||||
}
|
||||
|
||||
public function post(Request $request, $country, $post_slug)
|
||||
{
|
||||
$post = Post::where('slug', $post_slug)->where('status', 'publish')->first();
|
||||
|
||||
if (! is_null($post)) {
|
||||
|
||||
$request->session()->put('view_country_locale', $post->post_category->category->country_locale);
|
||||
|
||||
SEOMeta::setTitle($post->title);
|
||||
SEOMeta::setDescription($post->excerpt);
|
||||
SEOMeta::addMeta('article:published_time', $post->publish_date, 'property');
|
||||
SEOMeta::addMeta('article:section', $post->post_category->category->name, 'property');
|
||||
|
||||
OpenGraph::setDescription($post->excerpt);
|
||||
OpenGraph::setTitle($post->title);
|
||||
OpenGraph::setUrl(url()->current());
|
||||
OpenGraph::addProperty('type', 'article');
|
||||
OpenGraph::addProperty('locale', $post->post_category->category->country_locale->i18n);
|
||||
OpenGraph::addImage($post->featured_image);
|
||||
|
||||
$jsonld_multi = JsonLdMulti::newJsonLd();
|
||||
$jsonld_multi->setTitle($post->title)
|
||||
->setDescription($post->excerpt)
|
||||
->setType('Article')
|
||||
->addImage($post->featured_image)
|
||||
->addValue('author', $post->author->name)
|
||||
->addValue('datePublished', $post->publish_date->format('Y-m-d'))
|
||||
->addValue('dateCreated', $post->publish_date->format('Y-m-d'))
|
||||
->addValue('dateModified', $post->updated_at->format('Y-m-d'))
|
||||
->addValue('description', $post->excerpt)
|
||||
->addValue('articleBody', trim(preg_replace('/\s\s+/', ' ', strip_tags($post->html_body))));
|
||||
|
||||
return view('front.post', compact('post'));
|
||||
}
|
||||
abort(404);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -2,19 +2,19 @@
|
||||
|
||||
namespace App\Jobs\Tasks;
|
||||
|
||||
use fivefilters\Readability\Configuration as ReadabilityConfiguration;
|
||||
use fivefilters\Readability\ParseException as ReadabilityParseException;
|
||||
use fivefilters\Readability\Readability;
|
||||
use App\Helpers\FirstParty\OpenAI\OpenAI;
|
||||
use App\Helpers\FirstParty\OSSUploader\OSSUploader;
|
||||
use App\Models\AiWriteup;
|
||||
use App\Models\Category;
|
||||
use App\Models\Post;
|
||||
use App\Models\PostCategory;
|
||||
use App\Models\Category;
|
||||
use App\Models\ShopeeSellerCategory;
|
||||
use App\Models\ShopeeSellerScrape;
|
||||
use App\Models\ShopeeSellerScrapedImage;
|
||||
use Exception;
|
||||
use fivefilters\Readability\Configuration as ReadabilityConfiguration;
|
||||
use fivefilters\Readability\ParseException as ReadabilityParseException;
|
||||
use fivefilters\Readability\Readability;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use LaravelFreelancerNL\LaravelIndexNow\Facades\IndexNow;
|
||||
use LaravelGoogleIndexing;
|
||||
@@ -36,8 +36,6 @@ public static function handle(ShopeeSellerScrape $shopee_seller_scrape)
|
||||
$shopee_task->shopee_seller_scrape = $shopee_seller_scrape;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// dd($shopee_task);
|
||||
|
||||
// dd($shopee_task->product_task->response);
|
||||
@@ -57,11 +55,11 @@ public static function handle(ShopeeSellerScrape $shopee_seller_scrape)
|
||||
if (is_null($ai_writeup)) {
|
||||
|
||||
$categories = [
|
||||
'Beauty',
|
||||
'Technology',
|
||||
'Home & Living',
|
||||
'Health',
|
||||
'Fitness'
|
||||
'Beauty',
|
||||
'Technology',
|
||||
'Home & Living',
|
||||
'Health',
|
||||
'Fitness',
|
||||
];
|
||||
|
||||
$ai_output = OpenAI::writeProductArticle($excerpt, $photos, $categories);
|
||||
@@ -76,11 +74,10 @@ public static function handle(ShopeeSellerScrape $shopee_seller_scrape)
|
||||
throw ($e);
|
||||
} else {
|
||||
|
||||
$picked_category = Category::where('name', $ai_output->category)->where('country_locale_id', $shopee_seller_scrape->category->country_locale_id)->first();
|
||||
$picked_category = Category::where('name', $ai_output->category)->where('country_locale_id', $shopee_seller_scrape->category->country_locale_id)->first();
|
||||
|
||||
if (is_null($picked_category))
|
||||
{
|
||||
$picked_category = $shopee_seller_scrape->category;
|
||||
if (is_null($picked_category)) {
|
||||
$picked_category = $shopee_seller_scrape->category;
|
||||
}
|
||||
|
||||
// save
|
||||
@@ -122,13 +119,12 @@ public static function handle(ShopeeSellerScrape $shopee_seller_scrape)
|
||||
$shopee_seller_scrape->last_ai_written_at = now();
|
||||
$shopee_seller_scrape->save();
|
||||
|
||||
$shopee_seller_category = ShopeeSellerCategory::where('seller', $shopee_seller_scrape->seller)->first();
|
||||
$shopee_seller_category = ShopeeSellerCategory::where('seller', $shopee_seller_scrape->seller)->first();
|
||||
|
||||
if (is_null($shopee_seller_category))
|
||||
{
|
||||
$shopee_seller_category = new ShopeeSellerCategory;
|
||||
$shopee_seller_category->seller = $shopee_seller_scrape->seller;
|
||||
$shopee_seller_category->category_id = $shopee_seller_scrape->category_id;
|
||||
if (is_null($shopee_seller_category)) {
|
||||
$shopee_seller_category = new ShopeeSellerCategory;
|
||||
$shopee_seller_category->seller = $shopee_seller_scrape->seller;
|
||||
$shopee_seller_category->category_id = $shopee_seller_scrape->category_id;
|
||||
}
|
||||
|
||||
$shopee_seller_category->last_ai_written_at = $shopee_seller_scrape->last_ai_written_at;
|
||||
@@ -169,34 +165,33 @@ private static function getProductPricingExcerpt(array $jsonLdData)
|
||||
foreach ($jsonLdData as $data) {
|
||||
// Ensure the type is "Product" before proceeding
|
||||
if (isset($data->{'@type'}) && $data->{'@type'} === 'Product') {
|
||||
|
||||
// Extract necessary data
|
||||
$lowPrice = $data->offers->lowPrice ?? null;
|
||||
$highPrice = $data->offers->highPrice ?? null;
|
||||
$price = $data->offers->price ?? null;
|
||||
$currency = $data->offers->priceCurrency ?? null;
|
||||
$sellerName = $data->offers->seller->name ?? "online store"; // default to "online store" if name is not set
|
||||
|
||||
if (!is_empty($currency))
|
||||
{
|
||||
if ($currency == 'MYR')
|
||||
{
|
||||
$currency = 'RM';
|
||||
// Extract necessary data
|
||||
$lowPrice = $data->offers->lowPrice ?? null;
|
||||
$highPrice = $data->offers->highPrice ?? null;
|
||||
$price = $data->offers->price ?? null;
|
||||
$currency = $data->offers->priceCurrency ?? null;
|
||||
$sellerName = $data->offers->seller->name ?? 'online store'; // default to "online store" if name is not set
|
||||
|
||||
if (! is_empty($currency)) {
|
||||
if ($currency == 'MYR') {
|
||||
$currency = 'RM';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Determine and format pricing sentence
|
||||
if ($lowPrice && $highPrice) {
|
||||
$lowPrice = number_format($lowPrice, 0);
|
||||
$highPrice = number_format($highPrice, 0);
|
||||
|
||||
// Determine and format pricing sentence
|
||||
if ($lowPrice && $highPrice) {
|
||||
$lowPrice = number_format($lowPrice, 0);
|
||||
$highPrice = number_format($highPrice, 0);
|
||||
return "Price Range from {$currency} {$lowPrice} to {$highPrice} in {$sellerName} online store";
|
||||
} elseif ($price) {
|
||||
$price = number_format($price, 0);
|
||||
return "Priced at {$currency} {$price} in {$sellerName} online store";
|
||||
} else {
|
||||
return "Price not stated, refer to {$sellerName} online store";
|
||||
}
|
||||
return "Price Range from {$currency} {$lowPrice} to {$highPrice} in {$sellerName} online store";
|
||||
} elseif ($price) {
|
||||
$price = number_format($price, 0);
|
||||
|
||||
return "Priced at {$currency} {$price} in {$sellerName} online store";
|
||||
} else {
|
||||
return "Price not stated, refer to {$sellerName} online store";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,16 +7,12 @@
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
use Intervention\Image\Facades\Image;
|
||||
use Symfony\Component\DomCrawler\Crawler;
|
||||
use Masterminds\HTML5;
|
||||
|
||||
|
||||
class SaveShopeeSellerImagesTask
|
||||
{
|
||||
public static function handle($shopee_task)
|
||||
{
|
||||
|
||||
|
||||
$unblocker_proxy_server = get_smartproxy_unblocker_server();
|
||||
$rotating_proxy_server = get_smartproxy_rotating_server();
|
||||
$costs = [];
|
||||
@@ -174,9 +170,8 @@ private static function getFilteredImages(string $raw_html, string $proxy, strin
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($height > $width)
|
||||
{
|
||||
continue;
|
||||
if ($height > $width) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$interventionImage->resize(800, null, function ($constraint) {
|
||||
@@ -257,9 +252,8 @@ private static function getFilteredImages(string $raw_html, string $proxy, strin
|
||||
|
||||
$final_images = [];
|
||||
|
||||
foreach ($filteredImages as $image_obj)
|
||||
{
|
||||
$final_images[] = (object) $image_obj;
|
||||
foreach ($filteredImages as $image_obj) {
|
||||
$final_images[] = (object) $image_obj;
|
||||
}
|
||||
|
||||
return $final_images;
|
||||
|
||||
@@ -5,12 +5,9 @@
|
||||
use App\Helpers\FirstParty\OSSUploader\OSSUploader;
|
||||
use Exception;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Intervention\Image\Facades\Image;
|
||||
use Minifier\TinyMinify;
|
||||
use Spatie\Browsershot\Browsershot;
|
||||
use Spatie\Browsershot\Exceptions\UnsuccessfulResponse;
|
||||
use Symfony\Component\DomCrawler\Crawler;
|
||||
use thiagoalessio\TesseractOCR\TesseractOCR;
|
||||
|
||||
class UrlCrawlerTask
|
||||
{
|
||||
@@ -60,8 +57,7 @@ public static function handle(string $url, $directory, $postfix = null, $strip_h
|
||||
])
|
||||
->get($cached_url);
|
||||
|
||||
if ($response->successful())
|
||||
{
|
||||
if ($response->successful()) {
|
||||
$raw_html = $response->body();
|
||||
$costs['unblocker'] = calculate_smartproxy_cost(round(strlen($raw_html) / 1024, 2), 'unblocker');
|
||||
} else {
|
||||
@@ -195,7 +191,8 @@ private static function minifyAndCleanHtml(string $raw_html)
|
||||
return $crawler->html();
|
||||
}
|
||||
|
||||
private static function minifyHTML($input) {
|
||||
private static function minifyHTML($input)
|
||||
{
|
||||
// Remove extra white space between HTML tags
|
||||
$input = preg_replace('/>\s+</', '><', $input);
|
||||
|
||||
|
||||
@@ -11,25 +11,23 @@
|
||||
|
||||
/**
|
||||
* Class DailyTaskSchedule
|
||||
*
|
||||
*
|
||||
* @property int $id
|
||||
* @property string $task
|
||||
* @property Carbon $next_run_time
|
||||
* @property Carbon|null $created_at
|
||||
* @property Carbon|null $updated_at
|
||||
*
|
||||
* @package App\Models
|
||||
*/
|
||||
class DailyTaskSchedule extends Model
|
||||
{
|
||||
protected $table = 'daily_task_schedules';
|
||||
protected $table = 'daily_task_schedules';
|
||||
|
||||
protected $casts = [
|
||||
'next_run_time' => 'datetime'
|
||||
];
|
||||
protected $casts = [
|
||||
'next_run_time' => 'datetime',
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'task',
|
||||
'next_run_time'
|
||||
];
|
||||
protected $fillable = [
|
||||
'task',
|
||||
'next_run_time',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -36,4 +36,3 @@ class FailedJob extends Model
|
||||
'failed_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -152,36 +152,35 @@ public function getHtmlBodyAttribute()
|
||||
}
|
||||
});
|
||||
|
||||
// Modify the DOM by wrapping the <img> tags inside a <figure> and adding the desired structure
|
||||
$crawler->filter('img')->each(function (Crawler $node) {
|
||||
$imgElement = $node->getNode(0);
|
||||
|
||||
// Update the class of the <img>
|
||||
$existingClasses = $imgElement->getAttribute('class');
|
||||
$newClasses = 'img-fluid rounded-2 shadow-sm mb-2';
|
||||
$updatedClasses = ($existingClasses ? $existingClasses.' ' : '').$newClasses;
|
||||
$imgElement->setAttribute('class', $updatedClasses);
|
||||
|
||||
// Create a new <figure> element
|
||||
$figureElement = new \DOMElement('figure');
|
||||
$imgElement->parentNode->insertBefore($figureElement, $imgElement);
|
||||
|
||||
// Move the <img> inside the <figure>
|
||||
$figureElement->appendChild($imgElement);
|
||||
$figureElement->setAttribute('class', 'image');
|
||||
|
||||
// Create a new <footer> element inside <figure> without directly setting its content
|
||||
$footerElement = $imgElement->ownerDocument->createElement('footer');
|
||||
$figureElement->appendChild($footerElement);
|
||||
|
||||
// Add the content to <footer> using createTextNode to ensure special characters are handled
|
||||
$footerText = $imgElement->ownerDocument->createTextNode($imgElement->getAttribute('alt'));
|
||||
$footerElement->appendChild($footerText);
|
||||
|
||||
// Set the class attribute for <footer>
|
||||
$footerElement->setAttribute('class', 'image-caption');
|
||||
});
|
||||
// Modify the DOM by wrapping the <img> tags inside a <figure> and adding the desired structure
|
||||
$crawler->filter('img')->each(function (Crawler $node) {
|
||||
$imgElement = $node->getNode(0);
|
||||
|
||||
// Update the class of the <img>
|
||||
$existingClasses = $imgElement->getAttribute('class');
|
||||
$newClasses = 'img-fluid rounded-2 shadow-sm mb-2';
|
||||
$updatedClasses = ($existingClasses ? $existingClasses.' ' : '').$newClasses;
|
||||
$imgElement->setAttribute('class', $updatedClasses);
|
||||
|
||||
// Create a new <figure> element
|
||||
$figureElement = new \DOMElement('figure');
|
||||
$imgElement->parentNode->insertBefore($figureElement, $imgElement);
|
||||
|
||||
// Move the <img> inside the <figure>
|
||||
$figureElement->appendChild($imgElement);
|
||||
$figureElement->setAttribute('class', 'image');
|
||||
|
||||
// Create a new <footer> element inside <figure> without directly setting its content
|
||||
$footerElement = $imgElement->ownerDocument->createElement('footer');
|
||||
$figureElement->appendChild($footerElement);
|
||||
|
||||
// Add the content to <footer> using createTextNode to ensure special characters are handled
|
||||
$footerText = $imgElement->ownerDocument->createTextNode($imgElement->getAttribute('alt'));
|
||||
$footerElement->appendChild($footerText);
|
||||
|
||||
// Set the class attribute for <footer>
|
||||
$footerElement->setAttribute('class', 'image-caption');
|
||||
});
|
||||
|
||||
// Add Bootstrap 5 styling to tables
|
||||
$crawler->filter('table')->each(function (Crawler $node) {
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
/**
|
||||
* Class ShopeeSellerCategory
|
||||
*
|
||||
*
|
||||
* @property int $id
|
||||
* @property string $seller
|
||||
* @property int $category_id
|
||||
@@ -19,30 +19,27 @@
|
||||
* @property int $write_counts
|
||||
* @property Carbon|null $created_at
|
||||
* @property Carbon|null $updated_at
|
||||
*
|
||||
* @property Category $category
|
||||
*
|
||||
* @package App\Models
|
||||
*/
|
||||
class ShopeeSellerCategory extends Model
|
||||
{
|
||||
protected $table = 'shopee_seller_categories';
|
||||
protected $table = 'shopee_seller_categories';
|
||||
|
||||
protected $casts = [
|
||||
'category_id' => 'int',
|
||||
'last_ai_written_at' => 'datetime',
|
||||
'write_counts' => 'int'
|
||||
];
|
||||
protected $casts = [
|
||||
'category_id' => 'int',
|
||||
'last_ai_written_at' => 'datetime',
|
||||
'write_counts' => 'int',
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'seller',
|
||||
'category_id',
|
||||
'last_ai_written_at',
|
||||
'write_counts'
|
||||
];
|
||||
protected $fillable = [
|
||||
'seller',
|
||||
'category_id',
|
||||
'last_ai_written_at',
|
||||
'write_counts',
|
||||
];
|
||||
|
||||
public function category()
|
||||
{
|
||||
return $this->belongsTo(Category::class);
|
||||
}
|
||||
public function category()
|
||||
{
|
||||
return $this->belongsTo(Category::class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ class ShopeeSellerScrape extends Model
|
||||
'epoch',
|
||||
'filename',
|
||||
'last_ai_written_at',
|
||||
'write_counts'
|
||||
'write_counts',
|
||||
];
|
||||
|
||||
public function category()
|
||||
|
||||
@@ -27,11 +27,11 @@ public function register()
|
||||
public function boot()
|
||||
{
|
||||
// Using class based composers...
|
||||
View::composer('layouts.front.navigation', CategoryComposer::class);
|
||||
View::composer('layouts.front.navigation', CountryLocaleComposer::class);
|
||||
// View::composer('layouts.front.navigation', CategoryComposer::class);
|
||||
// View::composer('layouts.front.navigation', CountryLocaleComposer::class);
|
||||
|
||||
View::composer('layouts.front.footer', CategoryComposer::class);
|
||||
View::composer('layouts.front.footer', CountryLocaleComposer::class);
|
||||
// View::composer('layouts.front.footer', CategoryComposer::class);
|
||||
// View::composer('layouts.front.footer', CountryLocaleComposer::class);
|
||||
|
||||
if (auth()->check()) {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user