1
0
Fork 0
neonmodem/system/lobsters/lobsters.go

250 lines
4.4 KiB
Go

package lobsters
import (
"context"
"fmt"
"net/http"
"net/url"
"time"
md "github.com/JohannesKaufmann/html-to-markdown"
"github.com/araddon/dateparse"
"github.com/mrusme/neonmodem/models/author"
"github.com/mrusme/neonmodem/models/forum"
"github.com/mrusme/neonmodem/models/post"
"github.com/mrusme/neonmodem/models/reply"
"github.com/mrusme/neonmodem/system/adapter"
"github.com/mrusme/neonmodem/system/lobsters/api"
"go.uber.org/zap"
)
type System struct {
ID int
config map[string]interface{}
logger *zap.SugaredLogger
client *api.Client
}
func (sys *System) GetID() int {
return sys.ID
}
func (sys *System) SetID(id int) {
sys.ID = id
}
func (sys *System) GetConfig() map[string]interface{} {
return sys.config
}
func (sys *System) SetConfig(cfg *map[string]interface{}) {
sys.config = *cfg
}
func (sys *System) SetLogger(logger *zap.SugaredLogger) {
sys.logger = logger
}
func (sys *System) GetCapabilities() adapter.Capabilities {
var caps []adapter.Capability
caps = append(caps,
// TODO: Requires accounts
// adapter.Capability{
// ID: "connect:multiple",
// Name: "Connect Multiple",
// },
adapter.Capability{
ID: "list:forums",
Name: "List Forums",
},
adapter.Capability{
ID: "list:posts",
Name: "List Posts",
},
// adapter.Capability{
// ID: "create:post",
// Name: "Create Post",
// },
adapter.Capability{
ID: "list:replies",
Name: "List Replies",
},
// adapter.Capability{
// ID: "create:reply",
// Name: "Create Reply",
// },
)
return caps
}
func (sys *System) FilterValue() string {
return fmt.Sprintf(
"Lobsters %s",
sys.config["url"],
)
}
func (sys *System) Title() string {
sysUrl := sys.config["url"].(string)
u, err := url.Parse(sysUrl)
if err != nil {
return sysUrl
}
return u.Hostname()
}
func (sys *System) Description() string {
return fmt.Sprintf(
"Lobsters",
)
}
func (sys *System) Load() error {
url := sys.config["url"]
if url == nil {
return nil
}
credentials := make(map[string]string)
sys.client = api.NewClient(&api.ClientConfig{
Endpoint: url.(string),
Credentials: credentials,
HTTPClient: http.DefaultClient,
Logger: sys.logger,
})
return nil
}
func (sys *System) ListForums() ([]forum.Forum, error) {
var models []forum.Forum
tags, err := sys.client.Tags.List(context.Background())
if err != nil {
return []forum.Forum{}, err
}
for _, tag := range *tags {
models = append(models, forum.Forum{
ID: tag.Tag,
Name: tag.Tag,
Info: tag.Description,
SysIDX: sys.ID,
})
}
return models, nil
}
func (sys *System) ListPosts(forumID string) ([]post.Post, error) {
var err error
items, err := sys.client.Stories.List(context.Background(), forumID)
if err != nil {
return []post.Post{}, err
}
var models []post.Post
for _, i := range *items {
createdAt, err := dateparse.ParseAny(i.CreatedAt)
if err != nil {
createdAt = time.Now() // TODO: Errrr
}
models = append(models, post.Post{
ID: i.ShortID,
Subject: i.Title,
Type: "url",
Pinned: false,
Closed: false,
CreatedAt: createdAt,
LastCommentedAt: createdAt, // TODO
Author: author.Author{
ID: i.SubmitterUser.Username,
Name: i.SubmitterUser.Username,
},
Forum: forum.Forum{
ID: i.Tags[0],
Name: i.Tags[0], // TODO: Tag description
SysIDX: sys.ID,
},
URL: i.ShortIDURL,
SysIDX: sys.ID,
})
}
return models, nil
}
func (sys *System) LoadPost(p *post.Post) error {
item, err := sys.client.Stories.Show(context.Background(), p.ID)
if err != nil {
return err
}
converter := md.NewConverter("", true, nil)
p.Replies = []reply.Reply{}
for idx, i := range item.Comments {
cookedMd, err := converter.ConvertString(i.Comment)
if err != nil {
cookedMd = i.CommentPlain
}
if idx == 0 {
p.Body = cookedMd
continue
}
createdAt, err := dateparse.ParseAny(i.CreatedAt)
if err != nil {
createdAt = time.Now() // TODO: Errrrrr
}
inReplyTo := i.ParentComment
if inReplyTo == "" {
inReplyTo = p.ID
}
p.Replies = append(p.Replies, reply.Reply{
ID: i.ShortID,
InReplyTo: inReplyTo,
Body: cookedMd,
CreatedAt: createdAt,
Author: author.Author{
ID: i.CommentingUser.Username,
Name: i.CommentingUser.Username,
},
SysIDX: sys.ID,
})
}
return nil
}
func (sys *System) CreatePost(p *post.Post) error {
return nil
}
func (sys *System) CreateReply(r *reply.Reply) error {
return nil
}