diff --git a/app/Http/Controllers/Front/FrontHomeController.php b/app/Http/Controllers/Front/FrontHomeController.php index 7af55ea..733f885 100644 --- a/app/Http/Controllers/Front/FrontHomeController.php +++ b/app/Http/Controllers/Front/FrontHomeController.php @@ -25,7 +25,7 @@ public function home(Request $request) // $query->whereNotIn('id', $featured_posts->pluck('id')->toArray()); // })->where('status', 'publish')->where('published_at', '<=', now())->orderBy('published_at', 'desc')->limit(10)->get(); - $rss_posts = RssPost::where('status', 'published')->orderBy('published_at', 'desc')->paginate(15); + $rss_posts = RssPost::with('entities_keywords')->where('status', 'published')->orderBy('published_at', 'desc')->paginate(15); return response(view('front.welcome', compact('rss_posts')), 200); } diff --git a/app/Http/Controllers/Front/FrontListController.php b/app/Http/Controllers/Front/FrontListController.php index 8434b77..d78a916 100644 --- a/app/Http/Controllers/Front/FrontListController.php +++ b/app/Http/Controllers/Front/FrontListController.php @@ -40,7 +40,7 @@ public function searchResults(Request $request, $query) SEOTools::jsonLd(); SEOTools::setTitle($title, false); - $rss_posts = RssPost::with('category') + $rss_posts = RssPost::with('category', 'entities_keywords') ->where('status', 'published') ->whereRaw("to_tsvector('english', title || ' ' || bites || ' ' || keyword_list) @@ plainto_tsquery('english', ?)", [trim(preg_replace('/\s+/', ' ', $query))]) ->where('published_at', '<=', now()) @@ -81,7 +81,7 @@ public function index(Request $request) SEOTools::jsonLd(); SEOTools::setTitle($title, false); - $rss_posts = RssPost::with('category')->where('status', 'published') + $rss_posts = RssPost::with('category', 'entities_keywords')->where('status', 'published') ->where('published_at', '<=', now()) ->orderBy('published_at', 'desc') ->cursorPaginate(60) ?? collect(); @@ -128,7 +128,7 @@ public function category(Request $request, $category_slug) SEOTools::jsonLd(); SEOTools::setTitle($title, false); - $rss_posts = RssPost::with('category')->where('status', 'published') + $rss_posts = RssPost::with('category', 'entities_keywords')->where('status', 'published') ->where('category_id', $category->id) ->where('published_at', '<=', now()) ->orderBy('published_at', 'desc') diff --git a/app/Http/Controllers/Tests/TestController.php b/app/Http/Controllers/Tests/TestController.php index 2cb9c3f..e1971bd 100644 --- a/app/Http/Controllers/Tests/TestController.php +++ b/app/Http/Controllers/Tests/TestController.php @@ -25,13 +25,11 @@ public function prm(Request $request) } ParseRssPostMetadataTask::handle($id); - + return 'ok'; } - - public function crawlTask(Request $request) { $id = $request->input('id'); @@ -41,12 +39,11 @@ public function crawlTask(Request $request) } CrawlRssPostTask::handle($id); - + return 'ok'; } - public function opml(Request $request) { $raw_posts = BrowseRSSLatestNewsTask::handleSingle('https://hnrss.org/newest?q=ai', 240); diff --git a/app/Jobs/SaveOldKeywordsJob.php b/app/Jobs/SaveOldKeywordsJob.php index 89bdea5..83be52b 100644 --- a/app/Jobs/SaveOldKeywordsJob.php +++ b/app/Jobs/SaveOldKeywordsJob.php @@ -2,7 +2,6 @@ namespace App\Jobs; -use App\Jobs\Tasks\CrawlRssPostTask; use App\Models\RssPost; use App\Models\RssPostKeyword; use Illuminate\Bus\Queueable; @@ -32,114 +31,105 @@ public function __construct($rss_post_id) */ public function handle(): void { - $rss_post = RssPost::find($this->rss_post_id); + $rss_post = RssPost::find($this->rss_post_id); - if (is_null($rss_post)) - { - return ; - } + if (is_null($rss_post)) { + return; + } - if ($rss_post->keyword_saved == true) - { - return ; - } + if ($rss_post->keyword_saved == true) { + return; + } - $words_to_add_in_keyword_list = []; - $words_to_save = []; + $words_to_add_in_keyword_list = []; + $words_to_save = []; - $first_keyword_found = false; + $first_keyword_found = false; - // Entities - if (isset($rss_post->entities)) { - if (count($rss_post->entities) > 0) { + // Entities + if (isset($rss_post->entities)) { + if (count($rss_post->entities) > 0) { - foreach ($rss_post->entities as $key => $word) { + foreach ($rss_post->entities as $key => $word) { - $word = trim($word); + $word = trim($word); - $words_to_save[] = (object) [ - 'is_main' => ($key == 0) ? true : false, - 'type' => 'entity', - 'value' => $word, - 'value_lowercased' => strtolower($word), - ]; + $words_to_save[] = (object) [ + 'is_main' => ($key == 0) ? true : false, + 'type' => 'entity', + 'value' => $word, + 'value_lowercased' => strtolower($word), + ]; - $words_to_add_in_keyword_list[] = $word; - } - } - } - - // Keywords - if (isset($rss_post->keywords)) { - if (count($rss_post->keywords) > 0) { - - foreach ($rss_post->keywords as $word) { - - $word = trim($word); - - foreach($words_to_save as $saved_word) - { - if (strtolower($word) == $saved_word->value_lowercased) - { - continue 2; - } - } - - $words_to_save[] = (object) [ - 'is_main' => !$first_keyword_found, - 'type' => 'keyword', - 'value' => $word, - 'value_lowercased' => strtolower($word), - ]; - - $words_to_add_in_keyword_list[] = $word; - - if ($first_keyword_found == false) { - $first_keyword_found = true; - } - - } - } - } - - $rss_post->keyword_list = implode(',', $words_to_add_in_keyword_list); - - $rss_post->status = 'published'; - - if($rss_post->save()) - { - $has_saved_keyword = false; - - $deleted_rpk = RssPostKeyword::where('rss_post_id', $rss_post->id)->delete(); - - foreach ($words_to_save as $word_to_save) - { - - $new_rpk = new RssPostKeyword; - $new_rpk->rss_post_id = $rss_post->id; - $new_rpk->type = $word_to_save->type; - $new_rpk->is_main = $word_to_save->is_main; - $new_rpk->value = $word_to_save->value; - $new_rpk->value_lowercased = $word_to_save->value_lowercased; - $new_rpk->created_at = $rss_post->published_at; - $new_rpk->updated_at = $rss_post->published_at; - - if($new_rpk->save()) - { - if (!$has_saved_keyword) - { - $has_saved_keyword = true; + $words_to_add_in_keyword_list[] = $word; + } } - - } } - if ($has_saved_keyword) - { - $rss_post->keyword_saved = true; - $rss_post->save(); + // Keywords + if (isset($rss_post->keywords)) { + if (count($rss_post->keywords) > 0) { + + foreach ($rss_post->keywords as $word) { + + $word = trim($word); + + foreach ($words_to_save as $saved_word) { + if (strtolower($word) == $saved_word->value_lowercased) { + continue 2; + } + } + + $words_to_save[] = (object) [ + 'is_main' => ! $first_keyword_found, + 'type' => 'keyword', + 'value' => $word, + 'value_lowercased' => strtolower($word), + ]; + + $words_to_add_in_keyword_list[] = $word; + + if ($first_keyword_found == false) { + $first_keyword_found = true; + } + + } + } + } + + $rss_post->keyword_list = implode(',', $words_to_add_in_keyword_list); + + $rss_post->status = 'published'; + + if ($rss_post->save()) { + $has_saved_keyword = false; + + $deleted_rpk = RssPostKeyword::where('rss_post_id', $rss_post->id)->delete(); + + foreach ($words_to_save as $word_to_save) { + + $new_rpk = new RssPostKeyword; + $new_rpk->rss_post_id = $rss_post->id; + $new_rpk->type = $word_to_save->type; + $new_rpk->is_main = $word_to_save->is_main; + $new_rpk->value = $word_to_save->value; + $new_rpk->value_lowercased = $word_to_save->value_lowercased; + $new_rpk->created_at = $rss_post->published_at; + $new_rpk->updated_at = $rss_post->published_at; + + if ($new_rpk->save()) { + if (! $has_saved_keyword) { + $has_saved_keyword = true; + } + + } + } + + if ($has_saved_keyword) { + $rss_post->keyword_saved = true; + $rss_post->save(); + } } - } } } diff --git a/app/Jobs/Tasks/ParseRssPostMetadataTask.php b/app/Jobs/Tasks/ParseRssPostMetadataTask.php index fd4f7ab..3521760 100644 --- a/app/Jobs/Tasks/ParseRssPostMetadataTask.php +++ b/app/Jobs/Tasks/ParseRssPostMetadataTask.php @@ -63,10 +63,10 @@ public static function handle(int $rss_post_id) $word = trim($word); $words_to_save[] = (object) [ - 'is_main' => ($key == 0) ? true : false, - 'type' => 'entity', - 'value' => $word, - 'value_lowercased' => strtolower($word), + 'is_main' => ($key == 0) ? true : false, + 'type' => 'entity', + 'value' => $word, + 'value_lowercased' => strtolower($word), ]; $words_to_add_in_keyword_list[] = $word; @@ -82,26 +82,23 @@ public static function handle(int $rss_post_id) $word = trim($word); - foreach($words_to_save as $saved_word) - { - if (strtolower($word) == $saved_word->value_lowercased) - { - continue 2; - } + foreach ($words_to_save as $saved_word) { + if (strtolower($word) == $saved_word->value_lowercased) { + continue 2; + } } - $words_to_save[] = (object) [ - 'is_main' => !$first_keyword_found, - 'type' => 'keyword', - 'value' => $word, - 'value_lowercased' => strtolower($word), + 'is_main' => ! $first_keyword_found, + 'type' => 'keyword', + 'value' => $word, + 'value_lowercased' => strtolower($word), ]; $words_to_add_in_keyword_list[] = $word; if ($first_keyword_found == false) { - $first_keyword_found = true; + $first_keyword_found = true; } } @@ -145,38 +142,33 @@ public static function handle(int $rss_post_id) $rss_post->keyword_list = implode(',', $words_to_add_in_keyword_list); $rss_post->status = 'published'; - - if($rss_post->save()) - { - $has_saved_keyword = false; - $deleted_rpk = RssPostKeyword::where('rss_post_id', $rss_post->id)->delete(); + if ($rss_post->save()) { + $has_saved_keyword = false; - foreach ($words_to_save as $word_to_save) - { + $deleted_rpk = RssPostKeyword::where('rss_post_id', $rss_post->id)->delete(); - $new_rpk = new RssPostKeyword; - $new_rpk->rss_post_id = $rss_post->id; - $new_rpk->type = $word_to_save->type; - $new_rpk->is_main = $word_to_save->is_main; - $new_rpk->value = $word_to_save->value; - $new_rpk->value_lowercased = $word_to_save->value_lowercased; + foreach ($words_to_save as $word_to_save) { - if($new_rpk->save()) - { - if (!$has_saved_keyword) - { - $has_saved_keyword = true; - } - + $new_rpk = new RssPostKeyword; + $new_rpk->rss_post_id = $rss_post->id; + $new_rpk->type = $word_to_save->type; + $new_rpk->is_main = $word_to_save->is_main; + $new_rpk->value = $word_to_save->value; + $new_rpk->value_lowercased = $word_to_save->value_lowercased; + + if ($new_rpk->save()) { + if (! $has_saved_keyword) { + $has_saved_keyword = true; + } + + } } - } - if ($has_saved_keyword) - { - $rss_post->keyword_saved = true; - $rss_post->save(); - } + if ($has_saved_keyword) { + $rss_post->keyword_saved = true; + $rss_post->save(); + } } } diff --git a/app/Models/RssPost.php b/app/Models/RssPost.php index 51b48af..e828769 100644 --- a/app/Models/RssPost.php +++ b/app/Models/RssPost.php @@ -69,6 +69,11 @@ class RssPost extends Model implements Feedable 'keyword_saved', ]; + public function entities_keywords() + { + return $this->hasMany(RssPostKeyword::class); + } + public function category() { return $this->belongsTo(Category::class); diff --git a/app/Models/RssPostKeyword.php b/app/Models/RssPostKeyword.php index ea14210..75787f6 100644 --- a/app/Models/RssPostKeyword.php +++ b/app/Models/RssPostKeyword.php @@ -11,7 +11,7 @@ /** * Class RssPostKeyword - * + * * @property int $id * @property int $rss_post_id * @property string $type @@ -20,30 +20,27 @@ * @property string $value_lowercased * @property Carbon|null $created_at * @property Carbon|null $updated_at - * * @property RssPost $rss_post - * - * @package App\Models */ class RssPostKeyword extends Model { - protected $table = 'rss_post_keywords'; + protected $table = 'rss_post_keywords'; - protected $casts = [ - 'rss_post_id' => 'int', - 'is_main' => 'bool' - ]; + protected $casts = [ + 'rss_post_id' => 'int', + 'is_main' => 'bool', + ]; - protected $fillable = [ - 'rss_post_id', - 'type', - 'is_main', - 'value', - 'value_lowercased' - ]; + protected $fillable = [ + 'rss_post_id', + 'type', + 'is_main', + 'value', + 'value_lowercased', + ]; - public function rss_post() - { - return $this->belongsTo(RssPost::class); - } + public function rss_post() + { + return $this->belongsTo(RssPost::class); + } } diff --git a/database/migrations/2023_11_22_151403_create_rss_post_keywords_table.php b/database/migrations/2023_11_22_151403_create_rss_post_keywords_table.php index 63eacf1..0ae9770 100644 --- a/database/migrations/2023_11_22_151403_create_rss_post_keywords_table.php +++ b/database/migrations/2023_11_22_151403_create_rss_post_keywords_table.php @@ -14,7 +14,7 @@ public function up(): void Schema::create('rss_post_keywords', function (Blueprint $table) { $table->id(); $table->foreignId('rss_post_id'); - $table->enum('type',['keyword','entity']); + $table->enum('type', ['keyword', 'entity']); $table->boolean('is_main')->default(false); $table->string('value'); $table->string('value_lowercased'); diff --git a/database/migrations/2023_11_22_154104_add_keyword_saved_to_rss_posts_table.php b/database/migrations/2023_11_22_154104_add_keyword_saved_to_rss_posts_table.php index 3820aaa..a4d7b7f 100644 --- a/database/migrations/2023_11_22_154104_add_keyword_saved_to_rss_posts_table.php +++ b/database/migrations/2023_11_22_154104_add_keyword_saved_to_rss_posts_table.php @@ -12,7 +12,7 @@ public function up(): void { Schema::table('rss_posts', function (Blueprint $table) { - $table->boolean('keyword_saved')->default(false); + $table->boolean('keyword_saved')->default(false); }); } diff --git a/database/migrations/2023_11_22_181428_add_created_at_index_to_rss_post_keywords_table.php b/database/migrations/2023_11_22_181428_add_created_at_index_to_rss_post_keywords_table.php new file mode 100644 index 0000000..e48142e --- /dev/null +++ b/database/migrations/2023_11_22_181428_add_created_at_index_to_rss_post_keywords_table.php @@ -0,0 +1,28 @@ +index('created_at'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('rss_post_keywords', function (Blueprint $table) { + $table->dropIndex(['created_at']); + }); + } +}; diff --git a/resources/css/app-front.css b/resources/css/app-front.css index f84c0e8..88bad4f 100644 --- a/resources/css/app-front.css +++ b/resources/css/app-front.css @@ -101,3 +101,7 @@ @keyframes shimmer { background-position: -400% 0; } } + +.word-wrap-break-word { + word-wrap: break-word; +} diff --git a/resources/views/front/partials/news_bites.blade.php b/resources/views/front/partials/news_bites.blade.php index c17511d..32d7b4e 100644 --- a/resources/views/front/partials/news_bites.blade.php +++ b/resources/views/front/partials/news_bites.blade.php @@ -12,16 +12,18 @@
@if ($post->entities) - @foreach ($post->entities as $key => $keyword) - @if ($key == 0) -

- {{ $keyword }} -

- @else -

- {{ $keyword }} -

+ @foreach ($post->entities_keywords as $keyword) + @if($keyword->type == 'entity') + @if ($keyword->is_main) +

+ {{ $keyword->value }} +

+ @else +

+ {{ $keyword->value }} +

+ @endif @endif @endforeach @endif @@ -40,12 +42,12 @@ class="font-family-roboto-condensed mb-1 pb-1 d-inline badge bg-danger border-da @endif - @if($post->published_at->isBetween(now()->subDays(1), now())) - {{ $post->published_at->diffForHumans() }} - @else - {{ $post->published_at->format('d M') }} - @endif - + @if ($post->published_at->isBetween(now()->subDays(1), now())) + {{ $post->published_at->diffForHumans() }} + @else + {{ $post->published_at->format('d M') }} + @endif + {{ min_read($post->bites) }} @@ -68,10 +70,10 @@ class="font-family-roboto-condensed mb-1 pb-1 d-inline badge bg-danger border-da
@endif @if ($post->entities) -
- More about: @foreach ($post->all_keywords as $keyword) - {{ $keyword }} +
+ More about: @foreach ($post->entities_keywords as $keyword) + #{{ $keyword->value_lowercased }} @endforeach
@endif diff --git a/resources/views/front/partials/search.blade.php b/resources/views/front/partials/search.blade.php index 11e365a..a2c869b 100644 --- a/resources/views/front/partials/search.blade.php +++ b/resources/views/front/partials/search.blade.php @@ -1,8 +1,7 @@