✨ Add drop:tmdb command for adding shows/movies to watched log
This commit is contained in:
parent
21d27f8068
commit
88802020fe
10 changed files with 377 additions and 3 deletions
6
cli/common.go
Normal file
6
cli/common.go
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
package cli
|
||||||
|
|
||||||
|
import mycli "codeberg.org/danjones000/my-log/cli"
|
||||||
|
|
||||||
|
var outJson bool
|
||||||
|
var d mycli.Date
|
||||||
69
cli/tmdb.go
Normal file
69
cli/tmdb.go
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
Copyright © 2026 Dan Jones <danjones@goodevilgenius.org>
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package cli
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"my-log-wynter/tmdb"
|
||||||
|
|
||||||
|
mycli "codeberg.org/danjones000/my-log/cli"
|
||||||
|
"codeberg.org/danjones000/my-log/config"
|
||||||
|
"codeberg.org/danjones000/my-log/formatters"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TmdbDropCmd represents the drop command
|
||||||
|
var TmdbDropCmd = &cobra.Command{
|
||||||
|
Use: "drop:tmdb url",
|
||||||
|
Short: "Add a new show/movie from TMDB to the watched log",
|
||||||
|
// Long: ``,
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
SilenceUsage: true,
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
if outJson {
|
||||||
|
config.Overrides["output.stdout.config.format"] = "json"
|
||||||
|
}
|
||||||
|
|
||||||
|
url := args[0]
|
||||||
|
log, err := tmdb.Drop(cmd.Context(), url, d.Time())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
form, err := formatters.Preferred()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
out, err := form.Log(log)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(out) > 0 && out[len(out)-1] != 10 {
|
||||||
|
out = append(out, 10)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(cmd.OutOrStdout(), "%s", out)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
(&d).Set("now")
|
||||||
|
mycli.RootCmd.AddCommand(TmdbDropCmd)
|
||||||
|
TmdbDropCmd.Flags().VarP(&d, "date", "d", "Date for log entry")
|
||||||
|
TmdbDropCmd.Flags().BoolVarP(&outJson, "output_json", "o", false, "Output result as JSON")
|
||||||
|
}
|
||||||
|
|
@ -26,9 +26,6 @@ import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
var outJson bool
|
|
||||||
var d mycli.Date
|
|
||||||
|
|
||||||
// YtDropCmd represents the drop command
|
// YtDropCmd represents the drop command
|
||||||
var YtDropCmd = &cobra.Command{
|
var YtDropCmd = &cobra.Command{
|
||||||
Use: "drop:yt url",
|
Use: "drop:yt url",
|
||||||
|
|
|
||||||
2
go.mod
2
go.mod
|
|
@ -4,6 +4,7 @@ go 1.26.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
codeberg.org/danjones000/my-log v0.1.1
|
codeberg.org/danjones000/my-log v0.1.1
|
||||||
|
github.com/cyruzin/golang-tmdb v1.9.2
|
||||||
github.com/lrstanley/go-ytdlp v1.3.1
|
github.com/lrstanley/go-ytdlp v1.3.1
|
||||||
github.com/spf13/cobra v1.8.0
|
github.com/spf13/cobra v1.8.0
|
||||||
)
|
)
|
||||||
|
|
@ -14,6 +15,7 @@ require (
|
||||||
github.com/caarlos0/env/v10 v10.0.0 // indirect
|
github.com/caarlos0/env/v10 v10.0.0 // indirect
|
||||||
github.com/cloudflare/circl v1.6.3 // indirect
|
github.com/cloudflare/circl v1.6.3 // indirect
|
||||||
github.com/elliotchance/pie/v2 v2.7.0 // indirect
|
github.com/elliotchance/pie/v2 v2.7.0 // indirect
|
||||||
|
github.com/goccy/go-json v0.10.5 // indirect
|
||||||
github.com/google/uuid v1.6.0 // indirect
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
github.com/hablullah/go-hijri v1.0.2 // indirect
|
github.com/hablullah/go-hijri v1.0.2 // indirect
|
||||||
github.com/hablullah/go-juliandays v1.0.0 // indirect
|
github.com/hablullah/go-juliandays v1.0.0 // indirect
|
||||||
|
|
|
||||||
4
go.sum
4
go.sum
|
|
@ -9,10 +9,14 @@ github.com/caarlos0/env/v10 v10.0.0/go.mod h1:ZfulV76NvVPw3tm591U4SwL3Xx9ldzBP9a
|
||||||
github.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8=
|
github.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8=
|
||||||
github.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4=
|
github.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
|
github.com/cyruzin/golang-tmdb v1.9.2 h1:8G9w16PgzYNkmkbT0Sdu/Asx+yeQ93rbp3kQUxBu+AE=
|
||||||
|
github.com/cyruzin/golang-tmdb v1.9.2/go.mod h1:Yx4f4KyLgWAnvwgZ729nJPOTKkD4epYoK+cGDZ3AFzs=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/elliotchance/pie/v2 v2.7.0 h1:FqoIKg4uj0G/CrLGuMS9ejnFKa92lxE1dEgBD3pShXg=
|
github.com/elliotchance/pie/v2 v2.7.0 h1:FqoIKg4uj0G/CrLGuMS9ejnFKa92lxE1dEgBD3pShXg=
|
||||||
github.com/elliotchance/pie/v2 v2.7.0/go.mod h1:18t0dgGFH006g4eVdDtWfgFZPQEgl10IoEO8YWEq3Og=
|
github.com/elliotchance/pie/v2 v2.7.0/go.mod h1:18t0dgGFH006g4eVdDtWfgFZPQEgl10IoEO8YWEq3Og=
|
||||||
|
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
||||||
|
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/hablullah/go-hijri v1.0.2 h1:drT/MZpSZJQXo7jftf5fthArShcaMtsal0Zf/dnmp6k=
|
github.com/hablullah/go-hijri v1.0.2 h1:drT/MZpSZJQXo7jftf5fthArShcaMtsal0Zf/dnmp6k=
|
||||||
|
|
|
||||||
115
tmdb/drop.go
Normal file
115
tmdb/drop.go
Normal file
|
|
@ -0,0 +1,115 @@
|
||||||
|
package tmdb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"math/rand/v2"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"codeberg.org/danjones000/my-log/files"
|
||||||
|
"codeberg.org/danjones000/my-log/models"
|
||||||
|
sdk "github.com/cyruzin/golang-tmdb"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Drop(ctx context.Context, url string, now time.Time) (models.Log, error) {
|
||||||
|
var log models.Log
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return log, context.Cause(ctx)
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
inf, err := Parse(url)
|
||||||
|
if err != nil {
|
||||||
|
return log, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var entry models.Entry
|
||||||
|
|
||||||
|
if inf.Type == Movie {
|
||||||
|
det, err := FetchMovieDetails(inf)
|
||||||
|
if err != nil {
|
||||||
|
return log, err
|
||||||
|
}
|
||||||
|
entry, err = GetLogEntryForMovie(det)
|
||||||
|
if err != nil {
|
||||||
|
return log, err
|
||||||
|
}
|
||||||
|
} else if inf.Type == Series {
|
||||||
|
det, err := FetchEpisodeDetails(inf)
|
||||||
|
if err != nil {
|
||||||
|
return log, err
|
||||||
|
}
|
||||||
|
entry, err = GetLogEntryForEpisode(det)
|
||||||
|
if err != nil {
|
||||||
|
return log, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return log, fmt.Errorf("unknown type: %s", inf.Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Name = "watched"
|
||||||
|
log.Entries = []models.Entry{entry}
|
||||||
|
|
||||||
|
files.Append(log)
|
||||||
|
|
||||||
|
return log, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetLogEntryForEpisode(det TVDetails) (ent models.Entry, err error) {
|
||||||
|
ent.Title = fmt.Sprintf("%s - %s %dx%02d", det.Episode.Name, det.Series.Name, det.Episode.SeasonNumber, det.Episode.EpisodeNumber)
|
||||||
|
ent.Date = time.Now().Local()
|
||||||
|
|
||||||
|
fields := &models.Metas{}
|
||||||
|
fields.AppendTo("tmdb", det.Series.ID)
|
||||||
|
fields.AppendTo("show", det.Series.Name)
|
||||||
|
fields.AppendTo("episode", det.Episode.Name)
|
||||||
|
fields.AppendTo("air_date", det.Episode.AirDate)
|
||||||
|
fields.AppendTo("id", fmt.Sprintf("tag:themoviedborg,%s:Episode/%d/season/%d/episode/%d/%d", det.Episode.AirDate, det.Series.ID, det.Episode.SeasonNumber, det.Episode.EpisodeNumber, rand.Int()))
|
||||||
|
fields.AppendTo("url", fmt.Sprintf("https://themoviedb.org/tv/%d/season/%d/episode/%d", det.Series.ID, det.Episode.SeasonNumber, det.Episode.EpisodeNumber))
|
||||||
|
fields.AppendTo("episode_num", det.Episode.EpisodeNumber)
|
||||||
|
fields.AppendTo("season_num", det.Episode.SeasonNumber)
|
||||||
|
fields.AppendTo("via", "drop-tmdb")
|
||||||
|
if det.Episode.Overview != "" {
|
||||||
|
fields.AppendTo("note", det.Episode.Overview)
|
||||||
|
}
|
||||||
|
|
||||||
|
ent.Fields = *fields
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetLogEntryForMovie(det *sdk.MovieDetails) (ent models.Entry, err error) {
|
||||||
|
ent.Title = fmt.Sprintf("%s (%s)", det.Title, det.ReleaseDate)
|
||||||
|
ent.Date = time.Now().Local()
|
||||||
|
|
||||||
|
fields := &models.Metas{}
|
||||||
|
fields.AppendTo("tmdb", det.ID)
|
||||||
|
fields.AppendTo("id", fmt.Sprintf("tag:themoviedborg,%s:Movie/%d/%d", det.ReleaseDate, det.ID, rand.Int()))
|
||||||
|
fields.AppendTo("url", fmt.Sprintf("https://themoviedb.org/movie/%d", det.ID))
|
||||||
|
// url https://www.themoviedb.org/movie/776503
|
||||||
|
fields.AppendTo("release_date", det.ReleaseDate)
|
||||||
|
cts := det.OriginCountry
|
||||||
|
if len(cts) == 1 {
|
||||||
|
fields.AppendTo("country", cts[0])
|
||||||
|
} else if len(cts) > 1 {
|
||||||
|
fields.AppendTo("country", cts)
|
||||||
|
}
|
||||||
|
|
||||||
|
gens := make([]string, len(det.Genres))
|
||||||
|
for idx, g := range det.Genres {
|
||||||
|
gens[idx] = g.Name
|
||||||
|
}
|
||||||
|
if len(gens) == 1 {
|
||||||
|
fields.AppendTo("genre", gens[0])
|
||||||
|
} else if len(gens) > 1 {
|
||||||
|
fields.AppendTo("genre", gens)
|
||||||
|
}
|
||||||
|
|
||||||
|
// fields.AppendTo("mpaa")
|
||||||
|
if det.Overview != "" {
|
||||||
|
fields.AppendTo("note", det.Overview)
|
||||||
|
}
|
||||||
|
|
||||||
|
ent.Fields = *fields
|
||||||
|
return
|
||||||
|
}
|
||||||
79
tmdb/fetch.go
Normal file
79
tmdb/fetch.go
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
package tmdb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"math/rand/v2"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
sdk "github.com/cyruzin/golang-tmdb"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ErrMissingKey = errors.New("missing TMDB key")
|
||||||
|
|
||||||
|
func FetchMovieDetails(inf Info) (*sdk.MovieDetails, error) {
|
||||||
|
if inf.Type != Movie {
|
||||||
|
return nil, fmt.Errorf("%s is not a movie", inf.Type)
|
||||||
|
}
|
||||||
|
if inf.ID < 1 {
|
||||||
|
return nil, fmt.Errorf("%d is not a valid TMDB id", inf.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
sdk, err := GetClient()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return sdk.GetMovieDetails(inf.ID, map[string]string{
|
||||||
|
"cache": strconv.Itoa(rand.Int()),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func FetchEpisodeDetails(inf Info) (TVDetails, error) {
|
||||||
|
var det TVDetails
|
||||||
|
if inf.Type != Series {
|
||||||
|
return det, fmt.Errorf("%s is not an episode", inf.Type)
|
||||||
|
}
|
||||||
|
if inf.ID < 1 {
|
||||||
|
return det, fmt.Errorf("%d is not a valid TMDB id", inf.ID)
|
||||||
|
}
|
||||||
|
if inf.Season < 1 {
|
||||||
|
return det, fmt.Errorf("%d is not a valid season", inf.Season)
|
||||||
|
}
|
||||||
|
if inf.Episode < 1 {
|
||||||
|
return det, fmt.Errorf("%d is not a valid episode", inf.Episode)
|
||||||
|
}
|
||||||
|
|
||||||
|
sdk, err := GetClient()
|
||||||
|
if err != nil {
|
||||||
|
return det, err
|
||||||
|
}
|
||||||
|
|
||||||
|
epDet, err := sdk.GetTVEpisodeDetails(inf.ID, inf.Season, inf.Episode, map[string]string{
|
||||||
|
"cache": strconv.Itoa(rand.Int()),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return det, err
|
||||||
|
}
|
||||||
|
|
||||||
|
showDet, err := sdk.GetTVDetails(inf.ID, map[string]string{
|
||||||
|
"cache": strconv.Itoa(rand.Int()),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return det, err
|
||||||
|
}
|
||||||
|
|
||||||
|
det.Episode = epDet
|
||||||
|
det.Series = showDet
|
||||||
|
|
||||||
|
return det, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetClient() (*sdk.Client, error) {
|
||||||
|
key := os.Getenv("TMDB_KEY")
|
||||||
|
if key == "" {
|
||||||
|
return nil, ErrMissingKey
|
||||||
|
}
|
||||||
|
return sdk.Init(key)
|
||||||
|
}
|
||||||
52
tmdb/parse.go
Normal file
52
tmdb/parse.go
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
package tmdb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
var EpisodeRegex = regexp.MustCompile(`https?://(?:www\.)?themoviedb\.org/tv/([0-9]+)(?:-[A-Za-z0-9-]+)?/season/([0-9]+)/episode/([0-9]+)`)
|
||||||
|
var MovieRegex = regexp.MustCompile(`https?://(?:www\.)?themoviedb\.org/movie/([0-9]+)(?:-[A-Za-z0-9-]+)?/?`)
|
||||||
|
|
||||||
|
func Parse(url string) (inf Info, err error) {
|
||||||
|
if m := EpisodeRegex.FindStringSubmatch(url); len(m) > 0 {
|
||||||
|
var got int
|
||||||
|
|
||||||
|
got, err = strconv.Atoi(m[1])
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
inf.ID = got
|
||||||
|
|
||||||
|
got, err = strconv.Atoi(m[2])
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
inf.Season = got
|
||||||
|
|
||||||
|
got, err = strconv.Atoi(m[3])
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
inf.Episode = got
|
||||||
|
|
||||||
|
inf.Type = Series
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if m := MovieRegex.FindStringSubmatch(url); len(m) > 0 {
|
||||||
|
var got int
|
||||||
|
|
||||||
|
got, err = strconv.Atoi(m[1])
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
inf.ID = got
|
||||||
|
|
||||||
|
inf.Type = Movie
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return inf, fmt.Errorf("failed to parse %s", url)
|
||||||
|
}
|
||||||
24
tmdb/type.go
Normal file
24
tmdb/type.go
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
package tmdb
|
||||||
|
|
||||||
|
import sdk "github.com/cyruzin/golang-tmdb"
|
||||||
|
|
||||||
|
//go:generate stringer -type=Type
|
||||||
|
type Type uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
Unknown Type = iota
|
||||||
|
Movie
|
||||||
|
Series
|
||||||
|
)
|
||||||
|
|
||||||
|
type TVDetails struct {
|
||||||
|
Series *sdk.TVDetails
|
||||||
|
Episode *sdk.TVEpisodeDetails
|
||||||
|
}
|
||||||
|
|
||||||
|
type Info struct {
|
||||||
|
ID int
|
||||||
|
Type Type
|
||||||
|
Season int
|
||||||
|
Episode int
|
||||||
|
}
|
||||||
26
tmdb/type_string.go
Normal file
26
tmdb/type_string.go
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
// Code generated by "stringer -type=Type"; DO NOT EDIT.
|
||||||
|
|
||||||
|
package tmdb
|
||||||
|
|
||||||
|
import "strconv"
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||||
|
// Re-run the stringer command to generate them again.
|
||||||
|
var x [1]struct{}
|
||||||
|
_ = x[Unknown-0]
|
||||||
|
_ = x[Movie-1]
|
||||||
|
_ = x[Series-2]
|
||||||
|
}
|
||||||
|
|
||||||
|
const _Type_name = "UnknownMovieSeries"
|
||||||
|
|
||||||
|
var _Type_index = [...]uint8{0, 7, 12, 18}
|
||||||
|
|
||||||
|
func (i Type) String() string {
|
||||||
|
idx := int(i) - 0
|
||||||
|
if i < 0 || idx >= len(_Type_index)-1 {
|
||||||
|
return "Type(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||||
|
}
|
||||||
|
return _Type_name[_Type_index[idx]:_Type_index[idx+1]]
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue