Passed
Push — master ( 204398...443e32 )
by Chema
01:50 queued 12s
created

createFinanceYahooSiteCrawler()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 10
c 1
b 0
f 0
dl 0
loc 12
ccs 11
cts 11
cp 1
rs 9.9332
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Chemaclass\StockTicker;
6
7
use Chemaclass\StockTicker\Domain\Crawler\Mapper\CrawledInfoMapper;
8
use Chemaclass\StockTicker\Domain\Crawler\Mapper\CrawledInfoMapperInterface;
9
use Chemaclass\StockTicker\Domain\Crawler\QuoteCrawler;
10
use Chemaclass\StockTicker\Domain\Crawler\QuoteCrawlerInterface;
11
use Chemaclass\StockTicker\Domain\Crawler\Site\Barrons;
12
use Chemaclass\StockTicker\Domain\Crawler\Site\Barrons\BarronsSiteCrawler;
13
use Chemaclass\StockTicker\Domain\Crawler\Site\FinanceYahoo\FinanceYahooSiteCrawler;
14
use Chemaclass\StockTicker\Domain\Crawler\Site\FinanceYahoo\JsonExtractor;
15
use Chemaclass\StockTicker\Domain\Crawler\Site\MarketWatch;
16
use Chemaclass\StockTicker\Domain\Crawler\Site\MarketWatch\MarketWatchSiteCrawler;
17
use Chemaclass\StockTicker\Domain\Crawler\Site\Shared\NewsNormalizer;
18
use Chemaclass\StockTicker\Domain\Crawler\SiteCrawlerInterface;
19
use Chemaclass\StockTicker\Domain\Notifier\Channel\Email\EmailChannel;
20
use Chemaclass\StockTicker\Domain\Notifier\Channel\Slack\HttpSlackClient;
21
use Chemaclass\StockTicker\Domain\Notifier\Channel\Slack\SlackChannel;
22
use Chemaclass\StockTicker\Domain\Notifier\Channel\TwigTemplateGenerator;
23
use Chemaclass\StockTicker\Domain\Notifier\ChannelInterface;
24
use Chemaclass\StockTicker\Domain\Notifier\Notifier;
25
use Chemaclass\StockTicker\Domain\Notifier\NotifierInterface;
26
use Chemaclass\StockTicker\Domain\Notifier\NotifierPolicy;
27
use Chemaclass\StockTicker\Domain\WriteModel\Quote;
28
use DateTimeZone;
29
use Symfony\Component\HttpClient\HttpClient;
30
use Symfony\Component\Mailer\Bridge\Google\Transport\GmailSmtpTransport;
31
use Symfony\Component\Mailer\Mailer;
32
use Twig\Environment;
33
use Twig\Extension\DebugExtension;
34
use Twig\Loader\FilesystemLoader;
35
36
final class StockTickerFactory implements StockTickerFactoryInterface
37
{
38
    private const URLS = 'URLS';
39
40
    private StockTickerConfigInterface $config;
41
42 4
    public function __construct(StockTickerConfigInterface $config)
43
    {
44 4
        $this->config = $config;
45 4
    }
46
47 4
    public function createQuoteCrawler(SiteCrawlerInterface ...$siteCrawlers): QuoteCrawlerInterface
48
    {
49 4
        return new QuoteCrawler(
50 4
            HttpClient::create(),
51 4
            $this->createCrawledInfoMapper(),
52 4
            ...$siteCrawlers
53
        );
54
    }
55
56 2
    public function createNotifier(NotifierPolicy $policy, ChannelInterface ...$channels): NotifierInterface
57
    {
58 2
        return new Notifier($policy, ...$channels);
59
    }
60
61
    /**
62
     * @return Domain\Crawler\SiteCrawlerInterface[]
63
     */
64 4
    public function createSiteCrawlers(int $maxNewsToFetch): array
65
    {
66
        return [
67 4
            $this->createFinanceYahooSiteCrawler($maxNewsToFetch),
68 4
            $this->createBarronsSiteCrawler($maxNewsToFetch),
69 4
            $this->createMarketWatchSiteCrawler($maxNewsToFetch),
70
        ];
71
    }
72
73
    /**
74
     * @return ChannelInterface[]
75
     */
76 2
    public function createChannels(array $channelNames): array
77
    {
78 2
        $flipped = array_flip($channelNames);
79 2
        $channels = [];
80
81 2
        if (isset($flipped[EmailChannel::class])) {
82
            $channels[] = $this->createEmailChannel();
83
        }
84
85 2
        if (isset($flipped[SlackChannel::class])) {
86
            $channels[] = $this->createSlackChannel();
87
        }
88
89 2
        return $channels;
90
    }
91
92 4
    private function createCrawledInfoMapper(): CrawledInfoMapperInterface
93
    {
94 4
        return new CrawledInfoMapper(function (array $info): array {
95 4
            $info[Quote::URL] = $info[self::URLS][0];
96
97 4
            return $info;
98 4
        });
99
    }
100
101 4
    private function createFinanceYahooSiteCrawler(int $maxNewsToFetch): FinanceYahooSiteCrawler
102
    {
103 4
        return new FinanceYahooSiteCrawler([
104 4
            Quote::COMPANY_NAME => new JsonExtractor\QuoteSummaryStore\CompanyName(),
105 4
            Quote::REGULAR_MARKET_PRICE => new JsonExtractor\QuoteSummaryStore\RegularMarketPrice(),
106 4
            Quote::CURRENCY => new JsonExtractor\QuoteSummaryStore\Currency(),
107 4
            Quote::REGULAR_MARKET_CHANGE => new JsonExtractor\QuoteSummaryStore\RegularMarketChange(),
108 4
            Quote::REGULAR_MARKET_CHANGE_PERCENT => new JsonExtractor\QuoteSummaryStore\RegularMarketChangePercent(),
109 4
            Quote::MARKET_CAP => new JsonExtractor\QuoteSummaryStore\MarketCap(),
110 4
            Quote::LAST_TREND => new JsonExtractor\QuoteSummaryStore\RecommendationTrend(),
111 4
            Quote::LATEST_NEWS => new JsonExtractor\StreamStore\News($this->createNewsNormalizer($maxNewsToFetch)),
0 ignored issues
show
Bug introduced by
The type Chemaclass\StockTicker\D...ractor\StreamStore\News was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
112 4
            self::URLS => new JsonExtractor\RouteStore\ExternalUrl(),
113
        ]);
114
    }
115
116 4
    private function createNewsNormalizer(int $maxNewsToFetch): NewsNormalizer
117
    {
118 4
        return new NewsNormalizer(new DateTimeZone('Europe/Berlin'), $maxNewsToFetch);
119
    }
120
121 4
    private function createBarronsSiteCrawler(int $maxNewsToFetch): BarronsSiteCrawler
122
    {
123 4
        return new BarronsSiteCrawler([
124 4
            Quote::LATEST_NEWS => new Barrons\HtmlCrawler\News($this->createNewsNormalizer($maxNewsToFetch)),
125
        ]);
126
    }
127
128 4
    private function createMarketWatchSiteCrawler(int $maxNewsToFetch): MarketWatchSiteCrawler
129
    {
130 4
        return new MarketWatchSiteCrawler([
131 4
            Quote::LATEST_NEWS => new MarketWatch\HtmlCrawler\News($this->createNewsNormalizer($maxNewsToFetch)),
132
        ]);
133
    }
134
135
    private function createEmailChannel(string $templateName = 'email.twig'): EmailChannel
136
    {
137
        return new EmailChannel(
138
            $this->config->getToAddress(),
139
            new Mailer(new GmailSmtpTransport(
140
                $this->config->getMailerUsername(),
141
                $this->config->getMailerPassword()
142
            )),
143
            new TwigTemplateGenerator(
144
                $this->createTwigEnvironment(),
145
                $templateName
146
            )
147
        );
148
    }
149
150
    private function createSlackChannel(string $templateName = 'slack.twig'): SlackChannel
151
    {
152
        return new SlackChannel(
153
            $this->config->getSlackDestinyChannelId(),
154
            new HttpSlackClient(HttpClient::create([
155
                'auth_bearer' => $this->config->getSlackBotUserOauthAccessToken(),
156
            ])),
157
            new TwigTemplateGenerator(
158
                $this->createTwigEnvironment(),
159
                $templateName
160
            )
161
        );
162
    }
163
164
    private function createTwigEnvironment(): Environment
165
    {
166
        $loader = new FilesystemLoader($this->config->getTemplatesDir());
167
        $isDebug = $this->config->isDebug();
168
        $twig = new Environment($loader, ['debug' => $isDebug]);
169
170
        if ($isDebug) {
171
            $twig->addExtension(new DebugExtension());
172
        }
173
174
        return $twig;
175
    }
176
}
177