ocr识别-校核onlyoffice版

This commit is contained in:
liyawei
2022-04-12 19:05:31 +08:00
parent 63bc1c6f22
commit 02c44ea7ff
19 changed files with 2364 additions and 4 deletions
@@ -72,6 +72,8 @@ public class ShiroConfig {
// 配置不会被拦截的链接 顺序判断
filterChainDefinitionMap.put("/sys/cas/client/validateLogin", "anon"); //cas验证登录
filterChainDefinitionMap.put("/ocr/OcrRestful/ocrHandleResult", "anon"); //ocr回调接口
filterChainDefinitionMap.put("/ocr/ocrCheck/downFile", "anon"); //ocr校核下载文件
filterChainDefinitionMap.put("/ocr/ocrCheck/saveFile", "anon"); //ocr校核回调
filterChainDefinitionMap.put("/sys/randomImage/**", "anon"); //登录验证码接口排除
filterChainDefinitionMap.put("/sys/checkCaptcha", "anon"); //登录验证码接口排除
filterChainDefinitionMap.put("/sys/getRSAPublicKey", "anon"); //获取RSA公钥接口排除
+11
View File
@@ -150,6 +150,17 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>com.inversoft</groupId>
<artifactId>prime-jwt</artifactId>
<version>1.3.1</version>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,229 @@
package com.jero.modules.ocr.controller;
import com.jero.common.exception.JeroBootException;
import com.jero.common.system.vo.LoginUser;
import com.jero.modules.ocr.helpers.ConfigManager;
import com.jero.modules.ocr.helpers.DocumentManager;
import com.jero.modules.ocr.helpers.FileUtility;
import com.jero.modules.ocr.helpers.ServiceConverter;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.shiro.SecurityUtils;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
/**
* @Author: liyawei
* @Description:
* @Date: Created in 10:51 2022/4/11
*/
@Api(tags="OCR识别在线校核")
@RestController
@RequestMapping("/ocr/ocrCheck")
@Slf4j
public class OcrCheckController {
@Value("${OCR.ocrDownPath}")
private String ocrDownPath;
@Value("${OCR.ocrSavePath}")
private String ocrSavePath;
@Value("${OCR.serverUrl}")
private String serverUrl;
@Value("${OCR.ocrPath}")
private String ocrPath;
@ApiOperation(value = "下载word文件")
@GetMapping("/downFile")
public void downFile(String fileName, HttpServletResponse response, HttpServletRequest request) throws Exception {
InputStream is = null;
OutputStream os = null;
response.reset();
try {
String downFileName = fileName.substring(fileName.indexOf("_") + 1);
response.setHeader("Content-Disposition", "attachment; filename=" + downFileName);
response.setContentType("application/octet-stream");
String fullPath = ocrPath + fileName;
is = new FileInputStream(fullPath);
os = response.getOutputStream();
IOUtils.copy(is, os);
os.flush();
} catch (FileNotFoundException var4) {
throw new JeroBootException("文件[" + ocrPath + fileName + "]不存在");
} catch (IOException e) {
log.error(e.getMessage(), e);
} finally {
is.close();
os.close();
}
}
@ApiOperation(value = "编辑文件")
@RequestMapping("/editorFile")
public ModelAndView index(HttpServletRequest request, HttpServletResponse response, Model model) throws Exception {
String fileName = "";
if (request.getParameterMap().containsKey("fileName")) {
fileName = request.getParameter("fileName");
}
// String fileExt = null;
// if (request.getParameterMap().containsKey("fileExt")) {
// fileExt = request.getParameter("fileExt");
// }
// if (fileExt != null) {
// try {
// DocumentManager.Init(request, response);
// fileName = DocumentManager.CreateDemo(fileExt);
// } catch (Exception ex) {
// return new ModelAndView(new FastJsonJsonView(),"Error: " + ex.getMessage(), ex) ;
// }
// }
// String mode = "";
// if (request.getParameterMap().containsKey("mode"))
// {
// mode = request.getParameter("mode");
// }
// Boolean desktopMode = !"embedded".equals(mode);
// FileModel file = new FileModel();
// file.SetTypeDesktop(desktopMode);
// file.SetFileName(fileName);
log.info("==========EditorFile==========");
DocumentManager.Init(request, response);
//要编辑的文件名
model.addAttribute("fileName", fileName) ;
//要编辑的文件类型
model.addAttribute("fileType", FileUtility.GetFileExtension(fileName).replace(".", "")) ;
//要编辑的文档类型
model.addAttribute("documentType",FileUtility.GetFileType(fileName).toString().toLowerCase()) ;
//要编辑的文档访问url
// model.addAttribute("fileUri",DocumentManager.GetFileUri(fileName, true)) ;
// model.addAttribute("callbackUrl", DocumentManager.GetCallback(fileName)) ;
// model.addAttribute("serverUrl", DocumentManager.GetServerUrl(true)) ;
model.addAttribute("fileUri", ocrDownPath + "?fileName=" + fileName) ;
model.addAttribute("callbackUrl", ocrSavePath + "?fileName=" + fileName) ;
model.addAttribute("serverUrl", serverUrl) ;
model.addAttribute("fileKey", ServiceConverter.GenerateRevisionId(DocumentManager.CurUserHostAddress(null) + ocrDownPath + "?fileName=" + fileName)) ;
model.addAttribute("editorMode", DocumentManager.GetEditedExts().contains(FileUtility.GetFileExtension(fileName)) && !"view".equals(request.getAttribute("mode")) ? "edit" : "view") ;
model.addAttribute("editorUserId",DocumentManager.CurUserHostAddress(null)) ;
LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
model.addAttribute("editorUserName", loginUser.getUsername()) ;
// model.addAttribute("type", desktopMode ? "desktop" : "embedded");
model.addAttribute("type", true ? "desktop" : "embedded");
model.addAttribute("docserviceApiUrl", ConfigManager.GetProperty("files.docservice.url.api"));
model.addAttribute("docServiceUrlPreloader", ConfigManager.GetProperty("files.docservice.url.preloader")) ;
model.addAttribute("currentYear", "2022") ;
model.addAttribute("convertExts", String.join(",", DocumentManager.GetConvertExts())) ;
model.addAttribute("editedExts", String.join(",", DocumentManager.GetEditedExts())) ;
model.addAttribute("documentCreated", new SimpleDateFormat("MM/dd/yyyy").format(new Date())) ;
model.addAttribute("permissionsEdit", Boolean.toString(DocumentManager.GetEditedExts().contains(FileUtility.GetFileExtension(fileName))).toLowerCase()) ;
return new ModelAndView("editor") ;
}
/**
* 文档编辑服务使用JavaScript API通知callbackUrl,向文档存储服务通知文档编辑的状态。文档编辑服务使用具有正文中的信息的POST请求。
* https://api.onlyoffice.com/editors/callback
* 参数示例:
{
"actions": [{"type": 0, "userid": "78e1e841"}],
"changesurl": "https://documentserver/url-to-changes.zip",
"history": {
"changes": changes,
"serverVersion": serverVersion
},
"key": "Khirz6zTPdfd7",
"status": 2,
"url": "https://documentserver/url-to-edited-document.docx",
"users": ["6d5a81d0"]
}
*/
@ApiOperation(value = "保存文件")
@RequestMapping("/saveFile")
public void saveFile(HttpServletRequest request, HttpServletResponse response) {
String fileName = "";
if (request.getParameterMap().containsKey("fileName")) {
fileName = request.getParameter("fileName");
}
PrintWriter writer = null;
log.info("==========SaveEditedFile==========");
try {
writer = response.getWriter();
Scanner scanner = new Scanner(request.getInputStream()).useDelimiter("\\A");
String body = scanner.hasNext() ? scanner.next() : "";
JSONObject jsonObj = (JSONObject) new JSONParser().parse(body);
log.info("status:" + jsonObj.get("status"));
/*
0 - no document with the key identifier could be found,
1 - document is being edited,
2 - document is ready for saving,
3 - document saving error has occurred,
4 - document is closed with no changes,
6 - document is being edited, but the current document state is saved,
7 - error has occurred while force saving the document.
* */
if ((long) jsonObj.get("status") == 2) {
/*
* 当我们关闭编辑窗口后,十秒钟左右onlyoffice会将它存储的我们的编辑后的文件,,此时status = 2,通过request发给我们,我们需要做的就是接收到文件然后回写该文件。
* */
/*
* 定义要与文档存储服务保存的编辑文档的链接。当状态值仅等于2或3时,存在链路。
* */
String downloadUri = (String) jsonObj.get("url");
log.info("文档编辑完成,现在开始保存编辑后的文档,其下载地址为:" + downloadUri);
//解析得出文件名
// String fileName = downloadUri.substring(downloadUri.lastIndexOf('/') + 1);
log.info("下载的文件名:" + fileName);
URL url = new URL(downloadUri);
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
InputStream stream = connection.getInputStream();
File savedFile = new File(ocrPath + fileName);
try (FileOutputStream out = new FileOutputStream(savedFile)) {
int read;
final byte[] bytes = new byte[1024];
while ((read = stream.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
out.flush();
}
connection.disconnect();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/*
* status = 1,我们给onlyoffice的服务返回{"error":"0"}的信息,这样onlyoffice会认为回调接口是没问题的,这样就可以在线编辑文档了,否则的话会弹出窗口说明
* */
writer.write("{\"error\":0}");
}
}
@@ -0,0 +1,17 @@
package com.jero.modules.ocr.entity;
import java.util.List;
public class CommentGroups {
public List<String> view;
public List<String> edit;
public List<String> remove;
public CommentGroups(){
}
public CommentGroups(List<String> view, List<String> edit, List<String> remove){
this.view = view;
this.edit = edit;
this.remove = remove;
}
}
@@ -0,0 +1,370 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* 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 com.jero.modules.ocr.entity;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.jero.modules.ocr.helpers.DocumentManager;
import com.jero.modules.ocr.helpers.FileUtility;
import com.jero.modules.ocr.helpers.ServiceConverter;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import java.io.File;
import java.io.FileInputStream;
import java.util.*;
public class FileModel
{
public String type = "desktop";
public String mode = "edit";
public String documentType;
public Document document;
public EditorConfig editorConfig;
public String token;
// create file model
public FileModel(String fileName, String lang, String actionData, User user)
{
if (fileName == null) fileName = "";
fileName = fileName.trim(); // remove extra spaces in the file name
// get file type from the file name (word, cell or slide)
documentType = FileUtility.GetFileType(fileName).toString().toLowerCase();
// set the document parameters
document = new Document();
document.title = fileName;
document.url = DocumentManager.GetDownloadUrl(fileName); // get file url
document.urlUser = DocumentManager.GetFileUri(fileName, false);
document.fileType = FileUtility.GetFileExtension(fileName).replace(".", ""); // get file extension from the file name
// generate document key
document.key = ServiceConverter.GenerateRevisionId(DocumentManager.CurUserHostAddress(null) + "/" + fileName + "/" + Long.toString(new File(DocumentManager.StoragePath(fileName, null)).lastModified()));
document.info = new Info();
document.info.favorite = user.favorite;
String templatesImageUrl = DocumentManager.GetTemplateImageUrl(FileUtility.GetFileType(fileName));
List<Map<String, String>> templates = new ArrayList<>();
String createUrl = DocumentManager.GetCreateUrl(FileUtility.GetFileType(fileName));
// add templates for the "Create New" from menu option
Map<String, String> templateForBlankDocument = new HashMap<>();
templateForBlankDocument.put("image", "");
templateForBlankDocument.put("title", "Blank");
templateForBlankDocument.put("url", createUrl);
templates.add(templateForBlankDocument);
Map<String, String> templateForDocumentWithSampleContent = new HashMap<>();
templateForDocumentWithSampleContent.put("image", templatesImageUrl);
templateForDocumentWithSampleContent.put("title", "With sample content");
templateForDocumentWithSampleContent.put("url", createUrl + "&sample=true");
templates.add(templateForDocumentWithSampleContent);
// set the editor config parameters
editorConfig = new EditorConfig(actionData);
editorConfig.callbackUrl = DocumentManager.GetCallback(fileName); // get callback url
if (lang != null) editorConfig.lang = lang; // write language parameter to the config
editorConfig.createUrl = !user.id.equals("uid-0") ? createUrl : null;
editorConfig.templates = user.templates ? templates : null;
// write user information to the config (id, name and group)
editorConfig.user.id = user.id;
editorConfig.user.name = user.name;
editorConfig.user.group = user.group;
// write the absolute URL to the file location
editorConfig.customization.goback.url = DocumentManager.GetServerUrl(false) + "/IndexServlet";
changeType(mode, type, user);
}
// change the document type
public void changeType(String _mode, String _type, User user)
{
if (_mode != null) mode = _mode;
if (_type != null) type = _type;
// check if the file with such an extension can be edited
String fileExt = FileUtility.GetFileExtension(document.title);
Boolean canEdit = DocumentManager.GetEditedExts().contains(fileExt);
// check if the Submit form button is displayed or not
editorConfig.customization.submitForm = mode.equals("fillForms") && user.id.equals("uid-1") && false;
if ((!canEdit && mode.equals("edit") || mode.equals("fillForms")) && DocumentManager.GetFillExts().contains(fileExt)) {
canEdit = true;
mode = "fillForms";
}
// set the mode parameter: change it to view if the document can't be edited
editorConfig.mode = canEdit && !mode.equals("view") ? "edit" : "view";
// set document permissions
document.permissions = new Permissions(mode, type, canEdit, user);
if (type.equals("embedded")) InitDesktop(); // set parameters for the embedded document
}
public void InitDesktop()
{
editorConfig.InitDesktop(document.urlUser);
}
// generate document token
public void BuildToken()
{
// write all the necessary document parameters to the map
Map<String, Object> map = new HashMap<>();
map.put("type", type);
map.put("documentType", documentType);
map.put("document", document);
map.put("editorConfig", editorConfig);
// and create token from them
token = DocumentManager.CreateToken(map);
}
// get document history
public String[] GetHistory()
{
JSONParser parser = new JSONParser();
String histDir = DocumentManager.HistoryDir(DocumentManager.StoragePath(document.title, null)); // get history directory
if (DocumentManager.GetFileVersion(histDir) > 0) {
Integer curVer = DocumentManager.GetFileVersion(histDir); // get current file version if it is greater than 0
List<Object> hist = new ArrayList<>();
Map<String, Object> histData = new HashMap<String, Object>();
for (Integer i = 1; i <= curVer; i++) { // run through all the file versions
Map<String, Object> obj = new HashMap<String, Object>();
Map<String, Object> dataObj = new HashMap<String, Object>();
String verDir = DocumentManager.VersionDir(histDir, i); // get the path to the given file version
try {
String key = null;
// get document key
key = i == curVer ? document.key : readFileToEnd(new File(verDir + File.separator + "key.txt"));
obj.put("key", key);
obj.put("version", i);
if (i == 1) { // check if the version number is equal to 1
String createdInfo = readFileToEnd(new File(histDir + File.separator + "createdInfo.json")); // get file with meta data
JSONObject json = (JSONObject) parser.parse(createdInfo); // and turn it into json object
// write meta information to the object (user information and creation date)
obj.put("created", json.get("created"));
Map<String, Object> user = new HashMap<String, Object>();
user.put("id", json.get("id"));
user.put("name", json.get("name"));
obj.put("user", user);
}
dataObj.put("key", key);
dataObj.put("url", i == curVer ? document.url : DocumentManager.GetPathUri(verDir + File.separator + "prev" + FileUtility.GetFileExtension(document.title)));
dataObj.put("version", i);
if (i > 1) { //check if the version number is greater than 1
// if so, get the path to the changes.json file
JSONObject changes = (JSONObject) parser.parse(readFileToEnd(new File(DocumentManager.VersionDir(histDir, i - 1) + File.separator + "changes.json")));
JSONObject change = (JSONObject) ((JSONArray) changes.get("changes")).get(0);
// write information about changes to the object
obj.put("changes", !change.isEmpty() ? changes.get("changes") : null);
obj.put("serverVersion", changes.get("serverVersion"));
obj.put("created", !change.isEmpty() ? change.get("created") : null);
obj.put("user", !change.isEmpty() ? change.get("user") : null);
Map<String, Object> prev = (Map<String, Object>) histData.get(Integer.toString(i - 2)); // get the history data from the previous file version
Map<String, Object> prevInfo = new HashMap<String, Object>();
prevInfo.put("key", prev.get("key")); // write key and url information about previous file version
prevInfo.put("url", prev.get("url"));
dataObj.put("previous", prevInfo); // write information about previous file version to the data object
// write the path to the diff.zip archive with differences in this file version
dataObj.put("changesUrl", DocumentManager.GetPathUri(DocumentManager.VersionDir(histDir, i - 1) + File.separator + "diff.zip"));
}
if (DocumentManager.TokenEnabled())
{
dataObj.put("token", DocumentManager.CreateToken(dataObj));
}
hist.add(obj);
histData.put(Integer.toString(i - 1), dataObj);
} catch (Exception ex) { }
}
// write history information about the current file version to the history object
Map<String, Object> histObj = new HashMap<String, Object>();
histObj.put("currentVersion", curVer);
histObj.put("history", hist);
Gson gson = new Gson();
return new String[] { gson.toJson(histObj), gson.toJson(histData) };
}
return new String[] { "", "" };
}
// read a file
private String readFileToEnd(File file) {
String output = "";
try {
try(FileInputStream is = new FileInputStream(file))
{
Scanner scanner = new Scanner(is); // read data from the source
scanner.useDelimiter("\\A");
while (scanner.hasNext()) {
output += scanner.next();
}
scanner.close();
}
} catch (Exception e) { }
return output;
}
// the document parameters
public class Document
{
public String title;
public String url;
public String urlUser;
public String fileType;
public String key;
public Info info;
public Permissions permissions;
}
// the permissions parameters
public class Permissions
{
public Boolean comment;
public Boolean сopy;
public Boolean download;
public Boolean edit;
public Boolean print;
public Boolean fillForms;
public Boolean modifyFilter;
public Boolean modifyContentControl;
public Boolean review;
public List<String> reviewGroups;
public CommentGroups commentGroups;
// defines what can be done with a document
public Permissions(String mode, String type, Boolean canEdit, User user)
{
comment = !mode.equals("view") && !mode.equals("fillForms") && !mode.equals("embedded") && !mode.equals("blockcontent");
сopy = !user.deniedPermissions.contains("сopy");
download = !user.deniedPermissions.contains("download");
edit = canEdit && (mode.equals("edit") || mode.equals("view") || mode.equals("filter") || mode.equals("blockcontent"));
print = !user.deniedPermissions.contains("print");
fillForms = !mode.equals("view") && !mode.equals("comment") && !mode.equals("embedded") && !mode.equals("blockcontent");
modifyFilter = !mode.equals("filter");
modifyContentControl = !mode.equals("blockcontent");
review = canEdit && (mode.equals("edit") || mode.equals("review"));
reviewGroups = user.reviewGroups;
commentGroups = user.commentGroups;
}
}
// the Favorite icon state
public class Info
{
public Boolean favorite;
}
// the editor config parameters
public class EditorConfig
{
public HashMap<String, Object> actionLink = null;
public String mode = "edit";
public String callbackUrl;
public String lang = "en";
public String createUrl;
public List<Map<String, String>> templates;
public User user;
public Customization customization;
public Embedded embedded;
public EditorConfig(String actionData)
{
// get the action in the document that will be scrolled to (bookmark or comment)
if (actionData != null) {
Gson gson = new Gson();
actionLink = gson.fromJson(actionData, new TypeToken<HashMap<String, Object>>() { }.getType());
}
user = new User();
customization = new Customization();
}
// set parameters for the embedded document
public void InitDesktop(String url)
{
embedded = new Embedded();
embedded.saveUrl = url; // the absolute URL that will allow the document to be saved onto the user personal computer
embedded.embedUrl = url; // the absolute URL to the document serving as a source file for the document embedded into the web page
embedded.shareUrl = url; // the absolute URL that will allow other users to share this document
embedded.toolbarDocked = "top"; // the place for the embedded viewer toolbar, can be either top or bottom
}
// default user parameters (id, name and group)
public class User
{
public String id;
public String name;
public String group;
}
// customization parameters
public class Customization
{
public Goback goback;
public Boolean forcesave;
public Boolean submitForm;
public Customization()
{
forcesave = false;
goback = new Goback();
}
public class Goback
{
public String url;
}
}
// parameters for embedded document
public class Embedded
{
public String saveUrl;
public String embedUrl;
public String shareUrl;
public String toolbarDocked;
}
}
// turn java objects into json strings
public static String Serialize(FileModel model)
{
Gson gson = new Gson();
return gson.toJson(model);
}
}
@@ -0,0 +1,26 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* 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 com.jero.modules.ocr.entity;
public enum FileType
{
Word,
Cell,
Slide
}
@@ -0,0 +1,48 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* 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 com.jero.modules.ocr.entity;
import java.util.List;
public class User {
public String id;
public String name;
public String email;
public String group;
public List<String> reviewGroups;
public CommentGroups commentGroups;
public Boolean favorite;
public List<String> deniedPermissions;
public List<String> descriptions;
public Boolean templates;
public User(String id, String name, String email, String group, List<String> reviewGroups, CommentGroups commentGroups,
Boolean favorite, List<String> deniedPermissions, List<String> descriptions, Boolean templates) {
this.id = id;
this.name = name;
this.email = email;
this.group = group;
this.reviewGroups = reviewGroups;
this.commentGroups = commentGroups;
this.favorite = favorite;
this.deniedPermissions = deniedPermissions;
this.descriptions = descriptions;
this.templates = templates;
}
}
@@ -0,0 +1,61 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* 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 com.jero.modules.ocr.helpers;
import java.io.InputStream;
import java.util.Properties;
public class ConfigManager
{
private static Properties properties;
static
{
Init();
}
private static void Init()
{
try
{
// get stream from the settings.properties resource and load it
properties = new Properties();
InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream("settings.properties");
properties.load(stream);
}
catch (Exception ex)
{
properties = null;
}
}
// get name from the settings.properties file
public static String GetProperty(String name)
{
if (properties == null)
{
return "";
}
// get property by its name
String property = properties.getProperty(name);
return property == null ? "" : property;
}
}
@@ -0,0 +1,45 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* 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 com.jero.modules.ocr.helpers;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
public class CookieManager {
private HashMap<String, String> cookiesMap;
public CookieManager(HttpServletRequest request) throws UnsupportedEncodingException {
cookiesMap = new HashMap<String, String>();
Cookie[] cookies = request.getCookies(); // get all the cookies from the request
if (cookies != null) {
for (Cookie cookie : cookies) { // run through all the cookies
cookiesMap.putIfAbsent(cookie.getName(), URLDecoder.decode(cookie.getValue(), "UTF-8")); // add cookie to the cookies map if its name isn't in the map yet
}
}
}
// get cookie by its name
public String getCookie(String name) {
return cookiesMap.get(name);
}
}
@@ -0,0 +1,519 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* 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 com.jero.modules.ocr.helpers;
import com.jero.modules.ocr.entity.FileType;
import com.jero.modules.ocr.entity.User;
import org.json.simple.JSONObject;
import org.primeframework.jwt.Signer;
import org.primeframework.jwt.Verifier;
import org.primeframework.jwt.domain.JWT;
import org.primeframework.jwt.hmac.HMACSigner;
import org.primeframework.jwt.hmac.HMACVerifier;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.InetAddress;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.*;
public class DocumentManager
{
private static HttpServletRequest request;
public static void Init(HttpServletRequest req, HttpServletResponse resp)
{
request = req;
}
// get max file size
public static long GetMaxFileSize()
{
long size;
try
{
size = Long.parseLong(ConfigManager.GetProperty("filesize-max"));
}
catch (Exception ex)
{
size = 0;
}
return size > 0 ? size : 5 * 1024 * 1024;
}
// get all the supported file extensions
public static List<String> GetFileExts()
{
List<String> res = new ArrayList<>();
res.addAll(GetViewedExts());
res.addAll(GetEditedExts());
res.addAll(GetConvertExts());
res.addAll(GetFillExts());
return res;
}
public static List<String> GetFillExts() {
String exts = ConfigManager.GetProperty("files.docservice.fill-docs");
return Arrays.asList(exts.split("\\|"));
}
// get file extensions that can be viewed
public static List<String> GetViewedExts()
{
String exts = ConfigManager.GetProperty("files.docservice.viewed-docs");
return Arrays.asList(exts.split("\\|"));
}
// get file extensions that can be edited
public static List<String> GetEditedExts()
{
String exts = ConfigManager.GetProperty("files.docservice.edited-docs");
return Arrays.asList(exts.split("\\|"));
}
// get file extensions that can be converted
public static List<String> GetConvertExts()
{
String exts = ConfigManager.GetProperty("files.docservice.convert-docs");
return Arrays.asList(exts.split("\\|"));
}
// get current user host address
public static String CurUserHostAddress(String userAddress)
{
if(userAddress == null)
{
try
{
// use InetAddress class to get the user address if it wasn't passed to the function
userAddress = InetAddress.getLocalHost().getHostAddress();
}
catch (Exception ex)
{
userAddress = "";
}
}
return userAddress.replaceAll("[^0-9a-zA-Z.=]", "_");
}
// get the root directory of the user host
public static String FilesRootPath(String userAddress)
{
String hostAddress = CurUserHostAddress(userAddress); // get current user host address
String serverPath = request.getSession().getServletContext().getRealPath(""); // get the server url
String storagePath = ConfigManager.GetProperty("storage-folder"); // get the storage directory
String directory = serverPath + storagePath + File.separator + hostAddress + File.separator;
File file = new File(directory);
// if the root directory doesn't exist
if (!file.exists())
{
// create it
file.mkdirs();
}
return directory;
}
// get the storage path of the file
public static String StoragePath(String fileName, String userAddress)
{
String directory = FilesRootPath(userAddress);
return directory + FileUtility.GetFileName(fileName);
}
// get the path to the forcesaved file version
public static String ForcesavePath(String fileName, String userAddress, Boolean create)
{
String hostAddress = CurUserHostAddress(userAddress);
String serverPath = request.getSession().getServletContext().getRealPath("");
String storagePath = ConfigManager.GetProperty("storage-folder");
// create the directory to this file version
String directory = serverPath + storagePath + File.separator + hostAddress + File.separator;
File file = new File(directory);
if (!file.exists()) return "";
// create the directory to the history of this file version
directory = directory + fileName + "-hist" + File.separator;
file = new File(directory);
if (!create && !file.exists()) return "";
file.mkdirs();
directory = directory + fileName;
file = new File(directory);
if (!create && !file.exists()) {
return "";
}
return directory;
}
// get the history directory
public static String HistoryDir(String storagePath)
{
return storagePath += "-hist";
}
// get the path to the file version by the history path and file version
public static String VersionDir(String histPath, Integer version)
{
return histPath + File.separator + Integer.toString(version);
}
// get the path to the file version by the file name, user address and file version
public static String VersionDir(String fileName, String userAddress, Integer version)
{
return VersionDir(HistoryDir(StoragePath(fileName, userAddress)), version);
}
// get the file version by the history path
public static Integer GetFileVersion(String historyPath)
{
File dir = new File(historyPath);
if (!dir.exists()) return 1; // if the history path doesn't exist, then the file version is 1
File[] dirs = dir.listFiles(new FileFilter() { // take only directories from the history folder
@Override
public boolean accept(File pathname) {
return pathname.isDirectory();
}
});
return dirs.length + 1; // count the directories
}
// get the file version by the file name and user address
public static int GetFileVersion(String fileName, String userAddress)
{
return GetFileVersion(HistoryDir(StoragePath(fileName, userAddress)));
}
// get a file name with an index if the file with such a name already exists
public static String GetCorrectName(String fileName, String userAddress)
{
String baseName = FileUtility.GetFileNameWithoutExtension(fileName);
String ext = FileUtility.GetFileExtension(fileName);
String name = baseName + ext;
File file = new File(StoragePath(name, userAddress));
for (int i = 1; file.exists(); i++) // run through all the files with such a name in the storage directory
{
name = baseName + " (" + i + ")" + ext; // and add an index to the base name
file = new File(StoragePath(name, userAddress));
}
return name;
}
// create meta information
public static void CreateMeta(String fileName, String uid, String uname, String userAddress) throws Exception
{
String histDir = HistoryDir(StoragePath(fileName, userAddress));
File dir = new File(histDir); // create history directory
dir.mkdir();
// create json object and put there file information (creation time, user id and name)
JSONObject json = new JSONObject();
json.put("created", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
json.put("id", uid);
json.put("name", uname);
// create createdInfo.json file with meta information in the history directory
File meta = new File(histDir + File.separator + "createdInfo.json");
try (FileWriter writer = new FileWriter(meta)) {
json.writeJSONString(writer); // write information from the json object into this file
}
}
// get all the stored files from the user host address
public static File[] GetStoredFiles(String userAddress)
{
String directory = FilesRootPath(userAddress);
File file = new File(directory);
return file.listFiles(new FileFilter() { // take only files from the root directory
@Override
public boolean accept(File pathname) {
return pathname.isFile();
}
});
}
// create demo document
public static String CreateDemo(String fileExt, Boolean sample, User user) throws Exception
{
String demoName = (sample ? "sample." : "new.") + fileExt; // create sample or new template file with the necessary extension
String demoPath = "assets" + File.separator + (sample ? "sample" : "new") + File.separator; // get the path to the sample document
String fileName = GetCorrectName(demoName, null); // get a file name with an index if the file with such a name already exists
InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream(demoPath + demoName); // get the input file stream
CreateFile(Paths.get(StoragePath(fileName, null)), stream);
// create meta information of the demo file
CreateMeta(fileName, user.id, user.name, null);
return fileName;
}
public static boolean CreateFile(Path path, InputStream stream) {
if (Files.exists(path)){
return true;
}
try {
File file = Files.createFile(path).toFile();
try (FileOutputStream out = new FileOutputStream(file))
{
int read;
final byte[] bytes = new byte[1024];
while ((read = stream.read(bytes)) != -1)
{
out.write(bytes, 0, read);
}
out.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
// get file url
public static String GetFileUri(String fileName, Boolean forDocumentServer)
{
try
{
String serverPath = GetServerUrl(forDocumentServer);
String storagePath = ConfigManager.GetProperty("storage-folder");
String hostAddress = CurUserHostAddress(null);
String filePath = serverPath + "/" + storagePath + "/" + hostAddress + "/" + URLEncoder.encode(fileName, java.nio.charset.StandardCharsets.UTF_8.toString()).replace("+", "%20");
// String filePath = serverPath + "?fileName=" + URLEncoder.encode(fileName, java.nio.charset.StandardCharsets.UTF_8.toString()).replace("+", "%20") + "&useraddress=" + hostAddress;
return filePath;
}
catch (UnsupportedEncodingException e)
{
return "";
}
}
// get file information
public static ArrayList<Map<String, Object>> GetFilesInfo(){
ArrayList<Map<String, Object>> files = new ArrayList<>();
// run through all the stored files
for(File file : GetStoredFiles(null)){
Map<String, Object> map = new LinkedHashMap<>(); // write all the parameters to the map
map.put("version", GetFileVersion(file.getName(), null));
map.put("id", ServiceConverter.GenerateRevisionId(CurUserHostAddress(null) + "/" + file.getName() + "/" + Long.toString(new File(StoragePath(file.getName(), null)).lastModified())));
map.put("contentLength", new BigDecimal(String.valueOf((file.length()/1024.0))).setScale(2, RoundingMode.HALF_UP) + " KB");
map.put("pureContentLength", file.length());
map.put("title", file.getName());
map.put("updated", String.valueOf(new Date(file.lastModified())));
files.add(map);
}
return files;
}
// get file information by its id
public static ArrayList<Map<String, Object>> GetFilesInfo(String fileId){
ArrayList<Map<String, Object>> file = new ArrayList<>();
for (Map<String, Object> map : GetFilesInfo()){
if (map.get("id").equals(fileId)){
file.add(map);
break;
}
}
return file;
}
// get the path url
public static String GetPathUri(String path)
{
String serverPath = GetServerUrl(true);
String storagePath = ConfigManager.GetProperty("storage-folder");
String hostAddress = CurUserHostAddress(null);
String filePath = serverPath + "/" + storagePath + "/" + hostAddress + "/" + path.replace(File.separator, "/").substring(FilesRootPath(null).length()).replace(" ", "%20");
return filePath;
}
// get the server url
public static String GetServerUrl(Boolean forDocumentServer) {
if (forDocumentServer && !ConfigManager.GetProperty("files.docservice.url.example").equals("")) {
return ConfigManager.GetProperty("files.docservice.url.example");
} else {
return request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();
}
}
// get the callback url
public static String GetCallback(String fileName)
{
String serverPath = GetServerUrl(true);
String hostAddress = CurUserHostAddress(null);
try
{
String query = "?type=track&fileName=" + URLEncoder.encode(fileName, java.nio.charset.StandardCharsets.UTF_8.toString()) + "&userAddress=" + URLEncoder.encode(hostAddress, java.nio.charset.StandardCharsets.UTF_8.toString());
return serverPath + "/IndexServlet" + query;
}
catch (UnsupportedEncodingException e)
{
return "";
}
}
// get url to the created file
public static String GetCreateUrl (FileType fileType) {
String serverPath = GetServerUrl(false);
String fileExt = GetInternalExtension(fileType).replace(".", "");
String query = "?fileExt=" + fileExt;
return serverPath + "/EditorServlet" + query;
}
// get url to download a file
public static String GetDownloadUrl(String fileName) {
String serverPath = GetServerUrl(true);
String hostAddress = CurUserHostAddress(null);
try
{
String query = "?type=download&fileName=" + URLEncoder.encode(fileName, java.nio.charset.StandardCharsets.UTF_8.toString()) + "&userAddress=" + URLEncoder.encode(hostAddress, java.nio.charset.StandardCharsets.UTF_8.toString());
return serverPath + "/IndexServlet" + query;
}
catch (UnsupportedEncodingException e)
{
return "";
}
}
// get an editor internal extension
public static String GetInternalExtension(FileType fileType)
{
// .docx for word file type
if (fileType.equals(FileType.Word))
return ".docx";
// .xlsx for cell file type
if (fileType.equals(FileType.Cell))
return ".xlsx";
// .pptx for slide file type
if (fileType.equals(FileType.Slide))
return ".pptx";
// the default file type is .docx
return ".docx";
}
// get image url for templates
public static String GetTemplateImageUrl(FileType fileType)
{
String path = GetServerUrl(true) + "/css/img/";
// for word file type
if (fileType.equals(FileType.Word))
return path + "file_docx.svg";
// .xlsx for cell file type
if (fileType.equals(FileType.Cell))
return path + "file_xlsx.svg";
// .pptx for slide file type
if (fileType.equals(FileType.Slide))
return path + "file_pptx.svg";
// the default file type
return path + "file_docx.svg";
}
// create document token
public static String CreateToken(Map<String, Object> payloadClaims)
{
try
{
// build a HMAC signer using a SHA-256 hash
Signer signer = HMACSigner.newSHA256Signer(GetTokenSecret());
JWT jwt = new JWT();
for (String key : payloadClaims.keySet()) // run through all the keys from the payload
{
jwt.addClaim(key, payloadClaims.get(key)); // and write each claim to the jwt
}
return JWT.getEncoder().encode(jwt, signer); // sign and encode the JWT to a JSON string representation
}
catch (Exception e)
{
return "";
}
}
// read document token
public static JWT ReadToken(String token)
{
try
{
// build a HMAC verifier using the token secret
Verifier verifier = HMACVerifier.newVerifier(GetTokenSecret());
return JWT.getDecoder().decode(token, verifier); // verify and decode the encoded string JWT to a rich object
}
catch (Exception exception)
{
return null;
}
}
// check if the token is enabled
public static Boolean TokenEnabled()
{
String secret = GetTokenSecret();
return secret != null && !secret.isEmpty();
}
// get token secret from the config parameters
public static String GetTokenSecret()
{
return ConfigManager.GetProperty("files.docservice.secret");
}
}
@@ -0,0 +1,132 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* 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 com.jero.modules.ocr.helpers;
import com.jero.modules.ocr.entity.FileType;
import java.net.URL;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class FileUtility
{
static {}
// get file type
public static FileType GetFileType(String fileName)
{
String ext = GetFileExtension(fileName).toLowerCase();
// word type for document extensions
if (ExtsDocument.contains(ext))
return FileType.Word;
// cell type for spreadsheet extensions
if (ExtsSpreadsheet.contains(ext))
return FileType.Cell;
// slide type for presentation extensions
if (ExtsPresentation.contains(ext))
return FileType.Slide;
// default file type is word
return FileType.Word;
}
// document extensions
public static List<String> ExtsDocument = Arrays.asList
(
".doc", ".docx", ".docm",
".dot", ".dotx", ".dotm",
".odt", ".fodt", ".ott", ".rtf", ".txt",
".html", ".htm", ".mht", ".xml",
".pdf", ".djvu", ".fb2", ".epub", ".xps", ".oxps", ".oform"
);
// spreadsheet extensions
public static List<String> ExtsSpreadsheet = Arrays.asList
(
".xls", ".xlsx", ".xlsm",
".xlt", ".xltx", ".xltm",
".ods", ".fods", ".ots", ".csv"
);
// presentation extensions
public static List<String> ExtsPresentation = Arrays.asList
(
".pps", ".ppsx", ".ppsm",
".ppt", ".pptx", ".pptm",
".pot", ".potx", ".potm",
".odp", ".fodp", ".otp"
);
// get file name from the url
public static String GetFileName(String url)
{
if (url == null) return "";
// get file name from the last part of url
String fileName = url.substring(url.lastIndexOf('/') + 1, url.length());
fileName = fileName.split("\\?")[0];
return fileName;
}
// get file name without extension
public static String GetFileNameWithoutExtension(String url)
{
String fileName = GetFileName(url);
if (fileName == null) return null;
String fileNameWithoutExt = fileName.substring(0, fileName.lastIndexOf('.'));
return fileNameWithoutExt;
}
// get file extension from url
public static String GetFileExtension(String url)
{
String fileName = GetFileName(url);
if (fileName == null) return null;
String fileExt = fileName.substring(fileName.lastIndexOf("."));
return fileExt.toLowerCase();
}
// get url parameters
public static Map<String, String> GetUrlParams(String url)
{
try
{
String query = new URL(url).getQuery(); // take all the parameters which are placed after ? sign in the file url
String[] params = query.split("&"); // parameters are separated by & sign
Map<String, String> map = new HashMap<>();
for (String param : params) // write parameters and their values to the map dictionary
{
String name = param.split("=")[0];
String value = param.split("=")[1];
map.put(name, value);
}
return map;
}
catch (Exception ex)
{
return null;
}
}
}
@@ -0,0 +1,269 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* 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 com.jero.modules.ocr.helpers;
import com.google.gson.Gson;
import com.jero.modules.ocr.util.UUIDUtils;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.io.*;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class ServiceConverter
{
private static int ConvertTimeout = 120000;
private static final String DocumentConverterUrl = ConfigManager.GetProperty("files.docservice.url.site") + ConfigManager.GetProperty("files.docservice.url.converter");
private static final String DocumentJwtHeader = ConfigManager.GetProperty("files.docservice.header");
public static class ConvertBody
{
public String region;
public String url;
public String outputtype;
public String filetype;
public String title;
public String key;
public Boolean async;
public String token;
public String password;
}
static
{
try
{
// get timeout value from the settings.properties
int timeout = Integer.parseInt(ConfigManager.GetProperty("files.docservice.timeout"));
if (timeout > 0) // if it's greater than 0
{
ConvertTimeout = timeout; // assign this value to a convert timeout
}
}
catch (Exception ex)
{
}
}
// get the url of the converted file
public static String GetConvertedUri(String documentUri, String fromExtension, String toExtension, String documentRevisionId, String filePass, Boolean isAsync, String lang) throws Exception
{
// check if the fromExtension parameter is defined; if not, get it from the document url
fromExtension = fromExtension == null || fromExtension.isEmpty() ? FileUtility.GetFileExtension(documentUri) : fromExtension;
// check if the file name parameter is defined; if not, get random uuid for this file
String title = FileUtility.GetFileName(documentUri);
title = title == null || title.isEmpty() ? UUID.randomUUID().toString() : title;
documentRevisionId = documentRevisionId == null || documentRevisionId.isEmpty() ? documentUri : documentRevisionId;
documentRevisionId = GenerateRevisionId(documentRevisionId); // create document token
// write all the necessary parameters to the body object
ConvertBody body = new ConvertBody();
body.region = lang;
body.url = documentUri;
body.outputtype = toExtension.replace(".", "");
body.filetype = fromExtension.replace(".", "");
body.title = title;
body.key = documentRevisionId;
body.password = filePass;
if (isAsync)
body.async = true;
String headerToken = "";
if (DocumentManager.TokenEnabled())
{
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("region", lang);
map.put("url", body.url);
map.put("outputtype", body.outputtype);
map.put("filetype", body.filetype);
map.put("title", body.title);
map.put("key", body.key);
map.put("password", body.password);
if (isAsync)
map.put("async", body.async);
// add token to the body if it is enabled
String token = DocumentManager.CreateToken(map);
body.token = token;
Map<String, Object> payloadMap = new HashMap<String, Object>();
payloadMap.put("payload", map); // create payload object
headerToken = DocumentManager.CreateToken(payloadMap); // create header token
}
Gson gson = new Gson();
String bodyString = gson.toJson(body);
byte[] bodyByte = bodyString.getBytes(StandardCharsets.UTF_8);
// specify request parameters
URL url = new URL(DocumentConverterUrl);
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
connection.setFixedLengthStreamingMode(bodyByte.length);
connection.setRequestProperty("Accept", "application/json");
connection.setConnectTimeout(ConvertTimeout);
// write header token to the request
if (DocumentManager.TokenEnabled())
{
connection.setRequestProperty(DocumentJwtHeader.equals("") ? "Authorization" : DocumentJwtHeader, "Bearer " + headerToken);
}
connection.connect();
try (OutputStream os = connection.getOutputStream()) {
os.write(bodyByte);
}
InputStream stream = connection.getInputStream();
if (stream == null)
throw new Exception("Could not get an answer");
// convert string to json
String jsonString = ConvertStreamToString(stream);
connection.disconnect();
return GetResponseUri(jsonString);
}
// generate document key
public static String GenerateRevisionId(String expectedKey)
{
if (expectedKey.length() > 20) // if the expected key length is greater than 20
expectedKey = Integer.toString(expectedKey.hashCode()); // the expected key is hashed and a fixed length value is stored in the string format
String key = UUIDUtils.randomUUID(2) + expectedKey.replace("[^0-9-.a-zA-Z_=]", "_");
return key.substring(0, Math.min(key.length(), 20)); // the resulting key length is 20 or less
}
// create an error message for an error code
private static void ProcessConvertServiceResponceError(int errorCode) throws Exception
{
String errorMessage = "";
String errorMessageTemplate = "Error occurred in the ConvertService: ";
// add the error message to the error message template depending on the error code
switch (errorCode)
{
case -8:
errorMessage = errorMessageTemplate + "Error document VKey";
break;
case -7:
errorMessage = errorMessageTemplate + "Error document request";
break;
case -6:
errorMessage = errorMessageTemplate + "Error database";
break;
case -5:
errorMessage = errorMessageTemplate + "Incorrect password";
break;
case -4:
errorMessage = errorMessageTemplate + "Error download error";
break;
case -3:
errorMessage = errorMessageTemplate + "Error convertation error";
break;
case -2:
errorMessage = errorMessageTemplate + "Error convertation timeout";
break;
case -1:
errorMessage = errorMessageTemplate + "Error convertation unknown";
break;
case 0: // if the error code is equal to 0, the error message is empty
break;
default:
errorMessage = "ErrorCode = " + errorCode; // default value for the error message
break;
}
throw new Exception(errorMessage);
}
// get the response url
private static String GetResponseUri(String jsonString) throws Exception
{
JSONObject jsonObj = ConvertStringToJSON(jsonString);
Object error = jsonObj.get("error");
if (error != null) // if an error occurs
ProcessConvertServiceResponceError(Math.toIntExact((long)error)); // then get an error message
// check if the conversion is completed and save the result to a variable
Boolean isEndConvert = (Boolean) jsonObj.get("endConvert");
Long resultPercent = 0l;
String responseUri = null;
if (isEndConvert) // if the conversion is completed
{
resultPercent = 100l;
responseUri = (String) jsonObj.get("fileUrl"); // get the file url
}
else // if the conversion isn't completed
{
resultPercent = (Long) jsonObj.get("percent");
resultPercent = resultPercent >= 100l ? 99l : resultPercent; // get the percentage value
}
return resultPercent >= 100l ? responseUri : "";
}
// convert stream to string
public static String ConvertStreamToString(InputStream stream) throws IOException
{
InputStreamReader inputStreamReader = new InputStreamReader(stream); // create an object to get incoming stream
StringBuilder stringBuilder = new StringBuilder(); // create a string builder object
BufferedReader bufferedReader = new BufferedReader(inputStreamReader); // create an object to read incoming streams
String line = bufferedReader.readLine(); // get incoming streams by lines
while (line != null)
{
stringBuilder.append(line); // concatenate strings using the string builder
line = bufferedReader.readLine();
}
String result = stringBuilder.toString();
return result;
}
// convert string to json
public static JSONObject ConvertStringToJSON(String jsonString) throws ParseException
{
JSONParser parser = new JSONParser();
Object obj = parser.parse(jsonString); // parse json string
JSONObject jsonObj = (JSONObject) obj; // and turn it into a json object
return jsonObj;
}
}
@@ -0,0 +1,323 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* 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 com.jero.modules.ocr.helpers;
import com.google.gson.Gson;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.primeframework.jwt.domain.JWT;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Scanner;
public class TrackManager {
private static final String DocumentJwtHeader = ConfigManager.GetProperty("files.docservice.header");
// read request body
public static JSONObject readBody(HttpServletRequest request, PrintWriter writer) throws Exception {
String bodyString = "";
try {
// read request body by streams
Scanner scanner = new Scanner(request.getInputStream());
scanner.useDelimiter("\\A");
bodyString = scanner.hasNext() ? scanner.next() : "";
scanner.close();
}
catch (Exception ex) {
writer.write("get request.getInputStream error:" + ex.getMessage());
throw ex;
}
// error when the bodyString object is empty
if (bodyString.isEmpty()) {
writer.write("empty request.getInputStream");
throw new Exception("empty request.getInputStream");
}
JSONParser parser = new JSONParser();
JSONObject body;
try {
Object obj = parser.parse(bodyString); // parse bodyString object
body = (JSONObject) obj;
} catch (Exception ex) {
writer.write("JSONParser.parse error:" + ex.getMessage());
throw ex;
}
// if the secret key to generate token exists
if (DocumentManager.TokenEnabled()) {
String token = (String) body.get("token"); // get the document token
if (token == null) { // if JSON web token is not received
String header = (String) request.getHeader(DocumentJwtHeader == null || DocumentJwtHeader.isEmpty() ? "Authorization" : DocumentJwtHeader); // get it from the Authorization header
if (header != null && !header.isEmpty()) {
token = header.startsWith("Bearer ") ? header.substring(7) : header; // and save it without Authorization prefix
}
}
if (token == null || token.isEmpty()) { // if the token is not received
writer.write("{\"error\":1,\"message\":\"JWT expected\"}"); // an error occurs
throw new Exception("{\"error\":1,\"message\":\"JWT expected\"}");
}
JWT jwt = DocumentManager.ReadToken(token); // read token
if (jwt == null) {
writer.write("{\"error\":1,\"message\":\"JWT validation failed\"}"); // an error occurs
throw new Exception("{\"error\":1,\"message\":\"JWT validation failed\"}");
}
if (jwt.getObject("payload") != null) { // get the payload object from the request body
try {
@SuppressWarnings("unchecked") LinkedHashMap<String, Object> payload =
(LinkedHashMap<String, Object>)jwt.getObject("payload");
jwt.claims = payload;
} catch (Exception ex) {
writer.write("{\"error\":1,\"message\":\"Wrong payload\"}");
throw ex;
}
}
try {
Gson gson = new Gson();
Object obj = parser.parse(gson.toJson(jwt.claims));
body = (JSONObject) obj;
} catch (Exception ex) {
writer.write("JSONParser.parse error:" + ex.getMessage());
throw ex;
}
}
return body;
}
// file saving process
public static void processSave(JSONObject body, String fileName, String userAddress) throws Exception {
if (body.get("url") == null) {
throw new Exception("DownloadUrl is null");
}
String downloadUri = (String) body.get("url");
String changesUri = (String) body.get("changesurl");
String key = (String) body.get("key");
String newFileName = fileName;
String curExt = FileUtility.GetFileExtension(fileName); // get current file extension
String downloadExt = FileUtility.GetFileExtension(downloadUri); // get the extension of the downloaded file
// convert downloaded file to the file with the current extension if these extensions aren't equal
if (!curExt.equals(downloadExt)) {
try {
String newFileUri = ServiceConverter.GetConvertedUri(downloadUri, downloadExt, curExt, ServiceConverter.GenerateRevisionId(downloadUri), null, false, null); // convert file and get url to a new file
if (newFileUri.isEmpty()) {
newFileName = DocumentManager.GetCorrectName(FileUtility.GetFileNameWithoutExtension(fileName) + downloadExt, userAddress); // get the correct file name if it already exists
} else {
downloadUri = newFileUri;
}
} catch (Exception e){
newFileName = DocumentManager.GetCorrectName(FileUtility.GetFileNameWithoutExtension(fileName) + downloadExt, userAddress);
}
}
String storagePath = DocumentManager.StoragePath(newFileName, userAddress); // get the file path
File histDir = new File(DocumentManager.HistoryDir(storagePath)); // get the path to the history direction
if (!histDir.exists()) histDir.mkdirs(); // if the path doesn't exist, create it
String versionDir = DocumentManager.VersionDir(histDir.getAbsolutePath(), DocumentManager.GetFileVersion(histDir.getAbsolutePath())); // get the path to the file version
File ver = new File(versionDir);
File lastVersion = new File(DocumentManager.StoragePath(fileName, userAddress));
File toSave = new File(storagePath);
if (!ver.exists()) ver.mkdirs();
lastVersion.renameTo(new File(versionDir + File.separator + "prev" + curExt)); // get the path to the previous file version and rename the last file version with it
downloadToFile(downloadUri, toSave); // save file to the storage path
downloadToFile(changesUri, new File(versionDir + File.separator + "diff.zip")); // save file changes to the diff.zip archive
String history = (String) body.get("changeshistory");
if (history == null && body.containsKey("history")) {
history = ((JSONObject) body.get("history")).toJSONString();
}
if (history != null && !history.isEmpty()) {
FileWriter fw = new FileWriter(new File(versionDir + File.separator + "changes.json")); // write the history changes to the changes.json file
fw.write(history);
fw.close();
}
FileWriter fw = new FileWriter(new File(versionDir + File.separator + "key.txt")); // write the key value to the key.txt file
fw.write(key);
fw.close();
String forcesavePath = DocumentManager.ForcesavePath(newFileName, userAddress, false); // get the path to the forcesaved file version
if (!forcesavePath.equals("")) { // if the forcesaved file version exists
File forceSaveFile = new File(forcesavePath);
forceSaveFile.delete(); // remove it
}
}
// file force saving process
public static void processForceSave(JSONObject body, String fileName, String userAddress) throws Exception {
if (body.get("url") == null) {
throw new Exception("DownloadUrl is null");
}
String downloadUri = (String) body.get("url");
String curExt = FileUtility.GetFileExtension(fileName); // get current file extension
String downloadExt = FileUtility.GetFileExtension(downloadUri); // get the extension of the downloaded file
Boolean newFileName = false;
// convert downloaded file to the file with the current extension if these extensions aren't equal
if (!curExt.equals(downloadExt)) {
try {
String newFileUri = ServiceConverter.GetConvertedUri(downloadUri, downloadExt, curExt, ServiceConverter.GenerateRevisionId(downloadUri), null, false, null); // convert file and get url to a new file
if (newFileUri.isEmpty()) {
newFileName = true;
} else {
downloadUri = newFileUri;
}
} catch (Exception e){
newFileName = true;
}
}
String forcesavePath = "";
boolean isSubmitForm = body.get("forcesavetype").toString().equals("3"); // SubmitForm
if (isSubmitForm) { // if the form is submitted
// new file
if (newFileName){
fileName = DocumentManager.GetCorrectName(FileUtility.GetFileNameWithoutExtension(fileName) + "-form" + downloadExt, userAddress); // get the correct file name if it already exists
} else {
fileName = DocumentManager.GetCorrectName(FileUtility.GetFileNameWithoutExtension(fileName) + "-form" + curExt, userAddress);
}
forcesavePath = DocumentManager.StoragePath(fileName, userAddress);
} else {
if (newFileName){
fileName = DocumentManager.GetCorrectName(FileUtility.GetFileNameWithoutExtension(fileName) + downloadExt, userAddress);
}
// create forcesave path if it doesn't exist
forcesavePath = DocumentManager.ForcesavePath(fileName, userAddress, false);
if (forcesavePath == "") {
forcesavePath = DocumentManager.ForcesavePath(fileName, userAddress, true);
}
}
File toSave = new File(forcesavePath);
downloadToFile(downloadUri, toSave);
if (isSubmitForm) {
JSONArray actions = (JSONArray) body.get("actions");
JSONObject action = (JSONObject) actions.get(0);
String user = (String) action.get("userid"); // get the user id
DocumentManager.CreateMeta(fileName, user, "Filling Form", userAddress); // create meta data for forcesaved file
}
}
// save file information from the url to the file specified
private static void downloadToFile(String url, File file) throws Exception {
if (url == null || url.isEmpty()) throw new Exception("argument url"); // url isn't specified
if (file == null) throw new Exception("argument path"); // file isn't specified
URL uri = new URL(url);
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) uri.openConnection();
InputStream stream = connection.getInputStream(); // get input stream of the file information from the url
if (stream == null)
{
throw new Exception("Stream is null");
}
try (FileOutputStream out = new FileOutputStream(file))
{
int read;
final byte[] bytes = new byte[1024];
while ((read = stream.read(bytes)) != -1)
{
out.write(bytes, 0, read); // write bytes to the output stream
}
// force write data to the output stream that can be cached in the current thread
out.flush();
}
connection.disconnect();
}
// create a command request
public static void commandRequest(String method, String key) throws Exception {
String DocumentCommandUrl = ConfigManager.GetProperty("files.docservice.url.site") + ConfigManager.GetProperty("files.docservice.url.command");
URL url = new URL(DocumentCommandUrl);
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
HashMap<String, Object> params = new HashMap<String, Object>();
params.put("c", method);
params.put("key", key);
String headerToken = "";
if (DocumentManager.TokenEnabled()) // check if a secret key to generate token exists or not
{
Map<String, Object> payloadMap = new HashMap<String, Object>();
payloadMap.put("payload", params);
headerToken = DocumentManager.CreateToken(payloadMap); // encode a payload object into a header token
// add a header Authorization with a header token and Authorization prefix in it
connection.setRequestProperty(DocumentJwtHeader.equals("") ? "Authorization" : DocumentJwtHeader, "Bearer " + headerToken);
String token = DocumentManager.CreateToken(params); // encode a payload object into a body token
params.put("token", token);
}
Gson gson = new Gson();
String bodyString = gson.toJson(params);
byte[] bodyByte = bodyString.getBytes(StandardCharsets.UTF_8);
connection.setRequestMethod("POST"); // set the request method
connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); // set the Content-Type header
connection.setDoOutput(true); // set the doOutput field to true
connection.connect();
try (OutputStream os = connection.getOutputStream()) {
os.write(bodyByte); // write bytes to the output stream
}
InputStream stream = connection.getInputStream();; // get input stream
if (stream == null)
throw new Exception("Could not get an answer");
String jsonString = ServiceConverter.ConvertStreamToString(stream); // convert stream to json string
connection.disconnect();
JSONObject response = ServiceConverter.ConvertStringToJSON(jsonString); // convert json string to json object
if (!response.get("error").toString().equals("0")){
throw new Exception(response.toJSONString());
}
}
}
@@ -0,0 +1,110 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* 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 com.jero.modules.ocr.helpers;
import com.jero.modules.ocr.entity.CommentGroups;
import com.jero.modules.ocr.entity.User;
import java.util.*;
public class Users {
static List<String> descr_user_1 = new ArrayList<String>() {{
add("File author by default");
add("Doesnt belong to any group");
add("Can review all the changes");
add("Can perform all actions with comments");
add("The file favorite state is undefined");
add("Can create files from templates using data from the editor");
}};
static List<String> descr_user_2 = new ArrayList<String>() {{
add("Belongs to Group2");
add("Can review only his own changes or changes made by users with no group");
add("Can view comments, edit his own comments and comments left by users with no group. Can remove his own comments only");
add("This file is marked as favorite");
add("Can create new files from the editor");
}};
static List<String> descr_user_3 = new ArrayList<String>() {{
add("Belongs to Group3");
add("Can review changes made by Group2 users");
add("Can view comments left by Group2 and Group3 users. Can edit comments left by Group2 users");
add("This file isnt marked as favorite");
add("Cant copy data from the file to clipboard");
add("Cant download the file");
add("Cant print the file");
add("Can create new files from the editor");
}};
static List<String> descr_user_0 = new ArrayList<String>() {{
add("The name is requested when the editor is opened");
add("Doesnt belong to any group");
add("Can review all the changes");
add("Can perform all actions with comments");
add("The file favorite state is undefined");
add("Can't mention others in comments");
add("Can't create new files from the editor");
}};
private static List<User> users = new ArrayList<User>() {{
add(new User("uid-1", "John Smith", "smith@example.com",
null, null, new CommentGroups(),
null, new ArrayList<String>(), descr_user_1, true));
add(new User("uid-2", "Mark Pottato", "pottato@example.com",
"group-2", Arrays.asList("group-2", ""), new CommentGroups(null, Arrays.asList("group-2", ""), Arrays.asList("group-2")),
true, new ArrayList<String>(), descr_user_2, false));
add(new User("uid-3", "Hamish Mitchell", "mitchell@example.com",
"group-3", Arrays.asList("group-2"), new CommentGroups(Arrays.asList("group-3", "group-2"), Arrays.asList("group-2"), new ArrayList<String>()),
false, Arrays.asList("copy", "download", "print"), descr_user_3, false));
add(new User("uid-0", null, null,
null, null, new CommentGroups(),
null, new ArrayList<String>(), descr_user_0, false));
}};
// get a user by id specified
public static User getUser (String id) {
for (User user : users) {
if (user.id.equals(id)) {
return user;
}
}
return users.get(0);
}
// get a list of all the users
public static List<User> getAllUsers () {
return users;
}
// get a list of users with their names and emails for mentions
public static List<Map<String, Object>> getUsersForMentions (String id) {
List<Map<String, Object>> usersData = new ArrayList<>();
for (User user : users) {
if (!user.id.equals(id) && user.name != null && user.email != null) {
Map<String, Object> data = new HashMap<>();
data.put("name", user.name);
data.put("email", user.email);
usersData.add(data);
}
}
return usersData;
}
}
@@ -0,0 +1,44 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* 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.
*
*/
html {
height: 100%;
width: 100%;
}
body {
background: #fff;
color: #333;
font-family: Arial, Tahoma,sans-serif;
font-size: 12px;
font-weight: normal;
height: 100%;
margin: 0;
overflow-y: hidden;
padding: 0;
text-decoration: none;
}
.form {
height: 100%;
}
div {
margin: 0;
padding: 0;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

@@ -0,0 +1,24 @@
version=1.1.0
filesize-max=5242880
storage-folder=D:\\OOFILES
files.docservice.fill-docs=.oform|.docx
files.docservice.viewed-docs=.pdf|.djvu|.xps|.oxps
files.docservice.edited-docs=.docx|.xlsx|.csv|.pptx|.txt|.docxf
files.docservice.convert-docs=.docm|.dotx|.dotm|.dot|.doc|.odt|.fodt|.ott|.xlsm|.xltx|.xltm|.xlt|.xls|.ods|.fods|.ots|.pptm|.ppt|.ppsx|.ppsm|.pps|.potx|.potm|.pot|.odp|.fodp|.otp|.rtf|.mht|.html|.htm|.xml|.epub|.fb2
files.docservice.timeout=120000
files.docservice.url.site=http://172.29.96.1:9000/
files.docservice.url.command=http://172.29.96.1:9000/coauthoring/CommandService.ashx
files.docservice.url.converter= http://172.29.96.1:9000/ConvertService.ashx
files.docservice.url.tempstorage= http://172.29.96.1:9000/ResourceService.ashx
files.docservice.url.api= http://172.29.96.1:9000/web-apps/apps/api/documents/api.js
files.docservice.url.preloader= http://172.29.96.1:9000/web-apps/apps/api/documents/cache-scripts.html
files.docservice.url.example= http://172.29.96.1:9000
files.docservice.secret=
files.docservice.header=Authorization
@@ -0,0 +1,127 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>ONLYOFFICE</title>
<link rel="icon" href="../asstes/favicon.ico" type="image/x-icon" />
<body>
<script type="text/javascript" th:src="${docserviceApiUrl}"></script>
<script type="text/javascript" language="javascript">
var docEditor;
var fileName = "[[${fileName}]]";
var fileType = "[[${fileType}]]";
var innerAlert = function (message) {
if (console && console.log)
console.log(message);
};
var onReady = function () {
innerAlert("Document editor ready");
};
var onDocumentStateChange = function (event) {
var title = document.title.replace(/\*$/g, "");
document.title = title + (event.data ? "*" : "");
};
var onRequestEditRights = function () {
location.href = location.href.replace(RegExp("action=view\&?", "i"), "");
};
var onError = function (event) {
if (event)
innerAlert(event.data);
};
var onOutdatedVersion = function (event) {
location.reload(true);
};
var сonnectEditor = function () {
docEditor = new DocsAPI.DocEditor("iframeEditor",
{
type: "[[${type}]]",
documentType: "[[${documentType}]]",
document: {
title:"[[${fileName}]]",
url: "[[${fileUri}]]",
fileType: "[[${fileType}]]",
key: "[[${fileKey}]]",
info: {
author: "Me",
created: "[[${documentCreated}]]",
},
permissions: {
edit: "[[${permissionsEdit}]]",
download: true,
}
},
editorConfig: {
mode: "[[${editorMode}]]",
lang: "cn",
callbackUrl: "[[${callbackUrl}]]",
user: {
id: "[[${editorUserId}]]",
name: "[[${editorUserName}]]",
},
embedded: {
saveUrl: "[[${fileUri}]]",
embedUrl: "[[${fileUri}]]",
shareUrl: "[[${fileUri}]]",
toolbarDocked: "top",
},
customization: {
about: true,
feedback: true,
goback: {
url: "[[${serverUrl}]]",
},
},
},
events: {
"onReady": onReady,
"onDocumentStateChange": onDocumentStateChange,
'onRequestEditRights': onRequestEditRights,
"onError": onError,
"onOutdatedVersion": onOutdatedVersion,
}
});
};
if (window.addEventListener) {
window.addEventListener("load", сonnectEditor);
} else if (window.attachEvent) {
window.attachEvent("load", сonnectEditor);
}
function getXmlHttp() {
var xmlhttp;
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (ex) {
xmlhttp = false;
}
}
if (!xmlhttp && typeof XMLHttpRequest !== "undefined") {
xmlhttp = new XMLHttpRequest();
}
return xmlhttp;
}
</script>
</head>
<div class="form" style="height: 900px;">
<div id="iframeEditor" ></div>
</div>
</body>
</html>
@@ -195,7 +195,7 @@ jero :
path :
#文件上传根目录 设置
upload: D://opt//upFiles
img: D://opt//upFiles
img: D://opt//upFiles/
#webapp文件路径
webapp: D://opt//webapp
shiro:
@@ -324,9 +324,12 @@ OCR:
# OCR文件存储路径
ocrPath: D:/APPSOFT/LAWSOCRDEMO/OCRFILE/
#ocrPath: /data/DeploymentPackage/laws-shanqi/APPSOFT/LAWSOCRDEMO/OCRFILE/
# OCR文件下载地址
# ocrDownPath: http://139.9.235.66:9020/downfile/
ocrDownPath: http://127.0.0.1:9020/downfile/
# OCR文件下载地址(onlyoffice专用)
ocrDownPath: http://10.0.1.25:8080/jero-boot/ocr/ocrCheck/downFile
# OCR文件保存地址(onlyoffice专用)
ocrSavePath: http://10.0.1.25:8080/jero-boot/ocr/ocrCheck/saveFile
# OCR文件编辑失败返回列表页(onlyoffice专用)
serverUrl: http://10.0.1.25:3000/docManage/ocr
# OCR接口超时时间
times: 20
# OCR转换类型