1 Star 0 Fork 0

Arthur / redoron

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
dict.go 7.23 KB
一键复制 编辑 原始数据 按行查看 历史
Arthur Dayne 提交于 2021-06-04 18:27 . Adjust options
/*
Copyright © 2019 NAME HERE <EMAIL ADDRESS>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
import (
"log"
"net/http"
"os"
"regexp"
"strings"
"text/template"
"github.com/PuerkitoBio/goquery"
"github.com/spf13/cobra"
)
// dictCmd represents the dict command
var dictCmd = &cobra.Command{
Use: "dict",
Short: "Translation between English and Chinese.",
Run: func(cmd *cobra.Command, args []string) {
doTranslate(cmd, args)
},
}
func init() {
rootCmd.AddCommand(dictCmd)
// Here you will define your flags and configuration settings.
// Cobra supports Persistent Flags which will work for this command
// and all subcommands, e.g.:
// dictCmd.PersistentFlags().String("foo", "", "A help for foo")
// Cobra supports local flags which will only run when this command
// is called directly, e.g.:
// dictCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}
const api string = "https://dict.cn/"
type Word struct {
Name string
Phonetic string
Basic string
Detail string
Dualingo string //双语解释
EnExpl string //英英释义
Example string //例句
Pattern string //常见句型
Coll string //词汇搭配
Author string //经典引文
Ess string //词语语法
Etm string //词源解说
}
func (w *Word) show(detail bool) {
var t *template.Template
if detail {
t, _ = template.New("dict").Parse("{{ .Name }}: {{ .Phonetic }}{{ .Basic }}\n详解:\n\033[33m{{ .Detail }}\033[0m\n双语解释:\n\033[33m{{ .Dualingo }}\033[0m\n英英释义:\n\033[33m{{ .EnExpl }}\033[0m\n例句:\n\033[33m{{ .Example }}\033[0m\n常见句型:\n\033[33m{{ .Pattern }}\033[0m\n词汇搭配:\n\033[33m{{ .Coll }}\033[0m\n经典引文:\n\033[33m{{ .Author }}\033[0m\n词语语法:\n\033[33m{{ .Ess }}\033[0m\n词源解说:\n\033[33m{{ .Etm }}\033[0m\n")
} else {
t, _ = template.New("dict").Parse("{{ .Name }}: {{ .Phonetic }}{{ .Basic }}")
}
t.Execute(os.Stdout, w)
}
func doTranslate(cmd *cobra.Command, args []string) {
if len(args) == 0 {
log.Fatal("Please provide the WORD you want to search.")
}
requireDetail, _ := cmd.Flags().GetBool("long")
wordName := strings.Join(args, " ")
// Request the HTML page.
res, err := http.Get(api + wordName)
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
if res.StatusCode != 200 {
log.Fatalf("status code error: %d %s", res.StatusCode, res.Status)
}
// Load the HTML document
doc, err := goquery.NewDocumentFromReader(res.Body)
if err != nil {
log.Fatal(err)
}
w := Word{Name: wordName}
w.parse(doc)
w.show(requireDetail)
}
func (w *Word) parse(doc *goquery.Document) {
reg := regexp.MustCompile("\\s+")
sb := strings.Builder{}
doc.Find("ul.dict-basic-ul li").Each(func(i int, s *goquery.Selection) {
_, exists := s.Attr("style")
if !exists {
sb.WriteString(strings.Trim(reg.ReplaceAllString(s.Text(), " "), " "))
sb.WriteString("\n")
}
})
w.Basic = strings.Trim(sb.String(), " ")
sb.Reset()
doc.Find("div.phonetic").Each(func(i int, s *goquery.Selection) {
sb.WriteString(strings.Trim(reg.ReplaceAllString(s.Text(), " "), " "))
sb.WriteString("\n")
})
w.Phonetic = sb.String()
sb.Reset()
doc.Find("div.detail").Children().Each(func(i int, s *goquery.Selection) {
if goquery.NodeName(s) == "span" {
sb.WriteString(strings.Trim(reg.ReplaceAllString(s.Text(), " "), " "))
sb.WriteString("\n")
} else if goquery.NodeName(s) == "ol" {
s.Children().Each(func(i int, s *goquery.Selection) {
sb.WriteString(strings.Trim(reg.ReplaceAllString(s.Text(), " "), " "))
sb.WriteString("\n")
})
}
})
w.Detail = sb.String()
sb.Reset()
doc.Find("div.dual").Children().Each(func(i int, s *goquery.Selection) {
if goquery.NodeName(s) == "span" {
sb.WriteString(strings.Trim(reg.ReplaceAllString(s.Text(), " "), " "))
sb.WriteString("\n")
} else if goquery.NodeName(s) == "ol" {
s.Children().Each(func(i int, s *goquery.Selection) {
sb.WriteString(strings.Trim(reg.ReplaceAllString(s.Text(), " "), " "))
sb.WriteString("\n")
})
}
})
w.Dualingo = sb.String()
sb.Reset()
doc.Find("div.en").Children().Each(func(i int, s *goquery.Selection) {
if goquery.NodeName(s) == "span" {
sb.WriteString(strings.Trim(reg.ReplaceAllString(s.Text(), " "), " "))
sb.WriteString("\n")
} else if goquery.NodeName(s) == "ol" {
s.Children().Each(func(i int, s *goquery.Selection) {
sb.WriteString(strings.Trim(reg.ReplaceAllString(s.Text(), " "), " "))
sb.WriteString("\n")
})
}
})
w.EnExpl = sb.String()
sb.Reset()
doc.Find("div.sort").Children().Each(func(i int, s *goquery.Selection) {
if goquery.NodeName(s) == "span" {
sb.WriteString(strings.Trim(reg.ReplaceAllString(s.Text(), " "), " "))
sb.WriteString("\n")
} else if goquery.NodeName(s) == "ol" {
s.Children().Each(func(i int, s *goquery.Selection) {
sb.WriteString(strings.Trim(reg.ReplaceAllString(s.Text(), " "), " "))
sb.WriteString("\n")
})
}
})
w.Example = sb.String()
sb.Reset()
doc.Find("div.patt").Children().Each(func(i int, s *goquery.Selection) {
if goquery.NodeName(s) == "span" {
sb.WriteString(strings.Trim(reg.ReplaceAllString(s.Text(), " "), " "))
sb.WriteString("\n")
} else if goquery.NodeName(s) == "ol" {
s.Children().Each(func(i int, s *goquery.Selection) {
sb.WriteString(strings.Trim(reg.ReplaceAllString(s.Text(), " "), " "))
sb.WriteString("\n")
})
}
})
w.Pattern = sb.String()
sb.Reset()
doc.Find("div.coll").Children().Each(func(i int, s *goquery.Selection) {
if goquery.NodeName(s) == "div" || goquery.NodeName(s) == "b" {
sb.WriteString(strings.Trim(reg.ReplaceAllString(s.Text(), " "), " "))
sb.WriteString("\n")
} else if goquery.NodeName(s) == "ul" {
s.Children().Each(func(i int, s *goquery.Selection) {
sb.WriteString("\t")
sb.WriteString(strings.Trim(reg.ReplaceAllString(s.Text(), " "), " "))
sb.WriteString("\n")
})
}
})
w.Coll = sb.String()
sb.Reset()
doc.Find("div.auth ul").Children().Each(func(i int, s *goquery.Selection) {
s.Children().Each(func(i int, s *goquery.Selection) {
sb.WriteString(strings.Trim(reg.ReplaceAllString(s.Text(), " "), " "))
sb.WriteString("\n")
})
})
w.Author = sb.String()
sb.Reset()
doc.Find("div.ess").Children().Each(func(i int, s *goquery.Selection) {
if goquery.NodeName(s) == "span" {
sb.WriteString(strings.Trim(reg.ReplaceAllString(s.Text(), " "), " "))
sb.WriteString("\n")
} else if goquery.NodeName(s) == "ol" {
s.Children().Each(func(i int, s *goquery.Selection) {
sb.WriteString(strings.Trim(reg.ReplaceAllString(s.Text(), " "), " "))
sb.WriteString("\n")
})
}
})
w.Ess = sb.String()
sb.Reset()
doc.Find("div.etm ul").Children().Each(func(i int, s *goquery.Selection) {
sb.WriteString(strings.Trim(reg.ReplaceAllString(s.Text(), " "), " "))
sb.WriteString("\n")
})
w.Etm = sb.String()
}
1
https://gitee.com/palagend/redoron.git
git@gitee.com:palagend/redoron.git
palagend
redoron
redoron
v1.0.0

搜索帮助