diff --git a/board/board.go b/board.go similarity index 60% rename from board/board.go rename to board.go index f743c7e..9c7180c 100644 --- a/board/board.go +++ b/board.go @@ -1,15 +1,10 @@ -package board +package getmoe import ( "errors" - "fmt" "io/ioutil" "net/http" "time" - - "github.com/leonidboykov/getmoe" - "github.com/leonidboykov/getmoe/conf" - "github.com/leonidboykov/getmoe/provider" ) // Board related errors @@ -21,32 +16,31 @@ var ( // Board holds data for API access type Board struct { - Provider getmoe.Provider + Provider Provider httpClient *http.Client } -// New creates a new Board with provided configuration -func New(config conf.BoardConfiguration) (*Board, error) { - if config.Provider.Name == "" { - return nil, ErrProviderNotSpecified - } - p, ok := provider.Providers[config.Provider.Name] - if !ok { - return nil, fmt.Errorf(ErrProviderNotFound, config.Provider.Name) - } +// NewBoard creates a new board with provided configuration +func NewBoard(provider Provider) *Board { + // func New(config getmoe.BoardConfiguration) (*Board, error) { + // if config.Provider.Name == "" { + // return nil, ErrProviderNotSpecified + // } + // p, ok := provider.Providers[config.Provider.Name] + // if !ok { + // return nil, fmt.Errorf(ErrProviderNotFound, config.Provider.Name) + // } - board := &Board{ - Provider: p(config.Provider), + return &Board{ + Provider: provider, httpClient: &http.Client{ Timeout: 30 * time.Second, }, } - - return board, nil } // Request gets images by tags -func (b *Board) Request() ([]getmoe.Post, error) { +func (b *Board) Request() ([]Post, error) { req, err := b.Provider.PageRequest() if err != nil { return nil, err @@ -72,8 +66,8 @@ func (b *Board) Request() ([]getmoe.Post, error) { } // RequestAll checks all pages -func (b *Board) RequestAll() ([]getmoe.Post, error) { - var pages []getmoe.Post +func (b *Board) RequestAll() ([]Post, error) { + var pages []Post for { b.Provider.NextPage() page, err := b.Request() diff --git a/board/boards.go b/board/boards.go deleted file mode 100644 index 1135297..0000000 --- a/board/boards.go +++ /dev/null @@ -1,54 +0,0 @@ -package board - -import ( - "net/http" - "net/url" - "time" - - "github.com/leonidboykov/getmoe/conf" - "github.com/leonidboykov/getmoe/provider/danbooru" - "github.com/leonidboykov/getmoe/provider/gelbooru" - "github.com/leonidboykov/getmoe/provider/moebooru" - "github.com/leonidboykov/getmoe/provider/sankaku" -) - -// AvailableBoards ... -var AvailableBoards = map[string]Board{ - "yande.re": Board{ - Provider: moebooru.New(conf.ProviderConfiguration{ - URL: conf.URLString{URL: url.URL{Host: "yande.re"}}, - }), - httpClient: &http.Client{Timeout: 30 * time.Second}, - }, - "konachan.com": Board{ - Provider: moebooru.New(conf.ProviderConfiguration{ - URL: conf.URLString{URL: url.URL{Host: "konachan.com"}}, - PasswordSalt: "So-I-Heard-You-Like-Mupkids-?--%s--", - }), - httpClient: &http.Client{Timeout: 30 * time.Second}, - }, - "gelbooru.com": Board{ - Provider: gelbooru.New(conf.ProviderConfiguration{ - URL: conf.URLString{URL: url.URL{Host: "gelbooru.com"}}, - }), - httpClient: &http.Client{Timeout: 30 * time.Second}, - }, - "danbooru.donmai.us": Board{ - Provider: danbooru.New(conf.ProviderConfiguration{ - URL: conf.URLString{URL: url.URL{Host: "danbooru.donmai.us"}}, - }), - httpClient: &http.Client{Timeout: 30 * time.Second}, - }, - "chan.sankakucomplex.com": Board{ - Provider: sankaku.New(conf.ProviderConfiguration{ - URL: conf.URLString{URL: url.URL{Host: "capi-beta.sankakucomplex.com"}}, - }), - httpClient: &http.Client{Timeout: 30 * time.Second}, - }, - "idol.sankakucomplex.com": Board{ - Provider: sankaku.New(conf.ProviderConfiguration{ - URL: conf.URLString{URL: url.URL{Host: "iapi.sankakucomplex.com"}}, - }), - httpClient: &http.Client{Timeout: 30 * time.Second}, - }, -} diff --git a/cmd/getmoe/get.go b/cmd/getmoe/get.go index 83b5e24..2ff4c4f 100644 --- a/cmd/getmoe/get.go +++ b/cmd/getmoe/get.go @@ -7,9 +7,8 @@ import ( "github.com/urfave/cli" "github.com/leonidboykov/getmoe" - "github.com/leonidboykov/getmoe/board" - "github.com/leonidboykov/getmoe/conf" - "github.com/leonidboykov/getmoe/utils" + "github.com/leonidboykov/getmoe/internal/helper" + "github.com/leonidboykov/getmoe/provider" ) var getCommand = cli.Command{ @@ -48,18 +47,18 @@ func getAction(ctx *cli.Context) error { passwordFlag := ctx.String("password") quietFlag := ctx.GlobalBool("quiet") - board, ok := board.AvailableBoards[srcFlag] + board, ok := provider.AvailableBoards[srcFlag] if !ok { fmt.Printf("There is no %s source specified\n", srcFlag) os.Exit(1) } - board.Provider.Auth(conf.AuthConfiguration{ + board.Provider.Auth(getmoe.AuthConfiguration{ Login: loginFlag, Password: passwordFlag, }) - board.Provider.BuildRequest(conf.RequestConfiguration{ + board.Provider.BuildRequest(getmoe.RequestConfiguration{ Tags: tagFlag, }) diff --git a/conf/configuration.go b/configuration.go similarity index 99% rename from conf/configuration.go rename to configuration.go index ec26ef6..9fbd425 100644 --- a/conf/configuration.go +++ b/configuration.go @@ -1,4 +1,4 @@ -package conf +package getmoe import ( "io/ioutil" diff --git a/conf/configuration_test.go b/configuration_test.go similarity index 82% rename from conf/configuration_test.go rename to configuration_test.go index ab3cfc0..6dafa76 100644 --- a/conf/configuration_test.go +++ b/configuration_test.go @@ -1,11 +1,11 @@ -package conf_test +package getmoe_test import ( "testing" "gopkg.in/yaml.v2" - "github.com/leonidboykov/getmoe/conf" + "github.com/leonidboykov/getmoe" ) var testProviders = []byte(` @@ -24,7 +24,7 @@ providers: `) func TestProviders(t *testing.T) { - var config conf.GlobalConfiguration + var config getmoe.GlobalConfiguration if err := yaml.Unmarshal(testProviders, &config); err != nil { t.Error(err) } diff --git a/internal/hash/sha1.go b/internal/hash/sha1.go index 5d97e22..f5dc0ef 100644 --- a/internal/hash/sha1.go +++ b/internal/hash/sha1.go @@ -6,7 +6,7 @@ import ( "fmt" ) -// Sha1 builds Sha1 hash with proper salt +// Sha1 builds sha1 hash with proper salt func Sha1(value, salt string) string { value = fmt.Sprintf(salt, value) hash := sha1.New() diff --git a/utils/unescape.go b/internal/helper/unescape.go similarity index 100% rename from utils/unescape.go rename to internal/helper/unescape.go diff --git a/utils/unescape_test.go b/internal/helper/unescape_test.go similarity index 100% rename from utils/unescape_test.go rename to internal/helper/unescape_test.go diff --git a/post.go b/post.go index 8422edf..956b569 100644 --- a/post.go +++ b/post.go @@ -7,7 +7,7 @@ import ( "path" "time" - "github.com/leonidboykov/getmoe/utils" + "github.com/leonidboykov/getmoe/internal/helper" ) // Post contains post data, represents intersection of *boorus post structs diff --git a/provider.go b/provider.go index 0273198..cc6ea33 100644 --- a/provider.go +++ b/provider.go @@ -2,14 +2,12 @@ package getmoe import ( "net/http" - - "github.com/leonidboykov/getmoe/conf" ) // Provider describes Board provider type Provider interface { - Auth(conf.AuthConfiguration) - BuildRequest(conf.RequestConfiguration) + Auth(AuthConfiguration) + BuildRequest(RequestConfiguration) NextPage() PageRequest() (*http.Request, error) Parse([]byte) ([]Post, error) diff --git a/provider/boards.go b/provider/boards.go new file mode 100644 index 0000000..0f71db1 --- /dev/null +++ b/provider/boards.go @@ -0,0 +1,34 @@ +package provider + +import ( + "net/url" + + "github.com/leonidboykov/getmoe" + "github.com/leonidboykov/getmoe/provider/danbooru" + "github.com/leonidboykov/getmoe/provider/gelbooru" + "github.com/leonidboykov/getmoe/provider/moebooru" + "github.com/leonidboykov/getmoe/provider/sankaku" +) + +// AvailableBoards is a list of predefined boards. +var AvailableBoards = map[string]*getmoe.Board{ + "yande.re": getmoe.NewBoard(moebooru.New(getmoe.ProviderConfiguration{ + URL: getmoe.URLString{URL: url.URL{Host: "yande.re"}}, + })), + "konachan.com": getmoe.NewBoard(moebooru.New(getmoe.ProviderConfiguration{ + URL: getmoe.URLString{URL: url.URL{Host: "konachan.com"}}, + PasswordSalt: "So-I-Heard-You-Like-Mupkids-?--%s--", + })), + "gelbooru.com": getmoe.NewBoard(gelbooru.New(getmoe.ProviderConfiguration{ + URL: getmoe.URLString{URL: url.URL{Host: "gelbooru.com"}}, + })), + "danbooru.donmai.us": getmoe.NewBoard(danbooru.New(getmoe.ProviderConfiguration{ + URL: getmoe.URLString{URL: url.URL{Host: "danbooru.donmai.us"}}, + })), + "chan.sankakucomplex.com": getmoe.NewBoard(sankaku.New(getmoe.ProviderConfiguration{ + URL: getmoe.URLString{URL: url.URL{Host: "capi-beta.sankakucomplex.com"}}, + })), + "idol.sankakucomplex.com": getmoe.NewBoard(sankaku.New(getmoe.ProviderConfiguration{ + URL: getmoe.URLString{URL: url.URL{Host: "iapi.sankakucomplex.com"}}, + })), +} diff --git a/provider/danbooru/provider.go b/provider/danbooru/provider.go index 9c89a65..fc5f57d 100644 --- a/provider/danbooru/provider.go +++ b/provider/danbooru/provider.go @@ -14,7 +14,6 @@ import ( "github.com/imdario/mergo" "github.com/leonidboykov/getmoe" - "github.com/leonidboykov/getmoe/conf" "github.com/leonidboykov/getmoe/internal/query" ) @@ -45,7 +44,7 @@ type Provider struct { } // New creates a new moebooru provider with configuration -func New(config conf.ProviderConfiguration) *Provider { +func New(config getmoe.ProviderConfiguration) *Provider { provider := &Provider{ URL: &config.URL.URL, PasswordSalt: config.PasswordSalt, @@ -59,12 +58,12 @@ func New(config conf.ProviderConfiguration) *Provider { } // Auth builds query based on AuthConfiguration -func (p *Provider) Auth(config conf.AuthConfiguration) { +func (p *Provider) Auth(config getmoe.AuthConfiguration) { p.URL.User = url.UserPassword(config.Login, config.APIKey) } // BuildRequest builds query based on RequestConfiguration -func (p *Provider) BuildRequest(config conf.RequestConfiguration) { +func (p *Provider) BuildRequest(config getmoe.RequestConfiguration) { q := p.URL.Query() query.Array(&q, "tags", config.Tags) query.Int(&q, "limit", p.PostsLimit) diff --git a/provider/gelbooru/provider.go b/provider/gelbooru/provider.go index 6ccd918..a714be7 100644 --- a/provider/gelbooru/provider.go +++ b/provider/gelbooru/provider.go @@ -12,7 +12,6 @@ import ( "github.com/imdario/mergo" "github.com/leonidboykov/getmoe" - "github.com/leonidboykov/getmoe/conf" "github.com/leonidboykov/getmoe/internal/query" ) @@ -46,7 +45,7 @@ type Provider struct { } // New creates a new moebooru provider with configuration -func New(config conf.ProviderConfiguration) *Provider { +func New(config getmoe.ProviderConfiguration) *Provider { provider := &Provider{ URL: &config.URL.URL, PasswordSalt: config.PasswordSalt, @@ -60,12 +59,12 @@ func New(config conf.ProviderConfiguration) *Provider { } // Auth builds query based on AuthConfiguration -func (p *Provider) Auth(config conf.AuthConfiguration) { +func (p *Provider) Auth(config getmoe.AuthConfiguration) { // No auth required } // BuildRequest builds query based on RequestConfiguration -func (p *Provider) BuildRequest(config conf.RequestConfiguration) { +func (p *Provider) BuildRequest(config getmoe.RequestConfiguration) { q := p.URL.Query() query.Array(&q, "tags", config.Tags) query.Int(&q, "limit", p.PostsLimit) diff --git a/provider/moebooru/provider.go b/provider/moebooru/provider.go index 73e0608..9e2209d 100644 --- a/provider/moebooru/provider.go +++ b/provider/moebooru/provider.go @@ -14,7 +14,6 @@ import ( "github.com/imdario/mergo" "github.com/leonidboykov/getmoe" - "github.com/leonidboykov/getmoe/conf" "github.com/leonidboykov/getmoe/internal/hash" "github.com/leonidboykov/getmoe/internal/query" ) @@ -48,7 +47,7 @@ type Provider struct { } // New creates a new moebooru provider with configuration -func New(config conf.ProviderConfiguration) *Provider { +func New(config getmoe.ProviderConfiguration) *Provider { provider := &Provider{ URL: &config.URL.URL, PasswordSalt: config.PasswordSalt, @@ -62,7 +61,7 @@ func New(config conf.ProviderConfiguration) *Provider { } // Auth builds query based on AuthConfiguration -func (p *Provider) Auth(config conf.AuthConfiguration) { +func (p *Provider) Auth(config getmoe.AuthConfiguration) { var login, password, hashedPassword = config.Login, config.Password, config.HashedPassword q := p.URL.Query() if login != "" { @@ -78,7 +77,7 @@ func (p *Provider) Auth(config conf.AuthConfiguration) { } // BuildRequest builds query based on RequestConfiguration -func (p *Provider) BuildRequest(config conf.RequestConfiguration) { +func (p *Provider) BuildRequest(config getmoe.RequestConfiguration) { q := p.URL.Query() query.Array(&q, "tags", config.Tags) query.Int(&q, "limit", p.PostsLimit) diff --git a/provider/providers.go b/provider/providers.go index cbc5cd6..389294d 100644 --- a/provider/providers.go +++ b/provider/providers.go @@ -2,28 +2,27 @@ package provider import ( "github.com/leonidboykov/getmoe" - "github.com/leonidboykov/getmoe/conf" "github.com/leonidboykov/getmoe/provider/danbooru" "github.com/leonidboykov/getmoe/provider/gelbooru" "github.com/leonidboykov/getmoe/provider/moebooru" "github.com/leonidboykov/getmoe/provider/sankaku" ) -type factory func(conf.ProviderConfiguration) getmoe.Provider +type factory func(getmoe.ProviderConfiguration) getmoe.Provider -func newDanbooru(config conf.ProviderConfiguration) getmoe.Provider { +func newDanbooru(config getmoe.ProviderConfiguration) getmoe.Provider { return danbooru.New(config) } -func newGelbooru(config conf.ProviderConfiguration) getmoe.Provider { +func newGelbooru(config getmoe.ProviderConfiguration) getmoe.Provider { return gelbooru.New(config) } -func newMoebooru(config conf.ProviderConfiguration) getmoe.Provider { +func newMoebooru(config getmoe.ProviderConfiguration) getmoe.Provider { return moebooru.New(config) } -func newSankaku(config conf.ProviderConfiguration) getmoe.Provider { +func newSankaku(config getmoe.ProviderConfiguration) getmoe.Provider { return sankaku.New(config) } diff --git a/provider/sankaku/provider.go b/provider/sankaku/provider.go index d61966f..3204ae5 100644 --- a/provider/sankaku/provider.go +++ b/provider/sankaku/provider.go @@ -14,7 +14,6 @@ import ( "github.com/imdario/mergo" "github.com/leonidboykov/getmoe" - "github.com/leonidboykov/getmoe/conf" "github.com/leonidboykov/getmoe/internal/hash" "github.com/leonidboykov/getmoe/internal/query" ) @@ -51,7 +50,7 @@ type Provider struct { } // New creates a new moebooru provider with configuration -func New(config conf.ProviderConfiguration) *Provider { +func New(config getmoe.ProviderConfiguration) *Provider { provider := &Provider{ URL: &config.URL.URL, PasswordSalt: config.PasswordSalt, @@ -65,7 +64,7 @@ func New(config conf.ProviderConfiguration) *Provider { } // Auth builds query based on AuthConfiguration -func (p *Provider) Auth(config conf.AuthConfiguration) { +func (p *Provider) Auth(config getmoe.AuthConfiguration) { var login, password, hashedPassword = config.Login, config.Password, config.HashedPassword q := p.URL.Query() if login != "" { @@ -83,7 +82,7 @@ func (p *Provider) Auth(config conf.AuthConfiguration) { } // BuildRequest builds query based on RequestConfiguration -func (p *Provider) BuildRequest(config conf.RequestConfiguration) { +func (p *Provider) BuildRequest(config getmoe.RequestConfiguration) { q := p.URL.Query() query.Array(&q, "tags", config.Tags) query.Int(&q, "limit", p.PostsLimit) diff --git a/rating.go b/rating.go new file mode 100644 index 0000000..00e42db --- /dev/null +++ b/rating.go @@ -0,0 +1,11 @@ +package getmoe + +// Rating defines boorus rating system +type Rating string + +// Boorus rating system has safe, questionable and explicit tags +const ( + RatingSafe Rating = "s" + RatingQuestionable Rating = "q" + RatingExplicit Rating = "e" +) diff --git a/tags.go b/tags.go index 06f19a9..a228357 100644 --- a/tags.go +++ b/tags.go @@ -5,13 +5,6 @@ import ( "time" ) -// Tags interface provides a generic interface for the -// type Tags interface { -// With(t string) *Tag -// AfterDate(t time.Time) *Tag -// BeforeDate(t time.Time) *Tag -// } - const ( orPrefix = "~" noPrefix = "-" @@ -29,31 +22,24 @@ const ( const timeFormat = "2006-01-02" -// Rating defines boorus rating system -type Rating string - -// Boorus rating system has safe, questionable and explicit tags -const ( - RatingSafe Rating = "s" - RatingQuestionable = "q" - RatingExplicit = "e" -) - -// Tags ... +// Tags provides fluent-style builder for boorus tags. type Tags []string -// NewTags ... +// NewTags allocates a new list. You may provide as many tags as you want. +// t := getmoe.NewTags("tag1", "tag2") func NewTags(tags ...string) *Tags { return new(Tags).And(tags...) } -// And ... +// And appends tags to tag list. +// t.And("tag3", "tag4") func (t *Tags) And(tags ...string) *Tags { *t = append(*t, tags...) return t } -// Or ... +// Or appends tags with 'or' prefix to tag list. +// t.Or("tag5", "tag6") func (t *Tags) Or(tags ...string) *Tags { for i := range tags { *t = append(*t, orPrefix+tags[i]) @@ -61,7 +47,7 @@ func (t *Tags) Or(tags ...string) *Tags { return t } -// No ... +// No appends tags with 'no' prefix to tag list. func (t *Tags) No(tags ...string) *Tags { for i := range tags { *t = append(*t, noPrefix+tags[i]) @@ -69,31 +55,35 @@ func (t *Tags) No(tags ...string) *Tags { return t } -// HasRating appends rating tag -func (t *Tags) HasRating(r Rating) *Tags { - *t = append(*t, ratingKey+string(r)) +// WithRating appends rating tags. +func (t *Tags) WithRating(r ...Rating) *Tags { + for i := range r { + *t = append(*t, ratingKey+string(r[i])) + } return t } -// HasNotRating appends rating tag with a minus prefix -func (t *Tags) HasNotRating(r Rating) *Tags { - *t = append(*t, noPrefix+ratingKey+string(r)) +// WithoutRating appends rating tags with 'no' prefix. +func (t *Tags) WithoutRating(r ...Rating) *Tags { + for i := range r { + *t = append(*t, noPrefix+ratingKey+string(r[i])) + } return t } -// AtDate ... +// AtDate appends date tag. func (t *Tags) AtDate(date time.Time) *Tags { *t = append(*t, dateKey+date.Format(timeFormat)) return t } -// BeforeDate ... +// BeforeDate appends date tag with before prefix. func (t *Tags) BeforeDate(date time.Time) *Tags { *t = append(*t, dateKey+lessOrEqualPrefix+date.Format(timeFormat)) return t } -// AfterDate ... +// AfterDate appends date tag with after prefix. func (t *Tags) AfterDate(date time.Time) *Tags { *t = append(*t, dateKey+greaterOrEqualPrefix+date.Format(timeFormat)) return t diff --git a/tags_test.go b/tags_test.go new file mode 100644 index 0000000..9bb527f --- /dev/null +++ b/tags_test.go @@ -0,0 +1,17 @@ +package getmoe_test + +import ( + "fmt" + + "github.com/leonidboykov/getmoe" +) + +func ExampleTags() { + t := getmoe.NewTags("first_tag", "second_tag") + t.And("and_this_tag") + t.No("except_this_tag") + t.WithoutRating(getmoe.RatingQuestionable, getmoe.RatingExplicit) + + fmt.Println(t) + // Output: first_tag second_tag and_this_tag -except_this_tag -rating:q -rating:e +} diff --git a/conf/urlstring.go b/urlstring.go similarity index 96% rename from conf/urlstring.go rename to urlstring.go index 8caf999..0c39c17 100644 --- a/conf/urlstring.go +++ b/urlstring.go @@ -1,4 +1,4 @@ -package conf +package getmoe import "net/url" diff --git a/conf/urlstring_test.go b/urlstring_test.go similarity index 62% rename from conf/urlstring_test.go rename to urlstring_test.go index 299e235..6d76b96 100644 --- a/conf/urlstring_test.go +++ b/urlstring_test.go @@ -1,4 +1,4 @@ -package conf_test +package getmoe_test import ( "net/url" @@ -6,20 +6,20 @@ import ( "gopkg.in/yaml.v2" - "github.com/leonidboykov/getmoe/conf" + "github.com/leonidboykov/getmoe" ) type TestURLString struct { - Host conf.URLString `yaml:"host"` + Host getmoe.URLString `yaml:"host"` } func TestUnmarshalYAML(t *testing.T) { tests := []struct { in string - want conf.URLString `yaml:"host"` + want getmoe.URLString `yaml:"host"` }{ - {"host: https://example.com", conf.URLString{URL: url.URL{Scheme: "https", Host: "example.com"}}}, - {"", conf.URLString{URL: url.URL{}}}, + {"host: https://example.com", getmoe.URLString{URL: url.URL{Scheme: "https", Host: "example.com"}}}, + {"", getmoe.URLString{URL: url.URL{}}}, } for _, test := range tests { var field TestURLString