Skip to content

Commit

Permalink
feat(dicts): add google tts
Browse files Browse the repository at this point in the history
  • Loading branch information
crimx committed Jul 26, 2018
1 parent 39ed461 commit 5af7145
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 15 deletions.
2 changes: 1 addition & 1 deletion src/app-config/dicts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ export function getALlDicts () {
* the preferred height is used and a mask with a view-more button is shown.
* Otherwise the content height is used.
*/
preferredHeight: 110,
preferredHeight: 210,
/** Word count to start searching */
selectionWC: {
min: 1,
Expand Down
12 changes: 11 additions & 1 deletion src/components/dictionaries/google/View.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
import React from 'react'
import { GoogleResult } from './engine'
import Speaker from '@/components/Speaker'

export default class DictGoogle extends React.PureComponent<{ result: GoogleResult }> {
render () {
return <p>{this.props.result}</p>
const {
trans,
searchText,
} = this.props.result
return (
<>
<p>{trans.text} <Speaker src={trans.audio} /></p>
<p>{searchText.text} <Speaker src={searchText.audio} /></p>
</>
)
}
}
64 changes: 51 additions & 13 deletions src/components/dictionaries/google/engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,25 @@ import { DictSearchResult } from '@/typings/server'
import { isContainChinese, isContainEnglish } from '@/_helpers/lang-check'
import { first } from '@/_helpers/promise-more'

export type GoogleResult = string
export interface GoogleResult {
searchText: {
text: string
audio?: string
}
trans: {
text: string
audio?: string
}
}

interface GoogleRawResult {
json: string
base?: string
tl?: string
tk1?: number
tk2?: number
searchText: GoogleResult['searchText']
}

type GoogleSearchResult = DictSearchResult<GoogleResult>

Expand Down Expand Up @@ -32,42 +50,62 @@ export default function search (
.then(handleText)
}

function fetchWithToken (base: string, sl: string, tl: string, text: string): Promise<string> {
function fetchWithToken (base: string, sl: string, tl: string, text: string): Promise<GoogleRawResult> {
return fetch(base)
.then(r => r.text())
.then<Response>(body => {
.then<GoogleRawResult>(body => {
const tkk = (body.match(/TKK=(.*?)\(\)\)'\);/) || [''])[0]
.replace(/\\x([0-9A-Fa-f]{2})/g, '') // remove hex chars
.match(/[+-]?\d+/g)
if (tkk) {
const tk = getTK(text, Number(tkk[2]), (Number(tkk[0]) + Number(tkk[1])))
const tk1 = Number(tkk[2])
const tk2 = Number(tkk[0]) + Number(tkk[1])
const tk = getTK(text, tk1, tk2)
if (tk) {
return fetch(`${base}/translate_a/single?client=t&sl=${sl}&tl=${tl}&q=${encodeURIComponent(text)}&tk=${tk}&hl=en&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&ie=UTF-8&oe=UTF-8&otf=1&ssel=0&tsel=0&kc=5`)
const encodedText = encodeURIComponent(text)
return fetch(`${base}/translate_a/single?client=t&sl=${sl}&tl=${tl}&q=${encodedText}&tk=${tk}&hl=en&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&ie=UTF-8&oe=UTF-8&otf=1&ssel=0&tsel=0&kc=5`)
.then(r => r.text())
.then(json => ({
json, base, tl, tk1, tk2,
searchText: {
text,
audio: `${base}/translate_tts?ie=UTF-8&q=${encodedText}&tl=${sl}&total=1&idx=0&tk=${tk}&client=t`
}
}))
}
}
return handleNoResult()
})
.then(r => r.text())
}

function fetchWithoutToken (sl: string, tl: string, text: string): Promise<string> {
function fetchWithoutToken (sl: string, tl: string, text: string): Promise<GoogleRawResult> {
return fetch(`https://translate.googleapis.com/translate_a/single?client=gtx&sl=${sl}&tl=${tl}&dt=t&q=${encodeURIComponent(text)}`)
.then(r => r.text())
.then(json => ({
json,
searchText: {
text
}
}))
}

function handleText (
text: string
{ json, base, tl, tk1, tk2, searchText }: GoogleRawResult
): GoogleSearchResult | Promise<GoogleSearchResult> {
const json = JSON.parse(text.replace(/,+/g, ','))
const data = JSON.parse(json.replace(/,+/g, ','))

if (!json[0] || json[0].length <= 0) {
if (!data[0] || data[0].length <= 0) {
return handleNoResult()
}

const result: string = json[0].map(item => item[0]).join(' ')
const text: string = data[0].map(item => item[0]).join(' ')

if (text.length > 0) {
const audio = tk1 || tk2
? `${base}/translate_tts?ie=UTF-8&q=${encodeURIComponent(text)}&tl=${tl}&total=1&idx=0&tk=${getTK(text, tk1, tk2)}&client=t`
: ''

if (result.length > 0) {
return { result }
return { result: { trans: { text, audio }, searchText } }
}

return handleNoResult()
Expand Down

0 comments on commit 5af7145

Please sign in to comment.