Skip to content

Commit

Permalink
Merge pull request #5 from Cornatul/wip
Browse files Browse the repository at this point in the history
Wip
  • Loading branch information
jumbophp committed Oct 19, 2023
2 parents 253f056 + 8679b19 commit 0be1cf1
Show file tree
Hide file tree
Showing 33 changed files with 1,805 additions and 790 deletions.
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"php": "^8.1",
"guzzlehttp/guzzle": ">=7.5.0",
"illuminate/support": ">=9.0.0",
"laminas/laminas-feed": "2.23.x-dev",
"league/html-to-markdown": "^5.2@dev",
"sammyjo20/saloon-cache-plugin": "^2.0",
"sammyjo20/saloon-laravel": "^2.0",
Expand Down
2,072 changes: 1,393 additions & 679 deletions composer.lock

Large diffs are not rendered by default.

Empty file added config/config.php
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public function up()
$table->longText('text');
$table->longText('html');
$table->longText('markdown');
$table->longText('spacy');
$table->string('banner');
$table->longText('summary');
$table->json('authors')->nullable();
Expand Down
2 changes: 1 addition & 1 deletion resources/views/article.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
</div>
<div class="form-group">
<label for="content">Content</label>
<textarea id="editor" class="form-control" name="markdown" style="height: 100vh" rows="3">{{ $article->text }}</textarea>
<textarea id="editor" class="form-control" name="markdown" style="height: 100vh" rows="3">{{ $article->spacy }}</textarea>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Submit</button>
Expand Down
56 changes: 56 additions & 0 deletions src/Clients/FeedLaminasClient.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php
declare(strict_types=1);
namespace Cornatul\Feeds\Clients;

use Cornatul\Feeds\Connectors\FeedlyConnector;
use Cornatul\Feeds\Connectors\NlpConnector;
use Cornatul\Feeds\Contracts\ArticleManager;
use Cornatul\Feeds\Contracts\FeedManager;
use Cornatul\Feeds\Contracts\FeedFinderInterface;
use Cornatul\Feeds\DTO\ArticleDto;
use Cornatul\Feeds\Requests\FeedlyTopicRequest;
use Cornatul\Feeds\Requests\GetArticleRequest;
use GuzzleHttp\Client;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\GuzzleException;
use JsonException;
use Cornatul\Feeds\DTO\FeedDto;
use Saloon\Exceptions\InvalidResponseClassException;
use Saloon\Exceptions\PendingRequestException;
use Spatie\SchemaOrg\Contracts\ArticleContract;


class FeedLaminasClient implements \Laminas\Feed\Reader\Http\ClientInterface
{

private int $statusCode = 200;

private string $body = '';

/**
* @method get
* @throws GuzzleException
*/
public final function get($url)
{
$client = new Client();

$response = $client->get($url);

$this->body = $response->getBody()->getContents();

$this->statusCode = $response->getStatusCode();

return $this;
}

public final function getStatusCode(): int
{
return $this->statusCode;
}

public final function getBody(): string
{
return $this->body;
}
}
11 changes: 5 additions & 6 deletions src/Clients/FeedlyClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
namespace Cornatul\Feeds\Clients;

use Cornatul\Feeds\Connectors\FeedlyConnector;
use Cornatul\Feeds\Interfaces\FeedFinderInterface;
use Cornatul\Feeds\Contracts\FeedManager;
use Cornatul\Feeds\Contracts\FeedFinderInterface;
use Cornatul\Feeds\Requests\FeedlyTopicRequest;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\GuzzleException;
Expand All @@ -13,16 +14,14 @@
use Saloon\Exceptions\PendingRequestException;


class FeedlyClient implements FeedFinderInterface
class FeedlyClient implements FeedManager
{
/**
* @method find
*/
public function find(string $topic, string $language = "en"): FeedDTO
public final function find(string $topic, string $language = "en"): FeedDTO
{

$dataArray = [];

try {

$feedlyConnector = new FeedlyConnector();
Expand All @@ -36,7 +35,7 @@ public function find(string $topic, string $language = "en"): FeedDTO
logger($exception->getMessage());
}

return FeedDto::from($dataArray);
return FeedDto::from([]);

}

Expand Down
47 changes: 47 additions & 0 deletions src/Clients/NLPClient.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
namespace Cornatul\Feeds\Clients;

use Cornatul\Feeds\Connectors\FeedlyConnector;
use Cornatul\Feeds\Connectors\NlpConnector;
use Cornatul\Feeds\Contracts\ArticleManager;
use Cornatul\Feeds\Contracts\FeedManager;
use Cornatul\Feeds\Contracts\FeedFinderInterface;
use Cornatul\Feeds\DTO\ArticleDto;
use Cornatul\Feeds\Requests\FeedlyTopicRequest;
use Cornatul\Feeds\Requests\GetArticleRequest;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\GuzzleException;
use JsonException;
use Cornatul\Feeds\DTO\FeedDto;
use Saloon\Exceptions\InvalidResponseClassException;
use Saloon\Exceptions\PendingRequestException;
use Spatie\SchemaOrg\Contracts\ArticleContract;


class NLPClient implements ArticleManager
{
/**
* @method find
*/
public final function find(string $url, string $language = "en"): ArticleDto
{

try {

$nlpConnector = new NlpConnector();

$response = $nlpConnector->send(new GetArticleRequest($topic));

return ArticleDto::from($response->json());

} catch (GuzzleException|\ReflectionException|InvalidResponseClassException|PendingRequestException $exception) {

logger($exception->getMessage());
}

return ArticleDto::from([]);

}

}
3 changes: 2 additions & 1 deletion src/Connectors/NlpConnector.php
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
<?php
declare(strict_types=1);
namespace Cornatul\Feeds\Connectors;
use League\Flysystem\Config;
use Saloon\Http\Connector;
class NlpConnector extends Connector
{
public function resolveBaseUrl(): string
{
return 'https://v1.nlpapi.org/';
return Config::get('feeds.nlp-api-url');
}

protected function defaultHeaders(): array
Expand Down
1 change: 1 addition & 0 deletions src/Console/ArticleExtractorCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ private function getArticle(): void

$url = $this->argument('url');


$connector = new NlpConnector();

$response = $connector->send(new GetArticleRequest($url));
Expand Down
49 changes: 49 additions & 0 deletions src/Console/FeedEntriesExtractor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php
declare(strict_types=1);
namespace Cornatul\Feeds\Console;

use Cornatul\Feeds\Clients\FeedLaminasClient;
use Cornatul\Feeds\Connectors\FeedlyConnector;
use Cornatul\Feeds\Connectors\NlpConnector;
use Cornatul\Feeds\Jobs\FeedArticleExtractor;
use Cornatul\Feeds\Models\Feed;
use Cornatul\Feeds\Requests\FeedlyTopicRequest;
use Cornatul\Feeds\Requests\GetArticleRequest;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Config;
use Laminas\Feed\Reader\Reader;
use Saloon\Exceptions\InvalidResponseClassException;
use Saloon\Exceptions\PendingRequestException;

class FeedEntriesExtractor extends Command
{

protected $signature = 'feed:extract {url}';

protected $description = 'Extract the full list of articles from a given feed';

/**
* @throws \ReflectionException
* @throws InvalidResponseClassException
* @throws PendingRequestException
* @throws \JsonException
*/
public function handle(): void
{
$url = $this->argument('url');

$client = new FeedLaminasClient();

Reader::setHttpClient($client);

$data = Reader::import($url);

$feed = Feed::first();

foreach ($data as $entity)
{
dispatch(new FeedArticleExtractor($entity->getLink(), $feed))->onQueue("article-extractor");
}

}
}
13 changes: 13 additions & 0 deletions src/Contracts/ArticleManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php
declare(strict_types=1);
namespace Cornatul\Feeds\Contracts;

use Cornatul\Feeds\DTO\ArticleDto;
use Cornatul\Feeds\DTO\FeedDto;

interface ArticleManager
{
public function extract(string $url): ArticleDto;


}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<?php
declare(strict_types=1);
namespace Cornatul\Feeds\Interfaces;
namespace Cornatul\Feeds\Contracts;

use Cornatul\Feeds\DTO\FeedDto;

interface FeedFinderInterface
interface FeedManager
{
public function find(string $topic): FeedDto;
}
6 changes: 5 additions & 1 deletion src/DTO/ArticleDto.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,14 @@ class ArticleDto extends Data
public string $markdown;
public string $banner;
public string $summary;
public ?array $authors;
public string $spacy;

public array |string | null $authors;

public ?array $keywords;
public ?array $images;
public ?array $entities;

public ? StdClass $sentiment;
public ? StdClass $social;
}
6 changes: 4 additions & 2 deletions src/DTO/FeedDto.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Cornatul\Feeds\Models\Feed;
use Illuminate\Support\Carbon;
use Illuminate\Support\Collection;
use Spatie\LaravelData\Attributes\MapInputName;
use Spatie\LaravelData\Data;

Expand All @@ -26,7 +27,8 @@ class FeedDto extends Data

public string $visual;

final public function getFeeds(): array
//move this logic to a transformer
final public function getFeeds(): Collection
{
$content = collect();

Expand Down Expand Up @@ -55,7 +57,7 @@ final public function getFeeds(): array
$content->push($data);
}

return $content->sortBy('subscribers', $options = SORT_REGULAR, $descending = true)->toArray();
return $content->sortBy('subscribers', $options = SORT_REGULAR, $descending = true);
}

private function checkImported(string $url): bool
Expand Down
26 changes: 19 additions & 7 deletions src/FeedsServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@

use Cornatul\Feeds\Clients\FeedlyClient;
use Cornatul\Feeds\Console\ArticleExtractorCommand;
use Cornatul\Feeds\Repositories\Interfaces\ArticleRepositoryInterface;
use Cornatul\Feeds\Interfaces\FeedFinderInterface;
use Cornatul\Feeds\Repositories\ArticleRepository;
use Cornatul\Feeds\Console\FeedEntriesExtractor;
use Cornatul\Feeds\Contracts\FeedManager;
use Cornatul\Feeds\Repositories\Contracts\ArticleRepositoryInterface;
use Cornatul\Feeds\Contracts\FeedFinderInterface;
use Cornatul\Feeds\Repositories\ArticleEloquentRepository;
use Cornatul\Feeds\Repositories\FeedRepository;
use Cornatul\Feeds\Repositories\Interfaces\FeedRepositoryInterface;
use Cornatul\Feeds\Repositories\Interfaces\SortableInterface;
use Cornatul\Feeds\Repositories\Contracts\FeedRepositoryInterface;
use Cornatul\Feeds\Repositories\Contracts\SortableInterface;
use Cornatul\Feeds\Services\SortableService;
use GuzzleHttp\Client;
use GuzzleHttp\ClientInterface;
Expand All @@ -23,6 +25,9 @@ final public function boot(): void
$this->loadViewsFrom(__DIR__.'/../resources/views', 'feeds');
$this->loadMigrationsFrom(__DIR__.'/../database/migrations');
$this->loadRoutesFrom(__DIR__.'/../routes/feed.php');
$this->publishes([
__DIR__ . '/../config/config.php' => config_path('feeds.php'),
], 'feeds-config');

if ($this->app->runningInConsole()) {

Expand All @@ -45,6 +50,7 @@ final public function boot(): void

$this->commands([
ArticleExtractorCommand::class,
FeedEntriesExtractor::class
]);

}
Expand All @@ -53,9 +59,15 @@ final public function boot(): void
final public function register(): void
{
$this->app->bind(ClientInterface::class, Client::class);
$this->app->bind(FeedFinderInterface::class, FeedlyClient::class);
//todo move this to a system server manager class and use a system provider for every social provider
//@todo -> The provider should be able to register the social client and return a social client instance response that contais the feed dto , this can be a any response from rss clients which are contained into a docker server that is running on the system gateway.
$this->app->bind(FeedManager::class, FeedlyClient::class);




$this->app->bind(FeedRepositoryInterface::class, FeedRepository::class);
$this->app->bind(ArticleRepositoryInterface::class, ArticleRepository::class);
$this->app->bind(ArticleRepositoryInterface::class, ArticleEloquentRepository::class);
$this->app->bind(SortableInterface::class, SortableService::class);

}
Expand Down
6 changes: 3 additions & 3 deletions src/Http/Controllers/ArticlesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
declare(strict_types=1);
namespace Cornatul\Feeds\Http\Controllers;

use Cornatul\Feeds\Repositories\Interfaces\ArticleRepositoryInterface;
use Cornatul\Feeds\Repositories\Interfaces\FeedRepositoryInterface;
use Cornatul\Feeds\Interfaces\FeedFinderInterface;
use Cornatul\Feeds\Repositories\Contracts\ArticleRepositoryInterface;
use Cornatul\Feeds\Repositories\Contracts\FeedRepositoryInterface;
use Cornatul\Feeds\Contracts\FeedFinderInterface;
use Cornatul\Feeds\Jobs\FeedExtractor;
use Cornatul\Wordpress\Interfaces\WordpressRepositoryInterface;
use Cornatul\Wordpress\WordpressServiceProvider;
Expand Down
Loading

0 comments on commit 0be1cf1

Please sign in to comment.