where(function (Builder $query) { $query->whereNull('end'); $query->orWhere('end', '>', now()); }) ->get(); foreach ($events as $event) { try { $this->line('syncing '.$event->name); $this->syncEvent($event); } catch (\Exception $e) { $this->error('error syncing event '.$event->name.': '.$e->getMessage()); } } return Command::SUCCESS; } private function syncEvent(Event $event) { $episodes = $event->episodes()->whereBetween('start', [now()->sub(1, 'hour'), now()->add(30, 'minute')])->get(); if ($episodes->isEmpty()) return; $racerooms = $this->getRacetime($event->racetime_category); foreach ($episodes as $episode) { $rooms = $this->filterID($episode, $racerooms); //if (count($rooms) > 1) { // $rooms = $this->filterStartTime($episode, $rooms); //} if (count($rooms) > 1) { $rooms = $this->filterPlayerNames($episode, $rooms); } if (count($rooms) == 1) { $this->line(' - linking episode '.$episode->id.' with room '.$rooms[0]['name']); $episode->raceroom = 'https://racetime.gg'.$rooms[0]['url']; $episode->save(); } } } private function getRacetime($category) { if (isset($this->cat_cache[$category])) { return $this->cat_cache[$category]; } $category_data = HTTP::get('https://racetime.gg/'.$category.'/data'); $races_data = HTTP::get('https://racetime.gg/'.$category.'/races/data'); $this->cat_cache[$category] = array_merge(array_values($category_data['current_races']), array_values($races_data['races'])); return $this->cat_cache[$category]; } private function filterID(Episode $episode, $racerooms) { if (empty($episode->ext_id) || substr($episode->ext_id, 0, 3) != 'sg:') { return $racerooms; } $rooms = []; $id = substr($episode->ext_id, 3); foreach ($racerooms as $room) { if (strpos($room['info'], $id) !== false) { $rooms[] = $room; } } return empty($rooms) ? $racerooms : $rooms; } private function filterStartTime(Episode $episode, $racerooms) { if (empty($episode->start)) { return $racerooms; } $rooms = []; $from = Carbon::createFromFormat('Y-m-d H:i:s', $episode->start, 'UTC')->sub(1, 'hour'); $till = Carbon::createFromFormat('Y-m-d H:i:s', $episode->start, 'UTC')->add(1, 'hour'); foreach ($racerooms as $room) { $created = Carbon::createFromFormat('Y-m-d\TH:i:s.uP', $room['opened_at']); if ($created->isAfter($from) && $created->isBefore($till)) { $rooms[] = $room; } } return empty($rooms) ? $racerooms : $rooms; } private function filterPlayerNames(Episode $episode, $racerooms) { $pnames = []; foreach ($episode->players as $player) { $pname = trim($player->getName()); if (!empty($pname)) { $pnames[] = $pname; } } if (count($pnames) < 2) { return $racerooms; } $rooms = []; foreach ($racerooms as $room) { $missing = false; foreach ($pnames as $pname) { if (stripos($room['info'], $pname) === false) { $missing = true; break; } } if (!$missing) { $rooms[] = $room; } } return empty($rooms) ? $racerooms : $rooms; } private $cat_cache = []; }