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]); }
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); }
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]; }
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))]; }
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)); }
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)); }
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); }
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)); }
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]); }
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()); }
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']); }
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'); } }
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))); }); }
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); }
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); }
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'])); }
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."); }); }