1<?php
2
3// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0.
4// See the LICENCE file in the repository root for full licence text.
5
6namespace App\Models;
7
8use Cache;
9use Exception;
10use GuzzleHttp\Client;
11
12class LivestreamCollection
13{
14 const FEATURED_CACHE_KEY = 'featuredStream:arr:v2';
15
16 private $streams;
17 private $token;
18
19 public static function promote($id)
20 {
21 Cache::forever(static::FEATURED_CACHE_KEY, (string) $id);
22 }
23
24 public function all()
25 {
26 if ($this->streams === null) {
27 $this->streams = cache_remember_mutexed('livestreams:arr:v2', 300, [], function () {
28 $streams = $this->downloadStreams()['data'] ?? [];
29
30 return array_map(fn ($stream) => new Twitch\Stream($stream), $streams);
31 });
32 }
33
34 return $this->streams;
35 }
36
37 public function downloadStreams()
38 {
39 return $this->download('streams?first=40&game_id=21465');
40 }
41
42 public function download($api)
43 {
44 $clientId = $GLOBALS['cfg']['osu']['twitch_client_id'];
45 if ($clientId === null) {
46 return;
47 }
48
49 $token = $this->token();
50 if (empty($token)) {
51 log_error(new Exception('failed getting token'));
52
53 return;
54 }
55
56 try {
57 $response = (new Client(['base_uri' => 'https://api.twitch.tv/helix/']))
58 ->request('GET', $api, ['headers' => [
59 'Client-Id' => $clientId,
60 'Authorization' => "Bearer {$token['access_token']}",
61 ]])
62 ->getBody()
63 ->getContents();
64 } catch (Exception $e) {
65 log_error($e);
66
67 return;
68 }
69
70 return json_decode($response, true);
71 }
72
73 public function featured()
74 {
75 $featuredStreamId = presence((string) Cache::get(static::FEATURED_CACHE_KEY));
76
77 if ($featuredStreamId !== null) {
78 foreach ($this->all() as $stream) {
79 if ($stream->data['id'] === $featuredStreamId) {
80 return $stream;
81 }
82 }
83 }
84 }
85
86 public function token()
87 {
88 if ($this->token === null) {
89 try {
90 $response = (new Client(['base_uri' => 'https://id.twitch.tv']))
91 ->request('POST', '/oauth2/token', ['query' => [
92 'client_id' => $GLOBALS['cfg']['osu']['twitch_client_id'],
93 'client_secret' => $GLOBALS['cfg']['osu']['twitch_client_secret'],
94 'grant_type' => 'client_credentials',
95 ]])
96 ->getBody()
97 ->getContents();
98
99 $this->token = json_decode($response, true);
100 } catch (Exception $e) {
101 log_error($e);
102
103 $this->token = [];
104 }
105 }
106
107 return $this->token;
108 }
109}