Skip to content
This repository has been archived by the owner on Aug 13, 2024. It is now read-only.

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
lehhair committed May 20, 2024
1 parent 29db35c commit 33994fe
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 75 deletions.
76 changes: 49 additions & 27 deletions info.json
Original file line number Diff line number Diff line change
@@ -1,37 +1,59 @@
{
"id": "[plugin].com.pot-app.ocrspace",
"id": "gpt-vision.com.pot-app.ocrspace",
"plugin_type": "recognize",
"icon": "icon.png",
"display": "OCR Space",
"homepage": "https://github.com/pot-app/pot-app-recognize-plugin-template",
"display": "GPT vision",
"homepage": "https://github.com/lehhair/pot-app-recognize-plugin-template",
"needs": [
{
"key": "engine",
"display": "Engine",
"type": "select",
"options": { "1": "Engine 1", "2": "Engine 2", "3": "Engine 3" }
"key": "apikey",
"display": "API Key",
"type": "input"
},
{
"key": "endpoint",
"display": "API Endpoint",
"type": "input"
},
{
"key": "model",
"display": "Model",
"type": "input"
},
{ "key": "apikey", "display": "Api Key", "type": "input" }
{
"key": "prompt",
"display": "Prompt",
"type": "input"
},
{
"key": "stream",
"display": "Stream",
"type": "select",
"options": {
"true": "True",
"false": "False"
}
}
],
"language": {
"auto": "eng",
"zh_cn": "chs",
"zh_tw": "cht",
"en": "eng",
"ja": "jpn",
"ko": "kor",
"fr": "fre",
"es": "spa",
"ru": "rus",
"de": "ger",
"it": "ita",
"tr": "tur",
"pt_pt": "por",
"pt_br": "por",
"vi": "vie",
"th": "tai",
"ar": "ara",
"hi": "hin",
"fa": "per"
"auto": "auto",
"zh_cn": "zh",
"zh_tw": "zh-TW",
"en": "en",
"ja": "ja",
"ko": "ko",
"fr": "fr",
"es": "es",
"ru": "ru",
"de": "de",
"it": "it",
"tr": "tr",
"pt_pt": "pt",
"pt_br": "pt",
"vi": "vi",
"th": "th",
"ar": "ar",
"hi": "hi",
"fa": "fa"
}
}
68 changes: 68 additions & 0 deletions src/lib copy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use serde_json::Value;
use std::collections::HashMap;
use std::error::Error;

#[no_mangle]
pub fn recognize(
base64: &str, // 图像Base64
lang: &str, // 识别语言
// (pot会根据info.json 中的 language 字段传入插件需要的语言代码,无需再次转换)
needs: HashMap<String, String>, // 插件需要的其他参数,由info.json定义
) -> Result<Value, Box<dyn Error>> {
let client = reqwest::blocking::ClientBuilder::new().build()?;

let apikey = match needs.get("apikey") {
Some(apikey) => apikey.to_string(),
None => return Err("apikey not found".into()),
};
let engine = match needs.get("engine") {
Some(engine) => engine.to_string(),
None => "1".to_string(),
};
let base64 = format!("data:image/png;base64,{}", base64);
let mut form_data = HashMap::new();
form_data.insert("base64Image", base64);
form_data.insert("OCREngine", engine);
form_data.insert("language", lang.to_string());

let res: Value = client
.post("https://api.ocr.space/parse/image")
.header("apikey", apikey)
.header("content-type", "application/x-www-form-urlencoded")
.form(&form_data)
.send()?
.json()?;

fn parse_result(res: Value) -> Option<Result<Value, Box<dyn Error>>> {
println!("{res:?}");
if let Some(error) = res.as_object()?.get("ErrorMessage") {
return Some(Err(error.to_string().into()));
}
let result_list = res.as_object()?.get("ParsedResults")?.as_array()?;
let mut result = String::new();
for i in result_list {
let parsed_text = i.as_object()?.get("ParsedText")?.as_str()?;
result.push_str(parsed_text);
}
Some(Ok(Value::String(result)))
}

if let Some(result) = parse_result(res) {
return result;
} else {
return Err("Response Parse Error".into());
}
}

#[cfg(test)]
mod tests {
use super::*;
#[test]
fn try_request() {
let mut needs = HashMap::new();
needs.insert("apikey".to_string(), "K86964409388957".to_string());
needs.insert("engine".to_string(), "1".to_string());
let result = recognize("iVBORw0KGgoAAAANSUhEUgAAADsAAAAeCAYAAACSRGY2AAAAAXNSR0IArs4c6QAAArNJREFUWEftl19IU1Ecxz+O5uQiNTCJkNj0ZWhkSOyh7CEy0CWZQQoTWYgvk17KFAdr9GBBYGb/qD0oUpgSCZViGkTRQ/hwEVOYIIhlMF8kUjbGZGPFdGtrGvcWzTa79/Gec+79fb7fc36/38nQ6/Xf+E+eDAV2mzqdns6WtDNRqYP5UQ71D8i2RoGVLdW/mqg4K6287G3sqHtEdYEP8clrdpZXYdCCxzWE/dkHjp5poXa/AMEVZodvU+ea2/Dn0n2NnK8wYsgVQAWEAng+TfHiZTddy75NI83LtdBRfSS2xruIONKNNftccs9sFPbLkpqcXUCmei1At2uO3YU6CKnR7AhDLDJ204bdH4u/tKSdjkodmvCrEKz6A2iE9fWEVhAftmF1JwBnmxm0msjPinzHH2A1U42GFcSJZYzGJCaodVhYnRqgZngUCmw8rStC419gzOnA7iuio8HG8b3wccTC2clIkFkWhppPkKcK4H7bTev7cWbDQ5kHcZxqorpQAO8M929dp+eHPgJtNXepNajh6wx9j+9E3BeoONBCc7mOnCx18rJxFDYGYmbwson85Sm67nXSB9SXO7loFPCIDzj2anwtdOPhTpxlueB+h7W3BzF+w6pM9F8wYxACTPc30jAfHTTR22ymeMP78HicEMkqPX8Ku5kAMV6Ba/VOKvQJu4GIkCzx5sYlWuOOxE8CphcsbBQxjBOFXeD5VQftiekr2aUnOc4qsNvV2W12ZuVlYx9irxWrO82zMXLqbFz5WseVqLNlOnKyU7DOhkP/qx2Uysf05BLFJVvQQf1uUxHdmIY9Fq5UxfW5wQCezxK9sbYKx+mTGPMi/fRW9cbSd4rUnyH71pP6KNIRKrDSGqXnDMXZ9PRNOmrF2USNtFotXq+XYDAoLV8Kz5DlrAKbwg7+KrTvuhRWXxXeDuUAAAAASUVORK5CYII=", "eng", needs).unwrap();
println!("{result}");
}
}
109 changes: 61 additions & 48 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use serde_json::Value;
use serde_json::{json, Value};
use std::collections::HashMap;
use std::error::Error;

#[no_mangle]
pub fn recognize(
base64: &str, // 图像Base64
lang: &str, // 识别语言
// (pot会根据info.json 中的 language 字段传入插件需要的语言代码,无需再次转换)
base64: &str, // 图像Base64
lang: &str, // 识别语言
needs: HashMap<String, String>, // 插件需要的其他参数,由info.json定义
) -> Result<Value, Box<dyn Error>> {
let client = reqwest::blocking::ClientBuilder::new().build()?;
Expand All @@ -15,54 +14,68 @@ pub fn recognize(
Some(apikey) => apikey.to_string(),
None => return Err("apikey not found".into()),
};
let engine = match needs.get("engine") {
Some(engine) => engine.to_string(),
None => "1".to_string(),

let endpoint = match needs.get("endpoint") {
Some(endpoint) => endpoint.to_string(),
None => "https://api.openai.com/v1/chat/completions".to_string(),
};
let base64 = format!("data:image/png;base64,{}", base64);
let mut form_data = HashMap::new();
form_data.insert("base64Image", base64);
form_data.insert("OCREngine", engine);
form_data.insert("language", lang.to_string());

let res: Value = client
.post("https://api.ocr.space/parse/image")
.header("apikey", apikey)
.header("content-type", "application/x-www-form-urlencoded")
.form(&form_data)
.send()?
.json()?;
let model = match needs.get("model") {
Some(model) => model.to_string(),
None => "gpt-4o-vision".to_string(),
};

fn parse_result(res: Value) -> Option<Result<Value, Box<dyn Error>>> {
println!("{res:?}");
if let Some(error) = res.as_object()?.get("ErrorMessage") {
return Some(Err(error.to_string().into()));
}
let result_list = res.as_object()?.get("ParsedResults")?.as_array()?;
let mut result = String::new();
for i in result_list {
let parsed_text = i.as_object()?.get("ParsedText")?.as_str()?;
result.push_str(parsed_text);
}
Some(Ok(Value::String(result)))
}
let prompt = match needs.get("prompt") {
Some(prompt) => prompt.to_string(),
None => "".to_string(),
};

if let Some(result) = parse_result(res) {
return result;
} else {
return Err("Response Parse Error".into());
}
}
let stream = match needs.get("stream") {
Some(stream) => stream.to_lowercase() == "true",
None => false,
};

let request_body = json!({
"messages": [
{
"role": "system",
"content": prompt
},
{
"role": "user",
"content": [
{
"type": "text",
"text": "analyze"
},
{
"type": "image_url",
"image_url": {
"url": format!("data:image/jpeg;base64,{}", base64)
}
}
]
}
],
"stream": stream,
"model": model,
"temperature": 0.5,
"presence_penalty": 0,
"frequency_penalty": 0,
"top_p": 1
});

let response: Value = client
.post(&endpoint)
.header("Accept", "application/json, text/event-stream")
.header("Content-Type", "application/json")
.header("authorization", format!("Bearer {}", apikey))
.json(&request_body)
.send()?
.json()?;

#[cfg(test)]
mod tests {
use super::*;
#[test]
fn try_request() {
let mut needs = HashMap::new();
needs.insert("apikey".to_string(), "K86964409388957".to_string());
needs.insert("engine".to_string(), "1".to_string());
let result = recognize("iVBORw0KGgoAAAANSUhEUgAAADsAAAAeCAYAAACSRGY2AAAAAXNSR0IArs4c6QAAArNJREFUWEftl19IU1Ecxz+O5uQiNTCJkNj0ZWhkSOyh7CEy0CWZQQoTWYgvk17KFAdr9GBBYGb/qD0oUpgSCZViGkTRQ/hwEVOYIIhlMF8kUjbGZGPFdGtrGvcWzTa79/Gec+79fb7fc36/38nQ6/Xf+E+eDAV2mzqdns6WtDNRqYP5UQ71D8i2RoGVLdW/mqg4K6287G3sqHtEdYEP8clrdpZXYdCCxzWE/dkHjp5poXa/AMEVZodvU+ea2/Dn0n2NnK8wYsgVQAWEAng+TfHiZTddy75NI83LtdBRfSS2xruIONKNNftccs9sFPbLkpqcXUCmei1At2uO3YU6CKnR7AhDLDJ204bdH4u/tKSdjkodmvCrEKz6A2iE9fWEVhAftmF1JwBnmxm0msjPinzHH2A1U42GFcSJZYzGJCaodVhYnRqgZngUCmw8rStC419gzOnA7iuio8HG8b3wccTC2clIkFkWhppPkKcK4H7bTev7cWbDQ5kHcZxqorpQAO8M929dp+eHPgJtNXepNajh6wx9j+9E3BeoONBCc7mOnCx18rJxFDYGYmbwson85Sm67nXSB9SXO7loFPCIDzj2anwtdOPhTpxlueB+h7W3BzF+w6pM9F8wYxACTPc30jAfHTTR22ymeMP78HicEMkqPX8Ku5kAMV6Ba/VOKvQJu4GIkCzx5sYlWuOOxE8CphcsbBQxjBOFXeD5VQftiekr2aUnOc4qsNvV2W12ZuVlYx9irxWrO82zMXLqbFz5WseVqLNlOnKyU7DOhkP/qx2Uysf05BLFJVvQQf1uUxHdmIY9Fq5UxfW5wQCezxK9sbYKx+mTGPMi/fRW9cbSd4rUnyH71pP6KNIRKrDSGqXnDMXZ9PRNOmrF2USNtFotXq+XYDAoLV8Kz5DlrAKbwg7+KrTvuhRWXxXeDuUAAAAASUVORK5CYII=", "eng", needs).unwrap();
println!("{result}");
match response["choices"][0]["message"]["content"].as_str() {
Some(result) => Ok(Value::String(result.to_string())),
None => Err("Response Parse Error".into()),
}
}

0 comments on commit 33994fe

Please sign in to comment.