From 3617955bc5e83293ec9a5217a5d544b74e666455 Mon Sep 17 00:00:00 2001 From: bytedream Date: Sat, 16 Apr 2022 00:17:36 +0200 Subject: [PATCH] Fix typos & add more comments --- README.md | 2 +- cmd/crunchyroll-go/cmd/archive.go | 8 ++++---- cmd/crunchyroll-go/cmd/utils.go | 2 +- crunchyroll.go | 30 +++++++++++++++--------------- downloader.go | 30 +++++++++++++++--------------- episode.go | 10 ++++++---- error.go | 2 +- format.go | 7 ++++--- movie_listing.go | 8 +++++--- season.go | 6 ++++-- stream.go | 7 ++++--- subtitle.go | 2 ++ url.go | 4 ++-- utils/locale.go | 5 +++-- utils/sort.go | 12 +++++++----- video.go | 15 ++++++++------- 16 files changed, 82 insertions(+), 68 deletions(-) diff --git a/README.md b/README.md index 64c7cd9..8bfa193 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ _Before reading_: Because of the huge functionality not all cases can be covered ### Login -Before you can do something, you have to login first. +Before you can do something, you have to log in first. This can be performed via crunchyroll account email and password. diff --git a/cmd/crunchyroll-go/cmd/archive.go b/cmd/crunchyroll-go/cmd/archive.go index 9f5df94..23c2c68 100644 --- a/cmd/crunchyroll-go/cmd/archive.go +++ b/cmd/crunchyroll-go/cmd/archive.go @@ -728,7 +728,7 @@ func (tc *tarCompress) Close() error { err = tc.dst.Close() if err != nil && err2 != nil { - // best way to show double errors at once that i've found + // best way to show double errors at once that I've found return fmt.Errorf("%v\n%v", err, err2) } else if err == nil && err2 != nil { err = err2 @@ -750,11 +750,11 @@ func (tc *tarCompress) NewFile(information formatInformation) (io.WriteCloser, e ModTime: time.Now(), Mode: 0644, Typeflag: tar.TypeReg, - // fun fact: i did not set the size for quiet some time because i thought that it isn't - // required. well because of this i debugged this part for multiple hours because without + // fun fact: I did not set the size for quiet some time because I thought that it isn't + // required. well because of this I debugged this part for multiple hours because without // proper size information only a tiny amount gets copied into the tar (or zip) writer. // this is also the reason why the file content is completely copied into a buffer before - // writing it to the writer. i could bypass this and save some memory but this requires + // writing it to the writer. I could bypass this and save some memory but this requires // some rewriting and im nearly at the (planned) finish for version 2 so nah in the future // maybe Size: int64(buf.Len()), diff --git a/cmd/crunchyroll-go/cmd/utils.go b/cmd/crunchyroll-go/cmd/utils.go index 4d3faad..42fe7de 100644 --- a/cmd/crunchyroll-go/cmd/utils.go +++ b/cmd/crunchyroll-go/cmd/utils.go @@ -403,7 +403,7 @@ func (dp *downloadProgress) update(msg string, permanent bool) { pre := fmt.Sprintf("%s%s [", dp.Prefix, msg) post := fmt.Sprintf("]%4d%% %8d/%d", int(percentage), dp.Current, dp.Total) - // i don't really know why +2 is needed here but without it the Printf below would not print to the line end + // I don't really know why +2 is needed here but without it the Printf below would not print to the line end progressWidth := terminalWidth() - len(pre) - len(post) + 2 repeatCount := int(percentage / float32(100) * float32(progressWidth)) // it can be lower than zero when the terminal is very tiny diff --git a/crunchyroll.go b/crunchyroll.go index cc21b8b..d6d2744 100644 --- a/crunchyroll.go +++ b/crunchyroll.go @@ -13,7 +13,7 @@ import ( "strconv" ) -// LOCALE represents a locale / language +// LOCALE represents a locale / language. type LOCALE string const ( @@ -31,16 +31,16 @@ const ( ) type Crunchyroll struct { - // Client is the http.Client to perform all requests over + // Client is the http.Client to perform all requests over. Client *http.Client - // Context can be used to stop requests with Client and is context.Background by default + // Context can be used to stop requests with Client and is context.Background by default. Context context.Context - // Locale specifies in which language all results should be returned / requested + // Locale specifies in which language all results should be returned / requested. Locale LOCALE - // SessionID is the crunchyroll session id which was used for authentication + // SessionID is the crunchyroll session id which was used for authentication. SessionID string - // Config stores parameters which are needed by some api calls + // Config stores parameters which are needed by some api calls. Config struct { TokenType string AccessToken string @@ -56,11 +56,11 @@ type Crunchyroll struct { MaturityRating string } - // If cache is true, internal caching is enabled + // If cache is true, internal caching is enabled. cache bool } -// LoginWithCredentials logs in via crunchyroll username or email and password +// LoginWithCredentials logs in via crunchyroll username or email and password. func LoginWithCredentials(user string, password string, locale LOCALE, client *http.Client) (*Crunchyroll, error) { sessionIDEndpoint := fmt.Sprintf("https://api.crunchyroll.com/start_session.0.json?version=1.0&access_token=%s&device_type=%s&device_id=%s", "LNDJgOit5yaRIWN", "com.crunchyroll.windows.desktop", "Az2srGnChW65fuxYz2Xxl1GcZQgtGgI") @@ -87,7 +87,7 @@ func LoginWithCredentials(user string, password string, locale LOCALE, client *h } // LoginWithSessionID logs in via a crunchyroll session id. -// Session ids are automatically generated as a cookie when visiting https://www.crunchyroll.com +// Session ids are automatically generated as a cookie when visiting https://www.crunchyroll.com. func LoginWithSessionID(sessionID string, locale LOCALE, client *http.Client) (*Crunchyroll, error) { crunchy := &Crunchyroll{ Client: client, @@ -205,7 +205,7 @@ func LoginWithSessionID(sessionID string, locale LOCALE, client *http.Client) (* return crunchy, nil } -// request is a base function which handles api requests +// request is a base function which handles api requests. func (c *Crunchyroll) request(endpoint string) (*http.Response, error) { req, err := http.NewRequest(http.MethodGet, endpoint, nil) if err != nil { @@ -241,7 +241,7 @@ func (c *Crunchyroll) request(endpoint string) (*http.Response, error) { } // IsCaching returns if data gets cached or not. -// See SetCaching for more information +// See SetCaching for more information. func (c *Crunchyroll) IsCaching() bool { return c.cache } @@ -249,12 +249,12 @@ func (c *Crunchyroll) IsCaching() bool { // SetCaching enables or disables internal caching of requests made. // Caching is enabled by default. // If it is disabled the already cached data still gets called. -// The best way to prevent this is to create a complete new Crunchyroll struct +// The best way to prevent this is to create a complete new Crunchyroll struct. func (c *Crunchyroll) SetCaching(caching bool) { c.cache = caching } -// Search searches a query and returns all found series and movies within the given limit +// Search searches a query and returns all found series and movies within the given limit. func (c *Crunchyroll) Search(query string, limit uint) (s []*Series, m []*Movie, err error) { searchEndpoint := fmt.Sprintf("https://beta-api.crunchyroll.com/content/v1/search?q=%s&n=%d&type=&locale=%s", query, limit, c.Locale) @@ -397,7 +397,7 @@ func ParseEpisodeURL(url string) (seriesName, title string, episodeNumber int, w return } -// ParseBetaSeriesURL tries to extract the season id of the given crunchyroll beta url, pointing to a season +// ParseBetaSeriesURL tries to extract the season id of the given crunchyroll beta url, pointing to a season. func ParseBetaSeriesURL(url string) (seasonId string, ok bool) { pattern := regexp.MustCompile(`(?m)^https?://(www\.)?beta\.crunchyroll\.com/(\w{2}/)?series/(?P\w+).*`) if urlMatch := pattern.FindAllStringSubmatch(url, -1); len(urlMatch) != 0 { @@ -408,7 +408,7 @@ func ParseBetaSeriesURL(url string) (seasonId string, ok bool) { return } -// ParseBetaEpisodeURL tries to extract the episode id of the given crunchyroll beta url, pointing to an episode +// ParseBetaEpisodeURL tries to extract the episode id of the given crunchyroll beta url, pointing to an episode. func ParseBetaEpisodeURL(url string) (episodeId string, ok bool) { pattern := regexp.MustCompile(`(?m)^https?://(www\.)?beta\.crunchyroll\.com/(\w{2}/)?watch/(?P\w+).*`) if urlMatch := pattern.FindAllStringSubmatch(url, -1); len(urlMatch) != 0 { diff --git a/downloader.go b/downloader.go index be625b3..74546da 100644 --- a/downloader.go +++ b/downloader.go @@ -20,7 +20,7 @@ import ( ) // NewDownloader creates a downloader with default settings which should -// fit the most needs +// fit the most needs. func NewDownloader(context context.Context, writer io.Writer, goroutines int, onSegmentDownload func(segment *m3u8.MediaSegment, current, total int, file *os.File) error) Downloader { tmp, _ := os.MkdirTemp("", "crunchy_") @@ -43,12 +43,12 @@ type Downloader struct { // The files will be placed directly into the root of the directory. // If empty a random temporary directory on the system's default tempdir // will be created. - // If the directory does not exist, it will be created + // If the directory does not exist, it will be created. TempDir string // If DeleteTempAfter is true, the temp directory gets deleted afterwards. // Note that in case of a hard signal exit (os.Interrupt, ...) the directory // will NOT be deleted. In such situations try to catch the signal and - // cancel Context + // cancel Context. DeleteTempAfter bool // Context to control the download process with. @@ -56,7 +56,7 @@ type Downloader struct { // process. So it is not recommend stopping the program immediately after calling // the cancel function. It's better when canceling it and then exit the program // when Format.Download throws an error. See the signal handling section in - // cmd/crunchyroll-go/cmd/download.go for an example + // cmd/crunchyroll-go/cmd/download.go for an example. Context context.Context // Goroutines is the number of goroutines to download segments with @@ -65,11 +65,11 @@ type Downloader struct { // A method to call when a segment was downloaded. // Note that the segments are downloaded asynchronously (depending on the count of // Goroutines) and the function gets called asynchronously too, so for example it is - // first called on segment 1, then segment 254, then segment 3 and so on + // first called on segment 1, then segment 254, then segment 3 and so on. OnSegmentDownload func(segment *m3u8.MediaSegment, current, total int, file *os.File) error // If LockOnSegmentDownload is true, only one OnSegmentDownload function can be called at // once. Normally (because of the use of goroutines while downloading) multiple could get - // called simultaneously + // called simultaneously. LockOnSegmentDownload bool // If FFmpegOpts is not nil, ffmpeg will be used to merge and convert files. @@ -82,7 +82,7 @@ type Downloader struct { FFmpegOpts []string } -// download's the given format +// download's the given format. func (d Downloader) download(format *Format) error { if err := format.InitVideo(); err != nil { return err @@ -109,7 +109,7 @@ func (d Downloader) download(format *Format) error { } // mergeSegments reads every file in tempDir and writes their content to Downloader.Writer. -// The given output file gets created or overwritten if already existing +// The given output file gets created or overwritten if already existing. func (d Downloader) mergeSegments(files []string) error { for _, file := range files { select { @@ -132,7 +132,7 @@ func (d Downloader) mergeSegments(files []string) error { // mergeSegmentsFFmpeg reads every file in tempDir and merges their content to the outputFile // with ffmpeg (https://ffmpeg.org/). -// The given output file gets created or overwritten if already existing +// The given output file gets created or overwritten if already existing. func (d Downloader) mergeSegmentsFFmpeg(files []string) error { list, err := os.Create(filepath.Join(d.TempDir, "list.txt")) if err != nil { @@ -214,13 +214,13 @@ func (d Downloader) mergeSegmentsFFmpeg(files []string) error { // After every segment download onSegmentDownload will be called with: // the downloaded segment, the current position, the total size of segments to download, // the file where the segment content was written to an error (if occurred). -// The filename is always .ts +// The filename is always .ts. // // Short explanation: // The actual crunchyroll video is split up in multiple segments (or video files) which // have to be downloaded and merged after to generate a single video file. // And this function just downloads each of this segment into the given directory. -// See https://en.wikipedia.org/wiki/MPEG_transport_stream for more information +// See https://en.wikipedia.org/wiki/MPEG_transport_stream for more information. func (d Downloader) downloadSegments(format *Format) ([]string, error) { if err := format.InitVideo(); err != nil { return nil, err @@ -318,7 +318,7 @@ func (d Downloader) downloadSegments(format *Format) ([]string, error) { } } -// getCrypt extracts the key and iv of a m3u8 segment and converts it into a cipher.Block and an iv byte sequence +// getCrypt extracts the key and iv of a m3u8 segment and converts it into a cipher.Block and an iv byte sequence. func getCrypt(format *Format, segment *m3u8.MediaSegment) (block cipher.Block, iv []byte, err error) { var resp *http.Response @@ -341,7 +341,7 @@ func getCrypt(format *Format, segment *m3u8.MediaSegment) (block cipher.Block, i return block, iv, nil } -// downloadSegment downloads a segment, decrypts it and names it after the given index +// downloadSegment downloads a segment, decrypts it and names it after the given index. func (d Downloader) downloadSegment(format *Format, segment *m3u8.MediaSegment, filename string, block cipher.Block, iv []byte) (*os.File, error) { // every segment is aes-128 encrypted and has to be decrypted when downloaded content, err := d.decryptSegment(format.crunchy.Client, segment, block, iv) @@ -361,7 +361,7 @@ func (d Downloader) downloadSegment(format *Format, segment *m3u8.MediaSegment, return file, nil } -// https://github.com/oopsguy/m3u8/blob/4150e93ec8f4f8718875a02973f5d792648ecb97/tool/crypt.go#L25 +// https://github.com/oopsguy/m3u8/blob/4150e93ec8f4f8718875a02973f5d792648ecb97/tool/crypt.go#L25. func (d Downloader) decryptSegment(client *http.Client, segment *m3u8.MediaSegment, block cipher.Block, iv []byte) ([]byte, error) { req, err := http.NewRequestWithContext(d.Context, http.MethodGet, segment.URI, nil) if err != nil { @@ -387,7 +387,7 @@ func (d Downloader) decryptSegment(client *http.Client, segment *m3u8.MediaSegme return raw, nil } -// https://github.com/oopsguy/m3u8/blob/4150e93ec8f4f8718875a02973f5d792648ecb97/tool/crypt.go#L47 +// https://github.com/oopsguy/m3u8/blob/4150e93ec8f4f8718875a02973f5d792648ecb97/tool/crypt.go#L47. func (d Downloader) pkcs5UnPadding(origData []byte) []byte { length := len(origData) unPadding := int(origData[length-1]) diff --git a/episode.go b/episode.go index d9814cb..a25844c 100644 --- a/episode.go +++ b/episode.go @@ -9,6 +9,7 @@ import ( "time" ) +// Episode contains all information about an episode. type Episode struct { crunchy *Crunchyroll @@ -74,7 +75,7 @@ type Episode struct { StreamID string } -// EpisodeFromID returns an episode by its api id +// EpisodeFromID returns an episode by its api id. func EpisodeFromID(crunchy *Crunchyroll, id string) (*Episode, error) { resp, err := crunchy.request(fmt.Sprintf("https://beta-api.crunchyroll.com/cms/v2/%s/%s/%s/episodes/%s?locale=%s&Signature=%s&Policy=%s&Key-Pair-Id=%s", crunchy.Config.CountryCode, @@ -111,7 +112,8 @@ func EpisodeFromID(crunchy *Crunchyroll, id string) (*Episode, error) { // AudioLocale returns the audio locale of the episode. // Every episode in a season (should) have the same audio locale, -// so if you want to get the audio locale of a season, just call this method on the first episode of the season +// so if you want to get the audio locale of a season, just call +// this method on the first episode of the season. func (e *Episode) AudioLocale() (LOCALE, error) { streams, err := e.Streams() if err != nil { @@ -120,7 +122,7 @@ func (e *Episode) AudioLocale() (LOCALE, error) { return streams[0].AudioLocale, nil } -// GetFormat returns the format which matches the given resolution and subtitle locale +// GetFormat returns the format which matches the given resolution and subtitle locale. func (e *Episode) GetFormat(resolution string, subtitle LOCALE, hardsub bool) (*Format, error) { streams, err := e.Streams() if err != nil { @@ -186,7 +188,7 @@ func (e *Episode) GetFormat(resolution string, subtitle LOCALE, hardsub bool) (* return nil, fmt.Errorf("no matching resolution found") } -// Streams returns all streams which are available for the episode +// Streams returns all streams which are available for the episode. func (e *Episode) Streams() ([]*Stream, error) { if e.children != nil { return e.children, nil diff --git a/error.go b/error.go index 79ce1c0..b3e887f 100644 --- a/error.go +++ b/error.go @@ -3,7 +3,7 @@ package crunchyroll import "fmt" // AccessError is an error which will be returned when some special sort of api request fails. -// See Crunchyroll.request when the error gets used +// See Crunchyroll.request when the error gets used. type AccessError struct { error diff --git a/format.go b/format.go index ec94c16..6f17bf7 100644 --- a/format.go +++ b/format.go @@ -11,11 +11,12 @@ const ( MOVIE = "movies" ) +// Format contains detailed information about an episode video stream. type Format struct { crunchy *Crunchyroll ID string - // FormatType represents if the format parent is an episode or a movie + // FormatType represents if the format parent is an episode or a movie. FormatType FormatType Video *m3u8.Variant AudioLocale LOCALE @@ -27,7 +28,7 @@ type Format struct { // The Format.Video.Chunklist pointer is, by default, nil because an additional // request must be made to receive its content. The request is not made when // initializing a Format struct because it would probably cause an intense overhead -// since Format.Video.Chunklist is only used sometimes +// since Format.Video.Chunklist is only used sometimes. func (f *Format) InitVideo() error { if f.Video.Chunklist == nil { resp, err := f.crunchy.Client.Get(f.Video.URI) @@ -45,7 +46,7 @@ func (f *Format) InitVideo() error { return nil } -// Download downloads the Format with the via Downloader specified options +// Download downloads the Format with the via Downloader specified options. func (f *Format) Download(downloader Downloader) error { return downloader.download(f) } diff --git a/movie_listing.go b/movie_listing.go index 9646c18..63d7fab 100644 --- a/movie_listing.go +++ b/movie_listing.go @@ -5,6 +5,8 @@ import ( "fmt" ) +// MovieListing contains information about something which is called +// movie listing. I don't know what this means thb. type MovieListing struct { crunchy *Crunchyroll @@ -36,7 +38,7 @@ type MovieListing struct { AvailabilityNotes string `json:"availability_notes"` } -// MovieListingFromID returns a movie listing by its api id +// MovieListingFromID returns a movie listing by its api id. func MovieListingFromID(crunchy *Crunchyroll, id string) (*MovieListing, error) { resp, err := crunchy.request(fmt.Sprintf("https://beta-api.crunchyroll.com/cms/v2/%s/%s/%s/movie_listing/%s&locale=%s&Signature=%s&Policy=%s&Key-Pair-Id=%s", crunchy.Config.CountryCode, @@ -65,7 +67,7 @@ func MovieListingFromID(crunchy *Crunchyroll, id string) (*MovieListing, error) return movieListing, nil } -// AudioLocale is same as Episode.AudioLocale +// AudioLocale is same as Episode.AudioLocale. func (ml *MovieListing) AudioLocale() (LOCALE, error) { resp, err := ml.crunchy.request(fmt.Sprintf("https://beta-api.crunchyroll.com/cms/v2/%s/%s/%s/videos/%s/streams?locale=%s&Signature=%s&Policy=%s&Key-Pair-Id=%s", ml.crunchy.Config.CountryCode, @@ -86,7 +88,7 @@ func (ml *MovieListing) AudioLocale() (LOCALE, error) { return LOCALE(jsonBody["audio_locale"].(string)), nil } -// Streams returns all streams which are available for the movie listing +// Streams returns all streams which are available for the movie listing. func (ml *MovieListing) Streams() ([]*Stream, error) { return fromVideoStreams(ml.crunchy, fmt.Sprintf("https://beta-api.crunchyroll.com/cms/v2/%s/%s/%s/videos/%s/streams?locale=%s&Signature=%s&Policy=%s&Key-Pair-Id=%s", ml.crunchy.Config.CountryCode, diff --git a/season.go b/season.go index c9a17da..825a816 100644 --- a/season.go +++ b/season.go @@ -6,6 +6,7 @@ import ( "regexp" ) +// Season contains information about an anime season. type Season struct { crunchy *Crunchyroll @@ -41,7 +42,7 @@ type Season struct { SubtitleLocales []LOCALE } -// SeasonFromID returns a season by its api id +// SeasonFromID returns a season by its api id. func SeasonFromID(crunchy *Crunchyroll, id string) (*Season, error) { resp, err := crunchy.Client.Get(fmt.Sprintf("https://beta-api.crunchyroll.com/cms/v2/%s/%s/%s/seasons/%s?locale=%s&Signature=%s&Policy=%s&Key-Pair-Id=%s", crunchy.Config.CountryCode, @@ -70,6 +71,7 @@ func SeasonFromID(crunchy *Crunchyroll, id string) (*Season, error) { return season, nil } +// AudioLocale returns the audio locale of the season. func (s *Season) AudioLocale() (LOCALE, error) { episodes, err := s.Episodes() if err != nil { @@ -78,7 +80,7 @@ func (s *Season) AudioLocale() (LOCALE, error) { return episodes[0].AudioLocale() } -// Episodes returns all episodes which are available for the season +// Episodes returns all episodes which are available for the season. func (s *Season) Episodes() (episodes []*Episode, err error) { if s.children != nil { return s.children, nil diff --git a/stream.go b/stream.go index 5fe0f96..d8957e6 100644 --- a/stream.go +++ b/stream.go @@ -8,6 +8,7 @@ import ( "regexp" ) +// Stream contains information about all available video stream of an episode. type Stream struct { crunchy *Crunchyroll @@ -22,7 +23,7 @@ type Stream struct { streamURL string } -// StreamsFromID returns a stream by its api id +// StreamsFromID returns a stream by its api id. func StreamsFromID(crunchy *Crunchyroll, id string) ([]*Stream, error) { return fromVideoStreams(crunchy, fmt.Sprintf("https://beta-api.crunchyroll.com/cms/v2/%s/%s/%s/videos/%s/streams?locale=%s&Signature=%s&Policy=%s&Key-Pair-Id=%s", crunchy.Config.CountryCode, @@ -35,7 +36,7 @@ func StreamsFromID(crunchy *Crunchyroll, id string) ([]*Stream, error) { crunchy.Config.KeyPairID)) } -// Formats returns all formats which are available for the stream +// Formats returns all formats which are available for the stream. func (s *Stream) Formats() ([]*Format, error) { if s.children != nil { return s.children, nil @@ -70,7 +71,7 @@ func (s *Stream) Formats() ([]*Format, error) { return formats, nil } -// fromVideoStreams returns all streams which are accessible via the endpoint +// fromVideoStreams returns all streams which are accessible via the endpoint. func fromVideoStreams(crunchy *Crunchyroll, endpoint string) (streams []*Stream, err error) { resp, err := crunchy.request(endpoint) if err != nil { diff --git a/subtitle.go b/subtitle.go index 6a33e14..164b56e 100644 --- a/subtitle.go +++ b/subtitle.go @@ -5,6 +5,7 @@ import ( "net/http" ) +// Subtitle contains the information about a video subtitle. type Subtitle struct { crunchy *Crunchyroll @@ -13,6 +14,7 @@ type Subtitle struct { Format string `json:"format"` } +// Save writes the subtitle to the given io.Writer. func (s Subtitle) Save(writer io.Writer) error { req, err := http.NewRequestWithContext(s.crunchy.Context, http.MethodGet, s.URL, nil) if err != nil { diff --git a/url.go b/url.go index 5abf370..32603fc 100644 --- a/url.go +++ b/url.go @@ -5,7 +5,7 @@ import ( ) // ExtractEpisodesFromUrl extracts all episodes from an url. -// If audio is not empty, the episodes gets filtered after the given locale +// If audio is not empty, the episodes gets filtered after the given locale. func (c *Crunchyroll) ExtractEpisodesFromUrl(url string, audio ...LOCALE) ([]*Episode, error) { series, episodes, err := c.ParseUrl(url) if err != nil { @@ -78,7 +78,7 @@ func (c *Crunchyroll) ExtractEpisodesFromUrl(url string, audio ...LOCALE) ([]*Ep } // ParseUrl parses the given url into a series or episode. -// The returning episode is a slice because non-beta urls have the same episode with different languages +// The returning episode is a slice because non-beta urls have the same episode with different languages. func (c *Crunchyroll) ParseUrl(url string) (*Series, []*Episode, error) { if seriesId, ok := ParseBetaSeriesURL(url); ok { series, err := SeriesFromID(c, seriesId) diff --git a/utils/locale.go b/utils/locale.go index 8d78912..111496b 100644 --- a/utils/locale.go +++ b/utils/locale.go @@ -4,6 +4,7 @@ import ( "github.com/ByteDream/crunchyroll-go" ) +// AllLocales is an array of all available locales. var AllLocales = []crunchyroll.LOCALE{ crunchyroll.JP, crunchyroll.US, @@ -18,7 +19,7 @@ var AllLocales = []crunchyroll.LOCALE{ crunchyroll.AR, } -// ValidateLocale validates if the given locale actually exist +// ValidateLocale validates if the given locale actually exist. func ValidateLocale(locale crunchyroll.LOCALE) bool { for _, l := range AllLocales { if l == locale { @@ -28,7 +29,7 @@ func ValidateLocale(locale crunchyroll.LOCALE) bool { return false } -// LocaleLanguage returns the country by its locale +// LocaleLanguage returns the country by its locale. func LocaleLanguage(locale crunchyroll.LOCALE) string { switch locale { case crunchyroll.JP: diff --git a/utils/sort.go b/utils/sort.go index 82eb2b4..d4c7925 100644 --- a/utils/sort.go +++ b/utils/sort.go @@ -9,7 +9,7 @@ import ( ) // SortEpisodesBySeason sorts the given episodes by their seasons. -// Note that the same episodes just with different audio locales will cause problems +// Note that the same episodes just with different audio locales will cause problems. func SortEpisodesBySeason(episodes []*crunchyroll.Episode) [][]*crunchyroll.Episode { sortMap := map[string]map[int][]*crunchyroll.Episode{} @@ -43,7 +43,7 @@ func SortEpisodesBySeason(episodes []*crunchyroll.Episode) [][]*crunchyroll.Epis return eps } -// SortEpisodesByAudio sort the given episodes by their audio locale +// SortEpisodesByAudio sort the given episodes by their audio locale. func SortEpisodesByAudio(episodes []*crunchyroll.Episode) (map[crunchyroll.LOCALE][]*crunchyroll.Episode, error) { eps := map[crunchyroll.LOCALE][]*crunchyroll.Episode{} @@ -81,7 +81,7 @@ func SortEpisodesByAudio(episodes []*crunchyroll.Episode) (map[crunchyroll.LOCAL return eps, nil } -// MovieListingsByDuration sorts movie listings by their duration +// MovieListingsByDuration sorts movie listings by their duration. type MovieListingsByDuration []*crunchyroll.MovieListing func (mlbd MovieListingsByDuration) Len() int { @@ -94,7 +94,7 @@ func (mlbd MovieListingsByDuration) Less(i, j int) bool { return mlbd[i].DurationMS < mlbd[j].DurationMS } -// EpisodesByDuration sorts episodes by their duration +// EpisodesByDuration sorts episodes by their duration. type EpisodesByDuration []*crunchyroll.Episode func (ebd EpisodesByDuration) Len() int { @@ -107,6 +107,7 @@ func (ebd EpisodesByDuration) Less(i, j int) bool { return ebd[i].DurationMS < ebd[j].DurationMS } +// EpisodesByNumber sorts episodes after their episode number. type EpisodesByNumber []*crunchyroll.Episode func (ebn EpisodesByNumber) Len() int { @@ -119,7 +120,7 @@ func (ebn EpisodesByNumber) Less(i, j int) bool { return ebn[i].EpisodeNumber < ebn[j].EpisodeNumber } -// FormatsByResolution sorts formats after their resolution +// FormatsByResolution sorts formats after their resolution. type FormatsByResolution []*crunchyroll.Format func (fbr FormatsByResolution) Len() int { @@ -140,6 +141,7 @@ func (fbr FormatsByResolution) Less(i, j int) bool { return iResX+iResY < jResX+jResY } +// SubtitlesByLocale sorts subtitles after their locale. type SubtitlesByLocale []*crunchyroll.Subtitle func (sbl SubtitlesByLocale) Len() int { diff --git a/video.go b/video.go index f543df1..00b7734 100644 --- a/video.go +++ b/video.go @@ -30,8 +30,10 @@ type video struct { } `json:"images"` } +// Video is the base for Movie and Season. type Video interface{} +// Movie contains information about a movie. type Movie struct { video Video @@ -40,7 +42,7 @@ type Movie struct { children []*MovieListing - // not generated when calling MovieFromID + // not generated when calling MovieFromID. MovieListingMetadata struct { AvailabilityNotes string `json:"availability_notes"` AvailableOffline bool `json:"available_offline"` @@ -65,7 +67,7 @@ type Movie struct { } } -// MovieFromID returns a movie by its api id +// MovieFromID returns a movie by its api id. func MovieFromID(crunchy *Crunchyroll, id string) (*Movie, error) { resp, err := crunchy.request(fmt.Sprintf("https://beta-api.crunchyroll.com/cms/v2/%s/%s/%s/movies/%s&locale=%s&Signature=%s&Policy=%s&Key-Pair-Id=%s", crunchy.Config.CountryCode, @@ -95,8 +97,6 @@ func MovieFromID(crunchy *Crunchyroll, id string) (*Movie, error) { } // MovieListing returns all videos corresponding with the movie. -// Beside the normal movie, sometimes movie previews are returned too, but you can try to get the actual movie -// by sorting the returning MovieListing slice with the utils.MovieListingByDuration interface func (m *Movie) MovieListing() (movieListings []*MovieListing, err error) { if m.children != nil { return m.children, nil @@ -134,6 +134,7 @@ func (m *Movie) MovieListing() (movieListings []*MovieListing, err error) { return movieListings, nil } +// Series contains information about an anime series. type Series struct { video Video @@ -156,13 +157,13 @@ type Series struct { MatureRatings []string `json:"mature_ratings"` SeasonCount int `json:"season_count"` - // not generated when calling SeriesFromID + // not generated when calling SeriesFromID. SearchMetadata struct { Score float64 `json:"score"` } } -// SeriesFromID returns a series by its api id +// SeriesFromID returns a series by its api id. func SeriesFromID(crunchy *Crunchyroll, id string) (*Series, error) { resp, err := crunchy.request(fmt.Sprintf("https://beta-api.crunchyroll.com/cms/v2/%s/%s/%s/movies?movie_listing_id=%s&locale=%s&Signature=%s&Policy=%s&Key-Pair-Id=%s", crunchy.Config.CountryCode, @@ -191,7 +192,7 @@ func SeriesFromID(crunchy *Crunchyroll, id string) (*Series, error) { return series, nil } -// Seasons returns all seasons of a series +// Seasons returns all seasons of a series. func (s *Series) Seasons() (seasons []*Season, err error) { if s.children != nil { return s.children, nil