From c5caeecde88887bc9a02c85ccd2954126bad633d Mon Sep 17 00:00:00 2001 From: B4D_US3R Date: Thu, 10 Apr 2025 15:34:42 +0500 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=B1=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=B8=20=D0=BF=D0=BE=D1=81=D1=82=D0=B8=D0=BD?= =?UTF-8?q?=D0=B3=20=D0=BA=D0=B0=D1=80=D1=82=D0=B8=D0=BD=D0=BE=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + config.example.yaml | 2 + go.mod | 18 ++++---- main.go | 100 ++++++++++++++++++++++++++++++++++++++------ 4 files changed, 101 insertions(+), 20 deletions(-) create mode 100644 config.example.yaml diff --git a/.gitignore b/.gitignore index 363e416..bdd4986 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ secret.conf go.sum +config.yaml \ No newline at end of file diff --git a/config.example.yaml b/config.example.yaml new file mode 100644 index 0000000..3b02854 --- /dev/null +++ b/config.example.yaml @@ -0,0 +1,2 @@ +instance: https://pleroma.catgirls.asia +rss_url: https://4pda.to/feed \ No newline at end of file diff --git a/go.mod b/go.mod index 36ff9f2..4c8a8ee 100644 --- a/go.mod +++ b/go.mod @@ -1,25 +1,27 @@ module kiki -go 1.21 +go 1.23.0 + +toolchain go1.24.2 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 + github.com/urfave/cli/v3 v3.1.1 + golang.org/x/net v0.39.0 ) 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/PuerkitoBio/goquery v1.10.2 // indirect + github.com/andybalholm/cascadia v1.3.3 // indirect + github.com/gorilla/websocket v1.5.3 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/mmcdole/goxpp v1.1.1-0.20240225020742-a0c311522b23 // indirect + github.com/mmcdole/goxpp v1.1.1 // 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 + golang.org/x/text v0.24.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/main.go b/main.go index 98dfe9e..07eab1b 100644 --- a/main.go +++ b/main.go @@ -3,17 +3,22 @@ package main import ( "context" "fmt" + "io" "log" + "net/http" "net/url" "os" "path/filepath" "regexp" + "strings" "time" "github.com/go-yaml/yaml" "github.com/mattn/go-mastodon" "github.com/mmcdole/gofeed" "github.com/urfave/cli/v3" + "golang.org/x/net/html" + "golang.org/x/net/html/atom" ) type MastodonClientData struct { @@ -48,6 +53,25 @@ func getDataFromConfig(path string) *mastodon.Config { return config } +func returnImgArray(htmlText string) []string { + var imgArray []string + parser, err := html.Parse(strings.NewReader(htmlText)) + if err != nil { + log.Println(err) + } + for n := range parser.Descendants() { + if n.Type == html.ElementNode && n.DataAtom == atom.Img { + for _, img := range n.Attr { + if img.Key == "src" { + imgArray = append(imgArray, img.Val) + } + } + } + } + + return imgArray +} + func hasHTMLTags(s string) bool { re := regexp.MustCompile(`<(?i)[a-z][a-z0-9]*[^>]*>`) return re.MatchString(s) @@ -66,7 +90,7 @@ func getKikiConfig(path string) KikiSettings { return kikiSettings } -func ClientConfiguration(Instance string) { +func clientConfiguration(Instance string) { appConfig := &mastodon.AppConfig{ Server: Instance, ClientName: "Kiki", @@ -111,11 +135,13 @@ func ClientConfiguration(Instance string) { if err != nil { log.Println(err) } - secretConfig, err := os.OpenFile("secret.conf", os.O_CREATE, 0o644) + log.Println(string(marshaledYaml)) + secretConfig, err := os.OpenFile("secret.conf", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0o644) if err != nil { log.Println(err) } - secretConfig.WriteString(string(marshaledYaml)) + secretConfig.Write(marshaledYaml) + defer secretConfig.Close() } func newsText(url string) []*gofeed.Item { @@ -144,6 +170,59 @@ func createPost(statusText string) { } } +func picBytesArray(picturesArray []string) [][]byte { + var picturesBytes [][]byte + for _, picture := range picturesArray { + resp, err := http.Get(picture) + if err != nil { + log.Println(err) + return picturesBytes + } + defer resp.Body.Close() + picBytes, err := io.ReadAll(resp.Body) + if err != nil { + log.Println(err) + return picturesBytes + } + picturesBytes = append(picturesBytes, picBytes) + } + return picturesBytes +} + +func uploadPictures(filesBytes [][]byte) []*mastodon.Attachment { + config := getDataFromConfig("secret.conf") + var attachments []*mastodon.Attachment + mastoClient := mastodon.NewClient(config) + for _, file := range filesBytes { + att, err := mastoClient.UploadMediaFromBytes(context.Background(), file) + if err != nil { + log.Println(err) + return attachments + } + attachments = append(attachments, att) + } + return attachments +} + +func postWithPictures(attachments []*mastodon.Attachment) { + var mediaID []mastodon.ID + config := getDataFromConfig("secret.conf") + mastoClient := mastodon.NewClient(config) + for _, attach := range attachments { + mediaID = append(mediaID, attach.ID) + } + toot := mastodon.Toot{ + MediaIDs: mediaID, + Visibility: "unlisted", + Sensitive: true, + } + _, err := mastoClient.PostStatus(context.Background(), &toot) + if err != nil { + log.Println(err) + } + +} + func main() { cmd := &cli.Command{ Name: "kiki", @@ -163,7 +242,7 @@ func main() { log.Println(err) } instanceUrlParser.Scheme = "https" - ClientConfiguration(instanceUrlParser.String()) + clientConfiguration(instanceUrlParser.String()) return nil }, }, @@ -183,19 +262,16 @@ func main() { news := newsText(kikiConfig.RSSUri) if news[0].GUID != lastGUID { if !hasHTMLTags(news[0].Description) { + log.Println(news[0].Description) createPost(news[0].Description) lastGUID = news[0].GUID log.Println("Пост отправлен") + } else { + attachments := uploadPictures(picBytesArray(returnImgArray(news[0].Description))) + postWithPictures(attachments) + lastGUID = news[0].GUID } } - /*for _, item := range newsText(kikiConfig.RSSUri) { - if item.GUID == lastGUID { - break - } - createPost(item.Description) - lastGUID = item.GUID - log.Println("Пост отправлен") - }*/ } return nil },