From 27fbc1df12553602981fea36949a5f5b54200f6d Mon Sep 17 00:00:00 2001 From: xiangyu <3170102889@zju.edu.cn> Date: Tue, 4 Oct 2022 09:50:08 +0800 Subject: [PATCH] add: Xunfei OCR --- addon/chrome/content/overlay.xul | 1 + addon/chrome/locale/en-US/overlay.dtd | 1 + addon/chrome/locale/zh-CN/overlay.dtd | 1 + addon/defaults/preferences/defaults.js | 3 + package.json | 1 + src/events.ts | 105 +++++++++++++++++++++++++ 6 files changed, 112 insertions(+) diff --git a/addon/chrome/content/overlay.xul b/addon/chrome/content/overlay.xul index 499fc4e..0c51b81 100644 --- a/addon/chrome/content/overlay.xul +++ b/addon/chrome/content/overlay.xul @@ -110,6 +110,7 @@ + diff --git a/addon/chrome/locale/en-US/overlay.dtd b/addon/chrome/locale/en-US/overlay.dtd index 52f9a66..00d9ab7 100644 --- a/addon/chrome/locale/en-US/overlay.dtd +++ b/addon/chrome/locale/en-US/overlay.dtd @@ -15,6 +15,7 @@ + diff --git a/addon/chrome/locale/zh-CN/overlay.dtd b/addon/chrome/locale/zh-CN/overlay.dtd index 8eaa664..a48a400 100644 --- a/addon/chrome/locale/zh-CN/overlay.dtd +++ b/addon/chrome/locale/zh-CN/overlay.dtd @@ -15,6 +15,7 @@ + diff --git a/addon/defaults/preferences/defaults.js b/addon/defaults/preferences/defaults.js index 9a39e7d..55c7b35 100644 --- a/addon/defaults/preferences/defaults.js +++ b/addon/defaults/preferences/defaults.js @@ -14,3 +14,6 @@ pref("extensions.zotero.Knowledge4Zotero.exportPDF", false); pref("extensions.zotero.Knowledge4Zotero.OCREngine", "bing"); pref("extensions.zotero.Knowledge4Zotero.OCRMathpix.Appid", ""); pref("extensions.zotero.Knowledge4Zotero.OCRMathpix.Appkey", ""); +pref("extensions.zotero.Knowledge4Zotero.OCRXunfei.APPID", ""); +pref("extensions.zotero.Knowledge4Zotero.OCRMathpix.APISecret", ""); +pref("extensions.zotero.Knowledge4Zotero.OCRMathpix.APIKey", ""); diff --git a/package.json b/package.json index 7228e19..bd7baad 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "@syncfusion/ej2-navigations": "^20.1.51", "asciidoctor": "^2.2.6", "compressing": "^1.5.1", + "crypto-js": "^4.1.1", "esbuild": "^0.14.34", "replace-in-file": "^6.3.2", "seedrandom": "^3.0.5", diff --git a/src/events.ts b/src/events.ts index 372275f..ebfc22f 100644 --- a/src/events.ts +++ b/src/events.ts @@ -1,3 +1,4 @@ +const CryptoJS = require("crypto-js"); import Knowledge4Zotero from "./addon"; import { CopyHelper, EditorMessage } from "./base"; import AddonBase from "./module"; @@ -2067,6 +2068,28 @@ class AddonEvents extends AddonBase { Zotero.Prefs.get("Knowledge4Zotero.OCRMathpix.Appkey") as string ) ); + } else if (engine === "xunfei") { + Zotero.Prefs.set( + "Knowledge4Zotero.OCRXunfei.APPID", + prompt( + "Please input APPID", + Zotero.Prefs.get("Knowledge4Zotero.OCRXunfei.APPID") as string + ) + ); + Zotero.Prefs.set( + "Knowledge4Zotero.OCRXunfei.APISecret", + prompt( + "Please input APISecret", + Zotero.Prefs.get("Knowledge4Zotero.OCRXunfei.APISecret") as string + ) + ); + Zotero.Prefs.set( + "Knowledge4Zotero.OCRXunfei.APIKey", + prompt( + "Please input APIKey", + Zotero.Prefs.get("Knowledge4Zotero.OCRXunfei.APIKey") as string + ) + ); } Zotero.Prefs.set("Knowledge4Zotero.OCREngine", engine); } else if (message.type === "ocrImageAnnotation") { @@ -2107,6 +2130,88 @@ class AddonEvents extends AddonBase { xhr.status === 200 ? xhr.response.error : `${xhr.status} Error`; success = false; } + } else if (engine === "xunfei") { + /** + * 1.Doc:https://www.xfyun.cn/doc/words/formula-discern/API.html + * 2.Error code:https://www.xfyun.cn/document/error-code + * @author iflytek + */ + + const config = { + hostUrl: "https://rest-api.xfyun.cn/v2/itr", + host: "rest-api.xfyun.cn", + appid: Zotero.Prefs.get("Knowledge4Zotero.OCRXunfei.APPID"), + apiSecret: Zotero.Prefs.get("Knowledge4Zotero.OCRXunfei.APISecret"), + apiKey: Zotero.Prefs.get("Knowledge4Zotero.OCRXunfei.APIKey"), + uri: "/v2/itr", + }; + + let date = new Date().toUTCString(); + let postBody = getPostBody(); + let digest = getDigest(postBody); + + const xhr = await Zotero.HTTP.request("POST", config.hostUrl, { + headers: { + "Content-Type": "application/json", + Accept: "application/json,version=1.0", + Host: config.host, + Date: date, + Digest: digest, + Authorization: getAuthStr(date, digest), + }, + body: JSON.stringify(postBody), + responseType: "json", + }); + + if (xhr?.response?.code === 0) { + result = xhr.response.data.region + .filter((r) => r.type === "text") + .map((r) => r.recog.content) + .join(" ") + .replace(/ifly-latex-(begin)?(end)?/g, "$"); + console.log(xhr); + success = true; + } else { + result = + xhr.status === 200 + ? `${xhr.response.code} ${xhr.response.message}` + : `${xhr.status} Error`; + success = false; + } + + function getPostBody() { + let digestObj = { + common: { + app_id: config.appid, + }, + business: { + ent: "teach-photo-print", + aue: "raw", + }, + data: { + image: message.content.params.src.split(",").pop(), + }, + }; + return digestObj; + } + + function getDigest(body) { + return ( + "SHA-256=" + + CryptoJS.enc.Base64.stringify(CryptoJS.SHA256(JSON.stringify(body))) + ); + } + + function getAuthStr(date, digest) { + let signatureOrigin = `host: ${config.host}\ndate: ${date}\nPOST ${config.uri} HTTP/1.1\ndigest: ${digest}`; + let signatureSha = CryptoJS.HmacSHA256( + signatureOrigin, + config.apiSecret + ); + let signature = CryptoJS.enc.Base64.stringify(signatureSha); + let authorizationOrigin = `api_key="${config.apiKey}", algorithm="hmac-sha256", headers="host date request-line digest", signature="${signature}"`; + return authorizationOrigin; + } } else if (engine === "bing") { const xhr = await Zotero.HTTP.request( "POST",