Skip to content

Commit

Permalink
Add Sessionize-Data
Browse files Browse the repository at this point in the history
This introduces a parser that allows to read CfP-Infos from sessionize
# Bitte geben Sie eine Commit-Beschreibung für Ihre Änderungen ein. Zeilen,
# die mit '#' beginnen, werden ignoriert, und eine leere Beschreibung
# bricht den Commit ab.
#
# Auf Branch addConfsTech
# Ihr Branch ist auf demselben Stand wie 'origin/addConfsTech'.
#
# Zum Commit vorgemerkte Änderungen:
#	geändert:       bin/callingallpapers
#	geändert:       composer.json
#	geändert:       phpunit.xml.dist
#	neue Datei:     src/Command/AbstractParseEvents.php
#	neue Datei:     src/Service/ServiceContainer.php
#	neue Datei:     src/Subcommands/Sessionize/Command.php
#	neue Datei:     src/Subcommands/Sessionize/Parser/ClosingDate.php
#	neue Datei:     src/Subcommands/Sessionize/Parser/Description.php
#	neue Datei:     src/Subcommands/Sessionize/Parser/EntryParser.php
#	neue Datei:     src/Subcommands/Sessionize/Parser/EventEndDate.php
#	neue Datei:     src/Subcommands/Sessionize/Parser/EventName.php
#	neue Datei:     src/Subcommands/Sessionize/Parser/EventStartDate.php
#	neue Datei:     src/Subcommands/Sessionize/Parser/EventUri.php
#	neue Datei:     src/Subcommands/Sessionize/Parser/IconUri.php
#	neue Datei:     src/Subcommands/Sessionize/Parser/Location.php
#	neue Datei:     src/Subcommands/Sessionize/Parser/OpeningDate.php
#	neue Datei:     src/Subcommands/Sessionize/Parser/Sessionize.php
#	neue Datei:     tests/Subcommands/Sessionize/IntegrationTest.php
#	neue Datei:     tests/Subcommands/Sessionize/Parser/ClosingDateTest.php
#	neue Datei:     tests/Subcommands/Sessionize/Parser/EventDescriptionTest.php
#	neue Datei:     tests/Subcommands/Sessionize/Parser/EventEndDateTest.php
#	neue Datei:     tests/Subcommands/Sessionize/Parser/EventNameTest.php
#	neue Datei:     tests/Subcommands/Sessionize/Parser/EventStartDateTest.php
#	neue Datei:     tests/Subcommands/Sessionize/Parser/EventUriTest.php
#	neue Datei:     tests/Subcommands/Sessionize/Parser/IconUriTest.php
#	neue Datei:     tests/Subcommands/Sessionize/Parser/LocationTest.php
#	neue Datei:     tests/Subcommands/Sessionize/Parser/OpeningDateTest.php
#	neue Datei:     tests/Subcommands/Sessionize/__assets/Azure Day Rome 2019: Call for Speakers @ Sessionize.com.html
#	neue Datei:     "tests/Subcommands/Sessionize/__assets/React Week Medell\303\255n 2019: Call for Speakers @ Sessionize.com.html"
#
  • Loading branch information
heiglandreas committed Feb 2, 2020
1 parent ceb6fa4 commit aa0f797
Show file tree
Hide file tree
Showing 29 changed files with 2,235 additions and 0 deletions.
1 change: 1 addition & 0 deletions bin/callingallpapers
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use Symfony\Component\Console\Application;
$app = new Application();
$app->add(new \Callingallpapers\Command\ParseEvents());
$app->add(new \Callingallpapers\Command\ParseEventsConfsTech());
$app->add(new \Callingallpapers\Subcommands\Sessionize\Command());
$app->add(new \Callingallpapers\Command\NotifyClosingCfps());

$app->run();
2 changes: 2 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
"homepage" : "https://callingallpapers.com",
"license" : "MIT",
"require": {
"ext-dom" : "*",
"ext-json" : "*",
"symfony/console": "^2.7",
"org_heigl/trait-iterator": "^1.0",
"guzzlehttp/guzzle": "^6.2",
Expand Down
1 change: 1 addition & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<phpunit bootstrap="tests/bootstrap.php">
<testsuite name="callingallpapers-CLI Test-Suite">
<directory>tests</directory>
<directory>src/Subcommands/Tests</directory>
</testsuite>

<groups>
Expand Down
173 changes: 173 additions & 0 deletions src/Command/AbstractParseEvents.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
<?php
/**
* Copyright (c) 2015-2016 Andreas Heigl<andreas@heigl.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author Andreas Heigl<andreas@heigl.org>
* @copyright 2015-2016 Andreas Heigl/callingallpapers.com
* @license http://www.opensource.org/licenses/mit-license.php MIT-License
* @version 0.0
* @since 01.12.2015
* @link http://github.com/heiglandreas/callingallpapers-cli
*/
namespace Callingallpapers\Command;

use Callingallpapers\CfpFilter\FilterList;
use Callingallpapers\CfpFilter\FollowUriRedirect;
use Callingallpapers\CfpFilter\StripParamsFromUri;
use Callingallpapers\ErrorHandling\ErrorStore;
use Callingallpapers\Exception\UnverifiedUriException;
use Callingallpapers\Parser\ConfsTech\ConferenceParser;
use Callingallpapers\Parser\ConfsTechParser;
use Callingallpapers\Parser\JoindinCfpParser;
use Callingallpapers\Parser\Lanyrd\LanyrdCfpParser;
use Callingallpapers\Parser\PapercallIo\PapercallIoParserFactory;
use Callingallpapers\Parser\ParserInterface;
use Callingallpapers\ResultKeeper\ConsoleOutputResultKeeper;
use Callingallpapers\ResultKeeper\ResultKeeper;
use Callingallpapers\Service\ConfsTechParserFactory;
use Callingallpapers\Service\GeolocationService;
use Callingallpapers\Service\ServiceContainer;
use Callingallpapers\Service\TimezoneService;
use Callingallpapers\Writer\ApiCfpWriter;
use GuzzleHttp\Client;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

abstract class AbstractParseEvents extends Command
{
protected function configure()
{
$this->setName(sprintf("parseCfPs:%s", $this->getParserId()))
->setDescription(sprintf("Retrieve CfPs from %s only and parse them", $this->getParserName()))
->setDefinition(array(
new InputOption('start', 's', InputOption::VALUE_OPTIONAL, 'What should be the first date to be taken into account?', ''),
))
->setHelp(sprintf(<<<EOT
Get details about CfPs from https://sesionize.com
Usage:
<info>callingallpapers parseCfPs:sessionize 2015-02-23<env></info>
If you ommit the date the current date will be used instead
<info>callingallpapers parseCfPs:sessionize<env></info>
EOT
,$this->getServiceUrl()));
}

protected function execute(InputInterface $input, OutputInterface $output)
{
$header_style = new OutputFormatterStyle('white', 'green', array('bold'));
$style = new SymfonyStyle($input, $output);
$output->getFormatter()->setStyle('header', $header_style);

$start = new \DateTime($input->getOption('start'));

if (! $start instanceof \DateTime) {
throw new \InvalidArgumentException('The given date could not be parsed');
}

$config = parse_ini_file(__DIR__ . '/../../config/callingallpapers.ini');

$client = new Client([
'headers' => [
'Accept' => 'application/json',
'Authorization' => 'token ' . $config['github.token'],
],
]);

$resultKeeper = new ConsoleOutputResultKeeper($style);
$writer = new ApiCfpWriter($config['event_api_url'], $config['event_api_token'], $client);
$writer->setOutput($output);
$writer->setResultKeeper($resultKeeper);

$style->comment(sprintf('Starting to parse %s', $this->getParserName()));

// Set CfP-Filters
$filter = new FilterList();
$filter->add(new FollowUriRedirect(['conferenceUri'], $client));
$filter->add(new StripParamsFromUri(['conferenceUri']));
$writer->setFilter($filter);

$timezoneService = new TimezoneService($client, $config['timezonedb_token']);
$geolocationService = new GeolocationService($client);

// Parse Confs.tech
$parser = $this->getParser(new ServiceContainer($timezoneService, $geolocationService, $client));
$parser->parse($writer);

$style->newLine(2);

$items = [];
foreach ($resultKeeper->getCreated() as $created) {
$items[] = $created->getConference();
}

if ($items) {
$style->writeln('Added these new Conferences:');
$style->listing($items);
}

$items = [];
foreach ($resultKeeper->getUpdated() as $updated) {
$items[] = $updated->getConference();
}

if ($items) {
$style->writeln('Updated these Conferences:');
$style->listing($items);
}

$items = [];
foreach ($resultKeeper->getFailed() as $failed) {
$items[] = sprintf(
'%1$s (%2$s)',
$failed->getConference(),
$failed->getMessage()
);
}

foreach ($resultKeeper->getErrored() as $errored) {
$items[] = sprintf(
'%1$s (%2$s)',
$errored->getConference(),
$errored->getMessage()
);
}

if ($items) {
$style->writeln('There where issues with these conferences:');
$style->listing($items);
}
}

abstract protected function getParser(ServiceContainer $serviceContainer) : ParserInterface;

abstract protected function getParserName() : string;

abstract protected function getParserId() : string;

abstract protected function getServiceUrl() : string;
}
47 changes: 47 additions & 0 deletions src/Service/ServiceContainer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

declare(strict_types=1);

/**
* Copyright Andrea Heigl <andreas@heigl.org>
*
* Licenses under the MIT-license. For details see the included file LICENSE.md
*/

namespace Callingallpapers\Service;

use GuzzleHttp\Client;

class ServiceContainer
{
private $timezone;

private $geolocation;

private $client;

public function __construct(
TimezoneService $timezone,
GeolocationService $geolocation,
Client $client
) {
$this->timezone = $timezone;
$this->geolocation = $geolocation;
$this->client = $client;
}

public function getTimezoneService() : TimezoneService
{
return $this->timezone;
}

public function getGeolocationService() : GeolocationService
{
return $this->geolocation;
}

public function getClient() : Client
{
return $this->client;
}
}
68 changes: 68 additions & 0 deletions src/Subcommands/Sessionize/Command.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

declare(strict_types = 1);

/**
* Copyright (c) 2015-2016 Andreas Heigl<andreas@heigl.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author Andreas Heigl<andreas@heigl.org>
* @copyright 2015-2016 Andreas Heigl/callingallpapers.com
* @license http://www.opensource.org/licenses/mit-license.php MIT-License
* @version 0.0
* @since 01.12.2015
* @link http://github.com/heiglandreas/callingallpapers-cli
*/
namespace Callingallpapers\Subcommands\Sessionize;

use Callingallpapers\Command\AbstractParseEvents;
use Callingallpapers\Entity\Cfp;
use Callingallpapers\Parser\ParserInterface;
use Callingallpapers\Service\ServiceContainer;
use Callingallpapers\Subcommands\Sessionize\Parser\EntryParser;
use Callingallpapers\Subcommands\Sessionize\Parser\Sessionize;
use GuzzleHttp\Client;

class Command extends AbstractParseEvents
{
const NAME = 'Sessionize';

protected function getParser(ServiceContainer $serviceContainer): ParserInterface
{
$parser = new EntryParser(new Cfp(), $serviceContainer);

return new Sessionize($parser);
}

protected function getParserName(): string
{
return self::NAME;
}

protected function getParserId() : string
{
return strtolower($this->getParserName());
}

protected function getServiceUrl() : string
{
return 'https://sessionize.com';
}
}
49 changes: 49 additions & 0 deletions src/Subcommands/Sessionize/Parser/ClosingDate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

declare(strict_types=1);

/**
* Copyright Andrea Heigl <andreas@heigl.org>
*
* Licenses under the MIT-license. For details see the included file LICENSE.md
*/
namespace Callingallpapers\Subcommands\Sessionize\Parser;

use DateTimeImmutable;
use DateTimeZone;
use DOMDocument;
use DOMXPath;
use InvalidArgumentException;
use function str_replace;
use function trim;

class ClosingDate
{
protected $timezone;

public function __construct(DateTimeZone $timezone)
{
$this->timezone = $timezone;
}

public function parse(DOMDocument $dom, DOMXPath $xpath) : DateTimeImmutable
{
$closingDateHolder = $xpath->query('//div[./div/span[contains(text(), "CfS closes at")]]');

if (! $closingDateHolder || $closingDateHolder->length == 0) {
throw new InvalidArgumentException('The CfP does not seem to have a closing date');
}

$closingDay = $closingDateHolder->item(0)->getElementsByTagName('h2')->item(0)->textContent;
$closingHour = $closingDateHolder->item(0)->getElementsByTagName('span')->item(0)->textContent;

$closingHour = $this->clearClosingHour($closingHour);

return new DateTimeImmutable($closingDay . ' ' . $closingHour, $this->timezone);
}

private function clearClosingHour(string $closingHour) : string
{
return trim(str_replace('CfS closes at', '', $closingHour));
}
}
Loading

0 comments on commit aa0f797

Please sign in to comment.