Passed
Push — master ( 8b53ad...663a7d )
by Viktor
01:44
created

bot.*Twitch.AddStreamer   B

Complexity

Conditions 8

Size

Total Lines 32
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 26
nop 3
dl 0
loc 32
rs 7.3333
c 0
b 0
f 0
1
package bot
2
3
import (
4
	"encoding/json"
5
	"errors"
6
	"fmt"
7
	"github.com/bwmarrin/discordgo"
8
	"net/http"
9
	"strings"
10
	"time"
11
)
12
13
type Twitch struct {
0 ignored issues
show
introduced by
exported type Twitch should have comment or be unexported
Loading history...
14
	Streams []*TwitchStream
15
	Guilds  map[string]*TwitchGuild
16
	DB      *DBWorker
17
	Conf    *Config
18
	Discord *discordgo.Session
19
}
20
21
type TwitchGuild struct {
0 ignored issues
show
introduced by
exported type TwitchGuild should have comment or be unexported
Loading history...
22
	ID      string
23
	Streams []*TwitchStream
24
}
25
26
type TwitchStream struct {
0 ignored issues
show
introduced by
exported type TwitchStream should have comment or be unexported
Loading history...
27
	Login          string
28
	Guild          string
29
	Channel        string
30
	IsOnline       bool
31
	IsCustom       bool
32
	CustomMessage  string
33
	CustomImageURI string
34
}
35
36
type TwitchStreamResult struct {
0 ignored issues
show
introduced by
exported type TwitchStreamResult should have comment or be unexported
Loading history...
37
	Data []TwitchStreamData `json:"data"`
38
}
39
40
type TwitchStreamData struct {
0 ignored issues
show
introduced by
exported type TwitchStreamData should have comment or be unexported
Loading history...
41
	ID           string `json:"id"`
42
	UserID       string `json:"user_id"`
43
	UserName     string `json:"user_name"`
44
	GameID       string `json:"game_id"`
45
	Type         string `json:"type"`
46
	Title        string `json:"title"`
47
	Viewers      int    `json:"viewer_count"`
48
	Language     string `json:"language"`
49
	ThumbnailURL string `json:"thumbnail_url"`
50
}
51
52
type TwitchUserResult struct {
0 ignored issues
show
introduced by
exported type TwitchUserResult should have comment or be unexported
Loading history...
53
	Data []TwitchUserData `json:"data"`
54
}
55
56
type TwitchUserData struct {
0 ignored issues
show
introduced by
exported type TwitchUserData should have comment or be unexported
Loading history...
57
	ID              string `json:"id"`
58
	Login           string `json:"login"`
59
	Name            string `json:"display_name"`
60
	Type            string `json:"type"`
61
	BroadcasterType string `json:"broadcaster_type"`
62
	Description     string `json:"description"`
63
	ProfileImgURL   string `json:"profile_image_url"`
64
	OfflineImgURL   string `json:"offline_image_url"`
65
	Views           int    `json:"view_count"`
66
}
67
68
// TwitchInit makes new instance of twitch api worker
69
func TwitchInit(session *discordgo.Session, conf *Config, db *DBWorker) *Twitch {
70
	guilds := make(map[string]*TwitchGuild)
71
	var streams []*TwitchStream
72
	for _, g := range session.State.Guilds {
73
		guildStreams := db.GetTwitchStreams(g.ID)
74
		for _, s := range guildStreams {
75
			streams = append(streams, s)
76
		}
77
		guilds[g.ID] = &TwitchGuild{g.ID, guildStreams}
78
	}
79
	fmt.Printf("Loaded [%v] streamers", len(streams))
80
	return &Twitch{streams, guilds, db, conf, session}
81
}
82
83
// Update updates status of streamers and notify
84
func (t *Twitch) Update() {
85
	for _, s := range t.Streams {
86
		timeout := time.Duration(time.Duration(1) * time.Second)
87
		client := &http.Client{
88
			Timeout: time.Duration(timeout),
89
		}
90
		req, _ := http.NewRequest("GET", fmt.Sprintf("https://api.twitch.tv/helix/streams?user_login=%v", s.Login), nil)
91
		req.Header.Add("Client-ID", t.Conf.Twitch.ClientID)
92
		resp, err := client.Do(req)
93
		var result TwitchStreamResult
94
		if err == nil {
95
			err = json.NewDecoder(resp.Body).Decode(&result)
96
			if err != nil {
97
				t.DB.Log("Twitch", "", "Parsing Twitch API stream error")
98
				continue
99
			}
100
			if len(result.Data) > 0 {
101
				if s.IsOnline == false {
102
					s.IsOnline = true
103
					t.DB.UpdateStream(s)
104
					imgUrl := strings.Replace(result.Data[0].ThumbnailURL, "{width}", "720", -1)
0 ignored issues
show
introduced by
var imgUrl should be imgURL
Loading history...
105
					imgUrl = strings.Replace(imgUrl, "{height}", "480", -1)
106
					emb := NewEmbed(fmt.Sprintf("Hey %v is now live on https://www.twitch.tv/%v", result.Data[0].UserName, s.Login)).
107
						Field("Stream", result.Data[0].Title, true).
108
						AttachImgURL(imgUrl).
109
						Color(t.Conf.General.EmbedColor)
110
					_, _ = t.Discord.ChannelMessageSendEmbed(s.Channel, emb.GetEmbed())
111
				}
112
			} else {
113
				if s.IsOnline == true {
114
					s.IsOnline = false
115
					t.DB.UpdateStream(s)
116
				}
117
			}
118
119
		}
120
	}
121
}
122
123
// AddStreamer adds new streamer to list
124
func (t *Twitch) AddStreamer(guild, channel, login string) error {
125
	for _,s := range t.Streams {
126
		if s.Guild == guild && s.Login == login {
127
			return errors.New("streamer already exists")
128
		}
129
	}
130
	timeout := time.Duration(time.Duration(1) * time.Second)
131
	client := &http.Client{
132
		Timeout: time.Duration(timeout),
133
	}
134
	req, _ := http.NewRequest("GET", fmt.Sprintf("https://api.twitch.tv/helix/users?login=%v", login), nil)
135
	req.Header.Add("Client-ID", t.Conf.Twitch.ClientID)
136
	resp, err := client.Do(req)
137
	var result TwitchUserResult
138
	if err == nil {
139
		err = json.NewDecoder(resp.Body).Decode(&result)
140
		if err != nil {
141
			return errors.New("parsing streamer error")
142
		}
143
		if len(result.Data) > 0 {
144
			stream := TwitchStream{}
145
			stream.Login = login
146
			stream.Channel = channel
147
			stream.Guild = guild
148
			t.Streams = append(t.Streams, &stream)
149
			t.Guilds[guild].Streams = append(t.Guilds[guild].Streams, &stream)
150
			t.DB.AddStream(&stream)
151
		}
152
	} else {
153
		return errors.New("getting streamer error")
154
	}
155
	return nil
156
}
157
158
// RemoveStreamer removes streamer from list
159
func (t *Twitch) RemoveStreamer(login, guild string) error {
160
	complete := false
161
	for i, s := range t.Streams {
162
		if s.Guild == guild && s.Login == login {
163
			t.DB.RemoveStream(s)
164
			t.Streams[i] = t.Streams[len(t.Streams)-1]
165
			t.Streams[len(t.Streams)-1] = nil
166
			t.Streams = t.Streams[:len(t.Streams)-1]
167
			complete = true
168
		}
169
	}
170
	if _,ok := t.Guilds[guild]; ok {
171
		for i, s := range t.Guilds[guild].Streams {
172
			t.DB.RemoveStream(s)
173
			if s.Guild == guild && s.Login == login {
174
				t.Guilds[guild].Streams[i] = t.Guilds[guild].Streams[len(t.Guilds[guild].Streams)-1]
175
				t.Guilds[guild].Streams[len(t.Guilds[guild].Streams)-1] = nil
176
				t.Guilds[guild].Streams = t.Guilds[guild].Streams[:len(t.Guilds[guild].Streams)-1]
177
				complete = true
178
			}
179
		}
180
	} else {
181
		t.DB.Log("Twitch", guild,"Guild not found in array")
182
	}
183
	if !complete {
184
		return errors.New("streamer not found")
185
	}
186
	return nil
187
}
188