コード例 #1
0
ファイル: Xkcd.php プロジェクト: Room-11/Jeeves
 public function search(Command $command) : \Generator
 {
     if (!$command->hasParameters()) {
         return new Success();
     }
     $uri = "https://www.google.com/search?q=site:xkcd.com+intitle%3a%22xkcd%3a+%22+" . urlencode(implode(' ', $command->getParameters()));
     /** @var HttpResponse $response */
     $response = (yield $this->httpClient->request($uri));
     if ($response->getStatus() !== 200) {
         return $this->chatClient->postMessage($command->getRoom(), "Useless error message here so debugging this is harder than needed.");
     }
     $dom = domdocument_load_html($response->getBody());
     $nodes = (new \DOMXPath($dom))->query("//*[contains(concat(' ', normalize-space(@class), ' '), ' g ')]/h3/a");
     /** @var \DOMElement $node */
     foreach ($nodes as $node) {
         if (preg_match('~^/url\\?q=(https://xkcd\\.com/\\d+/)~', $node->getAttribute('href'), $matches)) {
             return $this->chatClient->postMessage($command->getRoom(), $matches[1]);
         }
     }
     if (preg_match('/^(\\d+)$/', trim(implode(' ', $command->getParameters())), $matches) !== 1) {
         return $this->chatClient->postMessage($command->getRoom(), self::NOT_FOUND_COMIC);
     }
     /** @var HttpResponse $response */
     $response = (yield $this->httpClient->request('https://xkcd.com/' . $matches[1]));
     if ($response->getStatus() !== 200) {
         return $this->chatClient->postMessage($command->getRoom(), self::NOT_FOUND_COMIC);
     }
     return $this->chatClient->postMessage($command->getRoom(), 'https://xkcd.com/' . $matches[1]);
 }
コード例 #2
0
ファイル: Should.php プロジェクト: Room-11/Jeeves
 public function should(Command $command)
 {
     static $expr = '~(\\S+?)\\s+(.*?)\\sor\\s(?:(?:should\\s+\\1|rather)\\s+)?(.*?)(?:\\?|$)~i';
     if (!preg_match($expr, implode(" ", $command->getParameters()), $match)) {
         return $this->chatClient->postMessage($command->getRoom(), "Dunno.");
     }
     $yes = $match[2];
     $no = strtolower($match[3]) === 'not' ? 'not ' . $match[2] : $match[3];
     $answer = $this->translatePronouns(random_int(0, 1) ? $yes : $no);
     $flags = PostFlags::NONE;
     if (strtolower($match[1]) === 'i') {
         $target = 'You';
     } else {
         if ($match[1][0] === '@') {
             $target = $match[1];
         } else {
             if (null !== ($pingableName = (yield $this->chatClient->getPingableName($command->getRoom(), $match[1])))) {
                 $target = "@{$pingableName}";
                 $flags |= PostFlags::ALLOW_PINGS;
             } else {
                 $target = $match[1];
             }
         }
     }
     $reply = "{$target} should {$answer}.";
     return $this->chatClient->postMessage($command->getRoom(), $reply, $flags);
 }
コード例 #3
0
ファイル: HttpRequester.php プロジェクト: Room-11/Jeeves
 private function getPostBody(Command $command) : string
 {
     $parameters = $command->getParameters();
     if (count($parameters) < 2) {
         throw new \RuntimeException('Usage: `!!post [options] postdata url`');
     }
     return $parameters[count($parameters) - 2];
 }
コード例 #4
0
ファイル: PHPSrcGrok.php プロジェクト: Room-11/Jeeves
 private function getBranchAndSearchTerm(Command $command) : array
 {
     $parameters = $command->getParameters();
     if (count($parameters) < 3 || strtolower($command->getParameter(0)) !== '-b' || !preg_match('#^(?:[0-9]+\\.[0-9]+|PECL|MASTER)$#i', $command->getParameter(1))) {
         return [self::DEFAULT_BRANCH, implode(' ', $parameters)];
     }
     return [strtoupper($command->getParameter(1)), implode(' ', array_slice($parameters, 2))];
 }
コード例 #5
0
ファイル: Imdb.php プロジェクト: DaveRandom/Jeeves
 public function search(Command $command) : \Generator
 {
     if (!$command->hasParameters()) {
         return new Success();
     }
     $response = (yield $this->httpClient->request('http://www.imdb.com/xml/find?xml=1&nr=1&tt=on&q=' . rawurlencode(implode(' ', $command->getParameters()))));
     return $this->chatClient->postMessage($command->getRoom(), $this->getMessage($response));
 }
コード例 #6
0
ファイル: Giphy.php プロジェクト: Room-11/Jeeves
 public function random(Command $command) : \Generator
 {
     if (!$command->hasParameters()) {
         return new Success();
     }
     /** @var HttpResponse $response */
     $response = (yield $this->httpClient->request(self::API_BASE_URL . 'v1/gifs/random?' . http_build_query(['api_key' => $this->apiKey, 'rating' => $this->rating, 'tag' => implode(' ', $command->getParameters())])));
     $result = json_decode($response->getBody(), true);
     return $this->chatClient->postMessage($command->getRoom(), $this->getMessage($result));
 }
コード例 #7
0
ファイル: Urban.php プロジェクト: Room-11/Jeeves
 public function search(Command $command) : \Generator
 {
     if (!$command->hasParameters()) {
         return new Success();
     }
     /** @var HttpResponse $response */
     $response = (yield $this->httpClient->request('http://api.urbandictionary.com/v0/define?term=' . rawurlencode(implode(' ', $command->getParameters()))));
     $result = json_decode($response->getBody(), true);
     return $this->chatClient->postMessage($command->getRoom(), $this->getMessage($result), PostFlags::TRUNCATE);
 }
コード例 #8
0
ファイル: Haskell.php プロジェクト: Room-11/Jeeves
 public function run(Command $command) : Generator
 {
     if (!$command->hasParameters()) {
         return $this->chatClient->postMessage($command->getRoom(), self::USAGE);
     }
     $form = (new FormBody())->addField("exp", implode(" ", $command->getParameters()));
     $request = (new Request())->setMethod("POST")->setUri("https://tryhaskell.org/eval")->setBody($form);
     $response = (yield $this->httpClient->request($request));
     return $this->chatClient->postMessage($command->getRoom(), $this->getMessage($response));
 }
コード例 #9
0
ファイル: Mdn.php プロジェクト: Room-11/Jeeves
 public function search(Command $command) : \Generator
 {
     if (!$command->hasParameters()) {
         return new Success();
     }
     /** @var HttpResponse $response */
     $response = (yield $this->httpClient->request('https://developer.mozilla.org/en-US/search.json?highlight=false&q=' . rawurlencode(implode('%20', $command->getParameters()))));
     $result = json_decode($response->getBody(), true);
     if (!isset($result["documents"][0]["id"], $result["documents"][0]["url"])) {
         return $this->postNoResult($command);
     }
     return $this->postResult($command, $result["documents"][0]);
 }
コード例 #10
0
ファイル: Man.php プロジェクト: Room-11/Jeeves
 public function search(Command $command) : \Generator
 {
     if (!$command->hasParameters()) {
         return new Success();
     }
     /** @var HttpResponse $response */
     $response = (yield $this->httpClient->request("https://man.freebsd.org/" . rawurlencode(implode("%20", $command->getParameters()))));
     $dom = domdocument_load_html($response->getBody());
     $xpath = new \DOMXPath($dom);
     if (!$this->isFound($xpath)) {
         return $this->postNoResult($command);
     }
     return $this->postResult($command, $xpath, $response->getRequest()->getUri());
 }
コード例 #11
0
ファイル: Wikipedia.php プロジェクト: Room-11/Jeeves
 public function search(Command $command) : \Generator
 {
     if (!$command->hasParameters()) {
         return new Success();
     }
     /** @var HttpResponse $response */
     $response = (yield $this->makeAPIRequest(['titles' => implode(' ', $command->getParameters())]));
     $result = json_try_decode($response->getBody(), true);
     $firstHit = reset($result['query']['pages']);
     if (!isset($firstHit['pageid'])) {
         return $this->chatClient->postReply($command, 'Sorry I couldn\'t find that page.');
     }
     $response = (yield $this->makeAPIRequest(['prop' => 'info', 'inprop' => 'url', 'pageids' => $firstHit['pageid']]));
     $page = json_try_decode($response->getBody(), true);
     return $this->chatClient->postMessage($command->getRoom(), $page['query']['pages'][$firstHit['pageid']]['canonicalurl']);
 }
コード例 #12
0
ファイル: Packagist.php プロジェクト: Room-11/Jeeves
 public function search(Command $command) : \Generator
 {
     $info = explode('/', implode('/', $command->getParameters()), 2);
     if (count($info) !== 2) {
         return $this->chatClient->postReply($command, "Usage: `!!packagist vendor package`");
     }
     list($vendor, $package) = $info;
     $url = 'https://packagist.org/packages/' . urlencode($vendor) . '/' . urldecode($package) . '.json';
     try {
         /** @var HttpResponse $response */
         $response = (yield $this->httpClient->request($url));
         if ($response->getStatus() !== 200) {
             $response = (yield from $this->getResultFromSearchFallback($vendor, $package));
         }
         $data = json_try_decode($response->getBody());
         return $this->chatClient->postMessage($command->getRoom(), sprintf("[ [%s](%s) ] %s", $data->package->name, $data->package->repository, $data->package->description));
     } catch (\Throwable $e) {
         return $this->chatClient->postReply($command, 'No matching packages found');
     }
 }
コード例 #13
0
ファイル: Docs.php プロジェクト: Room-11/Jeeves
 public function search(Command $command) : Promise
 {
     if (!$command->getParameters()) {
         return new Success();
     }
     $pattern = strtolower(implode(' ', $command->getParameters()));
     foreach ([$pattern, '$' . $pattern, $pattern . 's', $pattern . 'ing'] as $candidate) {
         if (isset($this->specialCases[$candidate])) {
             $result = $this->specialCases[$candidate][0] === '@' && isset($this->specialCases[substr($this->specialCases[$candidate], 1)]) ? $this->specialCases[substr($this->specialCases[$candidate], 1)] : $this->specialCases[$candidate];
             return $this->chatClient->postMessage($command->getRoom(), $result);
         }
     }
     if (substr($pattern, 0, 6) === "mysql_") {
         return $this->chatClient->postMessage($command->getRoom(), $this->getMysqlMessage());
     }
     $pattern = str_replace(['::', '->'], '.', $pattern);
     $url = self::LOOKUP_URL_BASE . rawurlencode($pattern);
     return resolve(function () use($command, $pattern, $url) {
         /** @var HttpResponse $response */
         $response = (yield $this->httpClient->request($url));
         return $this->chatClient->postMessage($command->getRoom(), $response->getPreviousResponse() !== null ? $this->getMessageFromMatch(yield from $this->preProcessMatch($response, $pattern)) : (yield from $this->getMessageFromSearch($response)));
     });
 }
コード例 #14
0
ファイル: Google.php プロジェクト: Room-11/Jeeves
 public function search(Command $command) : \Generator
 {
     if (!$command->hasParameters()) {
         return new Success();
     }
     $text = implode(' ', $command->getParameters());
     $searchTerm = (yield $this->messageResolver->resolveMessageText($command->getRoom(), $text));
     $uri = $this->getSearchURL($searchTerm);
     $request = (new HttpRequest())->setMethod('GET')->setUri($uri)->setHeader('User-Agent', self::USER_AGENT);
     /** @var HttpResponse $response */
     $response = (yield $this->httpClient->request($request));
     if ($response->getStatus() !== 200) {
         return $this->chatClient->postMessage($command->getRoom(), "Google responded with {$response->getStatus()}");
     }
     if (preg_match('#charset\\s*=\\s*([^;]+)#i', trim(implode(', ', $response->getHeader('Content-Type'))), $match) && !preg_match('/' . preg_quote(self::ENCODING, '/') . '/i', $match[1])) {
         $body = iconv($match[1], self::ENCODING, $response->getBody());
     }
     if (empty($body)) {
         $body = $response->getBody();
     }
     $dom = domdocument_load_html($body);
     $xpath = new \DOMXPath($dom);
     $nodes = $this->getResultNodes($xpath);
     if ($nodes->length === 0) {
         return $this->postNoResultsMessage($command);
     }
     $searchResults = $this->getSearchResults($nodes, $xpath);
     $postMessage = $this->getPostMessage($searchResults, $uri, $searchTerm);
     return $this->chatClient->postMessage($command->getRoom(), $postMessage);
 }
コード例 #15
0
ファイル: Translate.php プロジェクト: Room-11/Jeeves
 public function toLanguage(Command $command, string $toLanguage = null) : \Generator
 {
     $params = $command->getParameters();
     if ($params[0] === 'list') {
         return $this->postSupportedLanguagesList($command->getRoom());
     }
     $toLanguage = $toLanguage ?? array_shift($params);
     if (null === ($toLanguageCode = $this->getLanguageCode($toLanguage ?? array_shift($params)))) {
         return $this->chatClient->postReply($command, 'Sorry, I don\'t speak ' . $toLanguage);
     }
     $fromLanguageCode = null;
     if (preg_match('#^--from(?:=(.+))?$#', $params[0] ?? '', $match)) {
         array_shift($params);
         $fromLanguage = empty($match[1]) ? array_shift($params) : $match[1];
         if (null === ($fromLanguageCode = $this->getLanguageCode($fromLanguage))) {
             return $this->chatClient->postReply($command, 'Sorry, I don\'t speak ' . $fromLanguage);
         }
     }
     if (count($params) < 1) {
         return $this->chatClient->postReply($command, 'The empty string is the same in every language');
     }
     $text = (yield from $this->getTextFromArguments($command->getRoom(), $params));
     $translation = (yield from $this->getTranslation($command->getRoom(), $text, $toLanguageCode, $fromLanguageCode));
     return $this->chatClient->postMessage($command->getRoom(), $translation);
 }
コード例 #16
0
ファイル: JeevesDad.php プロジェクト: Room-11/Jeeves
 private function addCustomDadJoke(Command $command)
 {
     static $expr = '#^(?<name>\\w+)\\s*/(?<setup>(?:[^\\\\/]++|\\\\\\\\|\\\\/|\\\\)++)/(?<punchline>.+)$#';
     if (!preg_match($expr, implode(' ', $command->getParameters(1)), $match)) {
         return $this->chatClient->postReply($command, "Sorry, I don't get that joke, I need `name / setup / punchline`");
     }
     $jokes = (yield $this->storage->exists('jokes', $command->getRoom())) ? (yield $this->storage->get('jokes', $command->getRoom())) : [];
     if (isset($jokes[$match['name']])) {
         return $this->chatClient->postReply($command, sprintf("I already know a joke about %s! Tell me a new one.", $match['name']));
     }
     $jokes[$match['name']] = ['setup' => trim($match['setup']), 'punchline' => trim($match['punchline'])];
     (yield $this->storage->set('jokes', $jokes, $command->getRoom()));
     return $this->chatClient->postReply($command, sprintf("Ha ha ha! Brilliant! I'll save that one about %s for later!", $match['name']));
 }
コード例 #17
0
ファイル: Reminder.php プロジェクト: Room-11/Jeeves
 private function setReminder(Command $command, string $commandName) : Promise
 {
     return resolve(function () use($command, $commandName) {
         $intervalParser = new IntervalParser();
         switch ($commandName) {
             case 'in':
                 $parameters = $intervalParser->normalizeTimeInterval(implode(" ", $command->getParameters()));
                 $expression = IntervalParser::$intervalSeparatorDefinitions . IntervalParser::$intervalWithTrailingData;
                 if (preg_match($expression, $parameters, $matches)) {
                     $time = $matches['interval'] ?? false;
                     $text = $matches['trailing'] ?? false;
                 }
                 break;
             case 'at':
                 $time = $command->getParameter(0) ?? false;
                 // 24hrs
                 if ($time && preg_match(self::TIME_FORMAT_REGEX, $time)) {
                     // maybe @TODO support !!at monday next week remind?
                     $text = implode(" ", array_diff($command->getParameters(), array($time)));
                 }
                 break;
             case 'reminder':
                 $parameters = implode(" ", $command->getParameters());
                 if (!preg_match(self::REMINDER_REGEX, $parameters, $matches)) {
                     return $this->chatClient->postMessage($command->getRoom(), self::USAGE);
                 }
                 $time = $matches[2] ?? '';
                 $text = $matches[1] ?? false;
                 if ($time !== '') {
                     $time = $intervalParser->normalizeTimeInterval($time);
                 }
                 break;
         }
         if (!isset($time) || !$time) {
             return $this->chatClient->postMessage($command->getRoom(), "Have a look at the time again, yo!");
         }
         if (!isset($text) || !$text) {
             return $this->chatClient->postMessage($command->getRoom(), self::USAGE);
         }
         $timestamp = strtotime($time) ?: strtotime("+{$time}");
         // false|int
         if (!$timestamp) {
             return $this->chatClient->postMessage($command->getRoom(), "Have a look at the time again, yo!");
         }
         $key = (string) $command->getId();
         $value = ['id' => $key, 'text' => $text, 'delay' => $time, 'userId' => $command->getUserId(), 'username' => $command->getUserName(), 'timestamp' => $timestamp];
         $seconds = $timestamp - time();
         if ($seconds <= 0) {
             return $this->chatClient->postReply($command, "I guess I'm late: " . $text);
         }
         if ((yield $this->storage->set($key, $value, $command->getRoom()))) {
             $watcher = once(function () use($command, $value, $key) {
                 (yield $this->storage->unset($key, $command->getRoom()));
                 return $this->chatClient->postReply($command, $value['text']);
             }, $seconds * 1000);
             $this->watchers[] = $watcher;
             return $this->chatClient->postMessage($command->getRoom(), "Reminder set.");
         }
         return $this->chatClient->postMessage($command->getRoom(), "Dunno what happened but I couldn't set the reminder.");
     });
 }