generated from alecodes/base-template
feat: add basic linkding connection
This commit is contained in:
parent
43cd24e4d0
commit
43f6340a4a
8 changed files with 163 additions and 16 deletions
|
|
@ -9,10 +9,11 @@ import (
|
||||||
|
|
||||||
"git.alecodes.page/alecodes/miniflux-archiver/internal/app"
|
"git.alecodes.page/alecodes/miniflux-archiver/internal/app"
|
||||||
"git.alecodes.page/alecodes/miniflux-archiver/internal/miniflux"
|
"git.alecodes.page/alecodes/miniflux-archiver/internal/miniflux"
|
||||||
|
"git.alecodes.page/alecodes/miniflux-archiver/internal/service"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Services = []string{
|
var Services = []string{
|
||||||
"linkding",
|
string(service.ServiceLinkding),
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -29,13 +30,13 @@ var archiveCmd = &cobra.Command{
|
||||||
Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs),
|
Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs),
|
||||||
ValidArgs: Services,
|
ValidArgs: Services,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
service := args[0]
|
serviceOption := service.ServiceOption(args[0])
|
||||||
|
|
||||||
serviceConfig := app.ServiceConfig{
|
serviceConfig := service.ServiceConfig{
|
||||||
Service: service,
|
Service: serviceOption,
|
||||||
Host: service_host,
|
Host: viper.GetString("service_host"),
|
||||||
User: service_user,
|
User: viper.GetString("service_user"),
|
||||||
Token: service_token,
|
Token: viper.GetString("service_token"),
|
||||||
}
|
}
|
||||||
|
|
||||||
minifluxConfig := miniflux.MinifluxConfig{
|
minifluxConfig := miniflux.MinifluxConfig{
|
||||||
|
|
|
||||||
1
go.mod
1
go.mod
|
|
@ -16,6 +16,7 @@ require (
|
||||||
github.com/magiconair/properties v1.8.7 // indirect
|
github.com/magiconair/properties v1.8.7 // indirect
|
||||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||||
|
github.com/piero-vic/go-linkding v0.2.0 // indirect
|
||||||
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
||||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||||
|
|
|
||||||
2
go.sum
2
go.sum
|
|
@ -25,6 +25,8 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua
|
||||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
||||||
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||||
|
github.com/piero-vic/go-linkding v0.2.0 h1:1LNIeWvYe8Kd+kaG4hsWzYH/vvQ9OaJOMoV+XvXaH+Q=
|
||||||
|
github.com/piero-vic/go-linkding v0.2.0/go.mod h1:PuwOySAQYmbq4cIDAG1bXDMQwBUuorRkbjM43RdUhao=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,20 @@ import (
|
||||||
|
|
||||||
"git.alecodes.page/alecodes/miniflux-archiver/internal/logger"
|
"git.alecodes.page/alecodes/miniflux-archiver/internal/logger"
|
||||||
"git.alecodes.page/alecodes/miniflux-archiver/internal/miniflux"
|
"git.alecodes.page/alecodes/miniflux-archiver/internal/miniflux"
|
||||||
|
"git.alecodes.page/alecodes/miniflux-archiver/internal/service"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Archive(minifluxConfig miniflux.MinifluxConfig, serviceConfig ServiceConfig) {
|
func Archive(minifluxConfig miniflux.MinifluxConfig, serviceConfig service.ServiceConfig) {
|
||||||
mf, err := miniflux.NewMiniflux(minifluxConfig)
|
mf, err := miniflux.NewMiniflux(minifluxConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Fatal("Could not connect to the miniflux server: %v", err)
|
logger.Fatal("Could not connect to the miniflux server: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
externalService, err := service.ResolveService(serviceConfig)
|
||||||
|
if err != nil {
|
||||||
|
logger.Fatal(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
result, err := mf.GetEntries()
|
result, err := mf.GetEntries()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Fatal("Could not retrieve entries from the miniflux feed: %v", err)
|
logger.Fatal("Could not retrieve entries from the miniflux feed: %v", err)
|
||||||
|
|
@ -20,4 +26,9 @@ func Archive(minifluxConfig miniflux.MinifluxConfig, serviceConfig ServiceConfig
|
||||||
|
|
||||||
entry := result.Entries[0]
|
entry := result.Entries[0]
|
||||||
fmt.Println(entry.Title, entry.Status, entry.Tags)
|
fmt.Println(entry.Title, entry.Status, entry.Tags)
|
||||||
|
|
||||||
|
err = externalService.Archive(entry.URL)
|
||||||
|
if err != nil {
|
||||||
|
logger.Fatal("Could not archive entry from the service: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
package app
|
|
||||||
|
|
||||||
type ServiceConfig struct {
|
|
||||||
Service string
|
|
||||||
Host string
|
|
||||||
User string
|
|
||||||
Token string
|
|
||||||
}
|
|
||||||
17
internal/config/config.go
Normal file
17
internal/config/config.go
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
package config
|
||||||
|
|
||||||
|
import "git.alecodes.page/alecodes/miniflux-archiver/internal/service"
|
||||||
|
|
||||||
|
type MinifluxConfig struct {
|
||||||
|
Host string
|
||||||
|
User string
|
||||||
|
Token string
|
||||||
|
FeedId int64
|
||||||
|
}
|
||||||
|
|
||||||
|
type ServiceConfig struct {
|
||||||
|
Service service.ServiceOption
|
||||||
|
Host string
|
||||||
|
User string
|
||||||
|
Token string
|
||||||
|
}
|
||||||
81
internal/service/linkding.go
Normal file
81
internal/service/linkding.go
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
ldApi "github.com/piero-vic/go-linkding"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Linkding struct {
|
||||||
|
ServiceConfig
|
||||||
|
client *ldApi.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ld *Linkding) CheckBookmark(url string) (*ldApi.Bookmark, error) {
|
||||||
|
bookmark := &ldApi.Bookmark{}
|
||||||
|
|
||||||
|
req, err := http.NewRequest(
|
||||||
|
http.MethodGet,
|
||||||
|
fmt.Sprintf("%v/api/bookmarks/check/?url=%d", ld.Host, url),
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return bookmark, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Add("Content-Type", "application/json")
|
||||||
|
req.Header.Add("Accept", "application/json")
|
||||||
|
req.Header.Add("Authorization", fmt.Sprintf("Token %s", ld.Token))
|
||||||
|
|
||||||
|
res, err := http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return bookmark, err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
if err := json.NewDecoder(res.Body).Decode(bookmark); err != nil {
|
||||||
|
return bookmark, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return bookmark, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ld *Linkding) Archive(url string) error {
|
||||||
|
bookmark, err := ld.CheckBookmark(url)
|
||||||
|
|
||||||
|
payload := ldApi.CreateBookmarkRequest{
|
||||||
|
URL: url,
|
||||||
|
Unread: false,
|
||||||
|
TagNames: bookmark.TagNames,
|
||||||
|
}
|
||||||
|
|
||||||
|
if payload.TagNames == nil {
|
||||||
|
payload.TagNames = []string{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
_, err = ld.client.UpdateBookmark(bookmark.ID, payload)
|
||||||
|
} else {
|
||||||
|
_, err = ld.client.CreateBookmark(payload)
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ld *Linkding) IsAvailable() (bool, error) {
|
||||||
|
_, err := ld.client.ListTags(ldApi.ListTagsParams{})
|
||||||
|
|
||||||
|
return err == nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLinkding(config ServiceConfig) (*Linkding, error) {
|
||||||
|
mf := &Linkding{
|
||||||
|
ServiceConfig: config,
|
||||||
|
client: ldApi.NewClient(config.Host, config.Token),
|
||||||
|
}
|
||||||
|
|
||||||
|
return mf, nil
|
||||||
|
}
|
||||||
42
internal/service/service.go
Normal file
42
internal/service/service.go
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
package service
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type ServiceOption string
|
||||||
|
|
||||||
|
const (
|
||||||
|
ServiceLinkding ServiceOption = "linkding"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ServiceConfig struct {
|
||||||
|
Service ServiceOption
|
||||||
|
Host string
|
||||||
|
User string
|
||||||
|
Token string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Service interface {
|
||||||
|
IsAvailable() (bool, error)
|
||||||
|
Archive(string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
func ResolveService(serviceConfig ServiceConfig) (Service, error) {
|
||||||
|
var service Service
|
||||||
|
switch serviceConfig.Service {
|
||||||
|
case ServiceLinkding:
|
||||||
|
service, _ = NewLinkding(serviceConfig)
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("Could not determine service to connect to")
|
||||||
|
}
|
||||||
|
|
||||||
|
if isAvailable, err := service.IsAvailable(); !isAvailable {
|
||||||
|
return nil, fmt.Errorf(
|
||||||
|
"Could not connect to the service %v in %v: %v",
|
||||||
|
serviceConfig.Service,
|
||||||
|
serviceConfig.Host,
|
||||||
|
err,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return service, nil
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue