You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
145 lines
3.5 KiB
145 lines
3.5 KiB
package main |
|
|
|
import ( |
|
"encoding/json" |
|
"fmt" |
|
"log" |
|
"reflect" |
|
"strings" |
|
"time" |
|
|
|
"github.com/boltdb/bolt" |
|
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" |
|
"golang.org/x/net/html" |
|
) |
|
|
|
func in_array(val interface{}, array interface{}) (exists bool) { |
|
exists = false |
|
|
|
switch reflect.TypeOf(array).Kind() { |
|
case reflect.Slice: |
|
s := reflect.ValueOf(array) |
|
|
|
for i := 0; i < s.Len(); i++ { |
|
if reflect.DeepEqual(val, s.Index(i).Interface()) == true { |
|
exists = true |
|
return |
|
} |
|
} |
|
} |
|
|
|
return |
|
} |
|
|
|
func NormalizeHTMLforTelegram(s string) (out string) { |
|
|
|
tags := []string{"br", "img", "b", "strong", "i", "em", "code", "s", "strike", "del", "u", "pre"} |
|
|
|
domDocTest := html.NewTokenizer(strings.NewReader(s)) |
|
previousStartTokenTest := domDocTest.Token() |
|
flagendtag := false |
|
for { |
|
tt := domDocTest.Next() |
|
if len(out) > 2500 { |
|
if e := in_array(previousStartTokenTest.Data, tags) && previousStartTokenTest.Data != "img" && previousStartTokenTest.Data != "br" && !flagendtag; e { |
|
out += fmt.Sprintf("</%s> ...", previousStartTokenTest.Data) |
|
} else { |
|
out += " ..." |
|
} |
|
return |
|
} |
|
switch { |
|
case tt == html.ErrorToken: |
|
return |
|
case tt == html.StartTagToken: |
|
previousStartTokenTest = domDocTest.Token() |
|
if e := in_array(previousStartTokenTest.Data, tags); e { |
|
switch { |
|
case previousStartTokenTest.Data == "br": |
|
out += "\n" |
|
case previousStartTokenTest.Data == "img" && previousStartTokenTest.Attr[0].Key == "src": |
|
out += fmt.Sprintf("%s ", previousStartTokenTest.Attr[0].Val) |
|
// case previousStartTokenTest.Data == "a" && previousStartTokenTest.Attr[0].Key == "href": |
|
// out += fmt.Sprintf(" %s ", previousStartTokenTest.Attr[0].Val) |
|
default: |
|
out += fmt.Sprintf(" <%s>", previousStartTokenTest.Data) |
|
} |
|
flagendtag = false |
|
} |
|
case tt == html.EndTagToken: |
|
t := domDocTest.Token() |
|
if e := in_array(t.Data, tags); e { |
|
// switch { |
|
// case t.Data == "a": |
|
// out += " " |
|
// default: |
|
out += fmt.Sprintf("</%s> ", t.Data) |
|
// } |
|
flagendtag = true |
|
} |
|
case tt == html.SelfClosingTagToken: |
|
t := domDocTest.Token() |
|
if e := in_array(t.Data, tags); e { |
|
if t.Data == "br" { |
|
out += "\n" |
|
} |
|
} |
|
case tt == html.TextToken: |
|
if previousStartTokenTest.Data == "script" { |
|
continue |
|
} |
|
TxtContent := strings.TrimSpace(html.UnescapeString(string(domDocTest.Text()))) |
|
if len(TxtContent) > 0 { |
|
out += html.EscapeString(TxtContent) |
|
} |
|
} |
|
} |
|
} |
|
|
|
func SendAndWriteToDB(send SendItems, dbpath string, rssname string, token string, chatid int64, debug bool) error { |
|
|
|
db, err := bolt.Open(dbpath, 0600, nil) |
|
if err != nil { |
|
log.Fatal(err) |
|
} |
|
defer db.Close() |
|
|
|
for i := len(send.ItemList) - 1; i >= 0; i-- { |
|
v := send.ItemList[i] |
|
log.Printf("Send to telegram post: %s", v.Title) |
|
bot, err := tgbotapi.NewBotAPI(token) |
|
if err != nil { |
|
log.Panic(err) |
|
} |
|
bot.Debug = debug |
|
|
|
s := "<i>" + rssname + "</i>\n\n" + "<b>" + string(v.Title) + "</b>\n\n" + NormalizeHTMLforTelegram(html.UnescapeString(string(v.Description))) + |
|
"\n\n" + v.Link |
|
msg := tgbotapi.NewMessage(chatid, s) |
|
msg.ParseMode = "Html" |
|
_, err = bot.Send(msg) |
|
if err != nil { |
|
log.Panic(err) |
|
|
|
} |
|
duration := time.Duration(10) * time.Second |
|
time.Sleep(duration) |
|
|
|
db.Update(func(tx *bolt.Tx) error { |
|
b, err := tx.CreateBucketIfNotExists([]byte(rssname)) |
|
if err != nil { |
|
return err |
|
} |
|
encoded, err := json.Marshal(v) |
|
if err != nil { |
|
return err |
|
} |
|
err = b.Put([]byte(v.Link), encoded) |
|
if err != nil { |
|
return err |
|
} |
|
return nil |
|
}) |
|
} |
|
return nil |
|
}
|
|
|