Skip to content

Commit

Permalink
fix: news format (#21)
Browse files Browse the repository at this point in the history
Signed-off-by: ashing <[email protected]>
  • Loading branch information
ronething authored Mar 4, 2023
1 parent cd16e82 commit 0a334f4
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 53 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.DS_Store

.idea/
.vscode/
bin/
Expand All @@ -6,3 +8,4 @@ config/dev.yaml

go.sum
dist/

71 changes: 66 additions & 5 deletions example/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ package main
import (
"encoding/json"
"fmt"
"log"
"strings"

md "github.com/JohannesKaufmann/html-to-markdown"
)

type Node struct {
Expand All @@ -18,7 +22,10 @@ func main() {
{"type":"ul","children":[{"type":"li","children":[{"type":"lic","listStyleType":"","indent":0,"children":[{"text":"编辑: 鹿沐"}]}]},
{"type":"li","children":[{"type":"lic","listStyleType":"","indent":0,"children":[{"text":"订阅新闻: "},{"type":"a","url":"http://tinyletter.com/gocn","target":"_blank","children":[{"text":"http://tinyletter.com/gocn"}]},{"text":""}]}]},
{"type":"li","children":[{"type":"lic","listStyleType":"","indent":0,"children":[{"text":"招聘专区: "},{"type":"a","url":"https://gocn.vip/jobs","target":"_blank","children":[{"text":"https://gocn.vip/jobs"}]},{"text":""}]}]}]}]`
//data := `[{"type":"ol","children":[{"type":"li","children":[{"children":[{"text":"了解 Go 中的指针的一页 "},{"type":"a","url":"https://medium.com/@Lekia/a-one-pager-to-understanding-pointers-in-go-ad6cbfac3afc","children":[{"text":"https://medium.com/@Lekia/a-one-pager-to-understanding-pointers-in-go-ad6cbfac3afc"}]},{"text":""}],"type":"lic"}]},{"type":"li","children":[{"type":"lic","children":[{"text":"GO-select 的实现原理 "},{"type":"a","url":"https://juejin.cn/post/7201423410168741946","children":[{"text":"https://juejin.cn/post/7201423410168741946"}]},{"text":""}]}]},{"type":"li","children":[{"type":"lic","children":[{"text":"Golang:使用同步包将性能提高 10 倍并减少内存占用 "},{"type":"a","url":"https://medium.com/@aryehlevklein/golang-using-sync-package-to-10x-performance-and-reduce-memory-footprint-a1ed4ee14931","children":[{"text":"https://medium.com/@aryehlevklein/golang-using-sync-package-to-10x-performance-and-reduce-memory-footprint-a1ed4ee14931"}]},{"text":""}]}]},{"type":"li","children":[{"type":"lic","children":[{"text":"云原生系列Go语言篇-错误处理 "},{"type":"a","url":"https://juejin.cn/post/7201509055713427513","children":[{"text":"https://juejin.cn/post/7201509055713427513"}]},{"text":""}]}]},{"type":"li","children":[{"type":"lic","children":[{"text":"终极 2023 Web 服务器基准测试:NodeJS vs Java vs Rust vs Go "},{"type":"a","url":"https://medium.com/@alexeynovikov_89393/ultimate-2023-web-server-benchmark-nodejs-vs-java-vs-rust-vs-go-e367d932f699","children":[{"text":"https://medium.com/@alexeynovikov_89393/ultimate-2023-web-server-benchmark-nodejs-vs-java-vs-rust-vs-go-e367d932f699"}]},{"text":"","strikethrough":true}]}]}]},{"type":"p","children":[{"text":""}]},{"type":"ul","children":[{"type":"li","children":[{"type":"lic","children":[{"text":"编辑: zsr228"}]}]},{"type":"li","children":[{"type":"lic","children":[{"text":"订阅新闻: http://tinyletter.com/gocn"}]}]},{"type":"li","children":[{"type":"lic","children":[{"text":"招聘专区: https://gocn.vip/jobs"}]}]}]}]`
//data = `[{"type":"ol","children":[{"type":"li","children":[{"children":[{"text":"了解 Go 中的指针的一页 "},{"type":"a","url":"https://medium.com/@Lekia/a-one-pager-to-understanding-pointers-in-go-ad6cbfac3afc","children":[{"text":"https://medium.com/@Lekia/a-one-pager-to-understanding-pointers-in-go-ad6cbfac3afc"}]},{"text":""}],"type":"lic"}]},{"type":"li","children":[{"type":"lic","children":[{"text":"GO-select 的实现原理 "},{"type":"a","url":"https://juejin.cn/post/7201423410168741946","children":[{"text":"https://juejin.cn/post/7201423410168741946"}]},{"text":""}]}]},{"type":"li","children":[{"type":"lic","children":[{"text":"Golang:使用同步包将性能提高 10 倍并减少内存占用 "},{"type":"a","url":"https://medium.com/@aryehlevklein/golang-using-sync-package-to-10x-performance-and-reduce-memory-footprint-a1ed4ee14931","children":[{"text":"https://medium.com/@aryehlevklein/golang-using-sync-package-to-10x-performance-and-reduce-memory-footprint-a1ed4ee14931"}]},{"text":""}]}]},{"type":"li","children":[{"type":"lic","children":[{"text":"云原生系列Go语言篇-错误处理 "},{"type":"a","url":"https://juejin.cn/post/7201509055713427513","children":[{"text":"https://juejin.cn/post/7201509055713427513"}]},{"text":""}]}]},{"type":"li","children":[{"type":"lic","children":[{"text":"终极 2023 Web 服务器基准测试:NodeJS vs Java vs Rust vs Go "},{"type":"a","url":"https://medium.com/@alexeynovikov_89393/ultimate-2023-web-server-benchmark-nodejs-vs-java-vs-rust-vs-go-e367d932f699","children":[{"text":"https://medium.com/@alexeynovikov_89393/ultimate-2023-web-server-benchmark-nodejs-vs-java-vs-rust-vs-go-e367d932f699"}]},{"text":"","strikethrough":true}]}]}]},{"type":"p","children":[{"text":""}]},{"type":"ul","children":[{"type":"li","children":[{"type":"lic","children":[{"text":"编辑: zsr228"}]}]},{"type":"li","children":[{"type":"lic","children":[{"text":"订阅新闻: http://tinyletter.com/gocn"}]}]},{"type":"li","children":[{"type":"lic","children":[{"text":"招聘专区: https://gocn.vip/jobs"}]}]}]}]`
//data = `[{"type":"ol","children":[{"type":"li","children":[{"children":[{"text":"ServiceWeaver:一个编写分布式应用程序的框架 https://opensource.googleblog.com/2023/03/introducing-service-weaver-framework-for-writing-distributed-applications.html"}],"type":"lic"}]},{"type":"li","children":[{"type":"lic","children":[{"text":"Go1.20 arena 能手动管理内存了,怎么用? https://mp.weixin.qq.com/s/mwWMOwLsiY8EtODpyEoTIg"}]}]},{"type":"li","children":[{"type":"lic","children":[{"text":"Go 语言性能剖析利器:pprof 实战 https://toutiao.io/posts/ye9g2eb"}]}]},{"type":"li","children":[{"type":"lic","children":[{"text":"Go中gin框架中Session详解 https://juejin.cn/post/7205016004925423653"}]}]},{"type":"li","children":[{"type":"lic","children":[{"text":"Go-Benchmark入门-基础篇(上) "},{"type":"a","url":"https://juejin.cn/post/7205764215222403132","children":[{"text":"https://juejin.cn/post/7205764215222403132"}]},{"text":""}]}]}]},{"type":"p","children":[{"text":""}]},{"type":"ul","children":[{"type":"li","children":[{"type":"lic","children":[{"text":"编辑: flint"}]}]},{"type":"li","children":[{"type":"lic","children":[{"text":"订阅新闻: http://tinyletter.com/gocn"}]}]},{"type":"li","children":[{"type":"lic","children":[{"text":"招聘专区: https://gocn.vip/jobs"}]}]}]}]`
//data = `[{"type":"code_block","children":[{"type":"code_line","children":[{"text":"## GoCN 每日新闻 (2023-02-28)"}]},{"type":"code_line","children":[{"text":"1. [K8S] client-go 的正确打开方式 https://juejin.cn/post/7203690731276517432"}]},{"type":"code_line","children":[{"text":"2. 优化time.After后,性能提升34%,内存减少67% https://juejin.cn/post/7203274235426324536"}]},{"type":"code_line","children":[{"text":"3. 如何在Golang中进行热重载和优雅的关闭 https://medium.com/@ramseyjiang_22278/how-to-do-hot-reload-and-graceful-shutdown-in-golang-3f84a9f17d79"}]},{"type":"code_line","children":[{"text":"4. 带单位测试的Golang的代理设计模式 https://medium.com/@ramseyjiang_22278/proxy-design-pattern-in-golang-with-unit-tests-d9c6c0d01d49"}]},{"type":"code_line","children":[{"text":"5. 跨平台的Golang GUI库, 核心绑定自 Lazarus 创建的通用跨平台GUI库 liblcl https://github.com/ying32/govcl"}]},{"type":"code_line","children":[{"text":""}]},{"type":"code_line","children":[{"text":"- 编辑: Rolle"}]},{"type":"code_line","children":[{"text":"- 订阅新闻: http://tinyletter.com/gocn"}]},{"type":"code_line","children":[{"text":"- 招聘专区: https://gocn.vip/jobs"}]},{"type":"code_line","children":[{"text":""}]}],"lang":"markdown"},{"type":"p","children":[{"text":""}]}]`
data = `[{"type":"h2","children":[{"text":"GoCN 每日新闻 (2023-02-26)"}]},{"type":"ol","children":[{"type":"li","children":[{"type":"lic","children":[{"text":"内存对齐这个事儿只能自己搞明白 "},{"type":"a","url":"https://mp.weixin.qq.com/s/TphkrCag_Wr6uD9thPMwcg","children":[{"text":"https://mp.weixin.qq.com/s/TphkrCag_Wr6uD9thPMwcg"}]},{"text":""}]}]},{"type":"li","children":[{"type":"lic","children":[{"text":"紧急下班:修炼内功---内存模型和垃圾回收,不焦虑打工指南 "},{"type":"a","url":"https://mp.weixin.qq.com/s/qF5eiWYkcwTnZ2tFwpzx2Q","children":[{"text":"https://mp.weixin.qq.com/s/qF5eiWYkcwTnZ2tFwpzx2Q"}]},{"text":""}]}]},{"type":"li","children":[{"type":"lic","children":[{"text":"Go 语言跨平台文件监听库 fsnotify 怎么使用? "},{"type":"a","url":"https://mp.weixin.qq.com/s/tJ1LvDf14EKg-qQlJUQapQ","children":[{"text":"https://mp.weixin.qq.com/s/tJ1LvDf14EKg-qQlJUQapQ"}]},{"text":""}]}]},{"type":"li","children":[{"type":"lic","children":[{"text":"解析 Golang 网络 IO 模型之 EPOLL "},{"type":"a","url":"https://mp.weixin.qq.com/s/xt0Elppc_OaDFnTI_tW3hg","children":[{"text":"https://mp.weixin.qq.com/s/xt0Elppc_OaDFnTI_tW3hg"}]},{"text":""}]}]},{"type":"li","children":[{"type":"lic","children":[{"text":"Golang HTTP 标准库实现原理 "},{"type":"a","url":"https://mp.weixin.qq.com/s/zFG6_o0IKjXh4RxKmPTt4g","children":[{"text":"https://mp.weixin.qq.com/s/zFG6_o0IKjXh4RxKmPTt4g"}]},{"text":""}]}]}]},{"type":"p","children":[{"text":""}]},{"type":"ul","children":[{"type":"li","children":[{"type":"lic","children":[{"text":"编辑: 鱼雷"}]}]},{"type":"li","children":[{"type":"lic","children":[{"text":"订阅新闻: http://tinyletter.com/gocn"}]}]},{"type":"li","children":[{"type":"lic","children":[{"text":"招聘专区: https://gocn.vip/jobs"}]}]}]}]`

var nodes []*Node
err := json.Unmarshal([]byte(data), &nodes)
Expand All @@ -29,17 +36,34 @@ func main() {
var texts []string
for _, node := range nodes {
nodeTexts := getText(node)
fmt.Println("node texts is ", nodeTexts, len(nodeTexts))
//fmt.Println("node texts is ", nodeTexts, len(nodeTexts))
texts = append(texts, nodeTexts...)
}

fmt.Println(texts)
//fmt.Println(texts)
info := hello(texts)

converter := md.NewConverter("", true, nil)

markdown, err := converter.ConvertString(info)
if err != nil {
// 转换失败直接赋值
log.Printf("convert err: %v\n", err)
markdown = info
}

fmt.Println(markdown)

}

func getText(node *Node) []string {
var texts []string
if node.Text != "" {
texts = append(texts, node.Text)
if node.Type != "" {
texts = append(texts, node.Type)
}
text := strings.TrimSpace(strings.Trim(node.Text, "\n"))
if text != "" {
texts = append(texts, text)
}

for _, child := range node.Children {
Expand All @@ -49,3 +73,40 @@ func getText(node *Node) []string {

return texts
}

func hello(data []string) string {

var result strings.Builder
var stack []string
var stackText []string

for i := 0; i < len(data); i++ {
item := data[i]
switch item {
case "li", "ol", "ul", "h1", "h2":
if len(stack) > 0 && len(stackText) > 0 {
result.WriteString(fmt.Sprintf("</%s>\n", stack[len(stack)-1]))
stack = stack[:len(stack)-1]
stackText = stackText[:len(stackText)-1]
}
result.WriteString(fmt.Sprintf("<%s>", item))
stack = append(stack, item)
case "lic", "p", "code_line", "code_block": // pass
case "a":
result.WriteString(fmt.Sprintf("<a href=\"%s\">%s</a>", data[i+1], data[i+1]))
i = i + 1
default:
result.WriteString(item)
stackText = append(stackText, item)
}
}

//fmt.Println(stackText)
for i := len(stack) - 1; i >= 0; i-- {
result.WriteString(fmt.Sprintf("</%s>", stack[i]))
}

//fmt.Println(result.String())

return result.String()
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.17

require (
github.com/JohannesKaufmann/html-to-markdown v1.3.3
github.com/cloud-org/msgpush v0.0.2
github.com/cloud-org/msgpush v0.0.5
github.com/go-resty/resty/v2 v2.7.0
github.com/gocolly/colly v1.2.0
github.com/robfig/cron/v3 v3.0.1
Expand Down
93 changes: 53 additions & 40 deletions server/gocn_new_2023.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package server

import (
"bytes"
"encoding/json"
"fmt"
"log"
"strings"
"time"

md "github.com/JohannesKaufmann/html-to-markdown"
"github.com/go-resty/resty/v2"
)

Expand Down Expand Up @@ -119,50 +119,26 @@ func (g *GoCnNew2023) parseContent(title string, data string) (*string, error) {
return nil, err
}

var news bytes.Buffer
news.WriteString(title + "\n\n")
var texts []string
for _, node := range nodes {
nodeTexts := getText(node)
if len(nodeTexts) <= 1 { // 长度为 0 或者是标题
continue
}
if len(nodeTexts)&1 == 0 && len(nodeTexts) >= 8 { // 偶数 正文
count := 1
for i := 0; i < len(nodeTexts); i = i + 2 {
record := fmt.Sprintf("%d. %s %s\n", count, nodeTexts[i], nodeTexts[i+1])
if strings.HasPrefix(nodeTexts[i], fmt.Sprintf("%d", count)) {
record = fmt.Sprintf("%s %s\n", nodeTexts[i], nodeTexts[i+1])
}
news.WriteString(record)
count++
}
news.WriteString("\n")
}
if len(nodeTexts)&1 == 0 && len(nodeTexts) <= 4 { // 偶数 可能是宣传链接之类
for i := 0; i < len(nodeTexts); i = i + 2 {
news.WriteString(fmt.Sprintf("%s %s\n", nodeTexts[i], nodeTexts[i+1]))
}
news.WriteString("\n")
}
if len(nodeTexts)&1 == 1 { //奇数 编辑信息
news.WriteString(nodeTexts[0] + "\n")
// 适配奇怪的渲染 有些是 text 和 url 分开 有些则不是
if len(nodeTexts) <= 3 {
for i := 1; i < len(nodeTexts); i++ {
news.WriteString(fmt.Sprintf("%s\n", nodeTexts[i]))
}
}
if len(nodeTexts) > 3 {
for i := 1; i < len(nodeTexts); i = i + 2 {
news.WriteString(fmt.Sprintf("%s %s\n", nodeTexts[i], nodeTexts[i+1]))
}
}
}
//fmt.Println("node texts is ", nodeTexts, len(nodeTexts))
texts = append(texts, nodeTexts...)
}

res := news.String()
//fmt.Println(texts)
info := buildMarkdown(texts)

converter := md.NewConverter("", true, nil)

markdown, err := converter.ConvertString(info)
if err != nil {
// 转换失败直接赋值
log.Printf("convert err: %v\n", err)
markdown = info
}

return &res, nil
return &markdown, nil
}

type Node struct {
Expand All @@ -174,6 +150,9 @@ type Node struct {
//getText 递归获取 texts
func getText(node *Node) []string {
var texts []string
if node.Type != "" {
texts = append(texts, node.Type)
}
text := strings.TrimSpace(strings.Trim(node.Text, "\n"))
if text != "" {
texts = append(texts, text)
Expand All @@ -186,3 +165,37 @@ func getText(node *Node) []string {

return texts
}

func buildMarkdown(data []string) string {

var result strings.Builder
var stack []string
var stackText []string

for i := 0; i < len(data); i++ {
item := data[i]
switch item {
case "li", "ol", "ul", "h1", "h2":
if len(stack) > 0 && len(stackText) > 0 {
result.WriteString(fmt.Sprintf("</%s>\n", stack[len(stack)-1]))
stack = stack[:len(stack)-1]
stackText = stackText[:len(stackText)-1]
}
result.WriteString(fmt.Sprintf("<%s>", item))
stack = append(stack, item)
case "lic", "p", "code_line", "code_block": // pass
case "a":
result.WriteString(fmt.Sprintf("<a href=\"%s\">%s</a>", data[i+1], data[i+1]))
i = i + 1
default:
result.WriteString(item)
stackText = append(stackText, item)
}
}

for i := len(stack) - 1; i >= 0; i-- {
result.WriteString(fmt.Sprintf("</%s>", stack[i]))
}

return result.String()
}
7 changes: 0 additions & 7 deletions server/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,6 @@ func (n *NewsPush) Push() {
}
content := strings.Join(contents, "")
for i := 0; i < len(n.Notifys); i++ {
if n.Notifys[i].String() == "wecom" { // send text
w := n.Notifys[i].(*msgpush.WeCom)
if err = w.SendText(content); err != nil {
log.Printf("wecom 推送失败, err: %v\n", err)
}
continue
}
if err = n.Notifys[i].Send(content); err != nil {
log.Printf("%s 推送发生错误, err: %v\n", n.Notifys[i].String(), err)
continue
Expand Down

0 comments on commit 0a334f4

Please sign in to comment.