Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: lint errors #28

Merged
merged 3 commits into from
Jan 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ linters:
- nestif # reports deeply nested if statements
- nilerr # finds the code that returns nil even if it checks that the error is not nil
- nilnil # checks that there is no simultaneous return of nil error and an invalid value
- noctx # finds sending http request without context.Context
#- noctx # finds sending http request without context.Context
- nolintlint # reports ill-formed or insufficient nolint directives
- nonamedreturns # reports all named returns
- nosprintfhostport # checks for misuse of Sprintf to construct a host with port in a URL
Expand Down
31 changes: 24 additions & 7 deletions cmd/reddit-bot/discord.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"errors"
"fmt"
"html"
"os"
Expand All @@ -9,6 +10,7 @@ import (
"github.com/haveachin/reddit-bot/embed"
"github.com/haveachin/reddit-bot/reddit"
"github.com/haveachin/reddit-bot/regex"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)

Expand Down Expand Up @@ -36,6 +38,7 @@ type redditBot struct {
func newRedditBot(ppas []string) redditBot {
return redditBot{
redditPostPattern: regex.MustCompile(
//nolint:lll
`(?s)(?P<%s>.*)https:\/\/(?:www.|new.)?reddit.com\/r\/(?P<%s>.+)\/(?P<%s>comments|s)\/(?P<%s>[^\s\n\/]+)\/?[^\s\n]*\s?(?P<%s>.*)`,
captureNamePrefixMsg,
captureNameSubreddit,
Expand Down Expand Up @@ -116,7 +119,8 @@ func (rb redditBot) onRedditLinkMessage(s *discord.Session, m *discord.MessageCr
Color: colorReddit,
URL: "https://reddit.com" + post.Permalink,
Description: func() string {
if len(post.Text) > 1000 {
const maxTextLen = 1000
if len(post.Text) > maxTextLen {
return html.UnescapeString(fmt.Sprintf("%.1000s...", post.Text))
}
return post.Text
Expand All @@ -127,21 +131,35 @@ func (rb redditBot) onRedditLinkMessage(s *discord.Session, m *discord.MessageCr
},
}

rb.handlePost(s, m, logger, post, msg)
}

func (rb redditBot) handlePost(
s *discord.Session,
m *discord.MessageCreate,
logger zerolog.Logger,
post reddit.Post,
msg *discord.MessageSend,
) {
if post.WasRemoved {
_ = s.MessageReactionAdd(m.ChannelID, m.ID, emojiIDWasRemoved)
return
}

if post.IsVideo {
s.MessageReactionAdd(m.ChannelID, m.ID, emojiIDWorkingOnIt)
_ = s.MessageReactionAdd(m.ChannelID, m.ID, emojiIDWorkingOnIt)
logger.Info().Msg("Processing post video")
post.PostProcessingArgs = rb.postProcessingArgs
file, err := post.DownloadVideo()
if err != nil && file == nil {
logger.Error().
Err(err).
Msg("ffmpeg error")
_, _ = s.ChannelMessageSendReply(m.ChannelID, "Oh, no! Something went wrong while processing your video", m.Reference())
_, _ = s.ChannelMessageSendReply(
m.ChannelID,
"Oh, no! Something went wrong while processing your video",
m.Reference(),
)
_ = s.MessageReactionAdd(m.ChannelID, m.ID, emojiIDErrorFFMPEG)
return
}
Expand All @@ -152,7 +170,7 @@ func (rb redditBot) onRedditLinkMessage(s *discord.Session, m *discord.MessageCr

logger.Info().Msg("Embedding video file")
msg.File = &discord.File{
Name: postID + ".mp4",
Name: post.ID + ".mp4",
Reader: file,
}
} else if post.IsImage {
Expand All @@ -162,7 +180,7 @@ func (rb redditBot) onRedditLinkMessage(s *discord.Session, m *discord.MessageCr
}
} else if post.IsEmbed {
url, err := rb.embedder.Embed(&post)
if err == embed.ErrorNotImplemented {
if errors.Is(err, embed.ErrNotImplemented) {
logger.Warn().
Err(err).
Msg("embedded website (source) is not yet implemented")
Expand All @@ -175,8 +193,7 @@ func (rb redditBot) onRedditLinkMessage(s *discord.Session, m *discord.MessageCr
logger.Info().Msg("Sending embedded YouTube video")
}

_, err = s.ChannelMessageSendComplex(m.ChannelID, msg)
if err != nil {
if _, err := s.ChannelMessageSendComplex(m.ChannelID, msg); err != nil {
logger.Error().
Err(err).
Msg("Could not send embed")
Expand Down
2 changes: 1 addition & 1 deletion embed/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ package embed
import "errors"

var (
ErrorNotImplemented = errors.New("embed: embedded source (e.g. yt, gfycat, etc.) is not implemented")
ErrNotImplemented = errors.New("embed: embedded source (e.g. yt, gfycat, etc.) is not implemented")
)
6 changes: 3 additions & 3 deletions embed/matcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ type matcher struct {
urlTmpl string
}

// newMatcher returns a matcher for the provided source
// newMatcher returns a matcher for the provided source.
func newMatcher(s Source) (matcher, error) {
m := matcher{s: s}

Expand All @@ -22,13 +22,13 @@ func newMatcher(s Source) (matcher, error) {
m.p = pGfycat
m.urlTmpl = urlGfycat
default:
return m, ErrorNotImplemented
return m, ErrNotImplemented
}

return m, nil
}

// fetchID gets the ID of the embedded video
// fetchID gets the ID of the embedded video.
func (mchr matcher) fetchID(s string) (string, error) {
// match against html and fetch video id
m, err := mchr.p.FindStringSubmatch(s)
Expand Down
4 changes: 2 additions & 2 deletions embed/regex.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import "github.com/haveachin/reddit-bot/regex"

const patternID = "id"

// regex pattern of the sources
// Regex pattern of the sources.
const (
patternYoutube = `(?s).*https:\/\/(?:www\.)youtube\.com\/embed\/(?P<%s>.+?)[\?\\\/\&].*`
patternGfycat = `(?s).*url=https%3A%2F%2Fgfycat\.com%2F(?P<%s>.+?)\&.*`
)

// compiled patterns
// Compiled patterns.
var (
pYoutube = regex.MustCompile(patternYoutube, patternID)
pGfycat = regex.MustCompile(patternGfycat, patternID)
Expand Down
2 changes: 1 addition & 1 deletion embed/source.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package embed

type Source string

// possible sources that are already implemented; to be expanded
// possible sources that are already implemented; to be expanded.
const (
Youtube Source = "youtube.com"
Gfycat Source = "gfycat.com"
Expand Down
2 changes: 1 addition & 1 deletion embed/tmpl.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package embed

// link templates that will be posted in discord
// link templates that will be posted in discord.
const (
urlYoutube = `https://www.youtube.com/watch?v=%s`
urlGfycat = `https://gfycat.com/%s`
Expand Down
10 changes: 4 additions & 6 deletions reddit/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,11 @@ import (
"time"
)

var defaultClient http.Client
const cientTimeout = time.Second * 10

func init() {
defaultClient = http.Client{
Transport: &headerTransport{},
Timeout: time.Second * 5,
}
var defaultClient = http.Client{
Transport: &headerTransport{},
Timeout: cientTimeout,
}

type headerTransport struct{}
Expand Down
4 changes: 2 additions & 2 deletions reddit/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ package reddit
import "errors"

var (
// ErrBadResponse indicates a bad or unexpected response from the webapi
ErrBadResponse error = errors.New("bad response")
// ErrBadResponse indicates a bad or unexpected response from the webapi.
ErrBadResponse = errors.New("bad response")
)
55 changes: 31 additions & 24 deletions reddit/post.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,20 @@ import (
type PostType string

const (
PostTypeImage PostType = "image"
// PostTypeImage means an image that is hosted on Reddit.
PostTypeImage PostType = "image"
// PostTypeVideoHosted is a video that is hosted on Reddit.
PostTypeVideoHosted PostType = "hosted:video"
PostTypeVideoEmbed PostType = "rich:video"
PostTypeSelf PostType = "self"
PostTypeRedGif PostType = "redgifs.com"
PostTypeRedGifV3 PostType = "v3.redgifs.com"
// PostTypeVideoEmbed is a video that is hosted on an external platform.
// Normally these videos are embedded via an iFrame.
PostTypeVideoEmbed PostType = "rich:video"
PostTypeSelf PostType = "self"

PostTypeRedGif PostType = "redgifs.com"
PostTypeRedGifV3 PostType = "v3.redgifs.com"
)

// Post is a very simplified variation of a JSON response given from the reddit api
// Post is a very simplified variation of a JSON response given from the reddit api.
type Post struct {
ID string
Title string
Expand All @@ -43,7 +48,7 @@ type Embed struct {
Type string
} // html embedded media

type postJSON []struct {
type postDTO []struct {
Data struct {
Children []struct {
Data struct {
Expand Down Expand Up @@ -74,21 +79,28 @@ const (
CommentsLinkType = LinkType("comments")
)

func fetchPost(postID string) (*http.Response, error) {
func fetchPost(postID string) (postDTO, error) {
const apiPostURLf string = "https://www.reddit.com/%s/.json"
url := fmt.Sprintf(apiPostURLf, postID)

for i := 3; i > 0; i-- {
resp, err := defaultClient.Get(url)
if err != nil {
return nil, err
return postDTO{}, err
}

if resp.StatusCode != http.StatusOK {
resp.Body.Close()
continue
}

return resp, nil
dto := postDTO{}
if err := json.NewDecoder(resp.Body).Decode(&dto); err != nil {
return postDTO{}, err
}
resp.Body.Close()

return dto, nil
}
return nil, ErrBadResponse
}
Expand All @@ -100,39 +112,34 @@ func ResolvePostURLFromShareID(subreddit, shareID string) (string, error) {
if err != nil {
return "", err
}
resp.Body.Close()

return resp.Request.URL.String(), nil
}

// PostByID fetches the post with the corresponding ID
// A post ID is normally six characters long
// PostByID fetches the post with the corresponding ID.
// A post ID is normally six characters long.
func PostByID(postID string) (Post, error) {
resp, err := fetchPost(postID)
dto, err := fetchPost(postID)
if err != nil {
return Post{}, err
}

postJSON := postJSON{}

if err := json.NewDecoder(resp.Body).Decode(&postJSON); err != nil {
return Post{}, err
}

if len(postJSON) <= 0 {
if len(dto) == 0 {
return Post{}, ErrBadResponse
}

if len(postJSON[0].Data.Children) <= 0 {
if len(dto[0].Data.Children) == 0 {
return Post{}, ErrBadResponse
}

data := postJSON[0].Data.Children[0].Data
data := dto[0].Data.Children[0].Data
isVideo := data.IsVideo ||
data.Media.Type == string(PostTypeRedGif) ||
data.Media.Type == string(PostTypeRedGifV3)
isEmbed := data.PostHint == string(PostTypeVideoEmbed) // TODO: change this
isImage := data.PostHint == string(PostTypeImage)
isImage = isImage || (!isEmbed && !isVideo && data.URL != "")
isImage := data.PostHint == string(PostTypeImage) ||
(!isEmbed && !isVideo && data.URL != "")
wasRemoved := data.RemovedByCategory != "" && data.URL == ""
return Post{
ID: postID,
Expand Down
6 changes: 3 additions & 3 deletions regex/match.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package regex
import "fmt"

// Match represents a (sub)match as defined by the go regexp package.
// It stores a pointer to the underlying regex pattern as well as the capture groups' contents
// It stores a pointer to the underlying regex pattern as well as the capture groups' contents.
type Match struct {
Pattern *Pattern
groups []string
Expand All @@ -12,14 +12,14 @@ type Match struct {
// Capture returns an individual capture group of the given Match m in the
// order of their declaration in the pattern of m.Pattern.
// Beware that m.Capture(0) returns the entire match, so m.Capture(1) will
// return the first capture group of the match and so forth
// return the first capture group of the match and so forth.
func (m *Match) Capture(index int) string {
return m.groups[index]
}

// CaptureByName will return the capture group of the given Match m
// with the identifier name as specified in the pattern m.Pattern.
// This method will panic if name is not a valid name of any capture group of m.Pattern
// This method will panic if name is not a valid name of any capture group of m.Pattern.
func (m *Match) CaptureByName(name string) string {
names := m.Pattern.regex.SubexpNames()
for i, group := range m.groups {
Expand Down
2 changes: 1 addition & 1 deletion regex/pattern.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func MustCompile(pattern string, names ...string) Pattern {
}

// FindStringSubmatch works like *regexp.Regexp.FindStringSubmatch(...)
// but returns an error if s can't be matched against the pattern p
// but returns an error if s can't be matched against the pattern p.
func (p *Pattern) FindStringSubmatch(s string) (Match, error) {
if !p.regex.MatchString(s) {
return Match{}, fmt.Errorf("regex: no matches found in provided string s: %s", s)
Expand Down
Loading