Compare commits

..

127 Commits

Author SHA1 Message Date
7bedc4b877 Merge pull request #250 from ONLYOFFICE/feature/add-wopi-users
Node.js (wopi): Add selected user to editor
2022-01-24 13:14:40 +03:00
f25c211630 Merge pull request #251 from ONLYOFFICE/feature/filetype
Feature/filetype
2022-01-24 12:12:12 +03:00
0f4785d14f python: correct code (Support old versions) 2022-01-24 11:07:28 +03:00
288add4d45 python: correct code (Support old versions) 2022-01-24 10:56:57 +03:00
1ee492838c python: correct filetype arg 2022-01-21 16:35:33 +03:00
f9ce3d1d33 nodejs: correct filetype arg 2022-01-21 15:51:16 +03:00
5f6687571a Node.js (wopi): changing the receipt of a wopi query 2022-01-20 17:11:59 +03:00
a1e5a4d48e Node.js (wopi): Add selected user to editor 2022-01-19 19:05:21 +03:00
6e9518631f Merge pull request #246 from ONLYOFFICE/feature/add-upload-wopi
Feature/add upload wopi
2022-01-19 18:07:31 +03:00
88d8086853 Node.js (wopi): Add support InternetExplorer 2022-01-19 17:59:31 +03:00
c7f18f1085 Node.js (wopi): Fix filter 2022-01-18 15:39:16 +03:00
fb05ad32ab Merge remote-tracking branch 'remotes/origin/develop' into feature/add-upload-wopi 2022-01-18 14:49:28 +03:00
bac989efd1 Node.js (wopi): Filter extensions from config that are in discovery for edit action (+ Checking the Fano condition) 2022-01-17 18:36:47 +03:00
8a203ac062 Node.js (wopi): button layout for upload 2022-01-17 18:33:49 +03:00
7e1386008b Merge pull request #249 from ONLYOFFICE/feature/wopi-layout
Feature/wopi layout
2022-01-17 15:15:10 +03:00
8ff206a411 Node.js wopi: add information when hovering over the info icon 2022-01-17 14:06:59 +03:00
83a0330725 Merge pull request #245 from ONLYOFFICE/feature/wopi-editing
Feature/wopi editing
2022-01-17 11:23:27 +03:00
c5269a53cf Merge pull request #244 from ONLYOFFICE/bugfix/customization-fix-JavaExample
fix Customization in Java and JavaSpringExample
2022-01-17 11:12:32 +03:00
f86b26928d Node.js(wopi): create a unique version code 2022-01-14 19:29:46 +03:00
f8d77947c8 Node.js(wopi): layout of the index page (delete extra info users and checkbox simple) 2022-01-14 19:28:09 +03:00
a900183056 Merge pull request #241 from ONLYOFFICE/feature/fileTypeInsteadParsing
Feature/file type instead parsing
2022-01-14 16:52:30 +03:00
67d34f4bfa format 2022-01-14 16:52:12 +03:00
68ec626970 C# mvc: fix code 2022-01-11 18:19:14 +03:00
065f338a79 C#: fix code 2022-01-11 18:18:54 +03:00
43548c04b9 Node.js: fix code (Made links through ready-made functions) 2022-01-11 17:52:40 +03:00
c7c95ecfbe Node.js: fix upload page (links [edit, view] ) for wopi upload files 2022-01-11 17:34:34 +03:00
064c0dcc35 C#: fix code 2022-01-11 16:42:26 +03:00
9a01f465d0 C# mvc: fix code 2022-01-11 16:42:01 +03:00
2d85a4166e Ruby: fix code 2022-01-11 15:07:19 +03:00
8f18cc8ab2 Merge branch 'feature/fileTypeInsteadParsing' of github.com:ONLYOFFICE/document-server-integration into feature/fileTypeInsteadParsing
# Conflicts:
#	web/documentserver-example/csharp-mvc/Helpers/TrackManager.cs
2022-01-10 18:49:43 +03:00
db976766cc Ruby: fix[support old version] fileType instead parsing 2022-01-10 18:47:02 +03:00
57f6028829 Python: fix[support old version] fileType instead parsing 2022-01-10 18:46:03 +03:00
05706ff038 PHP: fix[support old version] fileType instead parsing 2022-01-10 18:45:27 +03:00
9cf7ce276e Node.js: fix[support old version] fileType instead parsing 2022-01-10 18:45:03 +03:00
0b35179ef0 Java-spring: fix[support old version] fileType instead parsing 2022-01-10 18:44:35 +03:00
d396f92f4d Java : fix[support old version] fileType instead parsing 2022-01-10 18:44:01 +03:00
1e78da4cfc C#: fix[support old version] fileType instead parsing 2022-01-10 18:42:41 +03:00
a8c9c331c1 C# mvc: fix[support old version] fileType instead parsing 2022-01-10 18:41:54 +03:00
4f3882f892 Merge pull request #248 from ONLYOFFICE/feature/ruby-add-mimemagic
Add licenses of mimemagic on ruby
2022-01-10 16:08:31 +03:00
727418277f ruby: correct license 2022-01-10 16:08:14 +03:00
2f795de6ad Merge pull request #247 from ONLYOFFICE/feature/fileType
Feature/file type
2022-01-10 16:03:35 +03:00
bb28257a2d Merge remote-tracking branch 'remotes/origin/develop' into feature/fileType
# Conflicts:
#	web/documentserver-example/php/doceditor.php
2022-01-10 16:03:18 +03:00
05ea165f77 format 2022-01-10 16:00:41 +03:00
7a61fac6b7 Add licenses of mimemagic on ruby 2022-01-10 15:57:57 +03:00
6efa357c19 Delete mimemagic on Ruby in order to add in a new branch 2022-01-10 15:36:13 +03:00
3b33846f9d fix fileRemove and links on wopi (node.js) 2022-01-10 15:27:16 +03:00
3de8463359 Add ConverExtList and EditedExtList for wopi upload files 2022-01-10 14:18:55 +03:00
15b7a07963 Merge pull request #242 from ONLYOFFICE/feature/bugRubyEditor
Feature/bug ruby editor
2022-01-10 12:30:47 +03:00
ef1c53d330 ruby: fix bug of displaying the editor 2022-01-10 12:30:28 +03:00
a21fbd6802 java-spring: revert format 2022-01-10 10:58:25 +03:00
c7249ab27f Add upload files for wopi on the node.js 2021-12-30 18:28:55 +03:00
450d37161b Preparing a wopi task for PR 2021-12-30 16:53:30 +03:00
ee46a77684 Removing link to "editnew" in the file line 2021-12-29 19:20:33 +03:00
3b7e3c9258 Аdd action processing ("editnew" and "edit") and Create files only through "editnew" 2021-12-29 19:20:08 +03:00
783ad9f2de fix Customization in Java and JavaSpringExample 2021-12-29 13:30:11 +03:00
19304920d1 fileType instead parsing url to save doc in C# MVC (take fileType out of body) 2021-12-24 18:13:12 +03:00
13b3eed5ed fileType instead parsing url to save doc in C# (take fileType out of body) 2021-12-24 18:12:40 +03:00
d9c1c7e051 fileType instead parsing url to save doc in Java-Spring (take fileType out of body) 2021-12-24 17:54:41 +03:00
2d0b17e334 fileType instead parsing url to save doc in Java (take fileType out of body) 2021-12-24 17:13:28 +03:00
384381cebc fileType instead parsing url to save doc in PHP (take fileType out of body) 2021-12-24 16:52:10 +03:00
16d830baf4 [fix] fileType instead parsing url to save doc in Python (take fileType out of body) 2021-12-24 16:51:48 +03:00
efcfaf95e8 [fix] fileType instead parsing url to save doc in node.js (take fileType out of body) 2021-12-24 16:50:23 +03:00
606f7d2d44 [fix] fileType instead parsing url to save doc in Ruby (take fileType out of body) 2021-12-24 16:47:57 +03:00
c5a2b72b39 fileType instead parsing url to save doc in Ruby (take fileType out of body) 2021-12-23 18:29:31 +03:00
dab9e4bb16 fileType instead parsing url to save doc in Python (take fileType out of body) 2021-12-23 18:24:28 +03:00
058b0c4f23 fileType in body Instead Parsing url on node.js 2021-12-22 20:21:08 +03:00
8d194b78a1 Update samples 2021-12-20 11:29:02 +03:00
b8e726a7be Update pptx sample 2021-12-20 11:02:24 +03:00
fbe0c18315 Merge pull request #238 from ONLYOFFICE/feature/update-readme
Readme
2021-12-16 18:10:38 +03:00
ec6ea72069 small fixes for readme files 2021-12-16 17:51:01 +03:00
c6e3af5d3b Merge pull request #236 from ONLYOFFICE/feature/csharp-server-configuration
csharp and csharp-mvc readme
2021-12-13 16:59:39 +03:00
63c3337938 Merge pull request #226 from ONLYOFFICE/bugfix/java-fixes
Bugfix/java fixes
2021-12-13 16:34:08 +03:00
0268298f2b Merge remote-tracking branch 'remotes/origin/develop' into bugfix/java-fixes
# Conflicts:
#	web/documentserver-example/java-spring/README.md
2021-12-13 16:32:54 +03:00
32ea01784c Merge pull request #234 from ONLYOFFICE/bugfix/group-fix
replace group value null with empty string
2021-12-13 16:27:14 +03:00
71041fea9f Merge pull request #233 from ONLYOFFICE/feature/pptx-xpath
Feature/pptx xpath
2021-12-13 16:16:54 +03:00
8b25a7a869 ruby: v 3.0 2021-12-13 16:02:48 +03:00
dd20d79236 Merge pull request #230 from ONLYOFFICE/feature/ruby-3.0
ruby 3.0 version
2021-12-13 15:47:25 +03:00
299a68e0bd Merge pull request #229 from ONLYOFFICE/bugfix/layout-fixes
fix layout
2021-12-13 15:42:15 +03:00
9ad27d2cf0 Merge pull request #216 from ONLYOFFICE/feature/change-files-folder
Feature/change files folder
2021-12-13 15:39:26 +03:00
828115e5b0 Merge remote-tracking branch 'remotes/origin/develop' into feature/change-files-folder
# Conflicts:
#	web/documentserver-example/java-spring/src/main/java/com/onlyoffice/integration/documentserver/storage/LocalFileStorage.java
2021-12-13 15:38:37 +03:00
c0d240728d edit (fileType in setHistoryData for php) 2021-12-10 17:49:09 +03:00
89c0f03318 csharp: added information about the IIS components 2021-12-09 17:22:39 +03:00
bc1c9f455c fileType in setHistoryData for ruby (+ Gemfile) 2021-12-08 17:25:43 +03:00
df1a5f38c1 fileType in setHistoryData for python 2021-12-08 17:25:01 +03:00
6559c76fbd fileType in setHistoryData for php 2021-12-08 17:24:30 +03:00
a7db14811f fileType in setHistoryData for node.js 2021-12-08 17:23:37 +03:00
abffa3e75f fileType in setHistoryData for java 2021-12-08 17:23:00 +03:00
631f70148f fileType in setHistoryData for java-spring 2021-12-08 17:22:36 +03:00
c7e7c9c19d fileType in setHistoryData for C# 2021-12-08 17:21:54 +03:00
f2d4eb2a42 fileType in setHistoryData for C# mvc 2021-12-08 17:20:19 +03:00
b453aa19f0 replace group value null with empty string 2021-12-02 17:39:48 +03:00
7841822c54 delete unused block 2021-12-02 10:37:05 +03:00
f3e24a8b5e nodejs: delete unused block 2021-12-01 22:31:08 +03:00
d3b962dcb8 fix layout 2021-11-26 15:45:53 +03:00
95ea50210f Merge remote-tracking branch 'remotes/origin/develop' into feature/change-files-folder
# Conflicts:
#	web/documentserver-example/csharp-mvc/web.appsettings.config
#	web/documentserver-example/java/src/main/java/helpers/DocumentManager.java
2021-11-18 12:54:57 +03:00
40016395a8 java-spring: update README.md, set empty server.address 2021-11-18 12:35:29 +03:00
8f2c2f96d2 java: fix docker 2021-11-17 00:10:28 +03:00
f9dbe89fd9 java-spring: fix docker, clean up application.properties 2021-11-16 18:48:52 +03:00
c3a4c0a66b java: add fields owner and uploaded for document info 2021-11-16 17:52:07 +03:00
edd423cd87 Merge remote-tracking branch 'remotes/origin/develop' into feature/change-files-folder
# Conflicts:
#	web/documentserver-example/csharp-mvc/web.appsettings.config
#	web/documentserver-example/java-spring/src/main/java/com/onlyoffice/integration/documentserver/managers/document/DefaultDocumentManager.java
2021-11-09 19:04:30 +03:00
e026a7027b java-spring: check if storage directory does not exist 2021-11-09 18:31:09 +03:00
11e8f40f8c ruby: fix embedded mode; fix media.css connect 2021-11-02 18:13:45 +03:00
bf18854ec0 csharp-mvc: fix embedded mode 2021-11-02 17:46:41 +03:00
08d1080527 csharp: fix embedded mode 2021-11-02 17:40:00 +03:00
9ca242fe82 python: fix storage path and embedded mode 2021-11-02 16:59:20 +03:00
b3c02a5afd php: fix embedded 2021-11-02 16:13:00 +03:00
ec65ebbfb8 php: layout fix 2021-11-02 16:01:39 +03:00
8544974202 java: layout fix 2021-11-02 16:01:16 +03:00
90eeae5334 php: fix file upload 2021-11-02 15:35:25 +03:00
970cfa6dd0 nodejs: fix embedded 2021-11-02 15:24:44 +03:00
f04a26a0f4 nodejs: fix file upload 2021-11-02 15:11:34 +03:00
53a58e2666 java: fix embedded mode 2021-11-02 14:33:29 +03:00
0ab0762aa5 java: remove urlUser param from config 2021-11-02 11:26:11 +03:00
4aeef2b873 php: fix highlighting of changes in history 2021-10-19 12:40:21 +03:00
60c03c1403 csharp-mvc: fix history 2021-10-19 11:41:28 +03:00
a597c37684 Merge branch 'develop' of https://github.com/ONLYOFFICE/document-server-integration into feature/change-files-folder 2021-10-17 15:38:48 +03:00
5206171a70 php: add ability to use custom path for files storage 2021-10-17 15:38:02 +03:00
375d916fe2 csharp-mvc: add ability to use custom path for files storage 2021-10-15 14:34:35 +03:00
35afb7a8fe csharp: add ability to custom path for files storage 2021-10-15 13:12:58 +03:00
8d1c4d8042 java-spring: add ability to use custom path for files storage 2021-10-14 12:28:36 +03:00
b969944ede python: update readme.md 2021-10-14 12:21:42 +03:00
da7450c732 ruby: add ability to use custom path for files storage 2021-10-14 12:19:45 +03:00
1db5e865a6 Merge remote-tracking branch 'remotes/origin/develop' into feature/change-files-folder 2021-10-14 12:11:38 +03:00
69ac7771d5 nodejs: add ability to use custom path for storage-folder 2021-09-24 17:53:59 +03:00
04f5cac85d java: fix; update README.md, add media.css to index.jsp 2021-09-24 17:51:43 +03:00
ccdd2a4cdc ruby 3.0 version 2021-09-20 12:29:55 +03:00
33140a2ca6 java: added ability to use absolute path for storage-folder in settings.properties, updated README.md 2021-09-13 18:49:38 +03:00
93 changed files with 756 additions and 287 deletions

View File

@ -87,10 +87,6 @@
}
@media (max-width: 1008px) {
#portal-info {
width: 65vw;
}
.left-panel {
margin-left: 0;
}
@ -312,6 +308,9 @@
.tableRow td:first-child {
max-width: 17%;
}
#portal-info {
max-width: 60vw;
}
}
.downloadContentCellShift:after {

View File

@ -22,6 +22,7 @@
}
body {
display: inline-table;
background: #FFFFFF;
color: #333333;
font-family: Open Sans;
@ -71,6 +72,7 @@ header img {
}
.main {
display: table;
height: calc(100% - 112px);
min-height: 536px;
}
@ -97,6 +99,10 @@ header img {
width: 896px;
}
#portal-info {
max-width: 65vw;
}
.portal-name {
color: #FF6F3D;
font-size: 24px;

View File

@ -79,19 +79,37 @@ namespace OnlineEditorsExampleMVC.Helpers
// get the storage path of the file
public static string StoragePath(string fileName, string userAddress = null)
{
var directory = HttpRuntime.AppDomainAppPath + CurUserHostAddress(userAddress) + "\\";
var directory = "";
if (!string.IsNullOrEmpty(WebConfigurationManager.AppSettings["storage-path"]) && Path.IsPathRooted(WebConfigurationManager.AppSettings["storage-path"]))
{
directory = WebConfigurationManager.AppSettings["storage-path"] + "\\";
}
else
{
directory = HttpRuntime.AppDomainAppPath + WebConfigurationManager.AppSettings["storage-path"] + CurUserHostAddress(userAddress) + "\\";
}
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
return directory + Path.GetFileName(fileName);
return directory + (fileName.Contains("\\") ? fileName : Path.GetFileName(fileName));
}
// get the path to the forcesaved file version
public static string ForcesavePath(string fileName, string userAddress, Boolean create)
{
// create the directory to this file version
var directory = HttpRuntime.AppDomainAppPath + CurUserHostAddress(userAddress) + "\\";
var directory = "";
if (!string.IsNullOrEmpty(WebConfigurationManager.AppSettings["storage-path"]) && Path.IsPathRooted(WebConfigurationManager.AppSettings["storage-path"]))
{
directory = WebConfigurationManager.AppSettings["storage-path"] + "\\";
}
else
{
directory = HttpRuntime.AppDomainAppPath + WebConfigurationManager.AppSettings["storage-path"] + CurUserHostAddress(userAddress) + "\\";
}
if (!Directory.Exists(directory))
{
return "";
@ -172,7 +190,16 @@ namespace OnlineEditorsExampleMVC.Helpers
// get all the stored files from the user host address
public static List<FileInfo> GetStoredFiles()
{
var directory = HttpRuntime.AppDomainAppPath + WebConfigurationManager.AppSettings["storage-path"] + CurUserHostAddress(null) + "\\";
var directory = "";
if (!string.IsNullOrEmpty(WebConfigurationManager.AppSettings["storage-path"]) && Path.IsPathRooted(WebConfigurationManager.AppSettings["storage-path"]))
{
directory = WebConfigurationManager.AppSettings["storage-path"] + "\\";
}
else
{
directory = HttpRuntime.AppDomainAppPath + WebConfigurationManager.AppSettings["storage-path"] + CurUserHostAddress(null) + "\\";
}
if (!Directory.Exists(directory)) return new List<FileInfo>();
var directoryInfo = new DirectoryInfo(directory);
@ -228,8 +255,7 @@ namespace OnlineEditorsExampleMVC.Helpers
{
var uri = new UriBuilder(GetServerUrl(true))
{
Path = HttpRuntime.AppDomainAppVirtualPath + "/"
+ path,
Path = HttpRuntime.AppDomainAppVirtualPath + "/" + path,
Query = ""
};

View File

@ -95,7 +95,11 @@ namespace OnlineEditorsExampleMVC.Helpers
}
var downloadUri = (string)fileData["url"];
string curExt = Path.GetExtension(fileName).ToLower(); // get current file extension
string downloadExt = Path.GetExtension(downloadUri).ToLower() ?? ""; // get the extension of the downloaded file
var downloadExt = fileData.ContainsKey("filetype")
? "." + (string)fileData["filetype"]
: Path.GetExtension(downloadUri).ToLower() ?? ""; // TODO: Delete in version 7.0 or higher. Support for versions below 7.0
var newFileName = fileName;
// convert downloaded file to the file with the current extension if these extensions aren't equal
@ -167,7 +171,11 @@ namespace OnlineEditorsExampleMVC.Helpers
var downloadUri = (string)fileData["url"];
string curExt = Path.GetExtension(fileName).ToLower(); // get current file extension
string downloadExt = Path.GetExtension(downloadUri).ToLower(); // get the extension of the downloaded file
var downloadExt = fileData.ContainsKey("filetype")
? "." + (string)fileData["filetype"]
: Path.GetExtension(downloadUri).ToLower(); // TODO: Delete in version 7.0 or higher. Support for versions below 7.0
Boolean newFileName = false;
// convert downloaded file to the file with the current extension if these extensions aren't equal

View File

@ -70,7 +70,7 @@ namespace OnlineEditorsExampleMVC.Helpers
"uid-1",
"John Smith",
"smith@example.com",
null,
"",
null,
new Dictionary<string, object>(),
null,
@ -116,7 +116,7 @@ namespace OnlineEditorsExampleMVC.Helpers
"uid-0",
null,
null,
null,
"",
null,
new Dictionary<string,object>(),
null,

View File

@ -21,6 +21,7 @@ using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Web;
using System.Web.Configuration;
using System.Web.Mvc;
using System.Web.Script.Serialization;
using OnlineEditorsExampleMVC.Helpers;
@ -42,7 +43,7 @@ namespace OnlineEditorsExampleMVC.Models
// get file url for user
public string FileUriUser
{
get { return DocManagerHelper.GetFileUri(FileName, false); }
get { return Path.IsPathRooted(WebConfigurationManager.AppSettings["storage-path"]) ? DownloadUrl + "&dmode=emb" : DocManagerHelper.GetFileUri(FileName, false); }
}
public string FileName { get; set; } // file name
@ -214,7 +215,8 @@ namespace OnlineEditorsExampleMVC.Models
// get the document history
public void GetHistory(out string history, out string historyData)
{
{
var storagePath = WebConfigurationManager.AppSettings["storage-path"];
var jss = new JavaScriptSerializer();
var histDir = DocManagerHelper.HistoryDir(DocManagerHelper.StoragePath(FileName, null));
@ -253,9 +255,22 @@ namespace OnlineEditorsExampleMVC.Models
}
}
var ext = Path.GetExtension(FileName).ToLower();
dataObj.Add("fileType", ext.Replace(".", ""));
dataObj.Add("key", key);
// write file url to the data object
dataObj.Add("url", i == currentVersion ? FileUri : DocManagerHelper.GetPathUri(Directory.GetFiles(verDir, "prev.*")[0].Substring(HttpRuntime.AppDomainAppPath.Length)));
string prevFileUrl;
if (Path.IsPathRooted(storagePath) && !string.IsNullOrEmpty(storagePath))
{
prevFileUrl = i == currentVersion ? DocManagerHelper.GetDownloadUrl(FileName)
: DocManagerHelper.GetDownloadUrl(Directory.GetFiles(verDir, "prev.*")[0].Replace(storagePath + "\\", ""));
}
else {
prevFileUrl = i == currentVersion ? FileUri
: DocManagerHelper.GetPathUri(Directory.GetFiles(verDir, "prev.*")[0].Substring(HttpRuntime.AppDomainAppPath.Length));
}
dataObj.Add("url", prevFileUrl);
dataObj.Add("version", i);
if (i > 1) // check if the version number is greater than 1 (the file was modified)
{
@ -274,11 +289,14 @@ namespace OnlineEditorsExampleMVC.Models
var prev = (Dictionary<string, object>)histData[(i - 2).ToString()]; // get the history data from the previous file version
dataObj.Add("previous", new Dictionary<string, object>() { // write information about previous file version to the data object
{ "fileType", prev["fileType"] },
{ "key", prev["key"] }, // write key and url information about previous file version
{ "url", prev["url"] },
});
// write the path to the diff.zip archive with differences in this file version
dataObj.Add("changesUrl", DocManagerHelper.GetPathUri(Path.Combine(DocManagerHelper.VersionDir(histDir, i - 1), "diff.zip").Substring(HttpRuntime.AppDomainAppPath.Length)));
var changesUrl = Path.IsPathRooted(storagePath) ? DocManagerHelper.GetDownloadUrl(Path.Combine(DocManagerHelper.VersionDir(histDir, i - 1), "diff.zip").Replace(storagePath + "\\", ""))
: DocManagerHelper.GetPathUri(Path.Combine(DocManagerHelper.VersionDir(histDir, i - 1), "diff.zip").Substring(HttpRuntime.AppDomainAppPath.Length));
dataObj.Add("changesUrl", changesUrl);
}
if(JwtManager.Enabled)
{

View File

@ -13,11 +13,14 @@ See the detailed guide to learn how to install Document Server [for Windows](htt
## Step 2. Download the .Net (C# MVC) code for the editors integration
Download the [.Net (C# MVC) example](https://api.onlyoffice.com/editors/demopreview) from our site.
You need to connnect the editors to your website. Specify path to the editors installation in the *settings.config* file:
To connect the editors to your website, specify the path to the editors installation and the path to the storage folder in the *settings.config* file:
```
<add key="storage-path" value=""/>
<add key="files.docservice.url.site" value="https://documentserver/" />
```
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed.
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed and the **storage-path** is the path where files will be created and stored. You can set an absolute path.
If you want to experiment with the editor configuration, modify the [parameters](https://api.onlyoffice.com/editors/advanced) in the *DocEditor.aspx* file.
## Step 3. Install the prerequisites
@ -25,6 +28,16 @@ If you want to experiment with the editor configuration, modify the [parameters]
* **Microsoft .NET Framework**: version 4.5 (download it from the [official Microsoft website](https://www.microsoft.com/en-US/download/details.aspx?id=30653));
* **Internet Information Services**: version 7 or later.
Configure the IIS components for the server to work correctly:
1. Open Windows features:
**Start** -> **Control Panel** -> **Programs** -> **Programs and Features** -> **Turn Windows features on or off**
2. In the opened window, find **Internet Information Services** and choose all the necessary features. To do this, open the **World Wide Web Services** list and check the following components:
* **Application Development Features**: .NET Extensibility 4.8, ASP.NET 4.8, ISAPI Extensions, ISAPI Filters,
* **Common HTTP Features**: Default Document,
* **Security**: Request Filtering.
## Step 4. Run your website with the editors
1. Run the Internet Information Service (IIS) Manager:

View File

@ -139,7 +139,7 @@
<td class="section">
<div class="main-panel">
<% var storedFiles = DocManagerHelper.GetStoredFiles(); %>
<div id="portal-info" style="display: <%= storedFiles.Any() ? "none" : "block" %>">
<div id="portal-info" style="display: <%= storedFiles.Any() ? "none" : "table-cell" %>">
<span class="portal-name">ONLYOFFICE Document Editors Welcome!</span>
<span class="portal-descr">
Get started with a demo-sample of ONLYOFFICE Document Editors, the first html5-based editors.
@ -222,9 +222,6 @@
</a>
</td>
<% } %>
<% if (docType != "word" && docType != "cell") { %>
<td class="contentCells contentCells-icon contentCellsEmpty"></td>
<% } %>
<% if (docType == "word") { %>
<td class="contentCells contentCells-icon">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "blockcontent" }) %>" target="_blank">

View File

@ -443,10 +443,12 @@ namespace OnlineEditorsExampleMVC
{
try
{
var fileName = Path.GetFileName(context.Request["fileName"]);
var fileName = Path.IsPathRooted(WebConfigurationManager.AppSettings["storage-path"]) ? context.Request["fileName"]
: Path.GetFileName(context.Request["fileName"]);
var userAddress = context.Request["userAddress"];
var isEmbedded = context.Request["dmode"];
if (JwtManager.Enabled)
if (JwtManager.Enabled && isEmbedded == null)
{
string JWTheader = WebConfigurationManager.AppSettings["files.docservice.header"].Equals("") ? "Authorization" : WebConfigurationManager.AppSettings["files.docservice.header"];

View File

@ -4,7 +4,8 @@
<add key="version" value="1.1.0"/>
<add key="filesize-max" value="52428800"/>
<add key="storage-path" value=""/>
<add key="files.docservice.fillform-docs" value=".oform|.docx"/>
<add key="files.docservice.viewed-docs" value=".pdf|.djvu|.xps|.oxps"/>
<add key="files.docservice.edited-docs" value=".docx|.xlsx|.csv|.pptx|.txt|.docxf"/>

View File

@ -87,10 +87,6 @@
}
@media (max-width: 1008px) {
#portal-info {
width: 65vw;
}
.left-panel {
margin-left: 0;
}
@ -312,6 +308,9 @@
.tableRow td:first-child {
max-width: 17%;
}
#portal-info {
max-width: 60vw;
}
}
.downloadContentCellShift:after {

View File

@ -22,6 +22,7 @@ html {
}
body {
display: inline-table;
background: #FFFFFF;
color: #333333;
font-family: Open Sans;
@ -71,6 +72,7 @@ header img {
}
.main {
display: table;
height: calc(100% - 112px);
min-height: 536px;
}
@ -97,6 +99,10 @@ header img {
width: 896px;
}
#portal-info {
max-width: 65vw;
}
.portal-name {
color: #FF6F3D;
font-size: 24px;

View File

@ -140,7 +140,7 @@
<td class="section">
<% var storedFiles = GetStoredFiles(); %>
<div class="main-panel">
<div id="portal-info" style="display: <%= storedFiles.Any() ? "none" : "block" %>">
<div id="portal-info" style="display: <%= storedFiles.Any() ? "none" : "table-cell" %>">
<span class="portal-name">ONLYOFFICE Document Editors Welcome!</span>
<span class="portal-descr">
Get started with a demo-sample of ONLYOFFICE Document Editors, the first html5-based editors.
@ -223,9 +223,6 @@
</a>
</td>
<% } %>
<%if (docType != "word" && docType != "cell") { %>
<td class="contentCells contentCells-icon contentCellsEmpty"></td>
<% } %>
<% if (docType == "word") { %>
<td class="contentCells contentCells-icon">
<a href="<%= editUrl + "&editorsType=desktop&editorsMode=blockcontent" %>" target="_blank">

View File

@ -78,7 +78,9 @@ namespace OnlineEditorsExample
{
get
{
return
return Path.IsPathRooted(WebConfigurationManager.AppSettings["storage-path"]) ?
WebConfigurationManager.AppSettings["storage-path"] + "/"
:
HttpRuntime.AppDomainAppVirtualPath
+ (HttpRuntime.AppDomainAppVirtualPath.EndsWith("/") ? "" : "/")
+ WebConfigurationManager.AppSettings["storage-path"]
@ -144,18 +146,36 @@ namespace OnlineEditorsExample
// get the storage path of the given file
public static string StoragePath(string fileName, string userAddress)
{
var directory = HttpRuntime.AppDomainAppPath + WebConfigurationManager.AppSettings["storage-path"] + CurUserHostAddress(userAddress) + "\\";
var directory = "";
if (Path.IsPathRooted(WebConfigurationManager.AppSettings["storage-path"]))
{
directory = WebConfigurationManager.AppSettings["storage-path"] + "\\";
}
else
{
directory = HttpRuntime.AppDomainAppPath + WebConfigurationManager.AppSettings["storage-path"] + CurUserHostAddress(userAddress) + "\\";
}
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory); // if the file directory doesn't exist, make it
}
return directory + Path.GetFileName(fileName);
return directory + (fileName.Contains("\\") ? fileName : Path.GetFileName(fileName));
}
// get the path to the forcesaved file version
public static string ForcesavePath(string fileName, string userAddress, Boolean create)
{
var directory = HttpRuntime.AppDomainAppPath + WebConfigurationManager.AppSettings["storage-path"] + CurUserHostAddress(userAddress) + "\\";
var directory = "";
if (Path.IsPathRooted(WebConfigurationManager.AppSettings["storage-path"]))
{
directory = WebConfigurationManager.AppSettings["storage-path"] + "\\";
}
else
{
directory = HttpRuntime.AppDomainAppPath + WebConfigurationManager.AppSettings["storage-path"] + CurUserHostAddress(userAddress) + "\\";
}
if (!Directory.Exists(directory)) // the directory with host address doesn't exist
{
return "";
@ -528,7 +548,16 @@ namespace OnlineEditorsExample
// get all the stored files from the folder
protected static List<FileInfo> GetStoredFiles()
{
var directory = HttpRuntime.AppDomainAppPath + WebConfigurationManager.AppSettings["storage-path"] + CurUserHostAddress(null) + "\\";
var directory = "";
if (Path.IsPathRooted(WebConfigurationManager.AppSettings["storage-path"]))
{
directory = WebConfigurationManager.AppSettings["storage-path"] + "\\";
}
else
{
directory = HttpRuntime.AppDomainAppPath + WebConfigurationManager.AppSettings["storage-path"] + CurUserHostAddress(null) + "\\";
}
if (!Directory.Exists(directory)) return new List<FileInfo>();
var directoryInfo = new DirectoryInfo(directory); // read the user host directory contents

View File

@ -41,7 +41,7 @@ namespace OnlineEditorsExample
// get url to the original file for Document Server
public static string FileUriUser
{
get { return _Default.FileUri(FileName, false); }
get { return Path.IsPathRooted(WebConfigurationManager.AppSettings["storage-path"]) ? getDownloadUrl(FileName) + "&dmode=emb" : _Default.FileUri(FileName, false); }
}
protected string Key
@ -100,20 +100,17 @@ namespace OnlineEditorsExample
}
// get url to download a file
public static string getDownloadUrl
public static string getDownloadUrl(string fileName)
{
get
{
var downloadUrl = new UriBuilder(_Default.GetServerUrl(true));
var downloadUrl = new UriBuilder(_Default.GetServerUrl(true));
downloadUrl.Path =
HttpRuntime.AppDomainAppVirtualPath
+ (HttpRuntime.AppDomainAppVirtualPath.EndsWith("/") ? "" : "/")
+ "webeditor.ashx";
downloadUrl.Query = "type=download"
+ "&fileName=" + HttpUtility.UrlEncode(FileName)
+ "&fileName=" + HttpUtility.UrlEncode(fileName)
+ "&userAddress=" + HttpUtility.UrlEncode(HttpContext.Current.Request.UserHostAddress);
return downloadUrl.ToString();
}
}
// loading a page
@ -195,7 +192,7 @@ namespace OnlineEditorsExample
"document", new Dictionary<string, object>
{
{ "title", FileName },
{ "url", getDownloadUrl },
{ "url", getDownloadUrl(FileName) },
{ "fileType", ext.Trim('.') },
{ "key", Key },
{
@ -318,6 +315,7 @@ namespace OnlineEditorsExample
// get the document history
private void GetHistory(out Dictionary<string, object> history, out Dictionary<string, object> historyData)
{
var storagePath = WebConfigurationManager.AppSettings["storage-path"];
var jss = new JavaScriptSerializer();
var histDir = _Default.HistoryDir(_Default.StoragePath(FileName, null));
@ -355,8 +353,16 @@ namespace OnlineEditorsExample
}
}
var ext = Path.GetExtension(FileName).ToLower();
dataObj.Add("fileType", ext.Replace(".", ""));
dataObj.Add("key", key);
dataObj.Add("url", i == currentVersion ? FileUri : MakePublicUrl(Directory.GetFiles(verDir, "prev.*")[0])); // write file url to the data object
var prevFileUrl = i == currentVersion ? FileUri : MakePublicUrl(Directory.GetFiles(verDir, "prev.*")[0]);
if (Path.IsPathRooted(storagePath))
{
prevFileUrl = i == currentVersion ? getDownloadUrl(FileName) : getDownloadUrl(Directory.GetFiles(verDir, "prev.*")[0].Replace(storagePath + "\\", ""));
}
dataObj.Add("url", prevFileUrl); // write file url to the data object
dataObj.Add("version", i);
if (i > 1) // check if the version number is greater than 1 (the file was modified)
{
@ -375,11 +381,14 @@ namespace OnlineEditorsExample
var prev = (Dictionary<string, object>)histData[(i - 2).ToString()]; // get the history data from the previous file version
dataObj.Add("previous", new Dictionary<string, object>() { // write information about previous file version to the data object
{ "fileType", prev["fileType"] },
{ "key", prev["key"] }, // write key and url information about previous file version
{ "url", prev["url"] },
});
// write the path to the diff.zip archive with differences in this file version
dataObj.Add("changesUrl", MakePublicUrl(Path.Combine(_Default.VersionDir(histDir, i - 1), "diff.zip")));
var changesUrl = Path.IsPathRooted(storagePath) ? getDownloadUrl(Path.Combine(_Default.VersionDir(histDir, i - 1), "diff.zip").Replace(storagePath + "\\", ""))
: MakePublicUrl(Path.Combine(_Default.VersionDir(histDir, i - 1), "diff.zip"));
dataObj.Add("changesUrl", changesUrl);
}
if (JwtManager.Enabled)
{
@ -503,7 +512,8 @@ namespace OnlineEditorsExample
// create the public url
private string MakePublicUrl(string fullPath)
{
var root = HttpRuntime.AppDomainAppPath + WebConfigurationManager.AppSettings["storage-path"];
var root = Path.IsPathRooted(WebConfigurationManager.AppSettings["storage-path"]) ? WebConfigurationManager.AppSettings["storage-path"]
: HttpRuntime.AppDomainAppPath + WebConfigurationManager.AppSettings["storage-path"];
return _Default.GetServerUrl(true) + fullPath.Substring(root.Length).Replace(Path.DirectorySeparatorChar, '/');
}

View File

@ -14,11 +14,12 @@ See the detailed guide to learn how to install Document Server [for Windows](htt
Download the [.Net (C#) example](https://api.onlyoffice.com/editors/demopreview) from our site.
Connect the editors to your website by specifying the path to the editors installation in the *settings.config* file:
To connect the editors to your website, specify the path to the editors installation and the path to the storage folder in the *settings.config* file:
```
<add key="storage-path" value=""/>
<add key="files.docservice.url.site" value="https://documentserver/" />
```
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed.
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed and the **storage-path** is the path where files will be created and stored. You can set an absolute path.
If you want to experiment with the editor configuration, modify the [parameters](https://api.onlyoffice.com/editors/advanced) in the *DocEditor.aspx* file.
@ -28,6 +29,16 @@ Check that your system meets the requirements:
* **Microsoft .NET Framework**: version 4.5 (download it from the [official Microsoft website](https://www.microsoft.com/en-US/download/details.aspx?id=30653));
* **Internet Information Services**: version 7 or later.
Configure the IIS components for the server to work correctly:
1. Open Windows features:
**Start** -> **Control Panel** -> **Programs** -> **Programs and Features** -> **Turn Windows features on or off**
2. In the opened window, find **Internet Information Services** and choose all the necessary features. To do this, open the **World Wide Web Services** list and check the following components:
* **Application Development Features**: .NET Extensibility 4.8, ASP.NET 4.8, ISAPI Extensions, ISAPI Filters,
* **Common HTTP Features**: Default Document,
* **Security**: Request Filtering.
## Step 4. Run your website with the editors
1. Run the Internet Information Service (IIS) Manager:

View File

@ -97,7 +97,11 @@ namespace OnlineEditorsExample
}
var downloadUri = (string)fileData["url"];
var curExt = Path.GetExtension(fileName).ToLower(); // get current file extension
var downloadExt = Path.GetExtension(downloadUri).ToLower() ?? ""; // get the extension of the downloaded file
var downloadExt = fileData.ContainsKey("filetype")
? "." + (string)fileData["filetype"]
: Path.GetExtension(downloadUri).ToLower() ?? ""; // TODO: Delete in version 7.0 or higher. Support for versions below 7.0
var newFileName = fileName;
// convert downloaded file to the file with the current extension if these extensions aren't equal
@ -175,7 +179,11 @@ namespace OnlineEditorsExample
var downloadUri = (string)fileData["url"];
string curExt = Path.GetExtension(fileName).ToLower(); // get current file extension
string downloadExt = Path.GetExtension(downloadUri).ToLower(); // get the extension of the downloaded file
var downloadExt = fileData.ContainsKey("filetype")
? "." + (string)fileData["filetype"]
: Path.GetExtension(downloadUri).ToLower(); // TODO: Delete in version 7.0 or higher. Support for versions below 7.0
Boolean newFileName = false;
// convert downloaded file to the file with the current extension if these extensions aren't equal

View File

@ -69,7 +69,7 @@ namespace OnlineEditorsExample
"uid-1",
"John Smith",
"smith@example.com",
null,
"",
null,
new Dictionary<string, object>(),
null,
@ -115,7 +115,7 @@ namespace OnlineEditorsExample
"uid-0",
null,
null,
null,
"",
null,
new Dictionary<string, object>(),
null,

View File

@ -271,10 +271,11 @@ namespace OnlineEditorsExample
{
try
{
var fileName = Path.GetFileName(context.Request["fileName"]);
var fileName = Path.IsPathRooted(WebConfigurationManager.AppSettings["storage-path"]) ? context.Request["fileName"] : Path.GetFileName(context.Request["fileName"]);
var userAddress = Path.GetFileName(context.Request["userAddress"]);
var isEmbedded = context.Request["dmode"];
if (JwtManager.Enabled)
if (JwtManager.Enabled && isEmbedded == null)
{
string JWTheader = WebConfigurationManager.AppSettings["files.docservice.header"].Equals("") ? "Authorization" : WebConfigurationManager.AppSettings["files.docservice.header"];

View File

@ -19,16 +19,15 @@ See the detailed guide to learn how to install Document Server [for Windows](htt
Download the [Java-Spring example](https://api.onlyoffice.com/editors/demopreview) from our site.
To connect the editors to your website, specify the path to the editors installation, server address and port in the *\src\main\resources\application.properties* file:
To connect the editors to your website, specify the path to the editors installation, server port and the path to the storage folder in the *\src\main\resources\application.properties* file:
```
server.address=address
files.storage=
server.port=port
files.docservice.url.site=https://documentserver/
```
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed.
**address** is the address of the server or comment this line to use localhost, **port** is the any available port.
where the **documentserver** is the name of the server with the ONLYOFFICE Docs installed, **port** is any available port and **files.storage** is the path where files will be created and stored (in the project folder by default). You can set an absolute path. For example, *D:\\\\folder*. Please note that on Windows OS the double backslash must be used as a separator.
If you want to experiment with the editor configuration, modify the [parameters](https://api.onlyoffice.com/editors/advanced) it the *\src\main\resources\editor.html* file.
@ -112,8 +111,6 @@ To run the Java example code, install the Java version 11 appropriate for your O
```
http://server.address:server.port/
```
### Step 6. Check accessibility
@ -173,13 +170,13 @@ See the detailed guide to learn how to install Document Server [for Linux](https
Edit the following lines:
```
server.address=address
files.storage=
server.port=port
files.docservice.url.site=https://documentserver/
```
Where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed.
**address** is the address of the server or comment this line to use localhost, **port** is the any available port.
where the **documentserver** is the name of the server with the ONLYOFFICE Docs installed, **port** is any available port and **files.storage** is the path where files will be created and stored (in the project folder by default). You can set an absolute path.
5. Install **Maven**:
@ -204,7 +201,6 @@ See the detailed guide to learn how to install Document Server [for Linux](https
```
### Step 3. Check accessibility
In case the example and Document Server are installed on different computers, make sure that your server with the example installed has access to the Document Server with the address which you specify instead of **documentserver** in the configuration files.
@ -222,13 +218,12 @@ Make sure that the Document Server has access to the server with the example ins
2. Edit the following lines:
```
server.address=address
files.storage=
server.port=port
files.docservice.url.site=https://documentserver/
```
Where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed.
**address** is the address of the server or comment this line to use localhost, **port** is the any available port.
where the **documentserver** is the name of the server with the ONLYOFFICE Docs installed, **port** is any available port and **files.storage** is the path where files will be created and stored (in the project folder by default). You can set an absolute path.
3. Run the next command in the java example directory:

View File

@ -7,7 +7,9 @@ services:
image: maven:3.8.1
working_dir: /java-spring
volumes:
- .:/java-spring
- .:/java-spring
ports:
- 4000:4000
command: mvn clean spring-boot:run

View File

@ -68,7 +68,7 @@ public class ExampleData {
"Can create a file from an editor"
);
userService.createUser("John Smith", "smith@example.com", // create user 1 with the specified parameters
description_user_1, null, List.of(FilterState.NULL.toString()),
description_user_1, "", List.of(FilterState.NULL.toString()),
List.of(FilterState.NULL.toString()),
List.of(FilterState.NULL.toString()),
List.of(FilterState.NULL.toString()), null);
@ -79,7 +79,7 @@ public class ExampleData {
description_user_3, "group-3", List.of("group-2"), List.of("group-2", "group-3"),
List.of("group-2"), new ArrayList<>(), false);
userService.createUser("Anonymous",null, // create user 0 with the specified parameters
description_user_0,null, List.of(FilterState.NULL.toString()), List.of(FilterState.NULL.toString()),
description_user_0,"", List.of(FilterState.NULL.toString()), List.of(FilterState.NULL.toString()),
List.of(FilterState.NULL.toString()), List.of(FilterState.NULL.toString()), null);
}
}

View File

@ -94,7 +94,10 @@ public class DefaultCallbackManager implements CallbackManager {
String newFileName = fileName;
String curExt = fileUtility.getFileExtension(fileName); // get current file extension
String downloadExt = fileUtility.getFileExtension(downloadUri); // get an extension of the downloaded file
String downloadExt = "." + body.getFiletype(); // get an extension of the downloaded file
// Todo [Delete in version 7.0 or higher]
if (downloadExt != "." + null) downloadExt = fileUtility.getFileExtension(downloadUri); // Support for versions below 7.0
//TODO: Refactoring
if (!curExt.equals(downloadExt)) { // convert downloaded file to the file with the current extension if these extensions aren't equal
@ -212,7 +215,11 @@ public class DefaultCallbackManager implements CallbackManager {
String downloadUri = body.getUrl();
String curExt = fileUtility.getFileExtension(fileName); // get current file extension
String downloadExt = fileUtility.getFileExtension(downloadUri); // get an extension of the downloaded file
String downloadExt = "."+body.getFiletype(); // get an extension of the downloaded file
// Todo [Delete in version 7.0 or higher]
if (downloadExt != "."+null) downloadExt = fileUtility.getFileExtension(downloadUri); // Support for versions below 7.0
Boolean newFileName = false;
// convert downloaded file to the file with the current extension if these extensions aren't equal

View File

@ -45,6 +45,8 @@ public class DefaultDocumentManager implements DocumentManager {
@Value("${files.storage.folder}")
private String storageFolder;
@Value("${files.storage}")
private String filesStorage;
@Value("${url.track}")
private String trackUrl;
@Value("${url.download}")
@ -93,6 +95,9 @@ public class DefaultDocumentManager implements DocumentManager {
String hostAddress = storagePathBuilder.getStorageLocation(); // get the storage directory
String filePathDownload = !fileName.contains(InetAddress.getLocalHost().getHostAddress()) ? fileName
: fileName.substring(fileName.indexOf(InetAddress.getLocalHost().getHostAddress()) + InetAddress.getLocalHost().getHostAddress().length() + 1);
if (!filesStorage.isEmpty() && filePathDownload.contains(filesStorage)) {
filePathDownload = filePathDownload.substring(filesStorage.length() + 1);
}
String filePath = serverPath + "/download?fileName=" + URLEncoder.encode(filePathDownload, java.nio.charset.StandardCharsets.UTF_8.toString())
+ "&userAddress" + URLEncoder.encode(hostAddress, java.nio.charset.StandardCharsets.UTF_8.toString());

View File

@ -87,6 +87,7 @@ public class DefaultHistoryManager implements HistoryManager {
obj.put("user", user);
}
dataObj.put("fileType", fileUtility.getFileExtension(document.getTitle()).replace(".", ""));
dataObj.put("key", key);
dataObj.put("url", i == curVer ? document.getUrl() :
documentManager.getFileUri(documentManager.versionDir(histDir, i, true) + File.separator + "prev" + fileUtility.getFileExtension(document.getTitle()), true));
@ -105,6 +106,7 @@ public class DefaultHistoryManager implements HistoryManager {
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("fileType", prev.get("fileType"));
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

View File

@ -44,4 +44,6 @@ public class Customization { // the parameters which allow to customize the edi
private Boolean hideRightMenu = false; // if the right menu is displayed or hidden on first loading
private Boolean hideRulers = false; // if the editor rulers are displayed or hidden
private Boolean submitForm = false; // if the Submit form button is displayed or hidden
private Boolean about = true;
private Boolean feedback =true;
}

View File

@ -20,7 +20,6 @@ package com.onlyoffice.integration.documentserver.models.configurations;
import com.onlyoffice.integration.documentserver.storage.FileStoragePathBuilder;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
@ -30,8 +29,6 @@ import javax.annotation.PostConstruct;
@Component
@Scope("prototype")
@Getter
@Setter
public class Goback { // the settings for the Open file location menu button and upper right corner button
@Autowired
@ -39,10 +36,12 @@ public class Goback { // the settings for the Open file location menu button an
@Value("${url.index}")
private String indexMapping;
@Getter
private String url; // the absolute URL to the website address which will be opened when clicking the Open file location menu button
@PostConstruct
private void init(){
this.url = storagePathBuilder.getServerUrl(false)+indexMapping;
private void init() {
this.url = storagePathBuilder.getServerUrl(false) + indexMapping;
}
}

View File

@ -85,10 +85,18 @@ public class LocalFileStorage implements FileStorageMutator, FileStoragePathBuil
// get the storage directory
public String getStorageLocation(){
String serverPath = System.getProperty("user.dir"); // get the path to the server
String directory = serverPath // create the storage directory
+ File.separator + storageFolder
+ File.separator + this.storageAddress
+ File.separator;
String directory; // create the storage directory
if (Paths.get(this.storageAddress).isAbsolute()) {
directory = this.storageAddress + File.separator;
} else {
directory = serverPath
+ File.separator + storageFolder
+ File.separator + this.storageAddress
+ File.separator;
}
if (!Files.exists(Paths.get(directory))) {
createDirectory(Paths.get(directory));
}
return directory;
}

View File

@ -1,6 +1,6 @@
server.version=1.1.0
server.address=127.0.0.1
server.address=
server.port=4000
filesize-max=5242880

View File

@ -98,6 +98,10 @@ header img {
width: 896px;
}
#portal-info {
max-width: 65vw;
}
.portal-name {
color: #FF6F3D;
font-size: 24px;

View File

@ -127,7 +127,7 @@
</td>
<td class="section">
<div class="main-panel">
<div id="portal-info" th:attr="tooltip=${tooltip}" th:style="${not #lists.isEmpty(files)} ? 'display: none' : 'display: block' ">
<div id="portal-info" th:attr="tooltip=${tooltip}" th:style="${not #lists.isEmpty(files)} ? 'display: none' : 'display: table-cell' ">
<span class="portal-name">ONLYOFFICE Document Editors Welcome!</span>
<span class="portal-descr">
Get started with a demo-sample of ONLYOFFICE Document Editors, the first html5-based editors.
@ -189,9 +189,6 @@
</a>
</td>
</div>
<div th:if="${docTypes[iState.index]} eq 'slide'">
<td class="contentCells contentCells-icon contentCellsEmpty"></td>
</div>
<div th:if="${docTypes[iState.index]} eq 'word'">
<td class="contentCells contentCells-icon">
<a th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='blockcontent')}" target="_blank">

View File

@ -0,0 +1,9 @@
FROM maven:3.6.1-jdk-8-alpine AS MVN_BLDR
COPY pom.xml /tmp/
COPY src /tmp/src/
WORKDIR /tmp/
RUN mvn package
FROM tomcat:alpine
RUN rm -fr /usr/local/tomcat/webapps/ROOT
COPY --from=MVN_BLDR /tmp/target/*.war $CATALINA_HOME/webapps/ROOT.war

View File

@ -16,13 +16,14 @@ See the detailed guide to learn how to [install Document Server for Windows](htt
Download the [Java example](https://api.onlyoffice.com/editors/demopreview) from our site.
To connect the editors to your website, specify the path to the editors installation in the *\src\main\resources\settings.properties* file:
To connect the editors to your website, specify the path to the editors installation and the path to the storage folder in the *\src\main\resources\settings.properties* file:
```
storage-folder = app_data
files.docservice.url.site=https://documentserver/
```
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed.
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed and the **storage-folder** is the path where files will be created and stored. You can set an absolute path. For example, *D:\\\\folder*. Please note that on Windows OS the double backslash must be used as a separator.
If you want to experiment with the editor configuration, modify the [parameters](https://api.onlyoffice.com/editors/advanced) in the *\src\main\webapp\editor.jsp* file.
@ -163,13 +164,17 @@ See the detailed guide to learn how to [install Document Server for Linux](https
nano src/main/resources/settings.properties
```
Edit the following line:
Edit the following lines:
```
storage-folder = app_data
files.docservice.url.site=https://documentserver/
```
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed.
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed and the **storage-folder** is the path where files will be created and stored. Please note that you must have read and write permissions to the folder. If you do not have them, please use the next command:
```
sudo chmod -R ugo+rw /{path}
```
5. Install **Maven**:
@ -238,13 +243,14 @@ Make sure that the Document Server has access to the server with the example ins
nano src/main/resources/settings.properties
```
2. Edit the following line:
2. Edit the following lines:
```
storage-folder = app_data
files.docservice.url.site=https://documentserver/
```
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed.
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed and the **storage-folder** is the path where files will be created and stored.
3. Run the next command in the Java example directory:

View File

@ -1,7 +1,9 @@
version: '3'
services:
build:
image: maven:3.6
volumes:
- .:/java
command: mvn -f /java package
java-intg-ex:
build:
context: ./
dockerfile: Dockerfile
ports:
- 8080:8080

View File

@ -45,8 +45,8 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<source>8</source>
<target>8</target>
<compilerArguments>
<endorseddirs>${endorsed.dir}</endorseddirs>
</compilerArguments>

View File

@ -72,7 +72,7 @@ public class EditorServlet extends HttpServlet
// create file model (get all the necessary parameters from cookies)
FileModel file = new FileModel(fileName, cm.getCookie("ulang"), request.getParameter("actionLink"), user);
// change type parameter if needed
file.changeType(request.getParameter("mode"), request.getParameter("type"), user);
file.changeType(request.getParameter("mode"), request.getParameter("type"), user, fileName);
// an image that will be inserted into the document
Map<String, Object> dataInsertImage = new HashMap<>();

View File

@ -436,8 +436,9 @@ public class IndexServlet extends HttpServlet
try {
String fileName = FileUtility.GetFileName(request.getParameter("fileName"));
String userAddress = request.getParameter("userAddress");
String isEmbedded = request.getParameter("dmode");
if (DocumentManager.TokenEnabled()) {
if (DocumentManager.TokenEnabled() && isEmbedded == null) {
String DocumentJwtHeader = ConfigManager.GetProperty("files.docservice.header");

View File

@ -20,16 +20,14 @@ package entities;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import helpers.DocumentManager;
import helpers.FileUtility;
import helpers.ServiceConverter;
import helpers.Users;
import helpers.*;
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.text.SimpleDateFormat;
import java.util.*;
public class FileModel
@ -54,7 +52,6 @@ public class FileModel
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()));
@ -94,11 +91,11 @@ public class FileModel
// write the absolute URL to the file location
editorConfig.customization.goback.url = DocumentManager.GetServerUrl(false) + "/IndexServlet";
changeType(mode, type, user);
changeType(mode, type, user, fileName);
}
// change the document type
public void changeType(String _mode, String _type, User user)
public void changeType(String _mode, String _type, User user, String fileName)
{
if (_mode != null) mode = _mode;
if (_type != null) type = _type;
@ -119,12 +116,12 @@ public class FileModel
// set document permissions
document.permissions = new Permissions(mode, type, canEdit, user);
if (type.equals("embedded")) InitDesktop(); // set parameters for the embedded document
if (type.equals("embedded")) InitDesktop(fileName); // set parameters for the embedded document
}
public void InitDesktop()
public void InitDesktop(String fileName)
{
editorConfig.InitDesktop(document.urlUser);
editorConfig.InitDesktop(DocumentManager.GetDownloadUrl(fileName) + "&dmode=emb");
}
// generate document token
@ -178,6 +175,7 @@ public class FileModel
obj.put("user", user);
}
dataObj.put("fileType", FileUtility.GetFileExtension(document.title).substring(1));
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);
@ -195,11 +193,17 @@ public class FileModel
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("fileType", prev.get("fileType"));
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"));
String storagePath = ConfigManager.GetProperty("storage-folder");
String changesUrl = DocumentManager.GetPathUri(DocumentManager.VersionDir(histDir, i - 1) + File.separator + "diff.zip");
if (new File(storagePath).isAbsolute()) {
changesUrl = DocumentManager.GetDownloadUrl((DocumentManager.VersionDir(histDir, i - 1) + File.separator + "diff.zip").replace(storagePath, ""));
}
dataObj.put("changesUrl", changesUrl);
}
if (DocumentManager.TokenEnabled())
@ -246,7 +250,6 @@ public class FileModel
{
public String title;
public String url;
public String urlUser;
public String fileType;
public String key;
public Info info;
@ -288,7 +291,14 @@ public class FileModel
// the Favorite icon state
public class Info
{
public String owner = "Me";
public Boolean favorite;
public String uploaded = getDate();
private String getDate() {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEE MMM dd yyyy", Locale.US);
return simpleDateFormat.format(new Date());
}
}
// the editor config parameters
public class EditorConfig
@ -338,9 +348,17 @@ public class FileModel
public Goback goback;
public Boolean forcesave;
public Boolean submitForm;
public Boolean about;
public Boolean chat;
public Boolean comments;
public Boolean feedback;
public Customization()
{
about = true;
chat = true;
comments = true;
feedback = true;
forcesave = false;
goback = new Goback();
}

View File

@ -130,7 +130,20 @@ public class DocumentManager
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 f = new File(storagePath);
if (f.isAbsolute()) {
if (!f.exists()) {
if (Files.isWritable(Paths.get(storagePath.substring(0, storagePath.lastIndexOf(File.separator))))) {
f.mkdirs();
} else {
throw new SecurityException("No write permission to path: " + f.toPath());
}
} else if (f.exists() && f.isFile()) {
throw new SecurityException("The path to the file is specified instead of the folder");
}
}
String directory = !f.isAbsolute() ? serverPath + storagePath + File.separator + hostAddress + File.separator : storagePath + File.separator;
File file = new File(directory);
@ -320,13 +333,20 @@ public class DocumentManager
{
String serverPath = GetServerUrl(forDocumentServer);
String storagePath = ConfigManager.GetProperty("storage-folder");
File f = new File(storagePath);
String hostAddress = CurUserHostAddress(null);
String filePath = serverPath + "/" + storagePath + "/" + hostAddress + "/" + URLEncoder.encode(fileName, java.nio.charset.StandardCharsets.UTF_8.toString()).replace("+", "%20");
if (f.isAbsolute() && f.isFile()) {
filePath = GetDownloadUrl(fileName);
if (!Files.isWritable(f.toPath())) {
throw new SecurityException("No write permission to path: " + f.toPath());
}
}
return filePath;
}
catch (UnsupportedEncodingException e)
catch (Exception e)
{
return "";
}

View File

@ -127,7 +127,10 @@ public class TrackManager {
String newFileName = fileName;
String curExt = FileUtility.GetFileExtension(fileName); // get current file extension
String downloadExt = FileUtility.GetFileExtension(downloadUri); // get the extension of the downloaded file
String downloadExt = "." + (String) body.get("filetype"); // get the extension of the downloaded file
// Todo [Delete in version 7.0 or higher]
if (downloadExt == "." + null) downloadExt = FileUtility.GetFileExtension(downloadUri); // Support for versions below 7.0
// convert downloaded file to the file with the current extension if these extensions aren't equal
if (!curExt.equals(downloadExt)) {
@ -188,7 +191,11 @@ public class TrackManager {
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
String downloadExt = "."+(String) body.get("filetype"); // get the extension of the downloaded file
// Todo [Delete in version 7.0 or higher]
if (downloadExt == "."+null) downloadExt = FileUtility.GetFileExtension(downloadUri); // Support for versions below 7.0
Boolean newFileName = false;
// convert downloaded file to the file with the current extension if these extensions aren't equal

View File

@ -64,7 +64,7 @@ public class Users {
private static List<User> users = new ArrayList<User>() {{
add(new User("uid-1", "John Smith", "smith@example.com",
null, null, new CommentGroups(),
"", 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")),
@ -73,7 +73,7 @@ public class Users {
"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 CommentGroups(),
null, new ArrayList<String>(), descr_user_0, false));
}};

View File

@ -86,10 +86,6 @@
}
@media (max-width: 1008px) {
#portal-info {
width: 65vw;
}
.left-panel {
margin-left: 0;
}
@ -299,6 +295,9 @@
.tableRow td:first-child {
max-width: 17%;
}
#portal-info {
max-width: 60vw;
}
}
.downloadContentCellShift:after {

View File

@ -22,6 +22,7 @@ html {
}
body {
display: inline-table;
background: #FFFFFF;
color: #333333;
font-family: Open Sans;
@ -71,6 +72,7 @@ header img {
}
.main{
display: table;
height: calc(100% - 112px);
min-height: 536px;
}
@ -97,6 +99,10 @@ header img {
width: 896px;
}
#portal-info {
max-width: 65vw;
}
.portal-name {
color: #FF6F3D;
font-size: 24px;

View File

@ -139,7 +139,7 @@
<% DocumentManager.Init(request, response); %>
<% File[] files = DocumentManager.GetStoredFiles(null); %>
<div class="main-panel">
<div id="portal-info" style="display: <%= files.length > 0 ? "none" : "block" %>">
<div id="portal-info" style="display: <%= files.length > 0 ? "none" : "table-cell" %>">
<span class="portal-name">ONLYOFFICE Document Editors Welcome!</span>
<span class="portal-descr">
Get started with a demo-sample of ONLYOFFICE Document Editors, the first html5-based editors.
@ -180,7 +180,7 @@
Boolean canEdit = DocumentManager.GetEditedExts().contains(FileUtility.GetFileExtension(files[i].getName()));
String version=" ["+DocumentManager.GetFileVersion(DocumentManager.HistoryDir(DocumentManager.StoragePath(files[i].getName(), null)))+"]";
%>
<tr class="tableRow" title="<%= files[i].getName() %> [<%= version %>]">
<tr class="tableRow" title="<%= files[i].getName() %><%= version %>">
<td class="contentCells">
<a class="stored-edit <%= docType %>" href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8") %>" target="_blank">
<span><%= files[i].getName() %></span>
@ -215,9 +215,6 @@
</a>
</td>
<% } %>
<% if (!docType.equals("cell") && !docType.equals("word")) { %>
<td class="contentCells contentCells-icon contentCellsEmpty"></td>
<% } %>
<% if (docType.equals("word")) { %>
<td class="contentCells contentCells-icon">
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8") %>&type=desktop&mode=blockcontent" target="_blank">

View File

@ -16,13 +16,15 @@ See the detailed guide to learn how to [install Document Server for Windows](htt
Download the [Node.js example](https://api.onlyoffice.com/editors/demopreview) from our site.
You need to connect the editors to your website. Specify the path to the editors installation in the *config/default.json* file:
To connect the editors to your website, specify the path to the editors installation and the path to the storage folder in the *config/default.json* file:
```
"storageFolder": "./files"
"storagePath": "/files"
"siteUrl": "https://documentserver/"
```
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed.
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed, the **storageFolder** and **storagePath** are the paths where files will be created and stored. You can set an absolute path. For example, *D:\\\\folder*. Please note that on Windows OS the double backslash must be used as a separator.
If you want to experiment with the editor configuration, modify the [parameters](https://api.onlyoffice.com/editors/advanced) in the *\views\editor.ejs* file.
@ -114,13 +116,18 @@ See the detailed guide to learn how to [install Document Server for Linux](https
nano config/default.json
```
Edit the following line:
Edit the following lines:
```
"storageFolder": "./files"
"storagePath": "/files"
"siteUrl": "https://documentserver/"
```
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed.
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed, the **storageFolder** and **storagePath** are the paths where files will be created and stored. Please note that you must have read and write permissions to the folder. If you do not have them, please use the next command:
```
sudo chmod -R ugo+rw /{path}
```
6. Run the project with Node.js:

View File

@ -124,8 +124,9 @@ app.get("/download", function(req, res) { // define a handler for downloading f
var fileName = fileUtility.getFileName(req.query.fileName);
var userAddress = req.query.useraddress;
var isEmbedded = req.query.dmode;
if (cfgSignatureEnable && cfgSignatureUseForRequest) {
if ((cfgSignatureEnable && cfgSignatureUseForRequest) && isEmbedded == null ) {
var authorization = req.get(cfgSignatureAuthorizationHeader);
if (authorization && authorization.startsWith(cfgSignatureAuthorizationHeaderPrefix)) {
var token = authorization.substring(cfgSignatureAuthorizationHeaderPrefix.length);
@ -159,7 +160,7 @@ app.post("/upload", function (req, res) { // define a handler for uploading fil
docManager.storagePath(""); // mkdir if not exist
const userIp = docManager.curUserHostAddress(); // get the path to the user host
const uploadDir = path.join(storageFolder, userIp);
const uploadDir = path.isAbsolute(storageFolder) ? storageFolder : path.join(storageFolder, userIp);
const uploadDirTmp = path.join(uploadDir, 'tmp'); // and create directory for temporary files if it doesn't exist
docManager.createDirectory(uploadDirTmp);
@ -396,12 +397,7 @@ app.delete("/file", function (req, res) { // define a handler for removing file
if (fileName) { // if the file name is defined
fileName = fileUtility.getFileName(fileName); // get its part without an extension
const filePath = docManager.storagePath(fileName); // get the path to this file
fileSystem.unlinkSync(filePath); // and delete it
const userAddress = docManager.curUserHostAddress();
const historyPath = docManager.historyPath(fileName, userAddress, true);
docManager.cleanFolderRecursive(historyPath, true); // clean all the files from the history folder
docManager.fileRemove(fileName); // delete file and his history
} else {
docManager.cleanFolderRecursive(docManager.storagePath(''), false); // if the file name is undefined, clean the storage folder
}
@ -503,7 +499,11 @@ app.post("/track", function (req, res) { // define a handler for tracking file
}
var curExt = fileUtility.getFileExtension(fileName); // get current file extension
var downloadExt = fileUtility.getFileExtension(downloadUri); // get the extension of the downloaded file
var downloadExt = "." + body.filetype; // get the extension of the downloaded file
// TODO [Delete in version 7.0 or higher]
if (downloadExt == ".") downloadExt = fileUtility.getFileExtension(downloadUri); // Support for versions below 7.0
var newFileName = fileName;
// convert downloaded file to the file with the current extension if these extensions aren't equal
@ -537,7 +537,11 @@ app.post("/track", function (req, res) { // define a handler for tracking file
// callback file force saving process
var callbackProcessForceSave = function (downloadUri, body, fileName, userAddress, newFileName = false){
try {
var downloadExt = fileUtility.getFileExtension(downloadUri);
var downloadExt = "." + body.fileType;
/// TODO [Delete in version 7.0 or higher]
if (downloadExt == ".") downloadExt = fileUtility.getFileExtension(downloadUri); // Support for versions below 7.0
var isSubmitForm = body.forcesavetype === 3; // SubmitForm
if (isSubmitForm) {
@ -588,7 +592,10 @@ app.post("/track", function (req, res) { // define a handler for tracking file
}
var curExt = fileUtility.getFileExtension(fileName);
var downloadExt = fileUtility.getFileExtension(downloadUri);
var downloadExt = "." + body.filetype;
// TODO [Delete in version 7.0 or higher]
if (downloadExt == ".") downloadExt = fileUtility.getFileExtension(downloadUri); // Support for versions below 7.0
// convert downloaded file to the file with the current extension if these extensions aren't equal
if (downloadExt != curExt) {
@ -728,7 +735,7 @@ app.get("/editor", function (req, res) { // define a handler for editing docume
var commentGroups = user.commentGroups;
if (fileExt != null) {
var fileName = docManager.createDemo(!!req.query.sample, fileExt, userid, name); // create demo document of a given extension
var fileName = docManager.createDemo(!!req.query.sample, fileExt, userid, name, false); // create demo document of a given extension
// get the redirect path
var redirectPath = docManager.getServerUrl() + "/editor?fileName=" + encodeURIComponent(fileName) + docManager.getCustomParams();
@ -745,7 +752,7 @@ app.get("/editor", function (req, res) { // define a handler for editing docume
}
var key = docManager.getKey(fileName);
var url = docManager.getDownloadUrl(fileName);
var urlUser = docManager.getlocalFileUri(fileName, 0, false)
var urlUser = path.isAbsolute(storageFolder) ? docManager.getDownloadUrl(fileName) + "&dmode=emb" : docManager.getlocalFileUri(fileName, 0, false);
var mode = req.query.mode || "edit"; // mode: view/edit/review/comment/fillForms/embedded
var type = req.query.type || ""; // type: embedded/mobile/desktop
if (type == "") {
@ -779,6 +786,7 @@ app.get("/editor", function (req, res) { // define a handler for editing docume
history.push(docManager.getHistory(fileName, changes, keyVersion, i)); // write all the file history information
var historyD = {
fileType: fileUtility.getFileExtension(fileName).slice(1),
version: i,
key: keyVersion,
url: i == countVersion ? url : (docManager.getlocalFileUri(fileName, i, true) + "/prev" + fileExt),
@ -786,10 +794,12 @@ app.get("/editor", function (req, res) { // define a handler for editing docume
if (i > 1 && docManager.existsSync(docManager.diffPath(fileName, userAddress, i-1))) { // check if the path to the file with document versions differences exists
historyD.previous = { // write information about previous file version
fileType: historyData[i-2].fileType,
key: historyData[i-2].key,
url: historyData[i-2].url,
};
historyD.changesUrl = docManager.getlocalFileUri(fileName, i-1) + "/diff.zip"; // get the path to the diff.zip file and write it to the history object
let changesUrl = docManager.getlocalFileUri(fileName, i-1);
historyD.changesUrl = changesUrl.includes("diff.zip") ? changesUrl : changesUrl + "/diff.zip"; // get the path to the diff.zip file and write it to the history object
}
historyData.push(historyD);

View File

@ -102,8 +102,38 @@ docManager.getCorrectName = function (fileName, userAddress) {
return name;
};
// processes a request editnew
docManager.RequestEditnew = function (req, fileName, user) {
if (req.params['id'] != fileName){ // processes a repeated request editnew
docManager.fileRemove(req.params['id']);
fileName = docManager.getCorrectName(req.params['id']);
}
docManager.fileSizeZero(fileName);
docManager.saveFileData(fileName, user.id, user.name);
return fileName;
}
// delete a file with its history
docManager.fileRemove = function (fileName) {
const filePath = docManager.storagePath(fileName); // get the path to this file
fileSystem.unlinkSync(filePath); // and delete it
const userAddress = docManager.curUserHostAddress();
const historyPath = docManager.historyPath(fileName, userAddress, true);
docManager.cleanFolderRecursive(historyPath, true); // clean all the files from the history folder
}
// create a zero-size file
docManager.fileSizeZero = function (fileName) {
var path = docManager.storagePath(fileName);
var fh = fileSystem.openSync(path, 'w');
fileSystem.closeSync(fh);
}
// create demo document
docManager.createDemo = function (isSample, fileExt, userid, username) {
docManager.createDemo = function (isSample, fileExt, userid, username, wopi) {
const demoName = (isSample ? "sample" : "new") + "." + fileExt;
const fileName = docManager.getCorrectName(demoName); // get the correct file name if such a name already exists
@ -151,7 +181,12 @@ docManager.getFileUri = function (fileName) {
docManager.getlocalFileUri = function (fileName, version, forDocumentServer) {
const serverPath = docManager.getServerUrl(forDocumentServer);
const hostAddress = docManager.curUserHostAddress();
const url = serverPath + configServer.get("storagePath") + "/" + hostAddress + "/" + encodeURIComponent(fileName); // get full url address to the file
let url = serverPath + configServer.get("storagePath") + "/" + hostAddress + "/" + encodeURIComponent(fileName); // get full url address to the file
if (path.isAbsolute(configServer.get("storageFolder"))) {
let separator = configServer.get("storagePath").includes("/") ? "/" : "\\";
url = docManager.getDownloadUrl(fileName + "-history" + separator + version + separator + "diff.zip");
return url;
}
if (!version) {
return url;
}
@ -208,14 +243,14 @@ docManager.getDownloadUrl = function (fileName) {
// get the storage path of the given file
docManager.storagePath = function (fileName, userAddress) {
fileName = fileUtility.getFileName(fileName); // get the file name with extension
const directory = path.join(docManager.dir, docManager.curUserHostAddress(userAddress)); // get the path to the directory for the host address
const directory = path.isAbsolute(docManager.dir) ? docManager.dir : path.join(docManager.dir, docManager.curUserHostAddress(userAddress)); // get the path to the directory for the host address
this.createDirectory(directory); // create a new directory if it doesn't exist
return path.join(directory, fileName); // put the given file to this directory
};
// get the path to the forcesaved file version
docManager.forcesavePath = function (fileName, userAddress, create) {
let directory = path.join(docManager.dir, docManager.curUserHostAddress(userAddress));
let directory = path.isAbsolute(docManager.dir) ? docManager.dir : path.join(docManager.dir, docManager.curUserHostAddress(userAddress));
if (!this.existsSync(directory)) { // the directory with host address doesn't exist
return "";
}
@ -233,7 +268,7 @@ docManager.forcesavePath = function (fileName, userAddress, create) {
// create the path to the file history
docManager.historyPath = function (fileName, userAddress, create) {
let directory = path.join(docManager.dir, docManager.curUserHostAddress(userAddress));
let directory = path.isAbsolute(docManager.dir) ? docManager.dir : path.join(docManager.dir, userAddress);
if (!this.existsSync(directory)) {
return "";
}
@ -278,7 +313,7 @@ docManager.changesUser = function (fileName, userAddress, version) {
// get all the stored files
docManager.getStoredFiles = function () {
const userAddress = docManager.curUserHostAddress();
const directory = path.join(docManager.dir, userAddress);
const directory = path.isAbsolute(docManager.dir) ? docManager.dir : path.join(docManager.dir, userAddress);
this.createDirectory(directory);
const result = [];
const storedFiles = fileSystem.readdirSync(directory); // read the user host directory contents
@ -451,7 +486,7 @@ docManager.cleanFolderRecursive = function (folder, me) {
// get files information
docManager.getFilesInfo = function (fileId) {
const userAddress = docManager.curUserHostAddress();
const directory = path.join(docManager.dir, userAddress);
const directory = path.isAbsolute(docManager.dir) ? docManager.dir : path.join(docManager.dir, userAddress);
const filesInDirectory = this.getStoredFiles(); // get all the stored files from the folder
let responseArray = [];
let responseObject;

View File

@ -257,14 +257,12 @@ function putFile(wopi, req, res, userHost) {
// return information about the file properties, access rights and editor settings
function checkFileInfo(wopi, req, res, userHost) {
let userAddress = docManager.curUserHostAddress(userHost);
let historyPath = docManager.historyPath(wopi.id, userAddress); // get the path to the file history
let version = 1;
if (historyPath != "") { // if it isn't empty
version = docManager.countVersion(historyPath) + 1; // get a number of a new file version
}
let version = docManager.getKey(wopi.id);
let path = docManager.storagePath(wopi.id, userAddress);
let user = users.getUser(req.query.userid);
// add wopi query
var query = new URLSearchParams(wopi.accessToken);
let user = users.getUser(query.get("userid"));
// create the file information object
let fileInfo = {

View File

@ -53,6 +53,14 @@ exports.registerRoutes = function(app) {
// get the wopi discovery information
let actions = await utils.getDiscoveryInfo(absSiteUrl);
let wopiEnable = actions.length != 0 ? true : false;
let docsExtEdit = []; // Supported extensions for WOPI
actions.forEach(el => {
if (el.name == "edit") docsExtEdit.push("."+el.ext);
});
let editedExts = configServer.get('editedDocs').filter(i => docsExtEdit.includes(i)); // Checking supported extensions
let fillExts = configServer.get("fillDocs").filter(i => docsExtEdit.includes(i));
try {
// get all the stored files
@ -72,6 +80,10 @@ exports.registerRoutes = function(app) {
params: docManager.getCustomParams(),
users: users,
serverUrl: docManager.getServerUrl(),
preloaderUrl: siteUrl + configServer.get('preloaderUrl'),
convertExts: configServer.get('convertedDocs'),
editedExts: editedExts,
fillExts: fillExts,
});
} catch (ex) {
@ -84,11 +96,10 @@ exports.registerRoutes = function(app) {
// define a handler for creating a new wopi editing session
app.get("/wopi-new", function(req, res) {
var fileExt = req.query.fileExt; // get the file extension from the request
var user = users.getUser(req.query.userid); // get a user by the id
if (fileExt != null) { // if the file extension exists
var fileName = docManager.createDemo(!!req.query.sample, fileExt, user.id, user.name); // create demo document of the given extension
var redirectPath = docManager.getServerUrl(true) + "/wopi-action/" + encodeURIComponent(fileName) + "?action=edit" + docManager.getCustomParams(); // get the redirect path
var fileName = docManager.getCorrectName("new." + fileExt)
var redirectPath = docManager.getServerUrl(true) + "/wopi-action/" + encodeURIComponent(fileName) + "?action=editnew" + docManager.getCustomParams(); // get the redirect path
res.redirect(redirectPath);
return;
}
@ -98,8 +109,16 @@ exports.registerRoutes = function(app) {
try {
docManager.init(storageFolder, req, res);
var fileName = docManager.getCorrectName(req.params['id'])
var fileExt = fileUtility.getFileExtension(fileName, true); // get the file extension from the request
var user = users.getUser(req.query.userid); // get a user by the id
// get an action for the specified extension and name
let action = await utils.getAction(fileUtility.getFileExtension(req.params['id'], true), req.query["action"]);
let action = await utils.getAction(fileExt, req.query["action"]);
if (action != null && req.query["action"] == "editnew") {
fileName = docManager.RequestEditnew(req, fileName, user);
}
// render wopiAction template with the parameters specified
res.render("wopiAction", {
@ -140,4 +159,11 @@ exports.registerRoutes = function(app) {
.all(tokenValidator.isValidToken)
.get(filesController.fileRequestHandler)
.post(filesController.fileRequestHandler);
// define a handler for upload files
app.route('/wopi/upload')
.all(tokenValidator.isValidToken)
.get(filesController.fileRequestHandler)
.post(filesController.fileRequestHandler);
};

View File

@ -198,8 +198,10 @@ if (typeof jQuery != "undefined") {
var posExt = fileName.lastIndexOf('.');
posExt = 0 <= posExt ? fileName.substring(posExt).trim().toLowerCase() : '';
if (EditedExtList.indexOf(posExt) != -1
|| FilledExtList.indexOf(posExt) != -1) {
var checkEdited = EditedExtList.split(",").filter(function(ext) { return ext == posExt;});
var checkFilled = FilledExtList.split(",").filter(function(ext) { return ext == posExt;});
if (checkEdited != "" || checkFilled != "") {
jq("#beginEdit").removeClass("disable");
}
};
@ -223,7 +225,11 @@ if (typeof jQuery != "undefined") {
jq(document).on("click", "#beginEdit:not(.disable)", function () {
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
var url = UrlEditor + "?fileName=" + fileId + "&lang=" + language + "&userid=" + userid;
if (UrlEditor == "wopi-action"){
var url = UrlEditor + "/" + fileId + "?action=edit";
}else{
var url = UrlEditor + "?fileName=" + fileId + "&lang=" + language + "&userid=" + userid;
}
window.open(url, "_blank");
jq('#hiddenFileName').val("");
jq.unblockUI();
@ -232,7 +238,11 @@ if (typeof jQuery != "undefined") {
jq(document).on("click", "#beginView:not(.disable)", function () {
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
var url = UrlEditor + "?mode=view&fileName=" + fileId + "&lang=" + language + "&userid=" + userid;
if (UrlEditor == "wopi-action"){
var url = UrlEditor + "/" + fileId + "?action=view";
}else{
var url = UrlEditor + "?mode=view&fileName=" + fileId + "&lang=" + language + "&userid=" + userid;
}
window.open(url, "_blank");
jq('#hiddenFileName').val("");
jq.unblockUI();

View File

@ -87,10 +87,6 @@
}
@media (max-width: 1008px) {
#portal-info {
width: 65vw;
}
.left-panel {
margin-left: 0;
}
@ -312,6 +308,9 @@
.tableRow td:first-child {
max-width: 17%;
}
#portal-info {
max-width: 60vw;
}
}
.downloadContentCellShift:after {

View File

@ -97,6 +97,10 @@ header img {
width: 896px;
}
#portal-info {
max-width: 65vw;
}
.portal-name {
color: #FF6F3D;
font-size: 24px;

View File

@ -133,7 +133,7 @@
</td>
<td class="section">
<div class="main-panel">
<div id="portal-info" style="display: <%= storedFiles.length > 0 ? "none" : "block" %>">
<div id="portal-info" style="display: <%= storedFiles.length > 0 ? "none" : "table-cell" %>">
<span class="portal-name">ONLYOFFICE Document Editors Welcome!</span>
<span class="portal-descr">
Get started with a demo-sample of ONLYOFFICE Document Editors, the first html5-based editors.
@ -200,9 +200,6 @@
<img src="images/filter.svg" alt="Open in editor without access to change the filter" title="Open in editor without access to change the filter" /></a>
</td>
<% } %>
<% if (storedFiles[i].documentType !== "word" && storedFiles[i].documentType !== "cell") {%>
<td class="contentCells contentCells-icon contentCellsEmpty"></td>
<% } %>
<% if (storedFiles[i].documentType == "word") { %>
<td class="contentCells contentCells-icon">
<a href="editor?type=desktop&mode=blockcontent&fileName=<%= encodeURIComponent(storedFiles[i].name) + params %>" target="_blank">

View File

@ -63,12 +63,15 @@
<a class="try-editor form reload-page" target="_blank" href="<%= serverUrl %>/wopi-new?fileExt=docxf<%= params %>" title="Create new form template">Form template</a>
</li>
</ul>
<label class="create-sample">
<input id="createSample" type="checkbox" class="checkbox" />With sample content
</label>
</div>
</div>
<div class="upload-panel clearFix">
<a class="file-upload">Upload file
<input type="file" id="fileupload" name="uploadedFile" data-url="upload?<%= params %>" />
</a>
</div>
<table class="user-block-table" cellspacing="0" cellpadding="0">
<tbody>
<tr>
@ -130,7 +133,7 @@
</td>
<td class="section">
<div class="main-panel">
<div id="portal-info">
<div id="portal-info" style="display: <%= storedFiles.length > 0 ? "none" : "table-cell" %>">
<% if (!wopiEnable)
{ %>
<span class="portal-name">ONLYOFFICE Document Editors Welcome!</span>
@ -139,7 +142,7 @@
<br />Set the <b>wopi.enable</b> parameter in the Document Server configuration file to <b>true</b> and restart ONLYOFFICE Docs.
</span>
<% }
else if (storedFiles.length <= 0)
else
{ %>
<span class="portal-name">ONLYOFFICE Document Editors Welcome!</span>
<span class="portal-descr">
@ -147,16 +150,6 @@
<br /> You may upload your own documents for testing using the "<b>Upload file</b>" button and <b>selecting</b> the necessary files on your PC.
</span>
<span class="portal-descr">You can open the same document using different users in different Web browser sessions, so you can check out multi-user editing functions.</span>
<% users.forEach(user => { %>
<div class="user-descr">
<b><%= user.name == null ? 'Anonymous' : user.name %></b>
<ul>
<% user.descriptions.forEach(description => { %>
<li><%= description %></li>
<% }) %>
</ul>
</div>
<% }) %>
<% } %>
</div>
<% if (storedFiles.length > 0)
@ -191,13 +184,15 @@
<% if (storedFiles[i].actions && storedFiles[i].actions.length > 0) { %>
<td class="contentCells contentCells-wopi contentCells-shift">
<% for (var j = 0; j < storedFiles[i].actions.length; j++) { %>
<a href="<%= serverUrl %>/wopi-action/<%= encodeURIComponent(storedFiles[i].name) %>?action=<%= storedFiles[i].actions[j].name %><%= params %>" target="_blank">
<% if (storedFiles[i].actions[j].name == "edit") { %>
<img src="images/fill-forms.svg" alt="<%= storedFiles[i].actions[j].name %>" title="<%= storedFiles[i].actions[j].name %>" />
<%} else { %>
<img src="images/desktop.svg" alt="<%= storedFiles[i].actions[j].name %>" title="<%= storedFiles[i].actions[j].name %>" />
<% } %>
</a>
<% if (storedFiles[i].actions[j].name != "editnew") { %>
<a href="<%= serverUrl %>/wopi-action/<%= encodeURIComponent(storedFiles[i].name) %>?action=<%= storedFiles[i].actions[j].name %><%= params %>" target="_blank">
<% if (storedFiles[i].actions[j].name == "edit") { %>
<img src="images/fill-forms.svg" alt="<%= storedFiles[i].actions[j].name %>" title="<%= storedFiles[i].actions[j].name %>" />
<%} else { %>
<img src="images/desktop.svg" alt="<%= storedFiles[i].actions[j].name %>" title="<%= storedFiles[i].actions[j].name %>" />
<% } %>
</a>
<% } %>
<% } %>
</td>
<% } %>
@ -223,6 +218,50 @@
</table>
</div>
<div id="mainProgress">
<div id="uploadSteps">
<span id="uploadFileName" class="uploadFileName"></span>
<div class="describeUpload">After these steps are completed, you can work with your document.</div>
<span id="step1" class="step">1. Loading the file.</span>
<span class="step-descr">The loading speed depends on file size and additional elements it contains.</span>
<br />
<span id="step2" class="step">2. Conversion.</span>
<span class="step-descr">The file is converted to OOXML so that you can edit it.</span>
<br />
<div id="blockPassword">
<span class="descrFilePass">The file is password protected.</span>
<br />
<div>
<input id="filePass" type="password"/>
<div id="enterPass" class="button orange">Enter</div>
<div id="skipPass" class="button gray">Skip</div>
</div>
<span class="errorPass"></span>
<br />
</div>
<span id="step3" class="step">3. Loading editor scripts.</span>
<span class="step-descr">They are loaded only once, they will be cached on your computer.</span>
<input type="hidden" name="hiddenFileName" id="hiddenFileName" />
<br />
<br />
<span class="progress-descr">Note the speed of all operations depends on your connection quality and server location.</span>
<br />
<br />
<div class="error-message">
<b>Upload error: </b><span></span>
<br />
Please select another file and try again.
</div>
</div>
<br />
<div id="beginEdit" class="button orange disable">Edit</div>
<div id="beginView" class="button gray disable">View</div>
<div style="visibility: hidden;" id="disable" class="button gray disable">Embedded view</div>
<div id="cancelEdit" class="button gray">Cancel</div>
</div>
<span id="loadScripts" data-docs="<%= preloaderUrl %>"></span>
<footer>
<div class="center">
<table>
@ -250,6 +289,14 @@
<script type="text/javascript" src="javascripts/jquery.fileupload.js"></script>
<script type="text/javascript" src="javascripts/jquery.dropdownToggle.js"></script>
<script type="text/javascript" src="javascripts/jscript.js"></script>
<script type="text/javascript">
var ConverExtList = "<%= convertExts %>";
var EditedExtList = "<%= editedExts %>";
var FilledExtList = "<%= fillExts %>";
var UrlConverter = "convert";
var UrlEditor = "wopi-action";
</script>
</body>
</html>

View File

@ -16,13 +16,14 @@ See the detailed guide to learn how to [install Document Server for Windows](htt
Download the [PHP example](https://api.onlyoffice.com/editors/demopreview) from our site.
You need to connect the editors to your website. Specify the path to the editors installation in the *config.php* file:
To connect the editors to your website, specify the path to the editors installation and the path to the storage folder in the *config.php* file:
```
$GLOBALS['STORAGE_PATH'] = "";
$GLOBALS['DOC_SERV_SITE_URL'] = "https://documentserver/";
```
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed.
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed and the **STORAGE_PATH** is the path where files will be created and stored. You can set an absolute path. For example, *D:\\\\folder*. Please note that on Windows OS the double backslash must be used as a separator.
If you want to experiment with the editor configuration, modify the [parameters](https://api.onlyoffice.com/editors/advanced) in the *doceditor.php* file.
@ -147,13 +148,14 @@ See the detailed guide to learn how to [install Document Server for Linux](https
nano config.php
```
Edit the following line:
Edit the following lines:
```
$GLOBALS['STORAGE_PATH'] = "";
$GLOBALS['DOC_SERV_SITE_URL'] = "https://documentserver/";
```
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed.
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed and the **STORAGE_PATH** is the path where files will be created and stored. You can set an absolute path.
5. Set permission for site:

View File

@ -200,7 +200,15 @@ function getScheme() {
// get the storage path of the given file
function getStoragePath($fileName, $userAddress = NULL) {
$storagePath = trim(str_replace(array('/','\\'), DIRECTORY_SEPARATOR, $GLOBALS['STORAGE_PATH']), DIRECTORY_SEPARATOR);
$directory = __DIR__ . DIRECTORY_SEPARATOR . $storagePath;
if (!empty($storagePath) && !file_exists($storagePath) && !is_dir($storagePath)) {
mkdir($storagePath);
}
if (realpath($storagePath) === $storagePath) {
$directory = $storagePath;
} else {
$directory = __DIR__ . DIRECTORY_SEPARATOR . $storagePath;
}
if ($storagePath != "")
{
@ -212,20 +220,27 @@ function getStoragePath($fileName, $userAddress = NULL) {
}
}
$directory = $directory . getCurUserHostAddress($userAddress) . DIRECTORY_SEPARATOR;
if (realpath($storagePath) !== $storagePath) {
$directory = $directory . getCurUserHostAddress($userAddress) . DIRECTORY_SEPARATOR;
}
if (!file_exists($directory) && !is_dir($directory)) {
mkdir($directory);
}
sendlog("getStoragePath result: " . $directory . basename($fileName), "common.log");
return $directory . basename($fileName);
return realpath($storagePath) === $storagePath ? $directory . $fileName : $directory . basename($fileName);
}
// get the path to the forcesaved file version
function getForcesavePath($fileName, $userAddress, $create) {
$storagePath = trim(str_replace(array('/','\\'), DIRECTORY_SEPARATOR, $GLOBALS['STORAGE_PATH']), DIRECTORY_SEPARATOR);
// create the directory to this file version
$directory = __DIR__ . DIRECTORY_SEPARATOR . $storagePath . getCurUserHostAddress($userAddress) . DIRECTORY_SEPARATOR;
if (realpath($storagePath) === $storagePath) {
$directory = $storagePath . DIRECTORY_SEPARATOR;
} else {
$directory = __DIR__ . DIRECTORY_SEPARATOR . $storagePath . getCurUserHostAddress($userAddress) . DIRECTORY_SEPARATOR;
}
if (!is_dir($directory)) return "";
@ -233,8 +248,9 @@ function getForcesavePath($fileName, $userAddress, $create) {
$directory = $directory . $fileName . "-hist" . DIRECTORY_SEPARATOR;
if (!$create && !is_dir($directory)) return "";
mkdir($directory);
if (!file_exists($directory) && !is_dir($directory)) {
mkdir($directory);
}
$directory = $directory . $fileName;
if (!$create && !file_exists($directory)) return "";
@ -275,7 +291,15 @@ function getFileVersion($histDir) {
// get all the stored files from the folder
function getStoredFiles() {
$storagePath = trim(str_replace(array('/','\\'), DIRECTORY_SEPARATOR, $GLOBALS['STORAGE_PATH']), DIRECTORY_SEPARATOR);
$directory = __DIR__ . DIRECTORY_SEPARATOR . $storagePath;
if (!empty($storagePath) && !file_exists($storagePath) && !is_dir($storagePath)) {
mkdir($storagePath);
}
if (realpath($storagePath) === $storagePath) {
$directory = $storagePath;
} else {
$directory = __DIR__ . DIRECTORY_SEPARATOR . $storagePath;
}
// get the storage path and check if it exists
$result = array();
@ -288,7 +312,9 @@ function getStoredFiles() {
}
}
$directory = $directory . getCurUserHostAddress() . DIRECTORY_SEPARATOR;
if (realpath($storagePath) !== $storagePath) {
$directory = $directory . getCurUserHostAddress() . DIRECTORY_SEPARATOR;
}
if (!file_exists($directory) && !is_dir($directory)) {
return $result;
@ -320,7 +346,11 @@ function getVirtualPath($forDocumentServer) {
$storagePath = $storagePath != "" ? $storagePath . '/' : "";
$virtPath = serverPath($forDocumentServer) . '/' . $storagePath . getCurUserHostAddress() . '/';
if (realpath($storagePath) === $storagePath) {
$virtPath = serverPath($forDocumentServer) . '/' . $storagePath . '/';
} else {
$virtPath = serverPath($forDocumentServer) . '/' . $storagePath . getCurUserHostAddress() . '/';
}
sendlog("getVirtualPath virtPath: " . $virtPath, "common.log");
return $virtPath;
}

View File

@ -87,10 +87,6 @@
}
@media (max-width: 1008px) {
#portal-info {
width: 65vw;
}
.left-panel {
margin-left: 0;
}
@ -312,6 +308,10 @@
.tableRow td:first-child {
max-width: 17%;
}
#portal-info {
max-width: 60vw;
}
}
.downloadContentCellShift:after {

View File

@ -22,6 +22,7 @@ html {
}
body {
display: inline-table;
background: #FFFFFF;
color: #333333;
font-family: Open Sans;
@ -70,6 +71,7 @@ header img {
}
.main{
display: table;
height: calc(100% - 112px);
min-height: 536px;
}
@ -96,6 +98,10 @@ header img {
width: 896px;
}
#portal-info {
max-width: 65vw;
}
.portal-name {
color: #FF6F3D;
font-size: 24px;

View File

@ -52,7 +52,7 @@
}
$fileuri = FileUri($filename, true);
$fileuriUser = FileUri($filename);
$fileuriUser = realpath($GLOBALS['STORAGE_PATH']) === $GLOBALS['STORAGE_PATH'] ? getDownloadUrl($filename) . "&dmode=emb" : FileUri($filename);
$docKey = getDocEditorKey($filename);
$filetype = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
@ -217,6 +217,7 @@
// get document history
function getHistory($filename, $filetype, $docKey, $fileuri) {
$storagePath = $GLOBALS['STORAGE_PATH'];
$histDir = getHistoryDir(getStoragePath($filename)); // get the path to the file history
if (getFileVersion($histDir) > 0) { // check if the file was modified (the file version is greater than 0)
@ -245,31 +246,40 @@
];
}
$fileT = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
$prevFileName = $verDir . DIRECTORY_SEPARATOR . "prev." . $filetype;
$prevFileName = substr($prevFileName, strlen(getStoragePath("")));
$dataObj["fileType"] = $fileT;
$dataObj["key"] = $key;
$dataObj["url"] = $i == $curVer ? $fileuri : getVirtualPath(true) . str_replace("%5C", "/", rawurlencode($prevFileName)); // write file url to the data object
$prevFileUrl = $i == $curVer ? $fileuri : getVirtualPath(true) . str_replace("%5C", "/", rawurlencode($prevFileName));
if (realpath($storagePath) === $storagePath) {
$prevFileUrl = $i == $curVer ? getDownloadUrl($filename) : getDownloadUrl($prevFileName);
}
$dataObj["url"] = $prevFileUrl; // write file url to the data object
$dataObj["version"] = $i;
if ($i > 1) { // check if the version number is greater than 1 (the document was modified)
$changes = json_decode(file_get_contents(getVersionDir($histDir, $i - 1) . DIRECTORY_SEPARATOR . "changes.json"), true); // get the path to the changes.json file
$change = $changes["changes"][0];
$obj["changes"] = $change ? $changes["changes"][0] : null; // write information about changes to the object
$obj["changes"] = $changes ? $changes["changes"] : null; // write information about changes to the object
$obj["serverVersion"] = $changes["serverVersion"];
$obj["created"] = $change ? $change["created"] : null;
$obj["user"] = $change ? $change["user"] : null;
$prev = $histData[$i - 2]; // get the history data from the previous file version
$dataObj["previous"] = [ // write information about previous file version to the data object
"fileType" => $prev["fileType"],
"key" => $prev["key"],
"url" => $prev["url"]
];
$changesUrl = getVersionDir($histDir, $i - 1) . DIRECTORY_SEPARATOR . "diff.zip";
$changesUrl = substr($changesUrl, strlen(getStoragePath("")));
$changesPath = getVersionDir($histDir, $i - 1) . DIRECTORY_SEPARATOR . "diff.zip";
$changesPath = substr($changesPath, strlen(getStoragePath("")));
// write the path to the diff.zip archive with differences in this file version
$dataObj["changesUrl"] = getVirtualPath(true) . str_replace("%5C", "/", rawurlencode($changesUrl));
$changesUrl = realpath($storagePath) === $storagePath ? getDownloadUrl($changesPath) : getVirtualPath(true) . str_replace("%5C", "/", rawurlencode($changesPath)) ;
$dataObj["changesUrl"] = $changesUrl;
}
if (isJwtEnabled()) {

View File

@ -144,7 +144,7 @@
if (!empty($storedFiles)): ?>
<div id="portal-info" style="display: none">
<?php else: ?>
<div id="portal-info" style="display: block">
<div id="portal-info" style="display: table-cell">
<?php endif; ?>
<span class="portal-name">ONLYOFFICE Document Editors Welcome!</span>
<span class="portal-descr">
@ -213,9 +213,6 @@
echo ' <img src="css/images/filter.svg" alt="Open in editor without access to change the filter" title="Open in editor without access to change the filter" /></a>';
echo ' </td>';
}
if($storeFile->documentType!="word" && $storeFile->documentType!="cell"){
echo ' <td class="contentCells contentCells-icon contentCellsEmpty"></td>';
}
if ($storeFile->documentType == "word") {
echo ' <td class="contentCells contentCells-icon ">';
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . '&action=blockcontent&type=desktop" target="_blank">';

View File

@ -82,7 +82,11 @@ function processSave($data, $fileName, $userAddress) {
}
$curExt = strtolower('.' . pathinfo($fileName, PATHINFO_EXTENSION)); // get current file extension
$downloadExt = strtolower('.' . pathinfo($downloadUri, PATHINFO_EXTENSION)); // get the extension of the downloaded file
$downloadExt = strtolower('.' . $data["filetype"]); // get the extension of the downloaded file
// TODO [Delete in version 7.0 or higher]
if (!$downloadExt) $downloadExt = strtolower('.' . pathinfo($downloadUri, PATHINFO_EXTENSION)); // Support for versions below 7.0
$newFileName = $fileName;
// convert downloaded file to the file with the current extension if these extensions aren't equal
@ -154,7 +158,11 @@ function processForceSave($data, $fileName, $userAddress) {
}
$curExt = strtolower('.' . pathinfo($fileName, PATHINFO_EXTENSION)); // get current file extension
$downloadExt = strtolower('.' . pathinfo($downloadUri, PATHINFO_EXTENSION)); // get the extension of the downloaded file
$downloadExt = strtolower('.' . $data["filetype"]); // get the extension of the downloaded file
// TODO [Delete in version 7.0 or higher]
if (!$downloadExt) $downloadExt = strtolower('.' . pathinfo($downloadUri, PATHINFO_EXTENSION)); // Support for versions below 7.0
$newFileName = false;
// convert downloaded file to the file with the current extension if these extensions aren't equal

View File

@ -73,7 +73,7 @@ $descr_user_0 = [
$users = [
new User("uid-1", "John Smith", "smith@example.com",
null, null, [],
"", null, [],
null, [], $descr_user_1, true),
new User("uid-2", "Mark Pottato", "pottato@example.com",
"group-2", ["group-2", ""], [
@ -90,7 +90,7 @@ $users = [
],
false, ["copy", "download", "print"], $descr_user_3, false),
new User("uid-0", null, null,
null, null, [],
"", null, [],
null, [], $descr_user_0, false)
];

View File

@ -353,10 +353,11 @@ function csv() {
// download a file
function download() {
try {
$fileName = basename($_GET["fileName"]); // get the file name
$fileName = realpath($GLOBALS['STORAGE_PATH']) === $GLOBALS['STORAGE_PATH'] ? $_GET["fileName"] : basename($_GET["fileName"]); // get the file name
$userAddress = $_GET["userAddress"];
$isEmbedded = $_GET["&dmode"];
if (isJwtEnabled()) {
if (isJwtEnabled() && $isEmbedded == null) {
$jwtHeader = $GLOBALS['DOC_SERV_JWT_HEADER'] == "" ? "Authorization" : $GLOBALS['DOC_SERV_JWT_HEADER'];
if (!empty(apache_request_headers()[$jwtHeader])) {
$token = jwtDecode(substr(apache_request_headers()[$jwtHeader], strlen("Bearer ")));

View File

@ -45,13 +45,14 @@ See the detailed guide to learn how to install Document Server [for Windows](htt
nano config.py
```
Edit the following line:
Edit the following lines:
```
STORAGE_PATH = 'app_data'
DOC_SERV_SITE_URL = 'https://documentserver/'
```
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed.
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed and the **STORAGE_PATH** is the path where files will be created and stored. You can set an absolute path. For example, *D:\\\\folder*. Please note that on Windows OS the double backslash must be used as a separator.
6. Run the **Python** server:

View File

@ -164,7 +164,7 @@ def getRootFolder(req):
else:
curAdr = req.META['REMOTE_ADDR']
directory = os.path.join(config.STORAGE_PATH, curAdr)
directory = config.STORAGE_PATH if os.path.isabs(config.STORAGE_PATH) else os.path.join(config.STORAGE_PATH, curAdr)
if not os.path.exists(directory): # if such a directory does not exist, make it
os.makedirs(directory)

View File

@ -176,6 +176,7 @@ def getHistoryObject(storagePath, filename, docKey, docUrl, req):
obj['key'] = key
obj['version'] = i
dataObj['fileType'] = fileUtils.getFileExt(filename)[1:]
dataObj['key'] = key
dataObj['version'] = i
@ -201,6 +202,7 @@ def getHistoryObject(storagePath, filename, docKey, docUrl, req):
prev = histData[str(i - 2)] # get the history data from the previous file version
prevInfo = { # write key and url information about previous file version
'fileType': prev['fileType'],
'key': prev['key'],
'url': prev['url']
}

View File

@ -60,7 +60,10 @@ def processSave(body, filename, usAddr):
newFilename = filename
curExt = fileUtils.getFileExt(filename) # get current file extension
downloadExt = fileUtils.getFileExt(download) # get the extension of the downloaded file
# Todo [Delete here in version 7.0 or higher]
downloadExt = "." + body.get('filetype') if (body.get('filetype') != None) else fileUtils.getFileExt(download) # get the extension of the downloaded file
# Support for versions below 7.0
# convert downloaded file to the file with the current extension if these extensions aren't equal
if (curExt != downloadExt):
@ -106,7 +109,11 @@ def processForceSave(body, filename, usAddr):
if (download is None):
raise Exception("DownloadUrl is null")
curExt = fileUtils.getFileExt(filename) # get current file extension
downloadExt = fileUtils.getFileExt(download) # get the extension of the downloaded file
# Todo [Delete here in version 7.0 or higher]
downloadExt = "." + body.get('filetype') if (body.get('filetype') != None) else fileUtils.getFileExt(download) # get the extension of the downloaded file
# Support for versions below 7.0
newFilename = False
# convert downloaded file to the file with the current extension if these extensions aren't equal

View File

@ -79,7 +79,7 @@ descr_user_0 = [
USERS = [
User('uid-1', 'John Smith', 'smith@example.com',
None, None, {},
'', None, {},
None, [], descr_user_1, True),
User('uid-2', 'Mark Pottato', 'pottato@example.com',
'group-2', ['group-2', ''], {
@ -96,7 +96,7 @@ USERS = [
},
False, ["copy", "download", "print"], descr_user_3, False),
User('uid-0', None, None,
None, None, {},
'', None, {},
None, [], descr_user_0, False)
]

View File

@ -154,7 +154,7 @@ def edit(request):
ext = fileUtils.getFileExt(filename)
fileUri = docManager.getFileUri(filename, True, request)
fileUriUser = docManager.getFileUri(filename, False, request)
fileUriUser = docManager.getDownloadUrl(filename, request) + "&dmode=emb" if os.path.isabs(config.STORAGE_PATH) else docManager.getFileUri(filename, False, request)
docKey = docManager.generateFileKey(filename, request)
fileType = fileUtils.getFileType(filename)
user = users.getUserFromReq(request) # get user
@ -361,8 +361,9 @@ def download(request):
try:
fileName = fileUtils.getFileName(request.GET['fileName']) # get the file name
userAddress = request.GET.get('userAddress') if request.GET.get('userAddress') else request
isEmbedded = request.GET.get('dmode')
if (jwtManager.isEnabled()):
if (jwtManager.isEnabled() and isEmbedded == None):
jwtHeader = 'Authorization' if config.DOC_SERV_JWT_HEADER is None or config.DOC_SERV_JWT_HEADER == '' else config.DOC_SERV_JWT_HEADER
token = request.headers.get(jwtHeader)
if token:

View File

@ -87,10 +87,6 @@
}
@media (max-width: 1008px) {
#portal-info {
width: 65vw;
}
.left-panel {
margin-left: 0;
}
@ -312,6 +308,10 @@
.tableRow td:first-child {
max-width: 17%;
}
#portal-info {
max-width: 60vw;
}
}
.downloadContentCellShift:after {

View File

@ -30,6 +30,7 @@ html {
}
body {
display: inline-table;
background: #FFFFFF;
color: #333333;
font-family: Open Sans;
@ -79,6 +80,7 @@ header img {
}
.main{
display: table;
height: calc(100% - 112px);
min-height: 536px;
}
@ -105,6 +107,10 @@ header img {
width: 896px;
}
#portal-info {
max-width: 65vw;
}
.portal-name {
color: #FF6F3D;
font-size: 24px;

View File

@ -113,7 +113,7 @@
{% if files %}
<div id="portal-info" style="display: none">
{% else %}
<div id="portal-info" style="display: block">
<div id="portal-info" style="display: table-cell">
{% endif %}
<span class="portal-name">ONLYOFFICE Document Editors Welcome!</span>
<span class="portal-descr">
@ -185,9 +185,6 @@
</a>
</td>
{% endif %}
{% if file.type == 'slide' %}
<td class="contentCells contentCells-icon contentCellsEmpty"></td>
{% endif %}
{% if file.type == 'word' %}
<td class="contentCells contentCells-icon">
<a href="edit?filename={{ file.title }}&type=desktop&mode=blockcontent" target="_blank">

View File

@ -36,6 +36,10 @@ jquery-rails - This gem provides jQuery and the jQuery-ujs driver for your Rail
License: MIT
License File: jquery-rails.license
mimemagic - А library to detect the mime type of a file by extension or by content. (https://github.com/mimemagicrb/mimemagic/blob/master/LICENSE)
License: MIT
License File: mimemagic.license
rails - Rails is a web-application framework that includes everything needed to create database-backed web applications according to the Model-View-Controller (MVC) pattern. (https://github.com/rails/rails/blob/v6.0.3.2/MIT-LICENSE)
License: MIT
License File: rails.license

View File

@ -1,6 +1,6 @@
source 'https://rubygems.org'
gem 'mimemagic', github: 'mimemagicrb/mimemagic', ref: '01f92d86d15d85cfd0f20dabd025dcbd36a8a60f'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '6.0.3.5'
# Use sqlite3 as the database for Active Record
@ -45,4 +45,6 @@ gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
gem 'uuid'
gem 'rack-cors'
gem 'rack-cors'
gem 'webrick'

View File

@ -12,14 +12,14 @@ See the detailed guide to learn how to install Document Server [for Windows](htt
## Step 2. Install the prerequisites and run the website with the editors
1. Install **Ruby Version Manager (RVM)** and the stable 2.7 **Ruby** version:
1. Install **Ruby Version Manager (RVM)** and the latest stable **Ruby** version:
```
gpg --keyserver "hkp://keys.gnupg.net" --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
```
```
\curl -sSL https://get.rvm.io | bash -s stable --ruby=2.7.0
\curl -sSL https://get.rvm.io | bash -s stable --ruby
```
2. Download the archive with the Ruby example and unpack the archive:
@ -50,17 +50,19 @@ See the detailed guide to learn how to install Document Server [for Windows](htt
nano config/application.rb
```
Edit the following line:
Edit the following lines:
```
Rails.configuration.storagePath="app_data"
Rails.configuration.urlSite="https://documentserver/"
```
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed.
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed and the **storagePath** is the path where files will be created and stored. You can set an absolute path. For example, *D:\\\\folder*. Please note that on Windows OS the double backslash must be used as a separator.
6. Run the **Rails** application:
```
rails server -u webrick
rails s -b 0.0.0.0 -p 80
```

View File

@ -87,10 +87,6 @@
}
@media (max-width: 1008px) {
#portal-info {
width: 65vw;
}
.left-panel {
margin-left: 0;
}
@ -312,6 +308,10 @@
.tableRow td:first-child {
max-width: 17%;
}
#portal-info {
max-width: 60vw;
}
}
.downloadContentCellShift:after {

View File

@ -22,6 +22,7 @@ html {
}
body {
display: inline-table;
background: #FFFFFF;
color: #333333;
font-family: Open Sans;
@ -34,6 +35,7 @@ body {
padding: 0;
text-decoration: none;
overflow-x: hidden;
width: 100%;
}
form {
@ -71,6 +73,7 @@ header img {
}
.main{
display: table;
height: calc(100% - 112px);
min-height: 536px;
}
@ -97,6 +100,10 @@ header img {
width: 896px;
}
#portal-info {
max-width: 65vw;
}
.portal-name {
color: #FF6F3D;
font-size: 24px;

View File

@ -236,8 +236,9 @@ class HomeController < ApplicationController
begin
file_name = File.basename(params[:fileName])
user_address = params[:userAddress]
isEmbedded = params[:dmode]
if JwtHelper.is_enabled
if JwtHelper.is_enabled && isEmbedded == nil
jwtHeader = Rails.configuration.header.empty? ? "Authorization" : Rails.configuration.header;
if request.headers[jwtHeader]
hdr = request.headers[jwtHeader]

View File

@ -83,7 +83,8 @@ class DocumentHelper
# get the storage path of the given file
def storage_path(file_name, user_address)
directory = Rails.root.join('public', Rails.configuration.storagePath, cur_user_host_address(user_address)) # get the path to the directory for the host address
directory = File.absolute_path?(Rails.configuration.storagePath) ? Rails.configuration.storagePath
: Rails.root.join('public', Rails.configuration.storagePath, cur_user_host_address(user_address)) # get the path to the directory for the host address
# create a new directory if it doesn't exist
unless File.directory?(directory)
@ -91,19 +92,20 @@ class DocumentHelper
end
# put the given file to this directory
directory.join(File.basename(file_name)).to_s
File.join(directory, File.basename(file_name))
end
# get the path to the forcesaved file version
def forcesave_path(file_name, user_address, create)
directory = Rails.root.join('public', Rails.configuration.storagePath, cur_user_host_address(user_address))
directory = File.absolute_path?(Rails.configuration.storagePath) ? Rails.configuration.storagePath
: Rails.root.join('public', Rails.configuration.storagePath, cur_user_host_address(user_address))
# the directory with host address doesn't exist
unless File.directory?(directory)
return ""
end
directory = directory.join("#{File.basename(file_name)}-hist") # get the path to the history of the given file
directory = File.join(directory,"#{File.basename(file_name)}-hist") # get the path to the history of the given file
unless File.directory?(directory)
if create
FileUtils.mkdir_p(directory) # create history directory if it doesn't exist
@ -112,7 +114,7 @@ class DocumentHelper
end
end
directory = directory.join(File.basename(file_name)) # get the path to the given file
directory = File.join(directory, File.basename(file_name)) # get the path to the given file
unless File.file?(directory)
if !create
return ""
@ -174,7 +176,8 @@ class DocumentHelper
# get all the stored files from the folder
def get_stored_files(user_address)
directory = Rails.root.join('public', Rails.configuration.storagePath, cur_user_host_address(user_address))
directory = File.absolute_path?(Rails.configuration.storagePath) ? Rails.configuration.storagePath
: Rails.root.join('public', Rails.configuration.storagePath, cur_user_host_address(user_address))
arr = [];

View File

@ -45,7 +45,7 @@ class FileModel
# get file uri for document server
def file_uri_user
DocumentHelper.get_file_uri(@file_name, false)
File.absolute_path?(Rails.configuration.storagePath) ? download_url + "&dmode=emb" : DocumentHelper.get_file_uri(@file_name, false)
end
# get document type from its name (word, cell or slide)
@ -208,6 +208,7 @@ class FileModel
end
# get the history data from the previous file version and write key and url information about it
dataObj["fileType"] = file_ext[1..file_ext.length]
dataObj["key"] = cur_key
dataObj["url"] = i == cur_ver ? doc_uri : DocumentHelper.get_path_uri(File.join("#{file_name}-hist", i.to_s, "prev#{file_ext}"))
dataObj["version"] = i
@ -229,6 +230,7 @@ class FileModel
prev = histData[(i - 2).to_s] # get the history data from the previous file version
dataObj["previous"] = { # write key and url information about previous file version
:fileType => prev["fileType"],
:key => prev["key"],
:url => prev["url"]
}

View File

@ -68,9 +68,14 @@ class TrackHelper
return saved
end
new_file_name = file_name
download_ext = "."+file_data['filetype'] # get the extension of the downloaded file
# TODO [Delete in version 7.0 or higher]
if (download_ext == ".")
download_ext = File.extname(download_uri).downcase; # Support for versions below 7.0
end
cur_ext = File.extname(file_name).downcase # get current file extension
download_ext = File.extname(download_uri).downcase # get the extension of the downloaded file
# convert downloaded file to the file with the current extension if these extensions aren't equal
if (!cur_ext.eql?(download_ext))
@ -138,9 +143,15 @@ class TrackHelper
saved = 1
return saved
end
download_ext = "."+file_data['filetype'] # get the extension of the downloaded file
# TODO [Delete in version 7.0 or higher]
if (download_ext == ".")
download_ext = File.extname(download_uri).downcase; # Support for versions below 7.0
end
cur_ext = File.extname(file_name).downcase # get current file extension
download_ext = File.extname(download_uri).downcase # get the extension of the downloaded file
new_file_name = false
# convert downloaded file to the file with the current extension if these extensions aren't equal

View File

@ -72,7 +72,7 @@ class Users
@@users = [
User.new("uid-1", "John Smith", "smith@example.com",
nil, nil, {},
"", nil, {},
nil, [], @@descr_user_1, true),
User.new("uid-2", "Mark Pottato", "pottato@example.com",
"group-2", ["group-2", ""], {
@ -89,7 +89,7 @@ class Users
},
false, ["copy", "download", "print"], @@descr_user_3, false),
User.new("uid-0", nil, nil,
nil, nil, {},
"", nil, {},
nil, [], @@descr_user_0, false)
]

View File

@ -117,7 +117,7 @@
docs = DocumentHelper.get_stored_files(nil)
%>
<div class="main-panel">
<div id="portal-info" style="display: <%= docs.length > 0 ? "none" : "block" %>">
<div id="portal-info" style="display: <%= docs.length > 0 ? "none" : "table-cell" %>">
<span class="portal-name">ONLYOFFICE Document Editors Welcome!</span>
<span class="portal-descr">
Get started with a demo-sample of ONLYOFFICE Document Editors, the first html5-based editors.
@ -192,9 +192,6 @@
<img src="assets/filter.svg" alt="Open in editor without access to change the filter" title="Open in editor without access to change the filter" />
</a>
</td>
<% end %>
<% if !docType.eql?("word") && !docType.eql?("cell")%>
<td class="contentCells contentCells-icon contentCellsEmpty"></td>
<% end %>
<% if docType.eql?("word") %>
<td class="contentCells contentCells-icon">

View File

@ -5,6 +5,7 @@ Rails.application.config.assets.version = '1.0'
Rails.application.config.assets.precompile += %w( editor.css )
Rails.application.config.assets.precompile += %w( jquery-ui.css )
Rails.application.config.assets.precompile += %w( stylesheet.css )
Rails.application.config.assets.precompile += %w( media.css )
# Add additional assets to the asset load path
# Rails.application.config.assets.paths << Emoji.images_path

View File

@ -0,0 +1,21 @@
The MIT License
Copyright (c) 2011 Daniel Mendler
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.