使用go构建彩云翻译的Alfred Workflow | 青训营笔记

2022-10-31 11:28:15 浏览数 (1)

  • 前言

  • AlfredWorkflow初体验
  • 使用方法
  • 构造思路
    • 代码
    • 适配Alfred
  • 后记

Author: 颖奇L’Amore

Blog: www.gem-love.com

最近参加了字节跳动的后端专场青训营,是一个免费的Go培训项目,正好最近入职了字节跳动的安全与风控部门,负责公司的业务安全(电商SDLC),公司大部分业务以Go为主,借此青训营机会希望也可以提升一下自己的Go后端开发水平,更好的为公司工作。

按照青训营要求,每个学员为了顺利结业需参加笔记创作活动,这是我的第一篇笔记,首发于掘金社区。

以下是正文


这是我参与「第三届青训营 -后端场」笔记创作活动的的第1篇笔记

前言▸

在Day1的『Go语言上手-基础语言』中,老师给了三个项目,其中一个是基于彩云翻译使用Go来实现一个建议的词典查询功能,代码支持英译汉。我发现彩云翻译很好用,不需要自己申请api就可以使用,于是我在此基础上加以改造,将其做成了一个Alfred Workflow,并且添加了中译英的功能。

AlfredWorkflow初体验▸

Alfred是MacOS上提升工作效率的工具。关于Alfred可以看我博客的两篇文章:

  • Alfred 4: MacOS效率提升大杀器(上篇)
  • Alfred 4: MacOS效率提升大杀器(下篇)

可以在我的github下载到这次的彩云翻译Workflow: https://github.com/y1nglamore/caiyunTranslator

效果如下:

如果上面的Gif动画加载不出来,可以看静态图:

使用方法▸

首先去我的github仓库下载彩云翻译.alfredworkflow

双击导入Alfred,然后双击这个Script Filter

将命令中的go的绝对路径改成你本机的绝对路径,可以用whereis go查看

然后只需要在Alfred中输入cy xxx即可。这里如果xxx是英文就是英译汉,如果是中文就是汉译英。

构造思路▸

代码▸

首先老师给的版本是这样的:

代码语言:javascript复制
<span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> (
	<span class="hljs-string">"bytes"</span>
	<span class="hljs-string">"encoding/json"</span>
	<span class="hljs-string">"fmt"</span>
	<span class="hljs-string">"io/ioutil"</span>
	<span class="hljs-string">"log"</span>
	<span class="hljs-string">"net/http"</span>
	<span class="hljs-string">"os"</span>
)

<span class="hljs-keyword">type</span> DictRequest <span class="hljs-keyword">struct</span> {
	TransType <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"trans_type"`</span>
	Source    <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"source"`</span>
	UserID    <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"user_id"`</span>
}

<span class="hljs-keyword">type</span> DictResponse <span class="hljs-keyword">struct</span> {
	Rc   <span class="hljs-keyword">int</span> <span class="hljs-string">`json:"rc"`</span>
	Wiki <span class="hljs-keyword">struct</span> {
		KnownInLaguages <span class="hljs-keyword">int</span> <span class="hljs-string">`json:"known_in_laguages"`</span>
		Description     <span class="hljs-keyword">struct</span> {
			Source <span class="hljs-keyword">string</span>      <span class="hljs-string">`json:"source"`</span>
			Target <span class="hljs-keyword">interface</span>{} <span class="hljs-string">`json:"target"`</span>
		} <span class="hljs-string">`json:"description"`</span>
		ID   <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"id"`</span>
		Item <span class="hljs-keyword">struct</span> {
			Source <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"source"`</span>
			Target <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"target"`</span>
		} <span class="hljs-string">`json:"item"`</span>
		ImageURL  <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"image_url"`</span>
		IsSubject <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"is_subject"`</span>
		Sitelink  <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"sitelink"`</span>
	} <span class="hljs-string">`json:"wiki"`</span>
	Dictionary <span class="hljs-keyword">struct</span> {
		Prons <span class="hljs-keyword">struct</span> {
			EnUs <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"en-us"`</span>
			En   <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"en"`</span>
		} <span class="hljs-string">`json:"prons"`</span>
		Explanations []<span class="hljs-keyword">string</span>      <span class="hljs-string">`json:"explanations"`</span>
		Synonym      []<span class="hljs-keyword">string</span>      <span class="hljs-string">`json:"synonym"`</span>
		Antonym      []<span class="hljs-keyword">string</span>      <span class="hljs-string">`json:"antonym"`</span>
		WqxExample   [][]<span class="hljs-keyword">string</span>    <span class="hljs-string">`json:"wqx_example"`</span>
		Entry        <span class="hljs-keyword">string</span>        <span class="hljs-string">`json:"entry"`</span>
		Type         <span class="hljs-keyword">string</span>        <span class="hljs-string">`json:"type"`</span>
		Related      []<span class="hljs-keyword">interface</span>{} <span class="hljs-string">`json:"related"`</span>
		Source       <span class="hljs-keyword">string</span>        <span class="hljs-string">`json:"source"`</span>
	} <span class="hljs-string">`json:"dictionary"`</span>
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">query</span><span class="hljs-params">(word <span class="hljs-keyword">string</span>)</span></span> {
	client := &amp;http.Client{}
	request := DictRequest{TransType: <span class="hljs-string">"en2zh"</span>, Source: word}
	buf, err := json.Marshal(request)
	<span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
		log.Fatal(err)
	}
	<span class="hljs-keyword">var</span> data = bytes.NewReader(buf)
	req, err := http.NewRequest(<span class="hljs-string">"POST"</span>, <span class="hljs-string">"https://api.interpreter.caiyunai.com/v1/dict"</span>, data)
	<span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
		log.Fatal(err)
	}
	req.Header.Set(<span class="hljs-string">"Connection"</span>, <span class="hljs-string">"keep-alive"</span>)
	req.Header.Set(<span class="hljs-string">"DNT"</span>, <span class="hljs-string">"1"</span>)
	req.Header.Set(<span class="hljs-string">"os-version"</span>, <span class="hljs-string">""</span>)
	req.Header.Set(<span class="hljs-string">"sec-ch-ua-mobile"</span>, <span class="hljs-string">"?0"</span>)
	req.Header.Set(<span class="hljs-string">"User-Agent"</span>, <span class="hljs-string">"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36"</span>)
	req.Header.Set(<span class="hljs-string">"app-name"</span>, <span class="hljs-string">"xy"</span>)
	req.Header.Set(<span class="hljs-string">"Content-Type"</span>, <span class="hljs-string">"application/json;charset=UTF-8"</span>)
	req.Header.Set(<span class="hljs-string">"Accept"</span>, <span class="hljs-string">"application/json, text/plain, */*"</span>)
	req.Header.Set(<span class="hljs-string">"device-id"</span>, <span class="hljs-string">""</span>)
	req.Header.Set(<span class="hljs-string">"os-type"</span>, <span class="hljs-string">"web"</span>)
	req.Header.Set(<span class="hljs-string">"X-Authorization"</span>, <span class="hljs-string">"token:qgemv4jr1y38jyq6vhvi"</span>)
	req.Header.Set(<span class="hljs-string">"Origin"</span>, <span class="hljs-string">"https://fanyi.caiyunapp.com"</span>)
	req.Header.Set(<span class="hljs-string">"Sec-Fetch-Site"</span>, <span class="hljs-string">"cross-site"</span>)
	req.Header.Set(<span class="hljs-string">"Sec-Fetch-Mode"</span>, <span class="hljs-string">"cors"</span>)
	req.Header.Set(<span class="hljs-string">"Sec-Fetch-Dest"</span>, <span class="hljs-string">"empty"</span>)
	req.Header.Set(<span class="hljs-string">"Referer"</span>, <span class="hljs-string">"https://fanyi.caiyunapp.com/"</span>)
	req.Header.Set(<span class="hljs-string">"Accept-Language"</span>, <span class="hljs-string">"zh-CN,zh;q=0.9"</span>)
	req.Header.Set(<span class="hljs-string">"Cookie"</span>, <span class="hljs-string">"_ym_uid=16456948721020430059; _ym_d=1645694872"</span>)
	resp, err := client.Do(req)
	<span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
		log.Fatal(err)
	}
	<span class="hljs-keyword">defer</span> resp.Body.Close()
	bodyText, err := ioutil.ReadAll(resp.Body)
	<span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
		log.Fatal(err)
	}
	<span class="hljs-keyword">if</span> resp.StatusCode != <span class="hljs-number">200</span> {
		log.Fatal(<span class="hljs-string">"bad StatusCode:"</span>, resp.StatusCode, <span class="hljs-string">"body"</span>, <span class="hljs-keyword">string</span>(bodyText))
	}
	<span class="hljs-keyword">var</span> dictResponse DictResponse
	err = json.Unmarshal(bodyText, &amp;dictResponse)
	<span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
		log.Fatal(err)
	}
	fmt.Println(word, <span class="hljs-string">"UK:"</span>, dictResponse.Dictionary.Prons.En, <span class="hljs-string">"US:"</span>, dictResponse.Dictionary.Prons.EnUs)
	<span class="hljs-keyword">for</span> _, item := <span class="hljs-keyword">range</span> dictResponse.Dictionary.Explanations {
		fmt.Println(item)
	}
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
	<span class="hljs-keyword">if</span> <span class="hljs-built_in">len</span>(os.Args) != <span class="hljs-number">2</span> {
		fmt.Fprintf(os.Stderr, <span class="hljs-string">`usage: simpleDict WORD</span>
<span class="hljs-string">example: simpleDict hello</span>
<span class="hljs-string">		`</span>)
		os.Exit(<span class="hljs-number">1</span>)
	}
	word := os.Args[<span class="hljs-number">1</span>]
	query(word)
}

先给出我的改良后适配Alfred的完整代码,也没什么大改:

代码语言:javascript复制
<span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> (
	<span class="hljs-string">"bytes"</span>
	<span class="hljs-string">"encoding/json"</span>
	<span class="hljs-string">"fmt"</span>
	<span class="hljs-string">"io/ioutil"</span>
	<span class="hljs-string">"log"</span>
	<span class="hljs-string">"net/http"</span>
	<span class="hljs-string">"os"</span>
	<span class="hljs-string">"strconv"</span>
	<span class="hljs-string">"strings"</span>
	<span class="hljs-string">"unicode"</span>
)

<span class="hljs-keyword">type</span> DictRequest <span class="hljs-keyword">struct</span> {
	TransType <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"trans_type"`</span>
	Source    <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"source"`</span>
	UserID    <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"user_id"`</span>
}

<span class="hljs-keyword">type</span> DictResponse <span class="hljs-keyword">struct</span> {
	Rc   <span class="hljs-keyword">int</span> <span class="hljs-string">`json:"rc"`</span>
	Wiki <span class="hljs-keyword">struct</span> {
		KnownInLaguages <span class="hljs-keyword">int</span> <span class="hljs-string">`json:"known_in_laguages"`</span>
		Description     <span class="hljs-keyword">struct</span> {
			Source <span class="hljs-keyword">string</span>      <span class="hljs-string">`json:"source"`</span>
			Target <span class="hljs-keyword">interface</span>{} <span class="hljs-string">`json:"target"`</span>
		} <span class="hljs-string">`json:"description"`</span>
		ID   <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"id"`</span>
		Item <span class="hljs-keyword">struct</span> {
			Source <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"source"`</span>
			Target <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"target"`</span>
		} <span class="hljs-string">`json:"item"`</span>
		ImageURL  <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"image_url"`</span>
		IsSubject <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"is_subject"`</span>
		Sitelink  <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"sitelink"`</span>
	} <span class="hljs-string">`json:"wiki"`</span>
	Dictionary <span class="hljs-keyword">struct</span> {
		Prons <span class="hljs-keyword">struct</span> {
			EnUs <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"en-us"`</span>
			En   <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"en"`</span>
		} <span class="hljs-string">`json:"prons"`</span>
		Explanations []<span class="hljs-keyword">string</span>      <span class="hljs-string">`json:"explanations"`</span>
		Synonym      []<span class="hljs-keyword">string</span>      <span class="hljs-string">`json:"synonym"`</span>
		Antonym      []<span class="hljs-keyword">string</span>      <span class="hljs-string">`json:"antonym"`</span>
		WqxExample   [][]<span class="hljs-keyword">string</span>    <span class="hljs-string">`json:"wqx_example"`</span>
		Entry        <span class="hljs-keyword">string</span>        <span class="hljs-string">`json:"entry"`</span>
		Type         <span class="hljs-keyword">string</span>        <span class="hljs-string">`json:"type"`</span>
		Related      []<span class="hljs-keyword">interface</span>{} <span class="hljs-string">`json:"related"`</span>
		Source       <span class="hljs-keyword">string</span>        <span class="hljs-string">`json:"source"`</span>
	} <span class="hljs-string">`json:"dictionary"`</span>
}

<span class="hljs-comment">// 用于翻译结果的图标显示</span>
<span class="hljs-keyword">type</span> icon <span class="hljs-keyword">struct</span> {
	Type <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"type"`</span>
	Path <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"path"`</span>
}

<span class="hljs-comment">// 用于单条结果</span>
<span class="hljs-keyword">type</span> item <span class="hljs-keyword">struct</span> {
	Subtitle <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"subtitle"`</span> <span class="hljs-comment">// 固定的小字的标题</span>
	Title    <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"title"`</span>
	Arg      <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"arg"`</span>
	Icon     icon   <span class="hljs-string">`json:"icon"`</span>
}

<span class="hljs-comment">// 结果集</span>
<span class="hljs-keyword">type</span> items <span class="hljs-keyword">struct</span> {
	Items []item <span class="hljs-string">`json:"items"`</span>
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">queryEnglish</span><span class="hljs-params">(word <span class="hljs-keyword">string</span>, icon icon)</span></span> {
	client := &amp;http.Client{}
	request := DictRequest{TransType: <span class="hljs-string">"en2zh"</span>, Source: word}
	buf, err := json.Marshal(request)
	<span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
		log.Fatal(err)
	}
	<span class="hljs-keyword">var</span> data = bytes.NewReader(buf)
	req, err := http.NewRequest(<span class="hljs-string">"POST"</span>, <span class="hljs-string">"https://api.interpreter.caiyunai.com/v1/dict"</span>, data)
	<span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
		log.Fatal(err)
	}
	req.Header.Set(<span class="hljs-string">"Connection"</span>, <span class="hljs-string">"keep-alive"</span>)
	req.Header.Set(<span class="hljs-string">"DNT"</span>, <span class="hljs-string">"1"</span>)
	req.Header.Set(<span class="hljs-string">"os-version"</span>, <span class="hljs-string">""</span>)
	req.Header.Set(<span class="hljs-string">"sec-ch-ua-mobile"</span>, <span class="hljs-string">"?0"</span>)
	req.Header.Set(<span class="hljs-string">"User-Agent"</span>, <span class="hljs-string">"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36"</span>)
	req.Header.Set(<span class="hljs-string">"app-name"</span>, <span class="hljs-string">"xy"</span>)
	req.Header.Set(<span class="hljs-string">"Content-Type"</span>, <span class="hljs-string">"application/json;charset=UTF-8"</span>)
	req.Header.Set(<span class="hljs-string">"Accept"</span>, <span class="hljs-string">"application/json, text/plain, */*"</span>)
	req.Header.Set(<span class="hljs-string">"device-id"</span>, <span class="hljs-string">""</span>)
	req.Header.Set(<span class="hljs-string">"os-type"</span>, <span class="hljs-string">"web"</span>)
	req.Header.Set(<span class="hljs-string">"X-Authorization"</span>, <span class="hljs-string">"token:qgemv4jr1y38jyq6vhvi"</span>)
	req.Header.Set(<span class="hljs-string">"Origin"</span>, <span class="hljs-string">"https://fanyi.caiyunapp.com"</span>)
	req.Header.Set(<span class="hljs-string">"Sec-Fetch-Site"</span>, <span class="hljs-string">"cross-site"</span>)
	req.Header.Set(<span class="hljs-string">"Sec-Fetch-Mode"</span>, <span class="hljs-string">"cors"</span>)
	req.Header.Set(<span class="hljs-string">"Sec-Fetch-Dest"</span>, <span class="hljs-string">"empty"</span>)
	req.Header.Set(<span class="hljs-string">"Referer"</span>, <span class="hljs-string">"https://fanyi.caiyunapp.com/"</span>)
	req.Header.Set(<span class="hljs-string">"Accept-Language"</span>, <span class="hljs-string">"zh-CN,zh;q=0.9"</span>)
	req.Header.Set(<span class="hljs-string">"Cookie"</span>, <span class="hljs-string">"_ym_uid=16456948721020430059; _ym_d=1645694872"</span>)
	resp, err := client.Do(req)
	<span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
		log.Fatal(err)
	}
	<span class="hljs-keyword">defer</span> resp.Body.Close()
	bodyText, err := ioutil.ReadAll(resp.Body)
	<span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
		log.Fatal(err)
	}

	<span class="hljs-comment">// 发生错误时的结果</span>
	<span class="hljs-keyword">if</span> resp.StatusCode != <span class="hljs-number">200</span> {
		<span class="hljs-comment">//log.Fatal("bad StatusCode:", resp.StatusCode, "body", string(bodyText))</span>
		<span class="hljs-keyword">var</span> errItem []item
		errItem = []item{
			{
				Subtitle: <span class="hljs-string">"error"</span>,
				Title:    <span class="hljs-string">"bad StatusCode: "</span>   strconv.FormatInt(<span class="hljs-keyword">int64</span>(resp.StatusCode), <span class="hljs-number">10</span>),
				Arg:      <span class="hljs-string">"bad StatusCode: "</span>   strconv.FormatInt(<span class="hljs-keyword">int64</span>(resp.StatusCode), <span class="hljs-number">10</span>),
				Icon:     icon,
			},
		}

		errItems := items{Items: errItem}
		itemsJson, _ := json.Marshal(errItems)
		fmt.Println(<span class="hljs-keyword">string</span>(itemsJson))
		<span class="hljs-keyword">return</span>
	}

	<span class="hljs-keyword">var</span> dictResponse DictResponse
	err = json.Unmarshal(bodyText, &amp;dictResponse)
	<span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
		log.Fatal(err)
	}
	<span class="hljs-comment">//fmt.Println(word, "UK:", dictResponse.Dictionary.Prons.En, "US:", dictResponse.Dictionary.Prons.EnUs)</span>
	<span class="hljs-comment">//for _, item := range dictResponse.Dictionary.Explanations {</span>
	<span class="hljs-comment">//	fmt.Println(item)</span>
	<span class="hljs-comment">//}</span>

	<span class="hljs-keyword">var</span> resultItem []item
	resultItem = []item{
		{
			Subtitle: <span class="hljs-string">"音标"</span>,
			Title:    <span class="hljs-string">"EN:"</span>   dictResponse.Dictionary.Prons.En   <span class="hljs-string">" US:"</span>   dictResponse.Dictionary.Prons.EnUs,
			Arg:      <span class="hljs-string">"EN:"</span>   dictResponse.Dictionary.Prons.En   <span class="hljs-string">" US:"</span>   dictResponse.Dictionary.Prons.EnUs,
			Icon:     icon,
		},
	}
	<span class="hljs-keyword">for</span> i, paraphrase := <span class="hljs-keyword">range</span> dictResponse.Dictionary.Explanations {
		paraphraseItem := item{Subtitle: <span class="hljs-string">"解释"</span>   strconv.FormatInt(<span class="hljs-keyword">int64</span>(i <span class="hljs-number">1</span>), <span class="hljs-number">10</span>), Title: paraphrase, Arg: <span class="hljs-string">"解释"</span>   strconv.FormatInt(<span class="hljs-keyword">int64</span>(i <span class="hljs-number">1</span>), <span class="hljs-number">10</span>), Icon: icon}
		resultItem = <span class="hljs-built_in">append</span>(resultItem, paraphraseItem)
	}
	resultItems := items{Items: resultItem}
	resultJson, _ := json.Marshal(resultItems)
	fmt.Println(<span class="hljs-keyword">string</span>(resultJson))
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">queryChinese</span><span class="hljs-params">(word <span class="hljs-keyword">string</span>, icon icon)</span></span> {
	client := &amp;http.Client{}
	request := DictRequest{TransType: <span class="hljs-string">"zh2en"</span>, Source: word}
	buf, err := json.Marshal(request)
	<span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
		log.Fatal(err)
	}
	<span class="hljs-keyword">var</span> data = bytes.NewReader(buf)
	req, err := http.NewRequest(<span class="hljs-string">"POST"</span>, <span class="hljs-string">"https://api.interpreter.caiyunai.com/v1/dict"</span>, data)
	<span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
		log.Fatal(err)
	}
	req.Header.Set(<span class="hljs-string">"Connection"</span>, <span class="hljs-string">"keep-alive"</span>)
	req.Header.Set(<span class="hljs-string">"DNT"</span>, <span class="hljs-string">"1"</span>)
	req.Header.Set(<span class="hljs-string">"os-version"</span>, <span class="hljs-string">""</span>)
	req.Header.Set(<span class="hljs-string">"sec-ch-ua-mobile"</span>, <span class="hljs-string">"?0"</span>)
	req.Header.Set(<span class="hljs-string">"User-Agent"</span>, <span class="hljs-string">"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36"</span>)
	req.Header.Set(<span class="hljs-string">"app-name"</span>, <span class="hljs-string">"xy"</span>)
	req.Header.Set(<span class="hljs-string">"Content-Type"</span>, <span class="hljs-string">"application/json;charset=UTF-8"</span>)
	req.Header.Set(<span class="hljs-string">"Accept"</span>, <span class="hljs-string">"application/json, text/plain, */*"</span>)
	req.Header.Set(<span class="hljs-string">"device-id"</span>, <span class="hljs-string">""</span>)
	req.Header.Set(<span class="hljs-string">"os-type"</span>, <span class="hljs-string">"web"</span>)
	req.Header.Set(<span class="hljs-string">"X-Authorization"</span>, <span class="hljs-string">"token:qgemv4jr1y38jyq6vhvi"</span>)
	req.Header.Set(<span class="hljs-string">"Origin"</span>, <span class="hljs-string">"https://fanyi.caiyunapp.com"</span>)
	req.Header.Set(<span class="hljs-string">"Sec-Fetch-Site"</span>, <span class="hljs-string">"cross-site"</span>)
	req.Header.Set(<span class="hljs-string">"Sec-Fetch-Mode"</span>, <span class="hljs-string">"cors"</span>)
	req.Header.Set(<span class="hljs-string">"Sec-Fetch-Dest"</span>, <span class="hljs-string">"empty"</span>)
	req.Header.Set(<span class="hljs-string">"Referer"</span>, <span class="hljs-string">"https://fanyi.caiyunapp.com/"</span>)
	req.Header.Set(<span class="hljs-string">"Accept-Language"</span>, <span class="hljs-string">"zh-CN,zh;q=0.9"</span>)
	req.Header.Set(<span class="hljs-string">"Cookie"</span>, <span class="hljs-string">"_ym_uid=16456948721020430059; _ym_d=1645694872"</span>)
	resp, err := client.Do(req)
	<span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
		log.Fatal(err)
	}
	<span class="hljs-keyword">defer</span> resp.Body.Close()
	bodyText, err := ioutil.ReadAll(resp.Body)
	<span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
		log.Fatal(err)
	}

	<span class="hljs-comment">// 发生错误时的结果</span>
	<span class="hljs-keyword">if</span> resp.StatusCode != <span class="hljs-number">200</span> {
		<span class="hljs-comment">//log.Fatal("bad StatusCode:", resp.StatusCode, "body", string(bodyText))</span>
		<span class="hljs-keyword">var</span> errItem []item
		errItem = []item{
			{
				Subtitle: <span class="hljs-string">"error"</span>,
				Title:    <span class="hljs-string">"bad StatusCode: "</span>   strconv.FormatInt(<span class="hljs-keyword">int64</span>(resp.StatusCode), <span class="hljs-number">10</span>),
				Arg:      <span class="hljs-string">"bad StatusCode: "</span>   strconv.FormatInt(<span class="hljs-keyword">int64</span>(resp.StatusCode), <span class="hljs-number">10</span>),
				Icon:     icon,
			},
		}

		errItems := items{Items: errItem}
		itemsJson, _ := json.Marshal(errItems)
		fmt.Println(<span class="hljs-keyword">string</span>(itemsJson))
		<span class="hljs-keyword">return</span>
	}

	<span class="hljs-keyword">var</span> dictResponse DictResponse
	err = json.Unmarshal(bodyText, &amp;dictResponse)
	<span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
		log.Fatal(err)
	}
	<span class="hljs-comment">//fmt.Println(word, "UK:", dictResponse.Dictionary.Prons.En, "US:", dictResponse.Dictionary.Prons.EnUs)</span>
	<span class="hljs-comment">//for _, item := range dictResponse.Dictionary.Explanations {</span>
	<span class="hljs-comment">//	fmt.Println(item)</span>
	<span class="hljs-comment">//}</span>

	<span class="hljs-keyword">var</span> resultItem []item
	resultItem = []item{}
	<span class="hljs-comment">//fmt.Printf("[ ] % vn", dictResponse.Dictionary)</span>
	i := <span class="hljs-number">1</span>
	<span class="hljs-keyword">for</span> _, paraphrase := <span class="hljs-keyword">range</span> dictResponse.Dictionary.Explanations {
		paraphraseArr := strings.Split(paraphrase, <span class="hljs-string">"; "</span>)
		<span class="hljs-keyword">for</span> _, singleParapharase := <span class="hljs-keyword">range</span> paraphraseArr {
			paraphraseItem := item{Subtitle: <span class="hljs-string">"解释"</span>   strconv.FormatInt(<span class="hljs-keyword">int64</span>(i), <span class="hljs-number">10</span>), Title: singleParapharase, Arg: <span class="hljs-string">"解释"</span>   strconv.FormatInt(<span class="hljs-keyword">int64</span>(i), <span class="hljs-number">10</span>), Icon: icon}
			resultItem = <span class="hljs-built_in">append</span>(resultItem, paraphraseItem)
			i  = <span class="hljs-number">1</span>
		}
	}
	resultItems := items{Items: resultItem}
	resultJson, _ := json.Marshal(resultItems)
	fmt.Println(<span class="hljs-keyword">string</span>(resultJson))
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">IsChinese</span><span class="hljs-params">(str <span class="hljs-keyword">string</span>)</span> <span class="hljs-title">bool</span></span> {
	<span class="hljs-keyword">var</span> count <span class="hljs-keyword">int</span>
	<span class="hljs-keyword">for</span> _, v := <span class="hljs-keyword">range</span> str {
		<span class="hljs-keyword">if</span> unicode.Is(unicode.Han, v) {
			count  
			<span class="hljs-keyword">break</span>
		}
	}
	<span class="hljs-keyword">return</span> count &gt; <span class="hljs-number">0</span>
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
	<span class="hljs-keyword">if</span> <span class="hljs-built_in">len</span>(os.Args) != <span class="hljs-number">2</span> {
		<span class="hljs-comment">//		fmt.Fprintf(os.Stderr, `usage: simpleDict WORD</span>
		<span class="hljs-comment">//example: simpleDict hello</span>
		<span class="hljs-comment">//		`)</span>
		os.Exit(<span class="hljs-number">1</span>)
	}
	word := os.Args[<span class="hljs-number">1</span>]
	icon := icon{Type: <span class="hljs-string">"file"</span>, Path: <span class="hljs-string">"logo2.png"</span>}
	<span class="hljs-keyword">if</span> !IsChinese(word) {
		queryEnglish(word, icon)
	} <span class="hljs-keyword">else</span> {
		queryChinese(word, icon)
	}
}

适配Alfred▸

为了适配Alfred,我们需要定义输出所需要的结构体:

代码语言:javascript复制

<span class="hljs-comment">// 用于翻译结果的图标显示</span>
<span class="hljs-keyword">type</span> icon <span class="hljs-keyword">struct</span> {
	Type <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"type"`</span>
	Path <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"path"`</span>
}

<span class="hljs-comment">// 用于单条结果</span>
<span class="hljs-keyword">type</span> item <span class="hljs-keyword">struct</span> {
	Subtitle <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"subtitle"`</span> <span class="hljs-comment">// 固定的小字的标题</span>
	Title    <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"title"`</span>
	Arg      <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"arg"`</span>
	Icon     icon   <span class="hljs-string">`json:"icon"`</span>
}

<span class="hljs-comment">// 结果集</span>
<span class="hljs-keyword">type</span> items <span class="hljs-keyword">struct</span> {
	Items []item <span class="hljs-string">`json:"items"`</span>
}

然后将输出都以特定的json形式(具体什么形式可以看我博客的Alfred 4: MacOS效率提升大杀器(下篇)的介绍)输出,首先是报错时候的输出:

代码语言:javascript复制
<span class="hljs-comment">// 发生错误时的结果</span>
<span class="hljs-keyword">if</span> resp.StatusCode != <span class="hljs-number">200</span> {
    <span class="hljs-comment">//log.Fatal("bad StatusCode:", resp.StatusCode, "body", string(bodyText))</span>
    <span class="hljs-keyword">var</span> errItem []item
    errItem = []item{
        {
            Subtitle: <span class="hljs-string">"error"</span>,
            Title:    <span class="hljs-string">"bad StatusCode: "</span>   strconv.FormatInt(<span class="hljs-keyword">int64</span>(resp.StatusCode), <span class="hljs-number">10</span>),
            Arg:      <span class="hljs-string">"bad StatusCode: "</span>   strconv.FormatInt(<span class="hljs-keyword">int64</span>(resp.StatusCode), <span class="hljs-number">10</span>),
            Icon:     icon,
        },
    }

    errItems := items{Items: errItem}
    itemsJson, _ := json.Marshal(errItems)
    fmt.Println(<span class="hljs-keyword">string</span>(itemsJson))
    <span class="hljs-keyword">return</span>
}

然后是结果通过json.Marshal序列化后输出,以英译汉为例:

代码语言:javascript复制
<span class="hljs-keyword">var</span> resultItem []item
resultItem = []item{
    {
        Subtitle: <span class="hljs-string">"音标"</span>,
        Title:    <span class="hljs-string">"EN:"</span>   dictResponse.Dictionary.Prons.En   <span class="hljs-string">" US:"</span>   dictResponse.Dictionary.Prons.EnUs,
        Arg:      <span class="hljs-string">"EN:"</span>   dictResponse.Dictionary.Prons.En   <span class="hljs-string">" US:"</span>   dictResponse.Dictionary.Prons.EnUs,
        Icon:     icon,
    },
}
<span class="hljs-keyword">for</span> i, paraphrase := <span class="hljs-keyword">range</span> dictResponse.Dictionary.Explanations {
    paraphraseItem := item{Subtitle: <span class="hljs-string">"解释"</span>   strconv.FormatInt(<span class="hljs-keyword">int64</span>(i <span class="hljs-number">1</span>), <span class="hljs-number">10</span>), Title: paraphrase, Arg: <span class="hljs-string">"解释"</span>   strconv.FormatInt(<span class="hljs-keyword">int64</span>(i <span class="hljs-number">1</span>), <span class="hljs-number">10</span>), Icon: icon}
    resultItem = <span class="hljs-built_in">append</span>(resultItem, paraphraseItem)
}
resultItems := items{Items: resultItem}
resultJson, _ := json.Marshal(resultItems)
fmt.Println(<span class="hljs-keyword">string</span>(resultJson))

最后写两个函数,通过网上抄的IsChinese()判断是否字符串含有中文,如果含有中文就是汉译英,否则英译汉:

代码语言:javascript复制
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">IsChinese</span><span class="hljs-params">(str <span class="hljs-keyword">string</span>)</span> <span class="hljs-title">bool</span></span> {
	<span class="hljs-keyword">var</span> count <span class="hljs-keyword">int</span>
	<span class="hljs-keyword">for</span> _, v := <span class="hljs-keyword">range</span> str {
		<span class="hljs-keyword">if</span> unicode.Is(unicode.Han, v) {
			count  
			<span class="hljs-keyword">break</span>
		}
	}
	<span class="hljs-keyword">return</span> count &gt; <span class="hljs-number">0</span>
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
	<span class="hljs-keyword">if</span> <span class="hljs-built_in">len</span>(os.Args) != <span class="hljs-number">2</span> {
		<span class="hljs-comment">//		fmt.Fprintf(os.Stderr, `usage: simpleDict WORD</span>
		<span class="hljs-comment">//example: simpleDict hello</span>
		<span class="hljs-comment">//		`)</span>
		os.Exit(<span class="hljs-number">1</span>)
	}
	word := os.Args[<span class="hljs-number">1</span>]
	icon := icon{Type: <span class="hljs-string">"file"</span>, Path: <span class="hljs-string">"logo2.png"</span>}
	<span class="hljs-keyword">if</span> !IsChinese(word) {
		queryEnglish(word, icon)
	} <span class="hljs-keyword">else</span> {
		queryChinese(word, icon)
	}
}

后记▸

第一天的知识比较简单,也没啥可记的,所以就分享一个我自己做的小工具吧。Alfred是真的神器,推荐用mac的同学都来试试,真的会爱不释手。

最后推荐一个我常用的翻译Workflow:有道翻译 超级好用,强烈推荐!

0 人点赞