Files
rss2wallabag/rss2wallabag.go
2022-03-25 15:19:01 +01:00

218 lines
5.4 KiB
Go

package main
import (
"bytes"
"encoding/json"
"log"
"net/http"
"gopkg.in/yaml.v2"
"io/ioutil"
"github.com/ungerik/go-rss"
"os"
"sync"
"strings"
"time"
"fmt"
)
//Structure de configuration du client Wallabag
type walla struct {
Url string `yaml:"host"`
Client_id string `yaml:"client_id"`
Client_secret string `yaml:"client_secret"`
Username string `yaml:"username"`
Password string `yaml:"password"`
Token string
}
//Structure rss
type sites struct {
Tags []string `yaml:"tags"`
Url string `yaml:"url"`
}
type Sites map[string]sites
//Get configuration from yaml file config.yaml
func (w *walla) getWallaConf() *walla {
yamlFile, err := ioutil.ReadFile("config.yaml")
if err != nil {
log.Printf("yamlFile.Get err #%v ", err)
}
err = yaml.UnmarshalStrict(yamlFile, w)
if err != nil {
log.Fatalf("Unmarshal: %v", err)
}
return w
}
//Get rss url and tags
func (c *Sites) getConf() *Sites {
yamlFile, err := ioutil.ReadFile("sites.yaml")
if err != nil {
log.Printf("yamlFile.Get err #%v ", err)
}
err = yaml.Unmarshal(yamlFile, c)
if err != nil {
log.Fatalf("Unmarshal: %v", err)
}
return c
}
//Get wallaba auth token
func (Walla *walla) Auth() *walla {
message := map[string]interface{}{
"grant_type":"password",
"client_id":Walla.Client_id,
"client_secret":Walla.Client_secret,
"username":Walla.Username,
"password":Walla.Password,
}
requestBody,err := json.Marshal(message)
if err != nil {
log.Fatalln(err)
}
resp, err := http.Post(Walla.Url+"/oauth/v2/token", "application/json", bytes.NewBuffer(requestBody))
if err != nil {
log.Fatalln(err)
}
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
Walla.Token=result["access_token"].(string)
return Walla
}
//Add a new article
func WallaAddUrl(Walla walla, url string, tags []string, title string) {
bearer := "Bearer " + Walla.Token
message := map[string]interface{}{
"url":url,
"tags":strings.Join(tags, ","),
}
requestBody,err := json.Marshal(message)
if err != nil {
log.Fatalln(err)
}
req, err := http.NewRequest("POST", Walla.Url+"/api/entries.json", bytes.NewBuffer(requestBody))
req.Header.Set("Content-Type", "application/json")
req.Header.Add("Authorization", bearer)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
log.Fatalln(err)
}
//Correction du titre
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
var id float64
id=result["id"].(float64)
defer resp.Body.Close()
message = map[string]interface{}{
"title":title,
}
requestBody,err = json.Marshal(message)
if err != nil {
log.Fatalln(err)
}
req, err = http.NewRequest("PATCH", Walla.Url+"/api/entries/"+fmt.Sprint(id)+".json", bytes.NewBuffer(requestBody))
req.Header.Set("Content-Type", "application/json")
req.Header.Add("Authorization", bearer)
client = &http.Client{}
resp, err = client.Do(req)
if err != nil {
log.Fatalln(err)
}
defer resp.Body.Close()
}
//Check if an article already exists in wallabag
func WallaCheckArticleExists(Walla walla, url string) bool {
bearer := "Bearer " + Walla.Token
client := &http.Client{}
req, err := http.NewRequest("GET", Walla.Url+"/api/entries/exists.json?url="+url, nil)
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Authorization", bearer)
resp, err := client.Do(req)
if err != nil {
log.Fatalln(err)
}
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
defer resp.Body.Close()
return result["exists"].(bool)
}
//Proccess rss and add new articles
func ProcessRss(k sites, wg *sync.WaitGroup, Walla walla) {
defer wg.Done()
var exists bool
client := &http.Client{Timeout: 25 * time.Second}
resp, err := rss.ReadWithClient(k.Url,client, false)
if err != nil {
log.Println(err)
}
channel, err := rss.Regular(resp)
for _, item := range channel.Item {
exists = WallaCheckArticleExists(Walla, item.Link)
//Mediapart fix
if(!exists){
exists = WallaCheckArticleExists(Walla, item.Link+"?onglet=full")
}
if(exists) {
log.Println(channel.Title+ " : " + item.Title + " Already exists skipping")
} else {
log.Println(channel.Title + " : " + "Adding " + item.Title)
WallaAddUrl(Walla, item.Link, k.Tags, item.Title)
}
}
}
func main() {
file, err := os.OpenFile("info.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
if err != nil {
log.Fatal(err)
}
defer file.Close()
log.SetOutput(file)
var MyWalla walla
MyWalla.getWallaConf()
MyWalla.Auth()
var c Sites
c.getConf()
log.Println(c)
var wg sync.WaitGroup
for k := range c {
wg.Add(1)
go ProcessRss(c[k], &wg, MyWalla)
}
wg.Wait()
log.Println("All done")
}