Skip to content

Commit

Permalink
feat: add sanqiu service.
Browse files Browse the repository at this point in the history
  • Loading branch information
syhily committed Nov 15, 2022
1 parent 90d5f86 commit d6b3a5c
Show file tree
Hide file tree
Showing 8 changed files with 194 additions and 5 deletions.
2 changes: 1 addition & 1 deletion cmd/sanqiu.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ var sanqiuCmd = &cobra.Command{
Row("Aliyun RefreshToken", "******").
Print()

// Set the fetcher config.
// Set the domain for using in resty.Client.
argument.Website = sanqiuWebsite

// Create the fetcher.
Expand Down
4 changes: 4 additions & 0 deletions internal/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ func NewConfig(rawURL, userAgent, proxy, configRoot string) (*Config, error) {
if err != nil {
return nil, err
}
} else {
if err := os.MkdirAll(configRoot, 0755); err != nil {
return nil, err
}
}

return &Config{
Expand Down
2 changes: 1 addition & 1 deletion internal/fetcher/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const (
Telegram Category = "telegram"
)

// Archive will return if this format is an archive.
// The Archive will return if this format is an archive.
func (f Format) Archive() bool {
return f == ZIP
}
Expand Down
6 changes: 5 additions & 1 deletion internal/fetcher/fetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ import (
"github.com/bookstairs/bookhunter/internal/progress"
)

const (
progressFile = "progress.db"
)

// Fetcher exposes the download method to the command line.
type Fetcher interface {
// Download the books from the given service.
Expand Down Expand Up @@ -44,7 +48,7 @@ func (f *commonFetcher) Download() error {
}

// Create download progress with ratelimit.
f.progress, err = progress.NewProgress(f.InitialBookID, size, f.RateLimit, filepath.Join(configPath, "process.db"))
f.progress, err = progress.NewProgress(f.InitialBookID, size, f.RateLimit, filepath.Join(configPath, progressFile))
if err != nil {
return err
}
Expand Down
66 changes: 66 additions & 0 deletions internal/fetcher/sanqiu.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package fetcher

import (
"errors"

"github.com/bookstairs/bookhunter/internal/client"
"github.com/bookstairs/bookhunter/internal/sanqiu"
)

var (
ErrEmptySanqiu = errors.New("couldn't find available books in sanqiu")
)

type sanqiuService struct {
config *Config
client *client.Client
}

func newSanqiuService(config *Config) (service, error) {
// Create the resty client for HTTP handing.
c, err := client.New(config.Config)
if err != nil {
return nil, err
}

return &sanqiuService{
config: config,
client: c,
}, nil
}

func (s *sanqiuService) size() (int64, error) {
resp, err := s.client.R().
SetQueryParams(map[string]string{
"orderby": "id",
"order": "desc",
"per_page": "1",
}).
Get("/wp-json/wp/v2/posts")

if err != nil {
return 0, err
}

books := make([]sanqiu.BookResp, 0, 1)
err = sanqiu.ParseAPIResponse(resp, books)
if err != nil {
return 0, err
}

if len(books) < 1 {
return 0, ErrEmptySanqiu
}

return books[0].ID, nil
}

func (s *sanqiuService) formats(id int64) (map[Format]string, error) {
// TODO implement me
panic("implement me")
}

func (s *sanqiuService) fetch(id int64, format Format, url string) (*fetch, error) {
// TODO implement me
panic("implement me")
}
6 changes: 4 additions & 2 deletions internal/fetcher/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,14 @@ func newService(c *Config) (service, error) {
case Talebook:
return newTalebookService(c)
case SanQiu:
return nil, errors.New("we don't support sanqiu now")
return newSanqiuService(c)
case Telegram:
return nil, errors.New("we don't support telegram now")
return newTelegramService(c)
case SoBooks:
// TODO We are working on this feature now.
return nil, errors.New("we don't support sobooks now")
case TianLang:
// TODO We are working on this feature now.
return nil, errors.New("we don't support tianlang now")
default:
return nil, fmt.Errorf("no such fetcher service [%s] supported", c.Category)
Expand Down
22 changes: 22 additions & 0 deletions internal/fetcher/telegram.go
Original file line number Diff line number Diff line change
@@ -1 +1,23 @@
package fetcher

type telegramService struct {
config *Config
}

func newTelegramService(config *Config) (service, error) {
return &telegramService{
config: config,
}, nil
}

func (s *telegramService) size() (int64, error) {
panic("implement me")
}

func (s *telegramService) formats(id int64) (map[Format]string, error) {
panic("implement me")
}

func (s *telegramService) fetch(id int64, format Format, url string) (*fetch, error) {
panic("implement me")
}
91 changes: 91 additions & 0 deletions internal/sanqiu/response.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package sanqiu

import (
"encoding/json"
"strings"

"github.com/go-resty/resty/v2"
)

// ParseAPIResponse will remove the unneeded error str in JSON response and try to parse it.
func ParseAPIResponse(resp *resty.Response, result any) error {
// Remove error messages.
str := resp.String()
str = str[strings.LastIndex(str, "\n")+1:]
decoder := json.NewDecoder(strings.NewReader(str))

return decoder.Decode(result)
}

// BookResp is the response for /wp-json/wp/v2/posts
type BookResp struct {
ID int64 `json:"id"`
Date string `json:"date"`
DateGmt string `json:"date_gmt"`
GUID struct {
Rendered string `json:"rendered"`
} `json:"guid"`
Modified string `json:"modified"`
ModifiedGmt string `json:"modified_gmt"`
Slug string `json:"slug"`
Status string `json:"status"`
Type string `json:"type"`
Link string `json:"link"`
Title struct {
Rendered string `json:"rendered"`
} `json:"title"`
Content struct {
Rendered string `json:"rendered"`
Protected bool `json:"protected"`
} `json:"content"`
Excerpt struct {
Rendered string `json:"rendered"`
Protected bool `json:"protected"`
} `json:"excerpt"`
Author int `json:"author"`
FeaturedMedia int `json:"featured_media"`
CommentStatus string `json:"comment_status"`
PingStatus string `json:"ping_status"`
Sticky bool `json:"sticky"`
Template string `json:"template"`
Format string `json:"format"`
Meta []interface{} `json:"meta"`
Categories []int `json:"categories"`
Tags []int `json:"tags"`
Links struct {
Self []struct {
Href string `json:"href"`
} `json:"self"`
Collection []struct {
Href string `json:"href"`
} `json:"collection"`
About []struct {
Href string `json:"href"`
} `json:"about"`
Author []struct {
Embeddable bool `json:"embeddable"`
Href string `json:"href"`
} `json:"author"`
Replies []struct {
Embeddable bool `json:"embeddable"`
Href string `json:"href"`
} `json:"replies"`
VersionHistory []struct {
Count int `json:"count"`
Href string `json:"href"`
} `json:"version-history"`
WpAttachment []struct {
Href string `json:"href"`
} `json:"wp:attachment"`
WpTerm []struct {
Taxonomy string `json:"taxonomy"`
Embeddable bool `json:"embeddable"`
Href string `json:"href"`
} `json:"wp:term"`
Curies []struct {
Name string `json:"name"`
Href string `json:"href"`
Templated bool `json:"templated"`
} `json:"curies"`
} `json:"_links"`
}

0 comments on commit d6b3a5c

Please sign in to comment.