-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit ac3651b
Showing
10 changed files
with
401 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
*.env | ||
news.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
.PHONY: fmt | ||
fmt: | ||
go mod tidy | ||
go fmt ./... | ||
|
||
.PHONY: refresh | ||
refresh: | ||
go run cmd/refresh_news/main.go |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package main | ||
|
||
import ( | ||
"encoding/json" | ||
"log" | ||
"net/http" | ||
"os" | ||
|
||
"sarcastick/pkg/news" | ||
|
||
"golang.org/x/net/html" | ||
) | ||
|
||
func main() { | ||
response, err := http.Get("https://www.expats.cz") | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
defer response.Body.Close() | ||
|
||
if response.StatusCode != http.StatusOK { | ||
log.Fatalf("HTTP request failed with status code %d", response.StatusCode) | ||
} | ||
|
||
htmlBody, err := html.Parse(response.Body) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
link := news.FindNewsLink(htmlBody) | ||
if link == "" { | ||
log.Fatal("No link found") | ||
} | ||
|
||
response, err = http.Get("https://www.expats.cz" + link) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
defer response.Body.Close() | ||
|
||
if response.StatusCode != http.StatusOK { | ||
log.Fatalf("HTTP request failed with status code %d", response.StatusCode) | ||
} | ||
|
||
htmlBody, err = html.Parse(response.Body) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
ct := news.ExtractContentWithTitle(htmlBody) | ||
file, err := os.Create("news.json") | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
err = json.NewEncoder(file).Encode(ct) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
module sarcastick | ||
|
||
go 1.21 | ||
|
||
require golang.org/x/net v0.24.0 | ||
|
||
require github.com/go-telegram/bot v1.2.1 | ||
|
||
require github.com/sashabaranov/go-openai v1.20.5 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
github.com/go-telegram/bot v1.2.1 h1:FkrixLCtMtPUQAN4plXdNElbhkdXkx2p68YPXKBruDg= | ||
github.com/go-telegram/bot v1.2.1/go.mod h1:i2TRs7fXWIeaceF3z7KzsMt/he0TwkVC680mvdTFYeM= | ||
github.com/sashabaranov/go-openai v1.20.5 h1:Sab4nzBLtoyxm4jRqH9G9pkIh50WpBFacPTEpruPB6o= | ||
github.com/sashabaranov/go-openai v1.20.5/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg= | ||
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= | ||
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package main | ||
|
||
import ( | ||
"context" | ||
"log" | ||
"os" | ||
"regexp" | ||
"sarcastick/pkg/news" | ||
"sarcastick/pkg/openai" | ||
"strings" | ||
|
||
"github.com/go-telegram/bot" | ||
"github.com/go-telegram/bot/models" | ||
) | ||
|
||
var detailsRegex = regexp.MustCompile("^/details [0-9]*$") | ||
var sarcasmRegex = regexp.MustCompile("^/sarcasm [0-9]*$") | ||
|
||
func main() { | ||
b, err := bot.New(os.Getenv("TELEGRAM_BOT_KEY")) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
client := openai.NewClient() | ||
b.RegisterHandler(bot.HandlerTypeMessageText, "/start", bot.MatchTypeExact, helpHandler) | ||
b.RegisterHandler(bot.HandlerTypeMessageText, "/help", bot.MatchTypeExact, helpHandler) | ||
b.RegisterHandler(bot.HandlerTypeMessageText, "/news", bot.MatchTypeExact, news.SummaryHandler) | ||
b.RegisterHandlerRegexp(bot.HandlerTypeMessageText, detailsRegex, news.DetailsHandler) | ||
b.RegisterHandlerRegexp(bot.HandlerTypeMessageText, sarcasmRegex, client.SarcasmHandler) | ||
b.Start(context.Background()) | ||
} | ||
|
||
func helpHandler(ctx context.Context, b *bot.Bot, update *models.Update) { | ||
var sb strings.Builder | ||
sb.WriteString("- use /news to get the main titles of the day (given with their ID)\n") | ||
sb.WriteString("- use /details with the ID of the news to know more\n") | ||
sb.WriteString("- use /sarcasm with the ID of the news to generate a sarcastic comment on the news\n") | ||
sb.WriteString("- use /help to show this message \n") | ||
b.SendMessage(ctx, &bot.SendMessageParams{ | ||
ChatID: update.Message.Chat.ID, | ||
Text: sb.String(), | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package news | ||
|
||
import ( | ||
"slices" | ||
"strings" | ||
|
||
"golang.org/x/net/html" | ||
) | ||
|
||
func FindNewsLink(n *html.Node) string { | ||
if n.Type == html.ElementNode && n.Data == "a" { | ||
for _, a := range n.Attr { | ||
if a.Key == "href" && strings.Contains(a.Val, "czech-news-in-brief") { | ||
return a.Val | ||
} | ||
} | ||
} | ||
for c := n.FirstChild; c != nil; c = c.NextSibling { | ||
if l := FindNewsLink(c); l != "" { | ||
return l | ||
} | ||
} | ||
return "" | ||
} | ||
|
||
func ExtractContentWithTitle(n *html.Node) []News { | ||
if n.Type == html.ElementNode && n.Data == "div" && slices.ContainsFunc(n.Attr, containContentClass) { | ||
ct := []News{} | ||
for c := n.FirstChild; c != nil; c = c.NextSibling { | ||
if c.Type == html.ElementNode && c.Data == "div" && slices.ContainsFunc(c.Attr, containTitleClass) { | ||
ct = append(ct, News{ | ||
Title: extractText(c), | ||
Content: extractContent(c.NextSibling), | ||
}) | ||
} | ||
} | ||
if len(ct) > 0 { | ||
return ct | ||
} | ||
} | ||
for c := n.FirstChild; c != nil; c = c.NextSibling { | ||
if ct := ExtractContentWithTitle(c); len(ct) > 0 { | ||
return ct | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func containTextWrapperClass(a html.Attribute) bool { | ||
return a.Key == "class" && strings.Contains(a.Val, "widget text") | ||
} | ||
|
||
func containTitleClass(a html.Attribute) bool { | ||
return a.Key == "class" && strings.Contains(a.Val, "headinglevel2") | ||
} | ||
|
||
func containContentClass(a html.Attribute) bool { | ||
return a.Key == "class" && strings.Contains(a.Val, "content") | ||
} | ||
|
||
func extractContent(n *html.Node) string { | ||
r := "" | ||
for c := n; c != nil; c = c.NextSibling { | ||
if c.Type == html.ElementNode && c.Data == "div" && slices.ContainsFunc(c.Attr, containTextWrapperClass) { | ||
r += extractText(c.FirstChild) | ||
} | ||
if c.Type == html.ElementNode && c.Data == "div" && slices.ContainsFunc(c.Attr, containTitleClass) { | ||
break | ||
} | ||
} | ||
return r | ||
} | ||
|
||
func extractText(n *html.Node) string { | ||
if n.Type == html.TextNode { | ||
return n.Data | ||
} | ||
r := "" | ||
if n.Type == html.ElementNode { | ||
for c := n.FirstChild; c != nil; c = c.NextSibling { | ||
r += extractText(c) | ||
} | ||
} | ||
return r | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package news | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"strconv" | ||
"strings" | ||
|
||
"github.com/go-telegram/bot" | ||
"github.com/go-telegram/bot/models" | ||
) | ||
|
||
func SummaryHandler(ctx context.Context, b *bot.Bot, update *models.Update) { | ||
t, err := getSummary() | ||
if err != nil { | ||
fmt.Println(err.Error()) | ||
return | ||
} | ||
b.SendMessage(ctx, &bot.SendMessageParams{ | ||
ChatID: update.Message.Chat.ID, | ||
Text: t, | ||
}) | ||
} | ||
|
||
func DetailsHandler(ctx context.Context, b *bot.Bot, update *models.Update) { | ||
id, err := ParseID(update) | ||
if err != nil { | ||
fmt.Println("Error", err.Error()) | ||
return | ||
} | ||
n, err := GetNewsById(id) | ||
if err != nil { | ||
fmt.Println("Error", err.Error()) | ||
return | ||
} | ||
var qb strings.Builder | ||
qb.WriteString(n.Title + "\n\n") | ||
qb.WriteString(n.Content) | ||
b.SendMessage(ctx, &bot.SendMessageParams{ | ||
ChatID: update.Message.Chat.ID, | ||
Text: qb.String(), | ||
}) | ||
} | ||
|
||
func ParseID(update *models.Update) (int, error) { | ||
text := update.Message.Text | ||
id := strings.Split(text, " ")[1] | ||
return strconv.Atoi(id) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package news | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"os" | ||
"strings" | ||
) | ||
|
||
type News struct { | ||
Title string | ||
Content string | ||
} | ||
|
||
func getSummary() (string, error) { | ||
allNews, err := getAllNews() | ||
if err != nil { | ||
return "", err | ||
} | ||
var sb strings.Builder | ||
sb.WriteString("TODAY'S NEWS (based on expat.cz)\n") | ||
for i, n := range allNews { | ||
sb.WriteString(fmt.Sprintf("%d. %s\n", i+1, n.Title)) | ||
} | ||
sb.WriteString("Use /details {news} or /sarcasm {news} for more") | ||
return sb.String(), nil | ||
} | ||
|
||
func getAllNews() ([]*News, error) { | ||
file, err := os.Open("news.json") | ||
if err != nil { | ||
return nil, err | ||
} | ||
var allNews []*News | ||
err = json.NewDecoder(file).Decode(&allNews) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return allNews, nil | ||
} | ||
|
||
func GetNewsById(id int) (*News, error) { | ||
allNews, err := getAllNews() | ||
if err != nil { | ||
return nil, err | ||
} | ||
if len(allNews) < id { | ||
return nil, nil | ||
} | ||
return allNews[id-1], nil | ||
} |
Oops, something went wrong.