--- /dev/null
+<?php
+
+namespace App\Console\Commands;
+
+use App\Models\Episode;
+use App\Models\Event;
+use Carbon\Carbon;
+use Illuminate\Console\Command;
+use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Support\Facades\Http;
+
+
+class SyncLadder extends Command {
+
+ /**
+ * The name and signature of the console command.
+ *
+ * @var string
+ */
+ protected $signature = 'sync:ladder';
+
+ /**
+ * The console command description.
+ *
+ * @var string
+ */
+ protected $description = 'Synchronize Ladder schedule';
+
+
+ /**
+ * Execute the console command.
+ *
+ * @return int
+ */
+ public function handle() {
+ $events = Event::where('external_schedule', 'LIKE', 'ladder:%')
+ ->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());
+ }
+ }
+ }
+
+ private function syncEvent(Event $event) {
+ $ladderHandle = substr($event->external_schedule, 7);
+ $ladderSchedule = Http::get('https://alttprladder.com/api/v1/PublicApi/GetSchedule', [
+ 'season_id' => $ladderHandle,
+ ])->json();
+ foreach ($ladderSchedule as $ladderEntry) {
+ try {
+ $this->syncSchedule($event, $ladderEntry);
+ } catch (Exception $e) {
+ $this->error('error syncing episode '.$ladderEntry['race_id'].': '.$e->getMessage());
+ }
+ }
+ }
+
+ private function syncSchedule(Event $event, $ladderEntry) {
+ $ext_id = 'ladder:'.$ladderEntry['race_id'].':'.$ladderEntry['RaceName'];
+ $episode = Episode::firstWhere('ext_id', '=', $ext_id);
+ if (!$episode) {
+ $episode = new Episode();
+ $episode->ext_id = $ext_id;
+ }
+ $episode->event()->associate($event);
+ $episode->title = $ladderEntry['Mode'];
+ $episode->start = Carbon::createFromFormat('m/d/y h a', $ladderEntry['StartTime'], 'America/Detroit')->setTimezone('UTC');
+ $episode->estimate = 2 * 60 * 60;
+ $episode->confirmed = true;
+ $episode->save();
+ }
+
+}