initial release

This commit is contained in:
B4D_US3R 2025-03-06 10:12:47 +05:00
commit 7d673bfa17
4 changed files with 229 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
secret.conf
go.sum

2
config.yaml Normal file
View file

@ -0,0 +1,2 @@
instance: pleroma.catgirls.asia
rss_url: https://pleroma.catgirls.asia/users/SiberiaBread/feed.atom

25
go.mod Normal file
View file

@ -0,0 +1,25 @@
module kiki
go 1.21
require (
github.com/go-yaml/yaml v2.1.0+incompatible
github.com/mattn/go-mastodon v0.0.9
github.com/mmcdole/gofeed v1.3.0
github.com/urfave/cli/v3 v3.0.0-beta1
)
require (
github.com/PuerkitoBio/goquery v1.8.0 // indirect
github.com/andybalholm/cascadia v1.3.1 // indirect
github.com/gorilla/websocket v1.5.1 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mmcdole/goxpp v1.1.1-0.20240225020742-a0c311522b23 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 // indirect
golang.org/x/net v0.25.0 // indirect
golang.org/x/text v0.15.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)

200
main.go Normal file
View file

@ -0,0 +1,200 @@
package main
import (
"context"
"fmt"
"log"
"net/url"
"os"
"path/filepath"
"time"
"github.com/go-yaml/yaml"
"github.com/mattn/go-mastodon"
"github.com/mmcdole/gofeed"
"github.com/urfave/cli/v3"
)
type MastodonClientData struct {
ClientID string `yaml:"clientID,omitempty"`
ClientSecret string `yaml:"clientSecret,omitempty"`
AccessToken string `yaml:"accessToken,omitempty"`
Instance string `yaml:"instance,omitempty"`
}
type KikiSettings struct {
Instance string `yaml:"instance,omitempty"`
RSSUri string `yaml:"rss_url,omitempty"`
}
func getDataFromConfig(path string) *mastodon.Config {
var clientData MastodonClientData
secretConfig, err := os.ReadFile(path)
if err != nil {
log.Println(err)
}
err = yaml.Unmarshal(secretConfig, &clientData)
if err != nil {
log.Println(err)
}
config := &mastodon.Config{
Server: clientData.Instance,
ClientID: clientData.ClientID,
ClientSecret: clientData.ClientSecret,
AccessToken: clientData.AccessToken,
}
return config
}
func getKikiConfig(path string) KikiSettings {
var kikiSettings KikiSettings
kikiConfigFile, err := os.ReadFile(path)
if err != nil {
log.Println(err)
}
err = yaml.Unmarshal(kikiConfigFile, &kikiSettings)
if err != nil {
log.Println(err)
}
return kikiSettings
}
func ClientConfiguration(Instance string) {
appConfig := &mastodon.AppConfig{
Server: Instance,
ClientName: "Kiki",
Scopes: "read write follow",
Website: "catgirls.asia",
RedirectURIs: "urn:ietf:wg:oauth:2.0:oob",
}
app, err := mastodon.RegisterApp(context.Background(), appConfig)
if err != nil {
log.Println(err)
}
u, err := url.Parse(app.AuthURI)
if err != nil {
log.Println(err)
}
var userToken string
fmt.Println(u)
fmt.Scanln(&userToken)
config := &mastodon.Config{
Server: Instance,
ClientID: app.ClientID,
ClientSecret: app.ClientSecret,
AccessToken: userToken,
}
mastoClient := mastodon.NewClient(config)
err = mastoClient.AuthenticateToken(context.Background(), userToken, "urn:ietf:wg:oauth:2.0:oob")
if err != nil {
log.Println(err)
}
clientData := MastodonClientData{
Instance: Instance,
ClientID: mastoClient.Config.ClientID,
ClientSecret: mastoClient.Config.ClientSecret,
AccessToken: mastoClient.Config.AccessToken,
}
marshaledYaml, err := yaml.Marshal(clientData)
if err != nil {
log.Println(err)
}
secretConfig, err := os.OpenFile("secret.conf", os.O_CREATE, 0o644)
if err != nil {
log.Println(err)
}
secretConfig.WriteString(string(marshaledYaml))
}
func newsText(url string) []*gofeed.Item {
fp := gofeed.NewParser()
feed, err := fp.ParseURL(url)
if err != nil {
log.Println(err)
}
log.Println("RSS лента получена")
return feed.Items
}
func createPost(statusText string) {
config := getDataFromConfig("secret.conf")
mastoClient := mastodon.NewClient(config)
toot := mastodon.Toot{
Status: statusText,
Visibility: "unlisted",
}
_, err := mastoClient.PostStatus(context.Background(), &toot)
if err != nil {
log.Println(err)
}
}
func main() {
cmd := &cli.Command{
Name: "kiki",
Usage: "Ретранслятор из RSS в Mastodon. Когда-нибудь...",
Commands: []*cli.Command{
{
Name: "init",
Usage: "Инициализировать клиента",
Action: func(ctx context.Context, cmd *cli.Command) error {
confFile, err := filepath.Abs("config.yaml")
if err != nil {
log.Println(err)
}
kikiConfig := getKikiConfig(confFile)
instanceUrlParser, err := url.Parse(kikiConfig.Instance)
if err != nil {
log.Println(err)
}
instanceUrlParser.Scheme = "https"
ClientConfiguration(instanceUrlParser.String())
return nil
},
},
{
Name: "run",
Usage: "Запуск транслятора",
Action: func(ctx context.Context, cmd *cli.Command) error {
var lastGUID string
confFile, err := filepath.Abs("config.yaml")
if err != nil {
log.Println(err)
}
kikiConfig := getKikiConfig(confFile)
ticker := time.NewTicker(1 * time.Minute)
defer ticker.Stop()
for range ticker.C {
news := newsText(kikiConfig.RSSUri)
if news[0].GUID != lastGUID {
createPost(news[0].Description)
lastGUID = news[0].GUID
log.Println("Пост отправлен")
}
/*for _, item := range newsText(kikiConfig.RSSUri) {
if item.GUID == lastGUID {
break
}
createPost(item.Description)
lastGUID = item.GUID
log.Println("Пост отправлен")
}*/
}
return nil
},
},
},
}
if err := cmd.Run(context.Background(), os.Args); err != nil {
log.Fatal(err)
}
}