Compare commits
No commits in common. "master" and "picker-service" have entirely different histories.
master
...
picker-ser
10 changed files with 451 additions and 626 deletions
17
.travis.yml
17
.travis.yml
|
@ -1,17 +0,0 @@
|
|||
language: php
|
||||
|
||||
php:
|
||||
- 7.1
|
||||
- 7.2
|
||||
- 7.3
|
||||
|
||||
env:
|
||||
matrix:
|
||||
- COMPOSER_FLAGS="--prefer-lowest"
|
||||
- COMPOSER_FLAGS=""
|
||||
|
||||
before_script:
|
||||
- composer install --dev --prefer-source --no-interaction
|
||||
|
||||
script:
|
||||
- bin/phpunit
|
11
README.md
11
README.md
|
@ -1,11 +0,0 @@
|
|||
# Joind.in Winner Picker
|
||||
|
||||
[](https://travis-ci.org/opdavies/joindin-winner-picker-new)
|
||||
|
||||
WIP
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
bin/console app:pick-winner <tag>
|
||||
```
|
|
@ -5,7 +5,6 @@
|
|||
"php": "^7.1.3",
|
||||
"ext-ctype": "*",
|
||||
"ext-iconv": "*",
|
||||
"ext-json": "^1.5",
|
||||
"guzzlehttp/guzzle": "^6.3",
|
||||
"josephlavin/tap": "^1.0",
|
||||
"symfony/cache": "4.2.*",
|
||||
|
@ -62,7 +61,6 @@
|
|||
}
|
||||
},
|
||||
"require-dev": {
|
||||
"fzaninotto/faker": "^1.8",
|
||||
"symfony/maker-bundle": "^1.11",
|
||||
"symfony/test-pack": "^1.0",
|
||||
"symfony/var-dumper": "4.2.*"
|
||||
|
|
657
composer.lock
generated
657
composer.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace App\Command;
|
||||
|
||||
use App\Comment;
|
||||
use App\Service\Picker;
|
||||
use GuzzleHttp\Client;
|
||||
use Symfony\Component\Cache\Simple\FilesystemCache;
|
||||
|
@ -11,7 +10,6 @@ use Symfony\Component\Console\Input\InputArgument;
|
|||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
use Tightenco\Collect\Support\Collection;
|
||||
|
||||
class PickWinnerCommand extends Command
|
||||
{
|
||||
|
@ -22,11 +20,6 @@ class PickWinnerCommand extends Command
|
|||
*/
|
||||
private $client;
|
||||
|
||||
/**
|
||||
* @var \Symfony\Contracts\Cache\CacheInterface
|
||||
*/
|
||||
private $cache;
|
||||
|
||||
/**
|
||||
* @var \App\Service\Picker
|
||||
*/
|
||||
|
@ -42,7 +35,6 @@ class PickWinnerCommand extends Command
|
|||
{
|
||||
parent::__construct();
|
||||
$this->client = new Client();
|
||||
$this->cache = new FilesystemCache();
|
||||
$this->picker = $picker;
|
||||
}
|
||||
|
||||
|
@ -66,122 +58,31 @@ class PickWinnerCommand extends Command
|
|||
{
|
||||
$io = new SymfonyStyle($input, $output);
|
||||
|
||||
$io->title('Joind.in Winner Picker!');
|
||||
|
||||
$tag = $input->getArgument('tag');
|
||||
$startDate = (new \DateTime($input->getArgument('start')))->format('Y-m-d');
|
||||
$endDate = (new \DateTime($input->getArgument('end')))->format('Y-m-d');
|
||||
|
||||
$io->comment(vsprintf('Selecting from #%s events between %s and %s.', [
|
||||
$tag,
|
||||
$startDate,
|
||||
$endDate,
|
||||
]));
|
||||
var_dump([
|
||||
'tag' => $tag,
|
||||
'start date' => $startDate,
|
||||
'end date' => $endDate,
|
||||
]);
|
||||
|
||||
$events = collect($this->getEventData($tag, $startDate, $endDate));
|
||||
$this->picker->setHosts($events);
|
||||
$this->picker->setComments($this->allComments($events));
|
||||
// $io->success('You have a new command! Now make it your own! Pass --help to see your options.');
|
||||
$cache = new FilesystemCache();
|
||||
$cacheKey = md5(collect([$tag, $startDate, $endDate])->implode('_'));
|
||||
|
||||
$this->picker->getWinners(1)->each(function (Comment $comment) use ($io) {
|
||||
$io->section(vsprintf('%s (%s)', [
|
||||
$comment->getUserDisplayName(),
|
||||
$comment->getTalkTitle(),
|
||||
]));
|
||||
$io->text($comment->getText());
|
||||
$io->text($comment->getUri());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all comments (talks and event) for the events.
|
||||
*
|
||||
* @param \Tightenco\Collect\Support\Collection $events
|
||||
* The retrieved events.
|
||||
*
|
||||
* @return \Tightenco\Collect\Support\Collection
|
||||
* The merged comments.
|
||||
*/
|
||||
private function allComments(Collection $events): Collection
|
||||
{
|
||||
return $events->map(function (\stdClass $event) {
|
||||
return $this
|
||||
->eventComments($event)
|
||||
->merge($this->talkComments($event))
|
||||
;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the event comments.
|
||||
*
|
||||
* @param \stdClass $event
|
||||
* The event.
|
||||
*
|
||||
* @return \Tightenco\Collect\Support\Collection
|
||||
*/
|
||||
private function eventComments(\stdClass $event): Collection
|
||||
{
|
||||
// TODO: Cache this.
|
||||
$response = $this->client->get(
|
||||
$event->comments_uri,
|
||||
['query' => ['resultsperpage' => 1000]]
|
||||
)->getBody();
|
||||
|
||||
return collect(json_decode($response)->comments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the talk comments.
|
||||
*
|
||||
* @param \stdClass $event
|
||||
* The event.
|
||||
*
|
||||
* @return \Tightenco\Collect\Support\Collection
|
||||
*/
|
||||
private function talkComments(\stdClass $event): Collection
|
||||
{
|
||||
// TODO: Cache this.
|
||||
$response = $this->client->get(
|
||||
$event->all_talk_comments_uri,
|
||||
['query' => ['resultsperpage' => 1000]]
|
||||
)->getBody();
|
||||
|
||||
return collect(json_decode($response)->comments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the event data.
|
||||
*
|
||||
* @param string $tag
|
||||
* The tag to search for.
|
||||
* @param string $startDate
|
||||
* The start date limit.
|
||||
* @param string $endDate
|
||||
* The end date limit.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \Psr\Cache\InvalidArgumentException
|
||||
* @throws \Psr\SimpleCache\InvalidArgumentException
|
||||
*/
|
||||
private function getEventData(string $tag, string $startDate, string $endDate): array
|
||||
{
|
||||
$cacheKey = md5(collect(['events:', $tag, $startDate, $endDate])->implode('_'));
|
||||
|
||||
if (!$events = $this->cache->get($cacheKey)) {
|
||||
if (!$events = $cache->get($cacheKey)) {
|
||||
$response = $this->client->get('http://api.joind.in/v2.1/events', [
|
||||
'query' => [
|
||||
'tags' => [$tag],
|
||||
'startdate' => $startDate,
|
||||
'enddate' => $endDate,
|
||||
'verbose' => 'yes',
|
||||
],
|
||||
]
|
||||
]);
|
||||
|
||||
$events = json_decode($response->getBody())->events;
|
||||
$this->cache->set($cacheKey, $events, 3600);
|
||||
}
|
||||
|
||||
return $events;
|
||||
$cache->set($cacheKey, json_decode($response->getBody())->events, 3600);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
106
src/Comment.php
106
src/Comment.php
|
@ -1,106 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
class Comment
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $text;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $userDisplayName;
|
||||
|
||||
/**
|
||||
* The URI for the comment.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $uri;
|
||||
|
||||
/**
|
||||
* The title of the talk that was commented on.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $talkTitle;
|
||||
|
||||
/**
|
||||
* Set the comment text.
|
||||
*
|
||||
* @param string $text
|
||||
*/
|
||||
public function setText(string $text): void
|
||||
{
|
||||
$this->text = $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the user's display name.
|
||||
*
|
||||
* @param string $name
|
||||
*/
|
||||
public function setUserDisplayName(string $name): void
|
||||
{
|
||||
$this->userDisplayName = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the URI for the comment.
|
||||
*
|
||||
* @param string $uri
|
||||
*/
|
||||
public function setUri(string $uri): void
|
||||
{
|
||||
$this->uri = $uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the talk title.
|
||||
*
|
||||
* @param string $talkTitle
|
||||
*/
|
||||
public function setTalkTitle(string $talkTitle): void
|
||||
{
|
||||
$this->talkTitle = $talkTitle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getText(): string
|
||||
{
|
||||
return $this->text;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getUserDisplayName(): string
|
||||
{
|
||||
return $this->userDisplayName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the URI for the comment.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUri(): string
|
||||
{
|
||||
return $this->uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the talk title.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTalkTitle(): string
|
||||
{
|
||||
return $this->talkTitle;
|
||||
}
|
||||
}
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace App\Service;
|
||||
|
||||
use App\Comment;
|
||||
use Tightenco\Collect\Support\Collection;
|
||||
|
||||
class Picker
|
||||
|
@ -78,16 +77,8 @@ class Picker
|
|||
{
|
||||
$this->comments = $comments
|
||||
->flatten(1)
|
||||
->filter(function (\stdClass $comment) {
|
||||
return !$this->isUserAnEventHost($comment->user_display_name);
|
||||
})
|
||||
->map(function (\stdClass $original) {
|
||||
return tap(new Comment(), function (Comment $comment) use ($original) {
|
||||
$comment->setText($original->comment);
|
||||
$comment->setUserDisplayName($original->user_display_name);
|
||||
$comment->setUri($original->uri);
|
||||
$comment->setTalkTitle($original->talk_title);
|
||||
});
|
||||
->filter(function (array $comment) {
|
||||
return !$this->isUserAnEventHost($comment['user_display_name']);
|
||||
})
|
||||
->values();
|
||||
|
||||
|
|
|
@ -5,9 +5,6 @@
|
|||
"facebook/webdriver": {
|
||||
"version": "1.6.0"
|
||||
},
|
||||
"fzaninotto/faker": {
|
||||
"version": "v1.8.0"
|
||||
},
|
||||
"guzzlehttp/guzzle": {
|
||||
"version": "6.3.3"
|
||||
},
|
||||
|
@ -23,9 +20,6 @@
|
|||
"nikic/php-parser": {
|
||||
"version": "v4.2.0"
|
||||
},
|
||||
"php": {
|
||||
"version": "7.3"
|
||||
},
|
||||
"psr/cache": {
|
||||
"version": "1.0.1"
|
||||
},
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Tests\Helpers\Factory;
|
||||
|
||||
use App\Comment;
|
||||
use Faker\Factory;
|
||||
use Tightenco\Collect\Support\Collection;
|
||||
|
||||
class CommentFactory
|
||||
{
|
||||
/**
|
||||
* @var \Faker\Factory
|
||||
*/
|
||||
private $faker;
|
||||
|
||||
/**
|
||||
* The number of comments to create.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $commentCount = 0;
|
||||
|
||||
/**
|
||||
* CommentFactory constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->faker = Factory::create();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new comments.
|
||||
*
|
||||
* @return \Tightenco\Collect\Support\Collection
|
||||
*/
|
||||
public function create(): Collection
|
||||
{
|
||||
$talkTitle = $this->faker->sentence;
|
||||
|
||||
return tap(collect(), function (Collection $data) use ($talkTitle) {
|
||||
if ($this->commentCount > 0) {
|
||||
foreach (range(1, $this->commentCount) as $i) {
|
||||
$comment = new \stdClass();
|
||||
$comment->talk_title = $talkTitle;
|
||||
$comment->comment = $this->faker->paragraph;
|
||||
$comment->uri = 'http://api.joind.in/v2.1/talk_comments/' . $this->faker->randomNumber(8);
|
||||
$comment->user_display_name = $this->faker->name;
|
||||
|
||||
$data->push($comment);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the number of comments to create.
|
||||
*
|
||||
* @param int $count
|
||||
*
|
||||
* @return \App\Tests\Helpers\Factory\CommentFactory
|
||||
*/
|
||||
public function setCount(int $count): self
|
||||
{
|
||||
$this->commentCount = $count;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
|
@ -2,9 +2,7 @@
|
|||
|
||||
namespace App\Tests\Service;
|
||||
|
||||
use App\Comment;
|
||||
use App\Service\Picker;
|
||||
use App\Tests\Helpers\Factory\CommentFactory;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Tightenco\Collect\Support\Collection;
|
||||
|
||||
|
@ -43,8 +41,22 @@ class PickerTest extends TestCase
|
|||
public function comments_for_multiple_events_are_flattened_and_combined()
|
||||
{
|
||||
$data = [
|
||||
(new CommentFactory())->setCount(2)->create(),
|
||||
(new CommentFactory())->setCount(1)->create(),
|
||||
[
|
||||
[
|
||||
'comment' => 'Great talk!',
|
||||
'user_display_name' => 'Dan Ackroyd',
|
||||
],
|
||||
[
|
||||
'comment' => 'Could be better.',
|
||||
'user_display_name' => 'Lucia Velasco',
|
||||
],
|
||||
],
|
||||
[
|
||||
[
|
||||
'comment' => 'Needs more cat pictures.',
|
||||
'user_display_name' => 'Rupert Jabelman',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$comments = (new Picker())
|
||||
|
@ -58,29 +70,58 @@ class PickerTest extends TestCase
|
|||
/** @test */
|
||||
public function comments_from_event_hosts_cannot_be_picked()
|
||||
{
|
||||
$comments = (new CommentFactory())->setCount(3)->create();
|
||||
|
||||
$event = [
|
||||
'hosts' => [
|
||||
['host_name' => $hostName = $comments[1]->user_display_name],
|
||||
['host_name' => 'Oliver Davies'],
|
||||
],
|
||||
];
|
||||
|
||||
/** @var \Tightenco\Collect\Support\Collection $userNames */
|
||||
$userNames = (new Picker())
|
||||
$comments = [
|
||||
[
|
||||
[
|
||||
'comment' => 'Great talk!',
|
||||
'user_display_name' => 'Peter Fisher',
|
||||
],
|
||||
[
|
||||
'comment' => 'Text on slides could be bigger.',
|
||||
'user_display_name' => 'Oliver Davies',
|
||||
],
|
||||
[
|
||||
'comment' => 'Speak slower.',
|
||||
'user_display_name' => 'Zan Baldwin',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$comments = (new Picker())
|
||||
->setHosts(collect([$event]))
|
||||
->setComments(collect($comments))
|
||||
->getComments()
|
||||
->map->getUserDisplayName();
|
||||
->getComments();
|
||||
|
||||
$this->assertCount(2, $userNames);
|
||||
$this->assertFalse($userNames->contains($hostName));
|
||||
$this->assertCount(2, $comments);
|
||||
$this->assertSame('Peter Fisher', $comments[0]['user_display_name']);
|
||||
$this->assertSame('Zan Baldwin', $comments[1]['user_display_name']);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function winners_can_be_selected()
|
||||
{
|
||||
$comments = (new CommentFactory())->setCount(3)->create();
|
||||
$comments = [
|
||||
[
|
||||
[
|
||||
'comment' => 'Great talk!',
|
||||
'user_display_name' => 'Peter Fisher',
|
||||
],
|
||||
[
|
||||
'comment' => 'Text on slides could be bigger.',
|
||||
'user_display_name' => 'Michael Bush',
|
||||
],
|
||||
[
|
||||
'comment' => 'Speak slower.',
|
||||
'user_display_name' => 'Zan Baldwin',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$picker = new Picker();
|
||||
$picker->setComments(collect($comments));
|
||||
|
@ -88,17 +129,12 @@ class PickerTest extends TestCase
|
|||
|
||||
tap($picker->getWinners(1), function (Collection $winners) use ($picker) {
|
||||
$this->assertCount(1, $winners);
|
||||
$this->assertInstanceOf(Comment::class, $winners->first());
|
||||
$this->assertTrue($picker->getComments()->contains($winners->first()));
|
||||
});
|
||||
|
||||
tap($picker->getWinners(2), function (Collection $winners) use ($picker) {
|
||||
$this->assertCount(2, $winners);
|
||||
|
||||
$this->assertInstanceOf(Comment::class, $winners->first());
|
||||
$this->assertTrue($picker->getComments()->contains($winners->first()));
|
||||
|
||||
$this->assertInstanceOf(Comment::class, $winners->last());
|
||||
$this->assertTrue($picker->getComments()->contains($winners->last()));
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue