Compare commits
71 Commits
v99.99.99.
...
v6.3.1.50
| Author | SHA1 | Date | |
|---|---|---|---|
| a9b82a299a | |||
| 46961db654 | |||
| 85255d878e | |||
| c8b17785e7 | |||
| 988e336f43 | |||
| 9ab94ee9c3 | |||
| fe02c4914c | |||
| 82981d3ce2 | |||
| 6870923b94 | |||
| 7d5c90e9cf | |||
| b541936473 | |||
| a2e59cf705 | |||
| dc074d4baf | |||
| 1cf5b1eea5 | |||
| 2635306e2e | |||
| f0cc80fd53 | |||
| c9f58e3ca6 | |||
| 821e481734 | |||
| f0309615d6 | |||
| 47588d135e | |||
| 8e6ae3b915 | |||
| 8fc9d6125c | |||
| b427594248 | |||
| 5c43308e14 | |||
| c5b67b4b00 | |||
| 8442def83c | |||
| 2cb91eb8d5 | |||
| cf82b0ffc9 | |||
| ffcf787f94 | |||
| ce2714c684 | |||
| 4ccd78053f | |||
| 7602183cf9 | |||
| 1a6744a814 | |||
| 6a89a073fa | |||
| 353119145c | |||
| 0aaaedc4d6 | |||
| 246ddc9f9c | |||
| 3e8b6aaffa | |||
| c95439c0db | |||
| 62873e4ce4 | |||
| e04155e7ad | |||
| 733f798968 | |||
| f7f0a07239 | |||
| ee79e02c54 | |||
| d8afda9b56 | |||
| 0569dc7271 | |||
| 823374e2fe | |||
| 3b89aae808 | |||
| cc488187b4 | |||
| 0e191eed91 | |||
| 6d27c1866b | |||
| 845b111a85 | |||
| 61c388a7af | |||
| c6deb13712 | |||
| 13250e18b3 | |||
| 7d373fa1a9 | |||
| 8af2607e62 | |||
| c2db28fbcf | |||
| d075855065 | |||
| 2ec0a3798d | |||
| 4ba7b3f02e | |||
| 620a097faa | |||
| c3bb70aa9a | |||
| 255ec7afe9 | |||
| 7996ea4825 | |||
| 38055f0b85 | |||
| 4e2a5fb175 | |||
| c54b760526 | |||
| cf4dd454f6 | |||
| 858b437e80 | |||
| 715ab7d690 |
@ -80,4 +80,4 @@ If you have any problems with or questions about [ONLYOFFICE Document Server][2]
|
||||
|
||||
## License
|
||||
|
||||
document-server-integration is released under the MIT License. See the LICENSE.txt file for more information.
|
||||
document-server-integration is released under the Apache-2.0 License. See the LICENSE.txt file for more information.
|
||||
|
||||
|
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 8.2 KiB |
|
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 8.2 KiB |
|
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 8.2 KiB |
@ -75,6 +75,39 @@ namespace OnlineEditorsExampleMVC.Helpers
|
||||
return directory + Path.GetFileName(fileName);
|
||||
}
|
||||
|
||||
public static string ForcesavePath(string fileName, string userAddress, Boolean create)
|
||||
{
|
||||
var directory = HttpRuntime.AppDomainAppPath + CurUserHostAddress(userAddress) + "\\";
|
||||
if (!Directory.Exists(directory))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
directory = directory + Path.GetFileName(fileName) + "-hist" + "\\";
|
||||
if (!Directory.Exists(directory))
|
||||
{
|
||||
if (create)
|
||||
{
|
||||
Directory.CreateDirectory(directory);
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
directory = directory + Path.GetFileName(fileName);
|
||||
if (!File.Exists(directory))
|
||||
{
|
||||
if (!create)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
return directory;
|
||||
}
|
||||
|
||||
public static string HistoryDir(string storagePath)
|
||||
{
|
||||
return storagePath += "-hist";
|
||||
@ -101,13 +134,13 @@ namespace OnlineEditorsExampleMVC.Helpers
|
||||
return GetFileVersion(HistoryDir(StoragePath(fileName, userAddress)));
|
||||
}
|
||||
|
||||
public static string GetCorrectName(string fileName)
|
||||
public static string GetCorrectName(string fileName, string userAddress = null)
|
||||
{
|
||||
var baseName = Path.GetFileNameWithoutExtension(fileName);
|
||||
var ext = Path.GetExtension(fileName);
|
||||
var name = baseName + ext;
|
||||
|
||||
for (var i = 1; File.Exists(StoragePath(name)); i++)
|
||||
for (var i = 1; File.Exists(StoragePath(name, userAddress)); i++)
|
||||
{
|
||||
name = baseName + " (" + i + ")" + ext;
|
||||
}
|
||||
@ -138,9 +171,9 @@ namespace OnlineEditorsExampleMVC.Helpers
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public static void CreateMeta(string fileName, string uid, string uname)
|
||||
public static void CreateMeta(string fileName, string uid, string uname, string userAddress = null)
|
||||
{
|
||||
var histDir = HistoryDir(StoragePath(fileName, null));
|
||||
var histDir = HistoryDir(StoragePath(fileName, userAddress));
|
||||
Directory.CreateDirectory(histDir);
|
||||
File.WriteAllText(Path.Combine(histDir, "createdInfo.json"), new JavaScriptSerializer().Serialize(new Dictionary<string, object> {
|
||||
{ "created", DateTime.Now.ToString("yyyy'-'MM'-'dd HH':'mm':'ss") },
|
||||
|
||||
290
web/documentserver-example/csharp-mvc/Helpers/TrackManager.cs
Normal file
@ -0,0 +1,290 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2020
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Collections.Generic;
|
||||
using System.Web.Script.Serialization;
|
||||
using System.Web.Configuration;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Text;
|
||||
|
||||
namespace OnlineEditorsExampleMVC.Helpers
|
||||
{
|
||||
public class TrackManager
|
||||
{
|
||||
public static Dictionary<string, object> readBody(HttpContext context)
|
||||
{
|
||||
string body;
|
||||
try
|
||||
{
|
||||
using (var receiveStream = context.Request.InputStream)
|
||||
using (var readStream = new StreamReader(receiveStream))
|
||||
{
|
||||
body = readStream.ReadToEnd();
|
||||
if (string.IsNullOrEmpty(body)) context.Response.Write("{\"error\":1,\"message\":\"Request stream is empty\"}");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new HttpException((int)HttpStatusCode.BadRequest, e.Message);
|
||||
}
|
||||
|
||||
var jss = new JavaScriptSerializer();
|
||||
var fileData = jss.Deserialize<Dictionary<string, object>>(body);
|
||||
|
||||
if (JwtManager.Enabled)
|
||||
{
|
||||
string JWTheader = WebConfigurationManager.AppSettings["files.docservice.header"].Equals("") ? "Authorization" : WebConfigurationManager.AppSettings["files.docservice.header"];
|
||||
|
||||
string token = null;
|
||||
|
||||
if (fileData.ContainsKey("token"))
|
||||
{
|
||||
token = JwtManager.Decode(fileData["token"].ToString());
|
||||
}
|
||||
else if (context.Request.Headers.AllKeys.Contains(JWTheader, StringComparer.InvariantCultureIgnoreCase))
|
||||
{
|
||||
var headerToken = context.Request.Headers.Get(JWTheader).Substring("Bearer ".Length);
|
||||
token = JwtManager.Decode(headerToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Response.Write("{\"error\":1,\"message\":\"JWT expected\"}");
|
||||
}
|
||||
|
||||
if (token != null && !token.Equals(""))
|
||||
{
|
||||
fileData = (Dictionary<string, object>)jss.Deserialize<Dictionary<string, object>>(token)["payload"];
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Response.Write("{\"error\":1,\"message\":\"JWT validation failed\"}");
|
||||
}
|
||||
}
|
||||
|
||||
return fileData;
|
||||
}
|
||||
|
||||
public static int processSave(Dictionary<string, object> fileData, string fileName, string userAddress)
|
||||
{
|
||||
var downloadUri = (string)fileData["url"];
|
||||
string curExt = Path.GetExtension(fileName);
|
||||
string downloadExt = Path.GetExtension(downloadUri) ?? "";
|
||||
var newFileName = fileName;
|
||||
|
||||
if (!curExt.Equals(downloadExt, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
try
|
||||
{
|
||||
string newFileUri;
|
||||
var result = ServiceConverter.GetConvertedUri(downloadUri, downloadExt, curExt, ServiceConverter.GenerateRevisionId(downloadUri), false, out newFileUri);
|
||||
if (string.IsNullOrEmpty(newFileUri))
|
||||
{
|
||||
newFileName = DocManagerHelper.GetCorrectName(Path.GetFileNameWithoutExtension(fileName) + downloadExt, userAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
downloadUri = newFileUri;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
newFileName = DocManagerHelper.GetCorrectName(Path.GetFileNameWithoutExtension(fileName) + downloadExt, userAddress);
|
||||
}
|
||||
}
|
||||
|
||||
var storagePath = DocManagerHelper.StoragePath(newFileName, userAddress);
|
||||
var histDir = DocManagerHelper.HistoryDir(storagePath);
|
||||
if (!Directory.Exists(histDir)) Directory.CreateDirectory(histDir);
|
||||
|
||||
var versionDir = DocManagerHelper.VersionDir(histDir, DocManagerHelper.GetFileVersion(histDir));
|
||||
if (!Directory.Exists(versionDir)) Directory.CreateDirectory(versionDir);
|
||||
|
||||
File.Move(DocManagerHelper.StoragePath(fileName, userAddress), Path.Combine(versionDir, "prev" + curExt));
|
||||
|
||||
DownloadToFile(downloadUri, storagePath);
|
||||
DownloadToFile((string)fileData["changesurl"], Path.Combine(versionDir, "diff.zip"));
|
||||
|
||||
var hist = fileData.ContainsKey("changeshistory") ? (string)fileData["changeshistory"] : null;
|
||||
if (string.IsNullOrEmpty(hist) && fileData.ContainsKey("history"))
|
||||
{
|
||||
var jss = new JavaScriptSerializer();
|
||||
hist = jss.Serialize(fileData["history"]);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(hist))
|
||||
{
|
||||
File.WriteAllText(Path.Combine(versionDir, "changes.json"), hist);
|
||||
}
|
||||
|
||||
File.WriteAllText(Path.Combine(versionDir, "key.txt"), (string)fileData["key"]);
|
||||
|
||||
string forcesavePath = DocManagerHelper.ForcesavePath(newFileName, userAddress, false);
|
||||
if (!forcesavePath.Equals(""))
|
||||
{
|
||||
File.Delete(forcesavePath);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int processForceSave(Dictionary<string, object> fileData, string fileName, string userAddress)
|
||||
{
|
||||
var downloadUri = (string)fileData["url"];
|
||||
|
||||
string curExt = Path.GetExtension(fileName);
|
||||
string downloadExt = Path.GetExtension(downloadUri);
|
||||
var newFileName = fileName;
|
||||
|
||||
if (!curExt.Equals(downloadExt))
|
||||
{
|
||||
try
|
||||
{
|
||||
string newFileUri;
|
||||
var result = ServiceConverter.GetConvertedUri(downloadUri, downloadExt, curExt, ServiceConverter.GenerateRevisionId(downloadUri), false, out newFileUri);
|
||||
if (string.IsNullOrEmpty(newFileUri))
|
||||
{
|
||||
newFileName = DocManagerHelper.GetCorrectName(Path.GetFileNameWithoutExtension(fileName) + downloadExt, userAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
downloadUri = newFileUri;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
newFileName = DocManagerHelper.GetCorrectName(Path.GetFileNameWithoutExtension(fileName) + downloadExt, userAddress);
|
||||
}
|
||||
}
|
||||
|
||||
string forcesavePath = "";
|
||||
Boolean isSubmitForm = fileData["forcesavetype"].ToString().Equals("3");
|
||||
|
||||
if (isSubmitForm)
|
||||
{
|
||||
if (newFileName.Equals(fileName))
|
||||
{
|
||||
newFileName = DocManagerHelper.GetCorrectName(fileName, userAddress);
|
||||
}
|
||||
forcesavePath = DocManagerHelper.StoragePath(newFileName, userAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
forcesavePath = DocManagerHelper.ForcesavePath(newFileName, userAddress, false);
|
||||
if (forcesavePath.Equals(""))
|
||||
{
|
||||
forcesavePath = DocManagerHelper.ForcesavePath(newFileName, userAddress, true);
|
||||
}
|
||||
}
|
||||
|
||||
DownloadToFile(downloadUri, forcesavePath);
|
||||
|
||||
if (isSubmitForm)
|
||||
{
|
||||
var jss = new JavaScriptSerializer();
|
||||
var actions = jss.Deserialize<List<object>>(jss.Serialize(fileData["actions"]));
|
||||
var action = jss.Deserialize<Dictionary<string, object>>(jss.Serialize(actions[0]));
|
||||
var user = action["userid"].ToString();
|
||||
DocManagerHelper.CreateMeta(newFileName, user, "Filling Form", userAddress);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static void commandRequest(string method, string key)
|
||||
{
|
||||
string documentCommandUrl = WebConfigurationManager.AppSettings["files.docservice.url.site"] + WebConfigurationManager.AppSettings["files.docservice.url.command"];
|
||||
|
||||
var request = (HttpWebRequest)WebRequest.Create(documentCommandUrl);
|
||||
request.Method = "POST";
|
||||
request.ContentType = "application/json";
|
||||
|
||||
var body = new Dictionary<string, object>() {
|
||||
{ "c", method },
|
||||
{ "key", key }
|
||||
};
|
||||
|
||||
if (JwtManager.Enabled)
|
||||
{
|
||||
var payload = new Dictionary<string, object>
|
||||
{
|
||||
{ "payload", body }
|
||||
};
|
||||
|
||||
var payloadToken = JwtManager.Encode(payload);
|
||||
var bodyToken = JwtManager.Encode(body);
|
||||
string JWTheader = WebConfigurationManager.AppSettings["files.docservice.header"].Equals("") ? "Authorization" : WebConfigurationManager.AppSettings["files.docservice.header"];
|
||||
request.Headers.Add(JWTheader, "Bearer " + payloadToken);
|
||||
|
||||
body.Add("token", bodyToken);
|
||||
}
|
||||
|
||||
var bytes = Encoding.UTF8.GetBytes(new JavaScriptSerializer().Serialize(body));
|
||||
request.ContentLength = bytes.Length;
|
||||
using (var requestStream = request.GetRequestStream())
|
||||
{
|
||||
requestStream.Write(bytes, 0, bytes.Length);
|
||||
}
|
||||
|
||||
string dataResponse;
|
||||
using (var response = request.GetResponse())
|
||||
using (var stream = response.GetResponseStream())
|
||||
{
|
||||
if (stream == null) throw new Exception("Response is null");
|
||||
|
||||
using (var reader = new StreamReader(stream))
|
||||
{
|
||||
dataResponse = reader.ReadToEnd();
|
||||
}
|
||||
}
|
||||
|
||||
var jss = new JavaScriptSerializer();
|
||||
var responseObj = jss.Deserialize<Dictionary<string, object>>(dataResponse);
|
||||
if (!responseObj["error"].ToString().Equals("0"))
|
||||
{
|
||||
throw new Exception(dataResponse);
|
||||
}
|
||||
}
|
||||
|
||||
private static void DownloadToFile(string url, string path)
|
||||
{
|
||||
if (string.IsNullOrEmpty(url)) throw new ArgumentException("url");
|
||||
if (string.IsNullOrEmpty(path)) throw new ArgumentException("path");
|
||||
|
||||
var req = (HttpWebRequest)WebRequest.Create(url);
|
||||
using (var stream = req.GetResponse().GetResponseStream())
|
||||
{
|
||||
if (stream == null) throw new Exception("stream is null");
|
||||
const int bufferSize = 4096;
|
||||
|
||||
using (var fs = File.Open(path, FileMode.Create))
|
||||
{
|
||||
var buffer = new byte[bufferSize];
|
||||
int readed;
|
||||
while ((readed = stream.Read(buffer, 0, bufferSize)) != 0)
|
||||
{
|
||||
fs.Write(buffer, 0, readed);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -68,6 +68,22 @@ namespace OnlineEditorsExampleMVC.Models
|
||||
|
||||
var canEdit = DocManagerHelper.EditedExts.Contains(ext);
|
||||
var mode = canEdit && editorsMode != "view" ? "edit" : "view";
|
||||
var submitForm = canEdit && (editorsMode.Equals("edit") || editorsMode.Equals("fillForms"));
|
||||
|
||||
var userId = request.Cookies.GetOrDefault("uid", "uid-1");
|
||||
var uname = userId.Equals("uid-0") ? null : request.Cookies.GetOrDefault("uname", "John Smith");
|
||||
string userGroup = null;
|
||||
List<string> reviewGroups = null;
|
||||
if (userId.Equals("uid-2"))
|
||||
{
|
||||
userGroup = "group-2";
|
||||
reviewGroups = new List<string>() { "group-2", "" };
|
||||
}
|
||||
if (userId.Equals("uid-3"))
|
||||
{
|
||||
userGroup = "group-3";
|
||||
reviewGroups = new List<string>() { "group-2" };
|
||||
}
|
||||
|
||||
object favorite = null;
|
||||
if (!string.IsNullOrEmpty(request.Cookies.GetOrDefault("uid", null)))
|
||||
@ -106,7 +122,8 @@ namespace OnlineEditorsExampleMVC.Models
|
||||
{ "fillForms", editorsMode != "view" && editorsMode != "comment" && editorsMode != "embedded" && editorsMode != "blockcontent" },
|
||||
{ "modifyFilter", editorsMode != "filter" },
|
||||
{ "modifyContentControl", editorsMode != "blockcontent" },
|
||||
{ "review", editorsMode == "edit" || editorsMode == "review" }
|
||||
{ "review", editorsMode == "edit" || editorsMode == "review" },
|
||||
{ "reviewGroups", reviewGroups }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -121,8 +138,9 @@ namespace OnlineEditorsExampleMVC.Models
|
||||
{
|
||||
"user", new Dictionary<string, object>
|
||||
{
|
||||
{ "id", request.Cookies.GetOrDefault("uid", "uid-1") },
|
||||
{ "name", request.Cookies.GetOrDefault("uname", "John Smith") }
|
||||
{ "id", userId },
|
||||
{ "name", uname },
|
||||
{ "group", userGroup }
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -139,6 +157,8 @@ namespace OnlineEditorsExampleMVC.Models
|
||||
{
|
||||
{ "about", true },
|
||||
{ "feedback", true },
|
||||
{ "forcesave", false },
|
||||
{ "submitForm", submitForm },
|
||||
{
|
||||
"goback", new Dictionary<string, object>
|
||||
{
|
||||
@ -247,7 +267,7 @@ namespace OnlineEditorsExampleMVC.Models
|
||||
Path = HttpRuntime.AppDomainAppVirtualPath
|
||||
+ (HttpRuntime.AppDomainAppVirtualPath.EndsWith("/") ? "" : "/")
|
||||
+ "webeditor.ashx",
|
||||
Query = "type=download&fileName=" + HttpUtility.UrlEncode("sample.docx")
|
||||
Query = "type=assets&fileName=" + HttpUtility.UrlEncode("sample.docx")
|
||||
};
|
||||
|
||||
var dataCompareFile = new Dictionary<string, object>
|
||||
|
||||
@ -46,7 +46,7 @@ namespace OnlineEditorsExampleMVC.Models
|
||||
".doc", ".docx", ".docm",
|
||||
".dot", ".dotx", ".dotm",
|
||||
".odt", ".fodt", ".ott", ".rtf", ".txt",
|
||||
".html", ".htm", ".mht",
|
||||
".html", ".htm", ".mht", ".xml",
|
||||
".pdf", ".djvu", ".fb2", ".epub", ".xps"
|
||||
};
|
||||
|
||||
|
||||
@ -105,6 +105,7 @@
|
||||
<Compile Include="Global.asax.cs">
|
||||
<DependentUpon>Global.asax</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Helpers\TrackManager.cs" />
|
||||
<Compile Include="Helpers\DocManagerHelper.cs" />
|
||||
<Compile Include="Helpers\DocumentConverter.cs" />
|
||||
<Compile Include="Helpers\JwtManager.cs" />
|
||||
@ -120,6 +121,7 @@
|
||||
<Content Include="Content\editor.css" />
|
||||
<Content Include="Content\images\alert.png" />
|
||||
<Content Include="Content\images\block-content-24.png" />
|
||||
<Content Include="Content\images\cell.ico" />
|
||||
<Content Include="Content\images\close.png" />
|
||||
<Content Include="Content\images\comment-24.png" />
|
||||
<Content Include="Content\images\corner.png" />
|
||||
@ -139,6 +141,8 @@
|
||||
<Content Include="Content\images\mobile-24.png" />
|
||||
<Content Include="Content\images\question_small.png" />
|
||||
<Content Include="Content\images\review-24.png" />
|
||||
<Content Include="Content\images\slide.ico" />
|
||||
<Content Include="Content\images\word.ico" />
|
||||
<Content Include="Content\jquery-ui.css" />
|
||||
<Content Include="Content\stylesheet.css" />
|
||||
<Content Include="favicon.ico" />
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
* limitations under the License.
|
||||
*
|
||||
-->
|
||||
<link rel="icon" href="~/favicon.ico" type="image/x-icon" />
|
||||
<link rel="icon" href="<%= "content/images/" + Model.DocumentType + ".ico" %>" type="image/x-icon" />
|
||||
<title><%= Model.FileName + " - ONLYOFFICE" %></title>
|
||||
|
||||
<%: Styles.Render("~/Content/editor") %>
|
||||
|
||||
@ -57,6 +57,7 @@
|
||||
<option value="uid-1">John Smith</option>
|
||||
<option value="uid-2">Mark Pottato</option>
|
||||
<option value="uid-3">Hamish Mitchell</option>
|
||||
<option value="uid-0">anonymous</option>
|
||||
</select>
|
||||
</td>
|
||||
<td width="70%" valign="middle">Select user name before opening the document; you can open the same document using different users in different Web browser sessions, so you can check out multi-user editing functions.</td>
|
||||
@ -160,7 +161,7 @@
|
||||
<a class="stored-edit <%= docType %>" href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name }) %>" target="_blank">
|
||||
<span title="<%= storedFile.Name %>"><%= storedFile.Name %></span>
|
||||
</a>
|
||||
<a href="<%= Url.Content(DocManagerHelper.CurUserHostAddress() + "/" + storedFile) %>">
|
||||
<a href="webeditor.ashx?type=download&filename=<%= HttpUtility.UrlEncode(storedFile.Name) %>">
|
||||
<img class="icon-download" src="content/images/download-24.png" alt="Download" title="Download" />
|
||||
</a>
|
||||
<a class="delete-file" data-filename="<%= storedFile.Name %>">
|
||||
|
||||
@ -27,6 +27,7 @@ using System.Web.Services;
|
||||
using System.Web.Configuration;
|
||||
using OnlineEditorsExampleMVC.Helpers;
|
||||
using OnlineEditorsExampleMVC.Models;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace OnlineEditorsExampleMVC
|
||||
{
|
||||
@ -41,6 +42,9 @@ namespace OnlineEditorsExampleMVC
|
||||
case "upload":
|
||||
Upload(context);
|
||||
break;
|
||||
case "download":
|
||||
Download(context);
|
||||
break;
|
||||
case "convert":
|
||||
Convert(context);
|
||||
break;
|
||||
@ -50,8 +54,8 @@ namespace OnlineEditorsExampleMVC
|
||||
case "remove":
|
||||
Remove(context);
|
||||
break;
|
||||
case "download":
|
||||
Download(context);
|
||||
case "assets":
|
||||
Assets(context);
|
||||
break;
|
||||
case "csv":
|
||||
GetCsv(context);
|
||||
@ -170,103 +174,70 @@ namespace OnlineEditorsExampleMVC
|
||||
MustSave = 2,
|
||||
Corrupted = 3,
|
||||
Closed = 4,
|
||||
MustForceSave = 6,
|
||||
CorruptedForceSave = 7
|
||||
}
|
||||
|
||||
private static void Track(HttpContext context)
|
||||
{
|
||||
var fileData = TrackManager.readBody(context);
|
||||
|
||||
var userAddress = context.Request["userAddress"];
|
||||
var fileName = Path.GetFileName(context.Request["fileName"]);
|
||||
|
||||
string body;
|
||||
try
|
||||
{
|
||||
using (var receiveStream = context.Request.InputStream)
|
||||
using (var readStream = new StreamReader(receiveStream))
|
||||
{
|
||||
body = readStream.ReadToEnd();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new HttpException((int) HttpStatusCode.BadRequest, e.Message);
|
||||
}
|
||||
|
||||
var jss = new JavaScriptSerializer();
|
||||
if (string.IsNullOrEmpty(body)) return;
|
||||
var fileData = jss.Deserialize<Dictionary<string, object>>(body);
|
||||
|
||||
if (JwtManager.Enabled)
|
||||
{
|
||||
string JWTheader = WebConfigurationManager.AppSettings["files.docservice.header"].Equals("") ? "Authorization" : WebConfigurationManager.AppSettings["files.docservice.header"];
|
||||
|
||||
string token = null;
|
||||
|
||||
if (fileData.ContainsKey("token"))
|
||||
{
|
||||
token = JwtManager.Decode(fileData["token"].ToString());
|
||||
}
|
||||
else if (context.Request.Headers.AllKeys.Contains(JWTheader, StringComparer.InvariantCultureIgnoreCase))
|
||||
{
|
||||
var headerToken = context.Request.Headers.Get(JWTheader).Substring("Bearer ".Length);
|
||||
token = JwtManager.Decode(headerToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Response.Write("{\"error\":1,\"message\":\"JWT expected\"}");
|
||||
}
|
||||
|
||||
if (token != null && !token.Equals(""))
|
||||
{
|
||||
fileData = (Dictionary<string, object>)jss.Deserialize<Dictionary<string, object>>(token)["payload"];
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Response.Write("{\"error\":1,\"message\":\"JWT validation failed\"}");
|
||||
}
|
||||
}
|
||||
|
||||
var status = (TrackerStatus) (int) fileData["status"];
|
||||
|
||||
var saved = 1;
|
||||
switch (status)
|
||||
{
|
||||
case TrackerStatus.MustSave:
|
||||
case TrackerStatus.Corrupted:
|
||||
var downloadUri = (string) fileData["url"];
|
||||
|
||||
var saved = 1;
|
||||
case TrackerStatus.Editing:
|
||||
try
|
||||
{
|
||||
var storagePath = DocManagerHelper.StoragePath(fileName, userAddress);
|
||||
var histDir = DocManagerHelper.HistoryDir(storagePath);
|
||||
var versionDir = DocManagerHelper.VersionDir(histDir, DocManagerHelper.GetFileVersion(histDir));
|
||||
|
||||
if (!Directory.Exists(versionDir)) Directory.CreateDirectory(versionDir);
|
||||
|
||||
File.Copy(storagePath, Path.Combine(versionDir, "prev" + Path.GetExtension(fileName)));
|
||||
|
||||
DownloadToFile(downloadUri, DocManagerHelper.StoragePath(fileName, userAddress));
|
||||
DownloadToFile((string)fileData["changesurl"], Path.Combine(versionDir, "diff.zip"));
|
||||
|
||||
var hist = fileData.ContainsKey("changeshistory") ? (string)fileData["changeshistory"] : null;
|
||||
if (string.IsNullOrEmpty(hist) && fileData.ContainsKey("history"))
|
||||
var jss = new JavaScriptSerializer();
|
||||
var actions = jss.Deserialize <List<object>> (jss.Serialize(fileData["actions"]));
|
||||
var action = jss.Deserialize <Dictionary<string, object>> (jss.Serialize(actions[0]));
|
||||
if (action != null && action["type"].ToString().Equals("0"))
|
||||
{
|
||||
hist = jss.Serialize(fileData["history"]);
|
||||
}
|
||||
var user = action["userid"].ToString();
|
||||
var users = jss.Deserialize<List<object>>(jss.Serialize(fileData["users"]));
|
||||
if (!users.Contains(user))
|
||||
{
|
||||
TrackManager.commandRequest("forcesave", fileData["key"].ToString());
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(hist))
|
||||
{
|
||||
File.WriteAllText(Path.Combine(versionDir, "changes.json"), hist);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Print(e.StackTrace);
|
||||
}
|
||||
break;
|
||||
|
||||
File.WriteAllText(Path.Combine(versionDir, "key.txt"), (string)fileData["key"]);
|
||||
case TrackerStatus.MustSave:
|
||||
case TrackerStatus.Corrupted:
|
||||
try
|
||||
{
|
||||
saved = TrackManager.processSave(fileData, fileName, userAddress);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
saved = 0;
|
||||
saved = 1;
|
||||
}
|
||||
context.Response.Write("{\"error\":" + saved + "}");
|
||||
return;
|
||||
|
||||
break;
|
||||
case TrackerStatus.MustForceSave:
|
||||
case TrackerStatus.CorruptedForceSave:
|
||||
try
|
||||
{
|
||||
saved = TrackManager.processForceSave(fileData, fileName, userAddress);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
saved = 1;
|
||||
}
|
||||
context.Response.Write("{\"error\":" + saved + "}");
|
||||
return;
|
||||
}
|
||||
|
||||
context.Response.Write("{\"error\":0}");
|
||||
}
|
||||
|
||||
@ -329,51 +300,48 @@ namespace OnlineEditorsExampleMVC
|
||||
}
|
||||
}
|
||||
|
||||
private static void Download(HttpContext context)
|
||||
private static void Assets(HttpContext context)
|
||||
{
|
||||
var fileName = "sample/" + Path.GetFileName(context.Request["filename"]);
|
||||
download(fileName, context);
|
||||
var fileName = Path.GetFileName(context.Request["filename"]);
|
||||
var filePath = HttpRuntime.AppDomainAppPath + "assets/sample/" + fileName;
|
||||
download(filePath, context);
|
||||
}
|
||||
|
||||
private static void GetCsv(HttpContext context)
|
||||
{
|
||||
var fileName = "sample/" + "csv.csv";
|
||||
download(fileName, context);
|
||||
var fileName = "csv.csv";
|
||||
var filePath = HttpRuntime.AppDomainAppPath + "assets/sample/" + fileName;
|
||||
download(filePath, context);
|
||||
}
|
||||
|
||||
private static void download(string fileName, HttpContext context)
|
||||
private static void Download(HttpContext context)
|
||||
{
|
||||
var csvPath = HttpRuntime.AppDomainAppPath + "assets/" + fileName;
|
||||
var fileinf = new FileInfo(csvPath);
|
||||
try
|
||||
{
|
||||
var fileName = Path.GetFileName(context.Request["filename"]);
|
||||
|
||||
var filePath = DocManagerHelper.ForcesavePath(fileName, null, false);
|
||||
if (filePath.Equals(""))
|
||||
{
|
||||
filePath = DocManagerHelper.StoragePath(fileName, null);
|
||||
}
|
||||
download(filePath, context);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
context.Response.Write("{ \"error\": \"File not found!\"}");
|
||||
}
|
||||
}
|
||||
|
||||
private static void download(string filePath, HttpContext context)
|
||||
{
|
||||
var fileinf = new FileInfo(filePath);
|
||||
context.Response.AddHeader("Content-Length", fileinf.Length.ToString());
|
||||
context.Response.AddHeader("Content-Type", MimeMapping.GetMimeMapping(csvPath));
|
||||
var tmp = HttpUtility.UrlEncode(Path.GetFileName(csvPath));
|
||||
context.Response.AddHeader("Content-Type", MimeMapping.GetMimeMapping(filePath));
|
||||
var tmp = HttpUtility.UrlEncode(Path.GetFileName(filePath));
|
||||
tmp = tmp.Replace("+", "%20");
|
||||
context.Response.AddHeader("Content-Disposition", "attachment; filename*=UTF-8\'\'" + tmp);
|
||||
context.Response.TransmitFile(csvPath);
|
||||
}
|
||||
|
||||
private static void DownloadToFile(string url, string path)
|
||||
{
|
||||
if (string.IsNullOrEmpty(url)) throw new ArgumentException("url");
|
||||
if (string.IsNullOrEmpty(path)) throw new ArgumentException("path");
|
||||
|
||||
var req = (HttpWebRequest)WebRequest.Create(url);
|
||||
using (var stream = req.GetResponse().GetResponseStream())
|
||||
{
|
||||
if (stream == null) throw new Exception("stream is null");
|
||||
const int bufferSize = 4096;
|
||||
|
||||
using (var fs = File.Open(path, FileMode.Create))
|
||||
{
|
||||
var buffer = new byte[bufferSize];
|
||||
int readed;
|
||||
while ((readed = stream.Read(buffer, 0, bufferSize)) != 0)
|
||||
{
|
||||
fs.Write(buffer, 0, readed);
|
||||
}
|
||||
}
|
||||
}
|
||||
context.Response.TransmitFile(filePath);
|
||||
}
|
||||
|
||||
public bool IsReusable
|
||||
|
||||
@ -11,17 +11,18 @@
|
||||
|
||||
<add key="files.docservice.viewed-docs" value=".pdf|.djvu|.xps"/>
|
||||
<add key="files.docservice.edited-docs" value=".docx|.xlsx|.csv|.pptx|.txt"/>
|
||||
<add key="files.docservice.convert-docs" value=".docm|.dotx|.dotm|.dot|.doc|.odt|.fodt|.ott|.xlsm|.xltx|.xltm|.xlt|.xls|.ods|.fods|.ots|.pptm|.ppt|.ppsx|.ppsm|.pps|.potx|.potm|.pot|.odp|.fodp|.otp|.rtf|.mht|.html|.htm|.epub|.fb2"/>
|
||||
<add key="files.docservice.convert-docs" value=".docm|.dotx|.dotm|.dot|.doc|.odt|.fodt|.ott|.xlsm|.xltx|.xltm|.xlt|.xls|.ods|.fods|.ots|.pptm|.ppt|.ppsx|.ppsm|.pps|.potx|.potm|.pot|.odp|.fodp|.otp|.rtf|.mht|.html|.htm|.xml|.epub|.fb2"/>
|
||||
<add key="files.docservice.timeout" value="120000" />
|
||||
<add key="files.docservice.secret" value="" />
|
||||
<add key="files.docservice.header" value="Authorization" />
|
||||
|
||||
<add key="files.docservice.url.site" value="http://documentserver/"/>
|
||||
|
||||
<add key="files.docservice.url.site" value="https://documentserver/"/>
|
||||
|
||||
<add key="files.docservice.url.converter" value="ConvertService.ashx"/>
|
||||
<add key="files.docservice.url.api" value="web-apps/apps/api/documents/api.js"/>
|
||||
<add key="files.docservice.url.preloader" value="web-apps/apps/api/documents/cache-scripts.html"/>
|
||||
<add key="files.docservice.url.command" value="coauthoring/CommandService.ashx"/>
|
||||
|
||||
<add key="files.docservice.url.example" value=""/>
|
||||
|
||||
|
||||
</appSettings>
|
||||
|
||||
|
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 8.2 KiB |
|
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 8.2 KiB |
|
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 8.2 KiB |
@ -77,6 +77,7 @@
|
||||
<option value="uid-1">John Smith</option>
|
||||
<option value="uid-2">Mark Pottato</option>
|
||||
<option value="uid-3">Hamish Mitchell</option>
|
||||
<option value="uid-0">anonymous</option>
|
||||
</select>
|
||||
</td>
|
||||
<td width="70%" valign="middle">Select user name before opening the document; you can open the same document using different users in different Web browser sessions, so you can check out multi-user editing functions.</td>
|
||||
@ -180,7 +181,7 @@
|
||||
<a class="stored-edit <%= docType %>" href="<%= editUrl %>" target="_blank">
|
||||
<span title="<%= storedFile.Name %>"><%= storedFile.Name %></span>
|
||||
</a>
|
||||
<a href="<%= VirtualPath + WebConfigurationManager.AppSettings["storage-path"] + storedFile.Name %>">
|
||||
<a href="webeditor.ashx?type=download&filename=<%= HttpUtility.UrlEncode(storedFile.Name) %>">
|
||||
<img class="icon-download" src="app_themes/images/download-24.png" alt="Download" title="Download" />
|
||||
</a>
|
||||
<a class="delete-file" data-filename="<%= storedFile.Name %>">
|
||||
|
||||
@ -52,7 +52,7 @@ namespace OnlineEditorsExample
|
||||
".doc", ".docx", ".docm",
|
||||
".dot", ".dotx", ".dotm",
|
||||
".odt", ".fodt", ".ott", ".rtf", ".txt",
|
||||
".html", ".htm", ".mht",
|
||||
".html", ".htm", ".mht", ".xml",
|
||||
".pdf", ".djvu", ".fb2", ".epub", ".xps"
|
||||
};
|
||||
|
||||
@ -135,6 +135,39 @@ namespace OnlineEditorsExample
|
||||
return directory + Path.GetFileName(fileName);
|
||||
}
|
||||
|
||||
public static string ForcesavePath(string fileName, string userAddress, Boolean create)
|
||||
{
|
||||
var directory = HttpRuntime.AppDomainAppPath + WebConfigurationManager.AppSettings["storage-path"] + CurUserHostAddress(userAddress) + "\\";
|
||||
if (!Directory.Exists(directory))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
directory = directory + Path.GetFileName(fileName) + "-hist" + "\\";
|
||||
if (!Directory.Exists(directory))
|
||||
{
|
||||
if (create)
|
||||
{
|
||||
Directory.CreateDirectory(directory);
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
directory = directory + Path.GetFileName(fileName);
|
||||
if (!File.Exists(directory))
|
||||
{
|
||||
if (!create)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
return directory;
|
||||
}
|
||||
|
||||
public static string HistoryDir(string storagePath)
|
||||
{
|
||||
return storagePath += "-hist";
|
||||
@ -234,13 +267,7 @@ namespace OnlineEditorsExample
|
||||
var savedFileName = StoragePath(_fileName, null);
|
||||
httpPostedFile.SaveAs(savedFileName);
|
||||
|
||||
var histDir = HistoryDir(savedFileName);
|
||||
Directory.CreateDirectory(histDir);
|
||||
File.WriteAllText(Path.Combine(histDir, "createdInfo.json"), new JavaScriptSerializer().Serialize(new Dictionary<string, object> {
|
||||
{ "created", DateTime.Now.ToString("yyyy'-'MM'-'dd HH':'mm':'ss") },
|
||||
{ "id", context.Request.Cookies.GetOrDefault("uid", "uid-1") },
|
||||
{ "name", context.Request.Cookies.GetOrDefault("uname", "John Smith") }
|
||||
}));
|
||||
DocEditor.CreateMeta(_fileName, context.Request.Cookies.GetOrDefault("uid", "uid-1"), context.Request.Cookies.GetOrDefault("uname", "John Smith"), null);
|
||||
|
||||
return _fileName;
|
||||
}
|
||||
@ -281,13 +308,7 @@ namespace OnlineEditorsExample
|
||||
}
|
||||
}
|
||||
|
||||
var histDir = HistoryDir(StoragePath(_fileName, null));
|
||||
Directory.CreateDirectory(histDir);
|
||||
File.WriteAllText(Path.Combine(histDir, "createdInfo.json"), new JavaScriptSerializer().Serialize(new Dictionary<string, object> {
|
||||
{ "created", DateTime.Now.ToString("yyyy'-'MM'-'dd HH':'mm':'ss") },
|
||||
{ "id", request.Cookies.GetOrDefault("uid", "uid-1") },
|
||||
{ "name", request.Cookies.GetOrDefault("uname", "John Smith") }
|
||||
}));
|
||||
DocEditor.CreateMeta(_fileName, request.Cookies.GetOrDefault("uid", "uid-1"), request.Cookies.GetOrDefault("uname", "John Smith"), null);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
@ -347,13 +368,7 @@ namespace OnlineEditorsExample
|
||||
if (Directory.Exists(histDir)) Directory.Delete(histDir, true);
|
||||
|
||||
_fileName = fileName;
|
||||
histDir = HistoryDir(StoragePath(_fileName, null));
|
||||
Directory.CreateDirectory(histDir);
|
||||
File.WriteAllText(Path.Combine(histDir, "createdInfo.json"), new JavaScriptSerializer().Serialize(new Dictionary<string, object> {
|
||||
{ "created", DateTime.Now.ToString() },
|
||||
{ "id", context.Request.Cookies.GetOrDefault("uid", "uid-1") },
|
||||
{ "name", context.Request.Cookies.GetOrDefault("uname", "John Smith") }
|
||||
}));
|
||||
DocEditor.CreateMeta(_fileName, context.Request.Cookies.GetOrDefault("uid", "uid-1"), context.Request.Cookies.GetOrDefault("uname", "John Smith"), null);
|
||||
}
|
||||
|
||||
return "{ \"filename\" : \"" + _fileName + "\"}";
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="mobile-web-app-capable" content="yes" />
|
||||
<link rel="icon" href="~/favicon.ico" type="image/x-icon" />
|
||||
<link rel="icon" href="<%= "app_themes/images/" + documentType + ".ico" %>" type="image/x-icon" />
|
||||
<title>ONLYOFFICE</title>
|
||||
<!--
|
||||
*
|
||||
|
||||
@ -63,6 +63,7 @@ namespace OnlineEditorsExample
|
||||
protected string InsertImageConfig { get; private set; }
|
||||
protected string compareFileData { get; private set; }
|
||||
protected string dataMailMergeRecipients { get; private set; }
|
||||
protected string documentType { get { return _Default.DocumentType(FileName); } }
|
||||
|
||||
public static string CallbackUrl
|
||||
{
|
||||
@ -105,6 +106,22 @@ namespace OnlineEditorsExample
|
||||
|
||||
var canEdit = _Default.EditedExts.Contains(ext);
|
||||
var mode = canEdit && editorsMode != "view" ? "edit" : "view";
|
||||
var submitForm = canEdit && (editorsMode.Equals("edit") || editorsMode.Equals("fillForms"));
|
||||
|
||||
var userId = Request.Cookies.GetOrDefault("uid", "uid-1");
|
||||
var uname = userId.Equals("uid-0") ? null : Request.Cookies.GetOrDefault("uname", "John Smith");
|
||||
string userGroup = null;
|
||||
List<string> reviewGroups = null;
|
||||
if (userId.Equals("uid-2"))
|
||||
{
|
||||
userGroup = "group-2";
|
||||
reviewGroups = new List<string>() { "group-2", "" };
|
||||
}
|
||||
if (userId.Equals("uid-3"))
|
||||
{
|
||||
userGroup = "group-3";
|
||||
reviewGroups = new List<string>() { "group-2" };
|
||||
}
|
||||
|
||||
var jss = new JavaScriptSerializer();
|
||||
|
||||
@ -120,7 +137,7 @@ namespace OnlineEditorsExample
|
||||
var config = new Dictionary<string, object>
|
||||
{
|
||||
{ "type", Request.GetOrDefault("editorsType", "desktop") },
|
||||
{ "documentType", _Default.DocumentType(FileName) },
|
||||
{ "documentType", documentType },
|
||||
{
|
||||
"document", new Dictionary<string, object>
|
||||
{
|
||||
@ -145,7 +162,8 @@ namespace OnlineEditorsExample
|
||||
{ "fillForms", editorsMode != "view" && editorsMode != "comment" && editorsMode != "embedded" && editorsMode != "blockcontent" },
|
||||
{ "modifyFilter", editorsMode != "filter" },
|
||||
{ "modifyContentControl", editorsMode != "blockcontent" },
|
||||
{ "review", editorsMode == "edit" || editorsMode == "review" }
|
||||
{ "review", editorsMode == "edit" || editorsMode == "review" },
|
||||
{ "reviewGroups", reviewGroups }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -160,8 +178,9 @@ namespace OnlineEditorsExample
|
||||
{
|
||||
"user", new Dictionary<string, object>
|
||||
{
|
||||
{ "id", Request.Cookies.GetOrDefault("uid", "uid-1") },
|
||||
{ "name", Request.Cookies.GetOrDefault("uname", "John Smith") }
|
||||
{ "id", userId },
|
||||
{ "name", uname },
|
||||
{ "group", userGroup }
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -178,6 +197,8 @@ namespace OnlineEditorsExample
|
||||
{
|
||||
{ "about", true },
|
||||
{ "feedback", true },
|
||||
{ "forcesave", false },
|
||||
{ "submitForm", submitForm },
|
||||
{
|
||||
"goback", new Dictionary<string, object>
|
||||
{
|
||||
@ -328,7 +349,7 @@ namespace OnlineEditorsExample
|
||||
compareFileUrl.Path = HttpRuntime.AppDomainAppVirtualPath
|
||||
+ (HttpRuntime.AppDomainAppVirtualPath.EndsWith("/") ? "" : "/")
|
||||
+ "webeditor.ashx";
|
||||
compareFileUrl.Query = "type=download&fileName=" + HttpUtility.UrlEncode("sample.docx");
|
||||
compareFileUrl.Query = "type=assets&fileName=" + HttpUtility.UrlEncode("sample.docx");
|
||||
|
||||
Dictionary<string, object> dataCompareFile = new Dictionary<string, object>
|
||||
{
|
||||
@ -400,12 +421,17 @@ namespace OnlineEditorsExample
|
||||
var filePath = _Default.StoragePath(FileName, null);
|
||||
File.Copy(HttpRuntime.AppDomainAppPath + demoPath + demoName, filePath);
|
||||
|
||||
var histDir = _Default.HistoryDir(filePath);
|
||||
CreateMeta(FileName, request.Cookies.GetOrDefault("uid", "uid-1"), request.Cookies.GetOrDefault("uname", "John Smith"), null);
|
||||
}
|
||||
|
||||
public static void CreateMeta(string fileName, string uid, string uname, string userAddress)
|
||||
{
|
||||
var histDir = _Default.HistoryDir(_Default.StoragePath(fileName, userAddress));
|
||||
Directory.CreateDirectory(histDir);
|
||||
File.WriteAllText(Path.Combine(histDir, "createdInfo.json"), new JavaScriptSerializer().Serialize(new Dictionary<string, object> {
|
||||
{ "created", DateTime.Now.ToString("yyyy'-'MM'-'dd HH':'mm':'ss") },
|
||||
{ "id", request.Cookies.GetOrDefault("uid", "uid-1") },
|
||||
{ "name", request.Cookies.GetOrDefault("uname", "John Smith") }
|
||||
{ "id", uid },
|
||||
{ "name", uname }
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,6 +70,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="App_Themes\images\block-content-24.png" />
|
||||
<Content Include="App_Themes\images\cell.ico" />
|
||||
<Content Include="App_Themes\images\comment-24.png" />
|
||||
<Content Include="App_Themes\images\delete-24.png" />
|
||||
<Content Include="App_Themes\images\desktop-24.png" />
|
||||
@ -86,6 +87,8 @@
|
||||
<Content Include="App_Themes\images\icon_xlsx.png" />
|
||||
<Content Include="App_Themes\images\mobile-24.png" />
|
||||
<Content Include="App_Themes\images\review-24.png" />
|
||||
<Content Include="App_Themes\images\slide.ico" />
|
||||
<Content Include="App_Themes\images\word.ico" />
|
||||
<Content Include="LICENSE" />
|
||||
<Content Include="licenses\jquery.license" />
|
||||
<Content Include="ReadMe.txt" />
|
||||
@ -109,6 +112,7 @@
|
||||
<Compile Include="Default.aspx.designer.cs">
|
||||
<DependentUpon>Default.aspx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="TrackManager.cs" />
|
||||
<Compile Include="Utils.cs" />
|
||||
<Compile Include="WebEditor.ashx.cs">
|
||||
<DependentUpon>WebEditor.ashx</DependentUpon>
|
||||
|
||||
304
web/documentserver-example/csharp/TrackManager.cs
Normal file
@ -0,0 +1,304 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2020
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Collections.Generic;
|
||||
using System.Web.Script.Serialization;
|
||||
using System.Web.Configuration;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Text;
|
||||
using ASC.Api.DocumentConverter;
|
||||
|
||||
|
||||
namespace OnlineEditorsExample
|
||||
{
|
||||
public class TrackManager
|
||||
{
|
||||
public static Dictionary<string, object> readBody(HttpContext context)
|
||||
{
|
||||
string body;
|
||||
try
|
||||
{
|
||||
using (var receiveStream = context.Request.InputStream)
|
||||
using (var readStream = new StreamReader(receiveStream))
|
||||
{
|
||||
body = readStream.ReadToEnd();
|
||||
if (string.IsNullOrEmpty(body)) context.Response.Write("{\"error\":1,\"message\":\"Request stream is empty\"}");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new HttpException((int)HttpStatusCode.BadRequest, e.Message);
|
||||
}
|
||||
|
||||
var jss = new JavaScriptSerializer();
|
||||
var fileData = jss.Deserialize<Dictionary<string, object>>(body);
|
||||
|
||||
if (JwtManager.Enabled)
|
||||
{
|
||||
string JWTheader = WebConfigurationManager.AppSettings["files.docservice.header"].Equals("") ? "Authorization" : WebConfigurationManager.AppSettings["files.docservice.header"];
|
||||
|
||||
string token = null;
|
||||
|
||||
if (fileData.ContainsKey("token"))
|
||||
{
|
||||
token = JwtManager.Decode(fileData["token"].ToString());
|
||||
}
|
||||
else if (context.Request.Headers.AllKeys.Contains(JWTheader, StringComparer.InvariantCultureIgnoreCase))
|
||||
{
|
||||
var headerToken = context.Request.Headers.Get(JWTheader).Substring("Bearer ".Length);
|
||||
token = JwtManager.Decode(headerToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Response.Write("{\"error\":1,\"message\":\"JWT expected\"}");
|
||||
}
|
||||
|
||||
if (token != null && !token.Equals(""))
|
||||
{
|
||||
fileData = (Dictionary<string, object>)jss.Deserialize<Dictionary<string, object>>(token)["payload"];
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Response.Write("{\"error\":1,\"message\":\"JWT validation failed\"}");
|
||||
}
|
||||
}
|
||||
|
||||
return fileData;
|
||||
}
|
||||
|
||||
public static int processSave(Dictionary<string, object> fileData, string fileName, string userAddress)
|
||||
{
|
||||
var downloadUri = (string)fileData["url"];
|
||||
var curExt = Path.GetExtension(fileName);
|
||||
var downloadExt = Path.GetExtension(downloadUri) ?? "";
|
||||
var newFileName = fileName;
|
||||
|
||||
if (!downloadExt.Equals(curExt, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
try
|
||||
{
|
||||
string newFileUri;
|
||||
ServiceConverter.GetConvertedUri(downloadUri, downloadExt, curExt, ServiceConverter.GenerateRevisionId(downloadUri), false, out newFileUri);
|
||||
if (string.IsNullOrEmpty(newFileUri))
|
||||
{
|
||||
newFileName = _Default.GetCorrectName(Path.GetFileNameWithoutExtension(fileName) + downloadExt, userAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
downloadUri = newFileUri;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
newFileName = _Default.GetCorrectName(Path.GetFileNameWithoutExtension(fileName) + downloadExt, userAddress);
|
||||
}
|
||||
}
|
||||
|
||||
// hack. http://ubuntuforums.org/showthread.php?t=1841740
|
||||
if (_Default.IsMono)
|
||||
{
|
||||
ServicePointManager.ServerCertificateValidationCallback += (s, ce, ca, p) => true;
|
||||
}
|
||||
|
||||
var storagePath = _Default.StoragePath(newFileName, userAddress);
|
||||
var histDir = _Default.HistoryDir(storagePath);
|
||||
if (!Directory.Exists(histDir)) Directory.CreateDirectory(histDir);
|
||||
|
||||
var versionDir = _Default.VersionDir(histDir, _Default.GetFileVersion(histDir));
|
||||
if (!Directory.Exists(versionDir)) Directory.CreateDirectory(versionDir);
|
||||
|
||||
File.Copy(_Default.StoragePath(fileName, userAddress), Path.Combine(versionDir, "prev" + curExt));
|
||||
|
||||
DownloadToFile(downloadUri, storagePath);
|
||||
DownloadToFile((string)fileData["changesurl"], Path.Combine(versionDir, "diff.zip"));
|
||||
|
||||
var hist = fileData.ContainsKey("changeshistory") ? (string)fileData["changeshistory"] : null;
|
||||
if (string.IsNullOrEmpty(hist) && fileData.ContainsKey("history"))
|
||||
{
|
||||
var jss = new JavaScriptSerializer();
|
||||
hist = jss.Serialize(fileData["history"]);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(hist))
|
||||
{
|
||||
File.WriteAllText(Path.Combine(versionDir, "changes.json"), hist);
|
||||
}
|
||||
|
||||
File.WriteAllText(Path.Combine(versionDir, "key.txt"), (string)fileData["key"]);
|
||||
|
||||
string forcesavePath = _Default.ForcesavePath(newFileName, userAddress, false);
|
||||
if (!forcesavePath.Equals(""))
|
||||
{
|
||||
File.Delete(forcesavePath);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int processForceSave(Dictionary<string, object> fileData, string fileName, string userAddress)
|
||||
{
|
||||
var downloadUri = (string)fileData["url"];
|
||||
|
||||
string curExt = Path.GetExtension(fileName);
|
||||
string downloadExt = Path.GetExtension(downloadUri);
|
||||
var newFileName = fileName;
|
||||
|
||||
if (!curExt.Equals(downloadExt))
|
||||
{
|
||||
try
|
||||
{
|
||||
string newFileUri;
|
||||
var result = ServiceConverter.GetConvertedUri(downloadUri, downloadExt, curExt, ServiceConverter.GenerateRevisionId(downloadUri), false, out newFileUri);
|
||||
if (string.IsNullOrEmpty(newFileUri))
|
||||
{
|
||||
newFileName = _Default.GetCorrectName(Path.GetFileNameWithoutExtension(fileName) + downloadExt, userAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
downloadUri = newFileUri;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
newFileName = _Default.GetCorrectName(Path.GetFileNameWithoutExtension(fileName) + downloadExt, userAddress);
|
||||
}
|
||||
}
|
||||
|
||||
// hack. http://ubuntuforums.org/showthread.php?t=1841740
|
||||
if (_Default.IsMono)
|
||||
{
|
||||
ServicePointManager.ServerCertificateValidationCallback += (s, ce, ca, p) => true;
|
||||
}
|
||||
|
||||
string forcesavePath = "";
|
||||
Boolean isSubmitForm = fileData["forcesavetype"].ToString().Equals("3");
|
||||
|
||||
if (isSubmitForm)
|
||||
{
|
||||
if (newFileName.Equals(fileName))
|
||||
{
|
||||
newFileName = _Default.GetCorrectName(fileName, userAddress);
|
||||
}
|
||||
forcesavePath = _Default.StoragePath(newFileName, userAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
forcesavePath = _Default.ForcesavePath(newFileName, userAddress, false);
|
||||
if (forcesavePath.Equals(""))
|
||||
{
|
||||
forcesavePath = _Default.ForcesavePath(newFileName, userAddress, true);
|
||||
}
|
||||
}
|
||||
|
||||
DownloadToFile(downloadUri, forcesavePath);
|
||||
|
||||
if (isSubmitForm)
|
||||
{
|
||||
var jss = new JavaScriptSerializer();
|
||||
var actions = jss.Deserialize<List<object>>(jss.Serialize(fileData["actions"]));
|
||||
var action = jss.Deserialize<Dictionary<string, object>>(jss.Serialize(actions[0]));
|
||||
var user = action["userid"].ToString();
|
||||
DocEditor.CreateMeta(newFileName, user, "Filling Form", userAddress);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static void commandRequest(string method, string key)
|
||||
{
|
||||
string documentCommandUrl = WebConfigurationManager.AppSettings["files.docservice.url.site"] + WebConfigurationManager.AppSettings["files.docservice.url.command"];
|
||||
|
||||
var request = (HttpWebRequest)WebRequest.Create(documentCommandUrl);
|
||||
request.Method = "POST";
|
||||
request.ContentType = "application/json";
|
||||
|
||||
var body = new Dictionary<string, object>() {
|
||||
{ "c", method },
|
||||
{ "key", key }
|
||||
};
|
||||
|
||||
if (JwtManager.Enabled)
|
||||
{
|
||||
var payload = new Dictionary<string, object>
|
||||
{
|
||||
{ "payload", body }
|
||||
};
|
||||
|
||||
var payloadToken = JwtManager.Encode(payload);
|
||||
var bodyToken = JwtManager.Encode(body);
|
||||
string JWTheader = WebConfigurationManager.AppSettings["files.docservice.header"].Equals("") ? "Authorization" : WebConfigurationManager.AppSettings["files.docservice.header"];
|
||||
request.Headers.Add(JWTheader, "Bearer " + payloadToken);
|
||||
|
||||
body.Add("token", bodyToken);
|
||||
}
|
||||
|
||||
var bytes = Encoding.UTF8.GetBytes(new JavaScriptSerializer().Serialize(body));
|
||||
request.ContentLength = bytes.Length;
|
||||
using (var requestStream = request.GetRequestStream())
|
||||
{
|
||||
requestStream.Write(bytes, 0, bytes.Length);
|
||||
}
|
||||
|
||||
string dataResponse;
|
||||
using (var response = request.GetResponse())
|
||||
using (var stream = response.GetResponseStream())
|
||||
{
|
||||
if (stream == null) throw new Exception("Response is null");
|
||||
|
||||
using (var reader = new StreamReader(stream))
|
||||
{
|
||||
dataResponse = reader.ReadToEnd();
|
||||
}
|
||||
}
|
||||
|
||||
var jss = new JavaScriptSerializer();
|
||||
var responseObj = jss.Deserialize<Dictionary<string, object>>(dataResponse);
|
||||
if (!responseObj["error"].ToString().Equals("0"))
|
||||
{
|
||||
throw new Exception(dataResponse);
|
||||
}
|
||||
}
|
||||
|
||||
private static void DownloadToFile(string url, string path)
|
||||
{
|
||||
if (string.IsNullOrEmpty(url)) throw new ArgumentException("url");
|
||||
if (string.IsNullOrEmpty(path)) throw new ArgumentException("path");
|
||||
|
||||
var req = (HttpWebRequest)WebRequest.Create(url);
|
||||
using (var stream = req.GetResponse().GetResponseStream())
|
||||
{
|
||||
if (stream == null) throw new Exception("stream is null");
|
||||
const int bufferSize = 4096;
|
||||
|
||||
using (var fs = File.Open(path, FileMode.Create))
|
||||
{
|
||||
var buffer = new byte[bufferSize];
|
||||
int readed;
|
||||
while ((readed = stream.Read(buffer, 0, bufferSize)) != 0)
|
||||
{
|
||||
fs.Write(buffer, 0, readed);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -16,16 +16,13 @@
|
||||
*
|
||||
*/
|
||||
|
||||
using ASC.Api.DocumentConverter;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Web;
|
||||
using System.Web.Script.Serialization;
|
||||
using System.Web.Services;
|
||||
using System.Web.Configuration;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace OnlineEditorsExample
|
||||
{
|
||||
@ -40,6 +37,9 @@ namespace OnlineEditorsExample
|
||||
case "upload":
|
||||
Upload(context);
|
||||
break;
|
||||
case "download":
|
||||
Download(context);
|
||||
break;
|
||||
case "convert":
|
||||
Convert(context);
|
||||
break;
|
||||
@ -49,8 +49,8 @@ namespace OnlineEditorsExample
|
||||
case "remove":
|
||||
Remove(context);
|
||||
break;
|
||||
case "download":
|
||||
Download(context);
|
||||
case "assets":
|
||||
Assets(context);
|
||||
break;
|
||||
case "csv":
|
||||
GetCsv(context);
|
||||
@ -94,126 +94,68 @@ namespace OnlineEditorsExample
|
||||
MustSave = 2,
|
||||
Corrupted = 3,
|
||||
Closed = 4,
|
||||
MustForceSave = 6,
|
||||
CorruptedForceSave = 7
|
||||
}
|
||||
|
||||
private static void Track(HttpContext context)
|
||||
{
|
||||
var fileData = TrackManager.readBody(context);
|
||||
|
||||
var userAddress = context.Request["userAddress"];
|
||||
var fileName = Path.GetFileName(context.Request["fileName"]);
|
||||
|
||||
string body;
|
||||
try
|
||||
{
|
||||
using (var receiveStream = context.Request.InputStream)
|
||||
using (var readStream = new StreamReader(receiveStream))
|
||||
{
|
||||
body = readStream.ReadToEnd();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new HttpException((int) HttpStatusCode.BadRequest, e.Message);
|
||||
}
|
||||
|
||||
var jss = new JavaScriptSerializer();
|
||||
if (string.IsNullOrEmpty(body)) return;
|
||||
var fileData = jss.Deserialize<Dictionary<string, object>>(body);
|
||||
|
||||
if (JwtManager.Enabled)
|
||||
{
|
||||
string JWTheader = WebConfigurationManager.AppSettings["files.docservice.header"].Equals("") ? "Authorization" : WebConfigurationManager.AppSettings["files.docservice.header"];
|
||||
|
||||
string token = null;
|
||||
|
||||
if (fileData.ContainsKey("token"))
|
||||
{
|
||||
token = JwtManager.Decode(fileData["token"].ToString());
|
||||
}
|
||||
else if (context.Request.Headers.AllKeys.Contains(JWTheader, StringComparer.InvariantCultureIgnoreCase))
|
||||
{
|
||||
var headerToken = context.Request.Headers.Get(JWTheader).Substring("Bearer ".Length);
|
||||
token = JwtManager.Decode(headerToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Response.Write("{\"error\":1,\"message\":\"JWT expected\"}");
|
||||
}
|
||||
|
||||
if (token != null && !token.Equals(""))
|
||||
{
|
||||
fileData = (Dictionary<string, object>)jss.Deserialize<Dictionary<string, object>>(token)["payload"];
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Response.Write("{\"error\":1,\"message\":\"JWT validation failed\"}");
|
||||
}
|
||||
}
|
||||
|
||||
var status = (TrackerStatus) (int) fileData["status"];
|
||||
|
||||
var saved = 1;
|
||||
switch (status)
|
||||
{
|
||||
case TrackerStatus.MustSave:
|
||||
case TrackerStatus.Corrupted:
|
||||
var downloadUri = (string) fileData["url"];
|
||||
|
||||
var curExt = Path.GetExtension(fileName);
|
||||
var downloadExt = Path.GetExtension(downloadUri) ?? "";
|
||||
if (!downloadExt.Equals(curExt, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
var key = ServiceConverter.GenerateRevisionId(downloadUri);
|
||||
|
||||
try
|
||||
{
|
||||
string newFileUri;
|
||||
ServiceConverter.GetConvertedUri(downloadUri, downloadExt, curExt, key, false, out newFileUri);
|
||||
downloadUri = newFileUri;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
fileName = _Default.GetCorrectName(Path.GetFileNameWithoutExtension(fileName) + downloadExt, userAddress);
|
||||
}
|
||||
}
|
||||
|
||||
// hack. http://ubuntuforums.org/showthread.php?t=1841740
|
||||
if (_Default.IsMono)
|
||||
{
|
||||
ServicePointManager.ServerCertificateValidationCallback += (s, ce, ca, p) => true;
|
||||
}
|
||||
|
||||
var saved = 1;
|
||||
case TrackerStatus.Editing:
|
||||
try
|
||||
{
|
||||
var storagePath = _Default.StoragePath(fileName, userAddress);
|
||||
var histDir = _Default.HistoryDir(storagePath);
|
||||
var versionDir = _Default.VersionDir(histDir, _Default.GetFileVersion(histDir));
|
||||
|
||||
if (!Directory.Exists(versionDir)) Directory.CreateDirectory(versionDir);
|
||||
|
||||
File.Copy(storagePath, Path.Combine(versionDir, "prev" + curExt));
|
||||
|
||||
DownloadToFile(downloadUri, _Default.StoragePath(fileName, userAddress));
|
||||
DownloadToFile((string)fileData["changesurl"], Path.Combine(versionDir, "diff.zip"));
|
||||
|
||||
var hist = fileData.ContainsKey("changeshistory") ? (string)fileData["changeshistory"] : null;
|
||||
if (string.IsNullOrEmpty(hist) && fileData.ContainsKey("history"))
|
||||
var jss = new JavaScriptSerializer();
|
||||
var actions = jss.Deserialize<List<object>>(jss.Serialize(fileData["actions"]));
|
||||
var action = jss.Deserialize<Dictionary<string, object>>(jss.Serialize(actions[0]));
|
||||
if (action != null && action["type"].ToString().Equals("0"))
|
||||
{
|
||||
hist = jss.Serialize(fileData["history"]);
|
||||
}
|
||||
var user = action["userid"].ToString();
|
||||
var users = jss.Deserialize<List<object>>(jss.Serialize(fileData["users"]));
|
||||
if (!users.Contains(user))
|
||||
{
|
||||
TrackManager.commandRequest("forcesave", fileData["key"].ToString());
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(hist))
|
||||
{
|
||||
File.WriteAllText(Path.Combine(versionDir, "changes.json"), hist);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Print(e.StackTrace);
|
||||
}
|
||||
break;
|
||||
|
||||
File.WriteAllText(Path.Combine(versionDir, "key.txt"), (string)fileData["key"]);
|
||||
case TrackerStatus.MustSave:
|
||||
case TrackerStatus.Corrupted:
|
||||
try
|
||||
{
|
||||
saved = TrackManager.processSave(fileData, fileName, userAddress);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
saved = 1;
|
||||
}
|
||||
context.Response.Write("{\"error\":" + saved + "}");
|
||||
return;
|
||||
|
||||
case TrackerStatus.MustForceSave:
|
||||
case TrackerStatus.CorruptedForceSave:
|
||||
try
|
||||
{
|
||||
saved = TrackManager.processForceSave(fileData, fileName, userAddress);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
saved = 0;
|
||||
saved = 1;
|
||||
}
|
||||
|
||||
break;
|
||||
context.Response.Write("{\"error\":" + saved + "}");
|
||||
return;
|
||||
}
|
||||
context.Response.Write("{\"error\":0}");
|
||||
}
|
||||
@ -272,51 +214,48 @@ namespace OnlineEditorsExample
|
||||
}
|
||||
}
|
||||
|
||||
private static void Download(HttpContext context)
|
||||
private static void Assets(HttpContext context)
|
||||
{
|
||||
var fileName = "sample/" + Path.GetFileName(context.Request["filename"]);
|
||||
download(fileName, context);
|
||||
var fileName = Path.GetFileName(context.Request["filename"]);
|
||||
var filePath = HttpRuntime.AppDomainAppPath + "assets/sample/" + fileName;
|
||||
download(filePath, context);
|
||||
}
|
||||
|
||||
private static void GetCsv(HttpContext context)
|
||||
{
|
||||
var fileName = "sample/" + "csv.csv";
|
||||
download(fileName, context);
|
||||
var fileName = "csv.csv";
|
||||
var filePath = HttpRuntime.AppDomainAppPath + "assets/sample/" + fileName;
|
||||
download(filePath, context);
|
||||
}
|
||||
|
||||
private static void download(string fileName, HttpContext context)
|
||||
private static void Download(HttpContext context)
|
||||
{
|
||||
var csvPath = HttpRuntime.AppDomainAppPath + "assets/" + fileName;
|
||||
FileInfo fileinf = new FileInfo(csvPath);
|
||||
try
|
||||
{
|
||||
var fileName = Path.GetFileName(context.Request["filename"]);
|
||||
|
||||
var filePath = _Default.ForcesavePath(fileName, null, false);
|
||||
if (filePath.Equals(""))
|
||||
{
|
||||
filePath = _Default.StoragePath(fileName, null);
|
||||
}
|
||||
download(filePath, context);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
context.Response.Write("{ \"error\": \"File not found!\"}");
|
||||
}
|
||||
}
|
||||
|
||||
private static void download(string filePath, HttpContext context)
|
||||
{
|
||||
FileInfo fileinf = new FileInfo(filePath);
|
||||
context.Response.AddHeader("Content-Length", "" + fileinf.Length);
|
||||
context.Response.AddHeader("Content-Type", MimeMapping.GetMimeMapping(csvPath));
|
||||
var tmp = HttpUtility.UrlEncode(Path.GetFileName(csvPath));
|
||||
context.Response.AddHeader("Content-Type", MimeMapping.GetMimeMapping(filePath));
|
||||
var tmp = HttpUtility.UrlEncode(Path.GetFileName(filePath));
|
||||
tmp = tmp.Replace("+", "%20");
|
||||
context.Response.AddHeader("Content-Disposition", "attachment; filename*=UTF-8\'\'" + tmp);
|
||||
context.Response.TransmitFile(csvPath);
|
||||
}
|
||||
|
||||
private static void DownloadToFile(string url, string path)
|
||||
{
|
||||
if (string.IsNullOrEmpty(url)) throw new ArgumentException("url");
|
||||
if (string.IsNullOrEmpty(path)) throw new ArgumentException("path");
|
||||
|
||||
var req = (HttpWebRequest)WebRequest.Create(url);
|
||||
using (var stream = req.GetResponse().GetResponseStream())
|
||||
{
|
||||
if (stream == null) throw new Exception("stream is null");
|
||||
const int bufferSize = 4096;
|
||||
|
||||
using (var fs = File.Open(path, FileMode.Create))
|
||||
{
|
||||
var buffer = new byte[bufferSize];
|
||||
int readed;
|
||||
while ((readed = stream.Read(buffer, 0, bufferSize)) != 0)
|
||||
{
|
||||
fs.Write(buffer, 0, readed);
|
||||
}
|
||||
}
|
||||
}
|
||||
context.Response.TransmitFile(filePath);
|
||||
}
|
||||
|
||||
public bool IsReusable
|
||||
|
||||
@ -7,17 +7,18 @@
|
||||
|
||||
<add key="files.docservice.viewed-docs" value=".pdf|.djvu|.xps"/>
|
||||
<add key="files.docservice.edited-docs" value=".docx|.xlsx|.csv|.pptx|.txt"/>
|
||||
<add key="files.docservice.convert-docs" value=".docm|.dotx|.dotm|.dot|.doc|.odt|.fodt|.ott|.xlsm|.xltx|.xltm|.xlt|.xls|.ods|.fods|.ots|.pptm|.ppt|.ppsx|.ppsm|.pps|.potx|.potm|.pot|.odp|.fodp|.otp|.rtf|.mht|.html|.htm|.epub|.fb2"/>
|
||||
<add key="files.docservice.convert-docs" value=".docm|.dotx|.dotm|.dot|.doc|.odt|.fodt|.ott|.xlsm|.xltx|.xltm|.xlt|.xls|.ods|.fods|.ots|.pptm|.ppt|.ppsx|.ppsm|.pps|.potx|.potm|.pot|.odp|.fodp|.otp|.rtf|.mht|.html|.htm|.xml|.epub|.fb2"/>
|
||||
<add key="files.docservice.timeout" value="120000" />
|
||||
<add key="files.docservice.secret" value="" />
|
||||
<add key="files.docservice.header" value="Authorization" />
|
||||
|
||||
<add key="files.docservice.url.site" value="http://documentserver/"/>
|
||||
|
||||
<add key="files.docservice.url.site" value="https://documentserver/"/>
|
||||
|
||||
<add key="files.docservice.url.converter" value="ConvertService.ashx"/>
|
||||
<add key="files.docservice.url.api" value="web-apps/apps/api/documents/api.js"/>
|
||||
<add key="files.docservice.url.preloader" value="web-apps/apps/api/documents/cache-scripts.html"/>
|
||||
<add key="files.docservice.url.command" value="coauthoring/CommandService.ashx"/>
|
||||
|
||||
<add key="files.docservice.url.example" value=""/>
|
||||
|
||||
|
||||
</appSettings>
|
||||
@ -74,7 +74,7 @@ public class EditorServlet extends HttpServlet
|
||||
|
||||
Map<String, Object> dataCompareFile = new HashMap<>();
|
||||
dataCompareFile.put("fileType", "docx");
|
||||
dataCompareFile.put("url", DocumentManager.GetServerUrl(true) + "/IndexServlet?type=download&name=sample.docx");
|
||||
dataCompareFile.put("url", DocumentManager.GetServerUrl(true) + "/IndexServlet?type=assets&name=sample.docx");
|
||||
|
||||
Map<String, Object> dataMailMergeRecipients = new HashMap<>();
|
||||
dataMailMergeRecipients.put("fileType", "csv");
|
||||
|
||||
@ -19,10 +19,7 @@
|
||||
package controllers;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import helpers.ConfigManager;
|
||||
import helpers.CookieManager;
|
||||
import helpers.DocumentManager;
|
||||
import helpers.ServiceConverter;
|
||||
import helpers.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URISyntaxException;
|
||||
@ -39,7 +36,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.Part;
|
||||
import entities.FileType;
|
||||
import helpers.FileUtility;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
|
||||
@ -49,8 +46,6 @@ import org.primeframework.jwt.domain.JWT;
|
||||
@MultipartConfig
|
||||
public class IndexServlet extends HttpServlet
|
||||
{
|
||||
private static final String DocumentJwtHeader = ConfigManager.GetProperty("files.docservice.header");
|
||||
|
||||
protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||
{
|
||||
String action = request.getParameter("type");
|
||||
@ -69,6 +64,8 @@ public class IndexServlet extends HttpServlet
|
||||
case "upload":
|
||||
Upload(request, response, writer);
|
||||
break;
|
||||
case "download":
|
||||
Download(request, response, writer);
|
||||
case "convert":
|
||||
Convert(request, response, writer);
|
||||
break;
|
||||
@ -78,8 +75,8 @@ public class IndexServlet extends HttpServlet
|
||||
case "remove":
|
||||
Remove(request, response, writer);
|
||||
break;
|
||||
case "download":
|
||||
Download(request, response, writer);
|
||||
case "assets":
|
||||
Assets(request, response, writer);
|
||||
break;
|
||||
case "csv":
|
||||
CSV(request, response, writer);
|
||||
@ -124,7 +121,7 @@ public class IndexServlet extends HttpServlet
|
||||
|
||||
InputStream fileStream = httpPostedFile.getInputStream();
|
||||
|
||||
fileName = DocumentManager.GetCorrectName(fileName);
|
||||
fileName = DocumentManager.GetCorrectName(fileName, null);
|
||||
String fileStoragePath = DocumentManager.StoragePath(fileName, null);
|
||||
|
||||
File file = new File(fileStoragePath);
|
||||
@ -142,7 +139,7 @@ public class IndexServlet extends HttpServlet
|
||||
}
|
||||
|
||||
CookieManager cm = new CookieManager(request);
|
||||
DocumentManager.CreateMeta(fileName, cm.getCookie("uid"), cm.getCookie("uname"));
|
||||
DocumentManager.CreateMeta(fileName, cm.getCookie("uid"), cm.getCookie("uname"), null);
|
||||
|
||||
writer.write("{ \"filename\": \"" + fileName + "\"}");
|
||||
|
||||
@ -177,7 +174,7 @@ public class IndexServlet extends HttpServlet
|
||||
return;
|
||||
}
|
||||
|
||||
String correctName = DocumentManager.GetCorrectName(FileUtility.GetFileNameWithoutExtension(fileName) + internalFileExt);
|
||||
String correctName = DocumentManager.GetCorrectName(FileUtility.GetFileNameWithoutExtension(fileName) + internalFileExt, null);
|
||||
|
||||
URL url = new URL(newFileUri);
|
||||
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
|
||||
@ -210,7 +207,7 @@ public class IndexServlet extends HttpServlet
|
||||
fileName = correctName;
|
||||
|
||||
CookieManager cm = new CookieManager(request);
|
||||
DocumentManager.CreateMeta(fileName, cm.getCookie("uid"), cm.getCookie("uname"));
|
||||
DocumentManager.CreateMeta(fileName, cm.getCookie("uid"), cm.getCookie("uname"), null);
|
||||
}
|
||||
|
||||
writer.write("{ \"filename\" : \"" + fileName + "\"}");
|
||||
@ -224,132 +221,53 @@ public class IndexServlet extends HttpServlet
|
||||
|
||||
private static void Track(HttpServletRequest request, HttpServletResponse response, PrintWriter writer)
|
||||
{
|
||||
JSONObject body = null;
|
||||
|
||||
try {
|
||||
body = TrackManager.readBody(request, writer);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
int status = Math.toIntExact((long) body.get("status"));
|
||||
int saved = 0;
|
||||
|
||||
if (status == 1) { //Editing
|
||||
JSONArray actions = (JSONArray) body.get("actions");
|
||||
JSONArray users = (JSONArray) body.get("users");
|
||||
JSONObject action = (JSONObject) actions.get(0);
|
||||
if (actions != null && action.get("type").toString().equals("0")) { //finished edit
|
||||
String user = (String) action.get("userid");
|
||||
if (users.indexOf(user) == -1) {
|
||||
String key = (String) body.get("key");
|
||||
try {
|
||||
TrackManager.commandRequest("forcesave", key);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String userAddress = request.getParameter("userAddress");
|
||||
String fileName = FileUtility.GetFileName(request.getParameter("fileName"));
|
||||
|
||||
String storagePath = DocumentManager.StoragePath(fileName, userAddress);
|
||||
String body = "";
|
||||
|
||||
try
|
||||
{
|
||||
Scanner scanner = new Scanner(request.getInputStream());
|
||||
scanner.useDelimiter("\\A");
|
||||
body = scanner.hasNext() ? scanner.next() : "";
|
||||
scanner.close();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
writer.write("get request.getInputStream error:" + ex.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
if (body.isEmpty())
|
||||
{
|
||||
writer.write("empty request.getInputStream");
|
||||
return;
|
||||
}
|
||||
|
||||
JSONParser parser = new JSONParser();
|
||||
JSONObject jsonObj;
|
||||
|
||||
try
|
||||
{
|
||||
Object obj = parser.parse(body);
|
||||
jsonObj = (JSONObject) obj;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
writer.write("JSONParser.parse error:" + ex.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
int status;
|
||||
String downloadUri;
|
||||
String changesUri;
|
||||
String key;
|
||||
|
||||
if (DocumentManager.TokenEnabled())
|
||||
{
|
||||
String token = (String) jsonObj.get("token");
|
||||
|
||||
if (token == null) {
|
||||
String header = (String) request.getHeader(DocumentJwtHeader == null || DocumentJwtHeader.isEmpty() ? "Authorization" : DocumentJwtHeader);
|
||||
if (header != null && !header.isEmpty()) {
|
||||
token = header.startsWith("Bearer ") ? header.substring(7) : header;
|
||||
}
|
||||
if (status == 2 || status == 3) { //MustSave, Corrupted
|
||||
try {
|
||||
TrackManager.processSave(body, fileName, userAddress);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
saved = 1;
|
||||
}
|
||||
|
||||
if (token == null || token.isEmpty()) {
|
||||
writer.write("{\"error\":1,\"message\":\"JWT expected\"}");
|
||||
return;
|
||||
}
|
||||
|
||||
JWT jwt = DocumentManager.ReadToken(token);
|
||||
if (jwt == null)
|
||||
{
|
||||
writer.write("{\"error\":1,\"message\":\"JWT validation failed\"}");
|
||||
return;
|
||||
}
|
||||
|
||||
if (jwt.getObject("payload") != null) {
|
||||
try {
|
||||
@SuppressWarnings("unchecked") LinkedHashMap<String, Object> payload =
|
||||
(LinkedHashMap<String, Object>)jwt.getObject("payload");
|
||||
|
||||
jwt.claims = payload;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
writer.write("{\"error\":1,\"message\":\"Wrong payload\"}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
status = jwt.getInteger("status");
|
||||
downloadUri = jwt.getString("url");
|
||||
changesUri = jwt.getString("changesurl");
|
||||
key = jwt.getString("key");
|
||||
}
|
||||
else
|
||||
{
|
||||
status = Math.toIntExact((long) jsonObj.get("status"));
|
||||
downloadUri = (String) jsonObj.get("url");
|
||||
changesUri = (String) jsonObj.get("changesurl");
|
||||
key = (String) jsonObj.get("key");
|
||||
}
|
||||
|
||||
int saved = 0;
|
||||
if (status == 2 || status == 3)//MustSave, Corrupted
|
||||
{
|
||||
try
|
||||
{
|
||||
String histDir = DocumentManager.HistoryDir(storagePath);
|
||||
String versionDir = DocumentManager.VersionDir(histDir, DocumentManager.GetFileVersion(histDir));
|
||||
File ver = new File(versionDir);
|
||||
File toSave = new File(storagePath);
|
||||
|
||||
if (!ver.exists()) ver.mkdirs();
|
||||
|
||||
toSave.renameTo(new File(versionDir + File.separator + "prev" + FileUtility.GetFileExtension(fileName)));
|
||||
|
||||
downloadToFile(downloadUri, toSave);
|
||||
downloadToFile(changesUri, new File(versionDir + File.separator + "diff.zip"));
|
||||
|
||||
String history = (String) jsonObj.get("changeshistory");
|
||||
if (history == null && jsonObj.containsKey("history")) {
|
||||
history = ((JSONObject) jsonObj.get("history")).toJSONString();
|
||||
}
|
||||
if (history != null && !history.isEmpty()) {
|
||||
FileWriter fw = new FileWriter(new File(versionDir + File.separator + "changes.json"));
|
||||
fw.write(history);
|
||||
fw.close();
|
||||
}
|
||||
|
||||
FileWriter fw = new FileWriter(new File(versionDir + File.separator + "key.txt"));
|
||||
fw.write(key);
|
||||
fw.close();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (status == 6 || status == 7) { //MustForceSave, CorruptedForceSave
|
||||
try {
|
||||
TrackManager.processForceSave(body, fileName, userAddress);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
saved = 1;
|
||||
}
|
||||
}
|
||||
@ -408,13 +326,41 @@ public class IndexServlet extends HttpServlet
|
||||
private static void CSV(HttpServletRequest request, HttpServletResponse response, PrintWriter writer)
|
||||
{
|
||||
String fileName = "assets/sample/csv.csv";
|
||||
download(fileName, response, writer);
|
||||
URL fileUrl = Thread.currentThread().getContextClassLoader().getResource(fileName);
|
||||
Path filePath = null;
|
||||
try {
|
||||
filePath = Paths.get(fileUrl.toURI());
|
||||
} catch (URISyntaxException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
download(filePath.toString(), response, writer);
|
||||
}
|
||||
|
||||
private static void Assets(HttpServletRequest request, HttpServletResponse response, PrintWriter writer)
|
||||
{
|
||||
String fileName = "assets/sample/" + FileUtility.GetFileName(request.getParameter("name"));
|
||||
URL fileUrl = Thread.currentThread().getContextClassLoader().getResource(fileName);
|
||||
Path filePath = null;
|
||||
try {
|
||||
filePath = Paths.get(fileUrl.toURI());
|
||||
} catch (URISyntaxException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
download(filePath.toString(), response, writer);
|
||||
}
|
||||
|
||||
private static void Download(HttpServletRequest request, HttpServletResponse response, PrintWriter writer)
|
||||
{
|
||||
String fileName = "assets/sample/" + FileUtility.GetFileName(request.getParameter("name"));
|
||||
download(fileName, response, writer);
|
||||
try {
|
||||
String fileName = FileUtility.GetFileName(request.getParameter("name"));
|
||||
String filePath = DocumentManager.ForcesavePath(fileName, null, false);
|
||||
if (filePath.equals("")) {
|
||||
filePath = DocumentManager.StoragePath(fileName, null);
|
||||
}
|
||||
download(filePath, response, writer);
|
||||
} catch (Exception e) {
|
||||
writer.write("{ \"error\": \"File not found\"}");
|
||||
}
|
||||
}
|
||||
|
||||
private static void delete(File f) throws Exception {
|
||||
@ -426,18 +372,15 @@ public class IndexServlet extends HttpServlet
|
||||
throw new Exception("Failed to delete file: " + f);
|
||||
}
|
||||
|
||||
private static void download(String fileName, HttpServletResponse response, PrintWriter writer) {
|
||||
URL fileUrl = Thread.currentThread().getContextClassLoader().getResource(fileName);
|
||||
Path filePath = null;
|
||||
private static void download(String filePath, HttpServletResponse response, PrintWriter writer) {
|
||||
String fileType = null;
|
||||
try {
|
||||
filePath = Paths.get(fileUrl.toURI());
|
||||
fileType = Files.probeContentType(filePath);
|
||||
} catch (URISyntaxException | IOException e) {
|
||||
fileType = Files.probeContentType(Paths.get(filePath));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
File file = new File(String.valueOf(filePath));
|
||||
File file = new File(filePath);
|
||||
|
||||
response.setHeader("Content-Length", String.valueOf(file.length()));
|
||||
response.setHeader("Content-Type", fileType);
|
||||
@ -461,34 +404,6 @@ public class IndexServlet extends HttpServlet
|
||||
}
|
||||
}
|
||||
|
||||
private static void downloadToFile(String url, File file) throws Exception {
|
||||
if (url == null || url.isEmpty()) throw new Exception("argument url");
|
||||
if (file == null) throw new Exception("argument path");
|
||||
|
||||
URL uri = new URL(url);
|
||||
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) uri.openConnection();
|
||||
InputStream stream = connection.getInputStream();
|
||||
|
||||
if (stream == null)
|
||||
{
|
||||
throw new Exception("Stream is null");
|
||||
}
|
||||
|
||||
try (FileOutputStream out = new FileOutputStream(file))
|
||||
{
|
||||
int read;
|
||||
final byte[] bytes = new byte[1024];
|
||||
while ((read = stream.read(bytes)) != -1)
|
||||
{
|
||||
out.write(bytes, 0, read);
|
||||
}
|
||||
|
||||
out.flush();
|
||||
}
|
||||
|
||||
connection.disconnect();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||
{
|
||||
|
||||
@ -62,7 +62,9 @@ public class FileModel
|
||||
if (lang != null) editorConfig.lang = lang;
|
||||
|
||||
if (uid != null) editorConfig.user.id = uid;
|
||||
if (uname != null) editorConfig.user.name = uname;
|
||||
if (uname != null) editorConfig.user.name = uid.equals("uid-0") ? null : uname;
|
||||
if (editorConfig.user.id.equals("uid-2")) editorConfig.user.group = "group-2";
|
||||
if (editorConfig.user.id.equals("uid-3")) editorConfig.user.group = "group-3";
|
||||
|
||||
editorConfig.customization.goback.url = DocumentManager.GetServerUrl(false) + "/IndexServlet";
|
||||
|
||||
@ -75,7 +77,7 @@ public class FileModel
|
||||
if (_type != null) type = _type;
|
||||
|
||||
Boolean canEdit = DocumentManager.GetEditedExts().contains(FileUtility.GetFileExtension(document.title));
|
||||
|
||||
editorConfig.customization.submitForm = canEdit && (mode.equals("edit") || mode.equals("fillForms"));
|
||||
editorConfig.mode = canEdit && !mode.equals("view") ? "edit" : "view";
|
||||
|
||||
document.permissions = new Permissions(mode, type, canEdit);
|
||||
@ -211,6 +213,7 @@ public class FileModel
|
||||
public Boolean modifyFilter;
|
||||
public Boolean modifyContentControl;
|
||||
public Boolean review;
|
||||
public List<String> reviewGroups;
|
||||
|
||||
public Permissions(String mode, String type, Boolean canEdit)
|
||||
{
|
||||
@ -221,6 +224,16 @@ public class FileModel
|
||||
modifyFilter = !mode.equals("filter");
|
||||
modifyContentControl = !mode.equals("blockcontent");
|
||||
review = mode.equals("edit") || mode.equals("review");
|
||||
reviewGroups = editorConfig.user.group != null ? GetReviewGroups(editorConfig.user.group) : null;
|
||||
}
|
||||
|
||||
private List<String> GetReviewGroups(String group){
|
||||
Map<String, List<String>> reviewGroups = new HashMap<>();
|
||||
|
||||
reviewGroups.put("group-2", Arrays.asList("group-2", ""));
|
||||
reviewGroups.put("group-3", Arrays.asList("group-2"));
|
||||
|
||||
return reviewGroups.get(group);
|
||||
}
|
||||
}
|
||||
|
||||
@ -262,14 +275,18 @@ public class FileModel
|
||||
{
|
||||
public String id = "uid-1";
|
||||
public String name = "John Smith";
|
||||
public String group = null;
|
||||
}
|
||||
|
||||
public class Customization
|
||||
{
|
||||
public Goback goback;
|
||||
public Boolean forcesave;
|
||||
public Boolean submitForm;
|
||||
|
||||
public Customization()
|
||||
{
|
||||
forcesave = false;
|
||||
goback = new Goback();
|
||||
}
|
||||
|
||||
|
||||
@ -135,6 +135,32 @@ public class DocumentManager
|
||||
return directory + FileUtility.GetFileName(fileName);
|
||||
}
|
||||
|
||||
public static String ForcesavePath(String fileName, String userAddress, Boolean create)
|
||||
{
|
||||
String hostAddress = CurUserHostAddress(userAddress);
|
||||
String serverPath = request.getSession().getServletContext().getRealPath("");
|
||||
String storagePath = ConfigManager.GetProperty("storage-folder");
|
||||
|
||||
String directory = serverPath + storagePath + File.separator + hostAddress + File.separator;
|
||||
|
||||
File file = new File(directory);
|
||||
if (!file.exists()) return "";
|
||||
|
||||
directory = directory + fileName + "-hist" + File.separator;
|
||||
file = new File(directory);
|
||||
if (!create && !file.exists()) return "";
|
||||
|
||||
file.mkdirs();
|
||||
|
||||
directory = directory + fileName;
|
||||
file = new File(directory);
|
||||
if (!create && !file.exists()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return directory;
|
||||
}
|
||||
|
||||
public static String HistoryDir(String storagePath)
|
||||
{
|
||||
return storagePath += "-hist";
|
||||
@ -171,26 +197,26 @@ public class DocumentManager
|
||||
return GetFileVersion(HistoryDir(StoragePath(fileName, userAddress)));
|
||||
}
|
||||
|
||||
public static String GetCorrectName(String fileName)
|
||||
public static String GetCorrectName(String fileName, String userAddress)
|
||||
{
|
||||
String baseName = FileUtility.GetFileNameWithoutExtension(fileName);
|
||||
String ext = FileUtility.GetFileExtension(fileName);
|
||||
String name = baseName + ext;
|
||||
|
||||
File file = new File(StoragePath(name, null));
|
||||
File file = new File(StoragePath(name, userAddress));
|
||||
|
||||
for (int i = 1; file.exists(); i++)
|
||||
{
|
||||
name = baseName + " (" + i + ")" + ext;
|
||||
file = new File(StoragePath(name, null));
|
||||
file = new File(StoragePath(name, userAddress));
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
public static void CreateMeta(String fileName, String uid, String uname) throws Exception
|
||||
public static void CreateMeta(String fileName, String uid, String uname, String userAddress) throws Exception
|
||||
{
|
||||
String histDir = HistoryDir(StoragePath(fileName, null));
|
||||
String histDir = HistoryDir(StoragePath(fileName, userAddress));
|
||||
|
||||
File dir = new File(histDir);
|
||||
dir.mkdir();
|
||||
@ -223,7 +249,7 @@ public class DocumentManager
|
||||
{
|
||||
String demoName = (sample ? "sample." : "new.") + fileExt;
|
||||
String demoPath = "assets" + File.separator + (sample ? "sample" : "new") + File.separator;
|
||||
String fileName = GetCorrectName(demoName);
|
||||
String fileName = GetCorrectName(demoName, null);
|
||||
|
||||
InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream(demoPath + demoName);
|
||||
|
||||
@ -240,7 +266,7 @@ public class DocumentManager
|
||||
out.flush();
|
||||
}
|
||||
|
||||
CreateMeta(fileName, uid, uname);
|
||||
CreateMeta(fileName, uid, uname, null);
|
||||
|
||||
return fileName;
|
||||
}
|
||||
|
||||
@ -50,7 +50,7 @@ public class FileUtility
|
||||
".doc", ".docx", ".docm",
|
||||
".dot", ".dotx", ".dotm",
|
||||
".odt", ".fodt", ".ott", ".rtf", ".txt",
|
||||
".html", ".htm", ".mht",
|
||||
".html", ".htm", ".mht", ".xml",
|
||||
".pdf", ".djvu", ".fb2", ".epub", ".xps"
|
||||
);
|
||||
|
||||
|
||||
@ -223,7 +223,7 @@ public class ServiceConverter
|
||||
return resultPercent >= 100l ? responseUri : "";
|
||||
}
|
||||
|
||||
private static String ConvertStreamToString(InputStream stream) throws IOException
|
||||
public static String ConvertStreamToString(InputStream stream) throws IOException
|
||||
{
|
||||
InputStreamReader inputStreamReader = new InputStreamReader(stream);
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
@ -241,7 +241,7 @@ public class ServiceConverter
|
||||
return result;
|
||||
}
|
||||
|
||||
private static JSONObject ConvertStringToJSON(String jsonString) throws ParseException
|
||||
public static JSONObject ConvertStringToJSON(String jsonString) throws ParseException
|
||||
{
|
||||
JSONParser parser = new JSONParser();
|
||||
Object obj = parser.parse(jsonString);
|
||||
|
||||
@ -0,0 +1,299 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2020
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package helpers;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
import org.primeframework.jwt.domain.JWT;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class TrackManager {
|
||||
private static final String DocumentJwtHeader = ConfigManager.GetProperty("files.docservice.header");
|
||||
|
||||
public static JSONObject readBody(HttpServletRequest request, PrintWriter writer) throws Exception {
|
||||
String bodyString = "";
|
||||
|
||||
try {
|
||||
Scanner scanner = new Scanner(request.getInputStream());
|
||||
scanner.useDelimiter("\\A");
|
||||
bodyString = scanner.hasNext() ? scanner.next() : "";
|
||||
scanner.close();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
writer.write("get request.getInputStream error:" + ex.getMessage());
|
||||
throw ex;
|
||||
}
|
||||
|
||||
if (bodyString.isEmpty()) {
|
||||
writer.write("empty request.getInputStream");
|
||||
throw new Exception("empty request.getInputStream");
|
||||
}
|
||||
|
||||
JSONParser parser = new JSONParser();
|
||||
JSONObject body;
|
||||
|
||||
try {
|
||||
Object obj = parser.parse(bodyString);
|
||||
body = (JSONObject) obj;
|
||||
} catch (Exception ex) {
|
||||
writer.write("JSONParser.parse error:" + ex.getMessage());
|
||||
throw ex;
|
||||
}
|
||||
|
||||
if (DocumentManager.TokenEnabled()) {
|
||||
String token = (String) body.get("token");
|
||||
|
||||
if (token == null) {
|
||||
String header = (String) request.getHeader(DocumentJwtHeader == null || DocumentJwtHeader.isEmpty() ? "Authorization" : DocumentJwtHeader);
|
||||
if (header != null && !header.isEmpty()) {
|
||||
token = header.startsWith("Bearer ") ? header.substring(7) : header;
|
||||
}
|
||||
}
|
||||
|
||||
if (token == null || token.isEmpty()) {
|
||||
writer.write("{\"error\":1,\"message\":\"JWT expected\"}");
|
||||
throw new Exception("{\"error\":1,\"message\":\"JWT expected\"}");
|
||||
}
|
||||
|
||||
JWT jwt = DocumentManager.ReadToken(token);
|
||||
if (jwt == null) {
|
||||
writer.write("{\"error\":1,\"message\":\"JWT validation failed\"}");
|
||||
throw new Exception("{\"error\":1,\"message\":\"JWT validation failed\"}");
|
||||
}
|
||||
|
||||
if (jwt.getObject("payload") != null) {
|
||||
try {
|
||||
@SuppressWarnings("unchecked") LinkedHashMap<String, Object> payload =
|
||||
(LinkedHashMap<String, Object>)jwt.getObject("payload");
|
||||
|
||||
jwt.claims = payload;
|
||||
} catch (Exception ex) {
|
||||
writer.write("{\"error\":1,\"message\":\"Wrong payload\"}");
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
Gson gson = new Gson();
|
||||
Object obj = parser.parse(gson.toJson(jwt.claims));
|
||||
body = (JSONObject) obj;
|
||||
} catch (Exception ex) {
|
||||
writer.write("JSONParser.parse error:" + ex.getMessage());
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
public static void processSave(JSONObject body, String fileName, String userAddress) throws Exception {
|
||||
String downloadUri = (String) body.get("url");
|
||||
String changesUri = (String) body.get("changesurl");
|
||||
String key = (String) body.get("key");
|
||||
String newFileName = fileName;
|
||||
|
||||
String curExt = FileUtility.GetFileExtension(fileName);
|
||||
String downloadExt = FileUtility.GetFileExtension(downloadUri);
|
||||
|
||||
if (!curExt.equals(downloadExt)) {
|
||||
try {
|
||||
String newFileUri = ServiceConverter.GetConvertedUri(downloadUri, downloadExt, curExt, ServiceConverter.GenerateRevisionId(downloadUri), false);
|
||||
if (newFileUri.isEmpty()) {
|
||||
newFileName = DocumentManager.GetCorrectName(FileUtility.GetFileNameWithoutExtension(fileName) + downloadExt, userAddress);
|
||||
} else {
|
||||
downloadUri = newFileUri;
|
||||
}
|
||||
} catch (Exception e){
|
||||
newFileName = DocumentManager.GetCorrectName(FileUtility.GetFileNameWithoutExtension(fileName) + downloadExt, userAddress);
|
||||
}
|
||||
}
|
||||
|
||||
String storagePath = DocumentManager.StoragePath(newFileName, userAddress);
|
||||
File histDir = new File(DocumentManager.HistoryDir(storagePath));
|
||||
if (!histDir.exists()) histDir.mkdirs();
|
||||
|
||||
String versionDir = DocumentManager.VersionDir(histDir.getAbsolutePath(), DocumentManager.GetFileVersion(histDir.getAbsolutePath()));
|
||||
File ver = new File(versionDir);
|
||||
File lastVersion = new File(DocumentManager.StoragePath(fileName, userAddress));
|
||||
File toSave = new File(storagePath);
|
||||
|
||||
if (!ver.exists()) ver.mkdirs();
|
||||
|
||||
lastVersion.renameTo(new File(versionDir + File.separator + "prev" + curExt));
|
||||
|
||||
downloadToFile(downloadUri, toSave);
|
||||
downloadToFile(changesUri, new File(versionDir + File.separator + "diff.zip"));
|
||||
|
||||
String history = (String) body.get("changeshistory");
|
||||
if (history == null && body.containsKey("history")) {
|
||||
history = ((JSONObject) body.get("history")).toJSONString();
|
||||
}
|
||||
if (history != null && !history.isEmpty()) {
|
||||
FileWriter fw = new FileWriter(new File(versionDir + File.separator + "changes.json"));
|
||||
fw.write(history);
|
||||
fw.close();
|
||||
}
|
||||
|
||||
FileWriter fw = new FileWriter(new File(versionDir + File.separator + "key.txt"));
|
||||
fw.write(key);
|
||||
fw.close();
|
||||
|
||||
String forcesavePath = DocumentManager.ForcesavePath(newFileName, userAddress, false);
|
||||
if (!forcesavePath.equals("")) {
|
||||
File forceSaveFile = new File(forcesavePath);
|
||||
forceSaveFile.delete();
|
||||
}
|
||||
}
|
||||
|
||||
public static void processForceSave(JSONObject body, String fileName, String userAddress) throws Exception {
|
||||
|
||||
String downloadUri = (String) body.get("url");
|
||||
|
||||
String curExt = FileUtility.GetFileExtension(fileName);
|
||||
String downloadExt = FileUtility.GetFileExtension(downloadUri);
|
||||
String newFileName = fileName;
|
||||
|
||||
if (!curExt.equals(downloadExt)) {
|
||||
try {
|
||||
String newFileUri = ServiceConverter.GetConvertedUri(downloadUri, downloadExt, curExt, ServiceConverter.GenerateRevisionId(downloadUri), false);
|
||||
if (newFileUri.isEmpty()) {
|
||||
newFileName = DocumentManager.GetCorrectName(FileUtility.GetFileNameWithoutExtension(fileName) + downloadExt, userAddress);
|
||||
} else {
|
||||
downloadUri = newFileUri;
|
||||
}
|
||||
} catch (Exception e){
|
||||
newFileName = DocumentManager.GetCorrectName(FileUtility.GetFileNameWithoutExtension(fileName) + downloadExt, userAddress);
|
||||
}
|
||||
}
|
||||
|
||||
String forcesavePath = "";
|
||||
boolean isSubmitForm = body.get("forcesavetype").toString().equals("3");
|
||||
|
||||
if (isSubmitForm) {
|
||||
//new file
|
||||
if (newFileName.equals(fileName)){
|
||||
newFileName = DocumentManager.GetCorrectName(fileName, userAddress);
|
||||
}
|
||||
forcesavePath = DocumentManager.StoragePath(newFileName, userAddress);
|
||||
} else {
|
||||
forcesavePath = DocumentManager.ForcesavePath(newFileName, userAddress, false);
|
||||
if (forcesavePath == "") {
|
||||
forcesavePath = DocumentManager.ForcesavePath(newFileName, userAddress, true);
|
||||
}
|
||||
}
|
||||
|
||||
File toSave = new File(forcesavePath);
|
||||
downloadToFile(downloadUri, toSave);
|
||||
|
||||
if (isSubmitForm) {
|
||||
JSONArray actions = (JSONArray) body.get("actions");
|
||||
JSONObject action = (JSONObject) actions.get(0);
|
||||
String user = (String) action.get("userid");
|
||||
DocumentManager.CreateMeta(newFileName, user, "Filling Form", userAddress);
|
||||
}
|
||||
}
|
||||
|
||||
private static void downloadToFile(String url, File file) throws Exception {
|
||||
if (url == null || url.isEmpty()) throw new Exception("argument url");
|
||||
if (file == null) throw new Exception("argument path");
|
||||
|
||||
URL uri = new URL(url);
|
||||
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) uri.openConnection();
|
||||
InputStream stream = connection.getInputStream();
|
||||
|
||||
if (stream == null)
|
||||
{
|
||||
throw new Exception("Stream is null");
|
||||
}
|
||||
|
||||
try (FileOutputStream out = new FileOutputStream(file))
|
||||
{
|
||||
int read;
|
||||
final byte[] bytes = new byte[1024];
|
||||
while ((read = stream.read(bytes)) != -1)
|
||||
{
|
||||
out.write(bytes, 0, read);
|
||||
}
|
||||
|
||||
out.flush();
|
||||
}
|
||||
|
||||
connection.disconnect();
|
||||
}
|
||||
|
||||
public static void commandRequest(String method, String key) throws Exception {
|
||||
String DocumentCommandUrl = ConfigManager.GetProperty("files.docservice.url.site") + ConfigManager.GetProperty("files.docservice.url.command");
|
||||
|
||||
URL url = new URL(DocumentCommandUrl);
|
||||
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
|
||||
|
||||
HashMap<String, Object> params = new HashMap<String, Object>();
|
||||
params.put("c", method);
|
||||
params.put("key", key);
|
||||
|
||||
String headerToken = "";
|
||||
if (DocumentManager.TokenEnabled())
|
||||
{
|
||||
Map<String, Object> payloadMap = new HashMap<String, Object>();
|
||||
payloadMap.put("payload", params);
|
||||
headerToken = DocumentManager.CreateToken(payloadMap);
|
||||
|
||||
connection.setRequestProperty(DocumentJwtHeader.equals("") ? "Authorization" : DocumentJwtHeader, "Bearer " + headerToken);
|
||||
|
||||
String token = DocumentManager.CreateToken(params);
|
||||
params.put("token", token);
|
||||
}
|
||||
|
||||
Gson gson = new Gson();
|
||||
String bodyString = gson.toJson(params);
|
||||
|
||||
byte[] bodyByte = bodyString.getBytes(StandardCharsets.UTF_8);
|
||||
|
||||
connection.setRequestMethod("POST");
|
||||
connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
|
||||
connection.setDoOutput(true);
|
||||
|
||||
connection.connect();
|
||||
try (OutputStream os = connection.getOutputStream()) {
|
||||
os.write(bodyByte);
|
||||
}
|
||||
InputStream stream = connection.getInputStream();;
|
||||
|
||||
if (stream == null)
|
||||
throw new Exception("Could not get an answer");
|
||||
|
||||
String jsonString = ServiceConverter.ConvertStreamToString(stream);
|
||||
connection.disconnect();
|
||||
|
||||
JSONObject response = ServiceConverter.ConvertStringToJSON(jsonString);
|
||||
if (!response.get("error").toString().equals("0")){
|
||||
throw new Exception(response.toJSONString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3,11 +3,12 @@ storage-folder=app_data
|
||||
|
||||
files.docservice.viewed-docs=.pdf|.djvu|.xps
|
||||
files.docservice.edited-docs=.docx|.xlsx|.csv|.pptx|.txt
|
||||
files.docservice.convert-docs=.docm|.dotx|.dotm|.dot|.doc|.odt|.fodt|.ott|.xlsm|.xltx|.xltm|.xlt|.xls|.ods|.fods|.ots|.pptm|.ppt|.ppsx|.ppsm|.pps|.potx|.potm|.pot|.odp|.fodp|.otp|.rtf|.mht|.html|.htm|.epub|.fb2
|
||||
files.docservice.convert-docs=.docm|.dotx|.dotm|.dot|.doc|.odt|.fodt|.ott|.xlsm|.xltx|.xltm|.xlt|.xls|.ods|.fods|.ots|.pptm|.ppt|.ppsx|.ppsm|.pps|.potx|.potm|.pot|.odp|.fodp|.otp|.rtf|.mht|.html|.htm|.xml|.epub|.fb2
|
||||
files.docservice.timeout=120000
|
||||
|
||||
files.docservice.url.site=https://documentserver/
|
||||
files.docservice.url.converter=ConvertService.ashx
|
||||
files.docservice.url.command=coauthoring/CommandService.ashx
|
||||
files.docservice.url.api=web-apps/apps/api/documents/api.js
|
||||
files.docservice.url.preloader=web-apps/apps/api/documents/cache-scripts.html
|
||||
files.docservice.url.example=
|
||||
|
||||
BIN
web/documentserver-example/java/src/main/webapp/css/img/cell.ico
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
|
After Width: | Height: | Size: 8.2 KiB |
BIN
web/documentserver-example/java/src/main/webapp/css/img/word.ico
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
@ -1,6 +1,8 @@
|
||||
<%@page import="entities.FileModel"%>
|
||||
<%@page contentType="text/html" pageEncoding="UTF-8"%>
|
||||
|
||||
<% FileModel Model = (FileModel) request.getAttribute("file"); %>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
@ -26,11 +28,9 @@
|
||||
*
|
||||
-->
|
||||
<title>ONLYOFFICE</title>
|
||||
<link rel="icon" href="favicon.ico" type="image/x-icon" />
|
||||
<link rel="icon" href="css/img/<%= Model.documentType %>.ico" type="image/x-icon" />
|
||||
<link rel="stylesheet" type="text/css" href="css/editor.css" />
|
||||
|
||||
<% FileModel Model = (FileModel) request.getAttribute("file"); %>
|
||||
|
||||
<script type="text/javascript" src="${docserviceApiUrl}"></script>
|
||||
|
||||
<script type="text/javascript" language="javascript">
|
||||
|
||||
@ -56,6 +56,7 @@
|
||||
<option value="uid-1">John Smith</option>
|
||||
<option value="uid-2">Mark Pottato</option>
|
||||
<option value="uid-3">Hamish Mitchell</option>
|
||||
<option value="uid-0">anonymous</option>
|
||||
</select>
|
||||
</td>
|
||||
<td width="70%" valign="middle">Select user name before opening the document; you can open the same document using different users in different Web browser sessions, so you can check out multi-user editing functions.</td>
|
||||
@ -156,7 +157,7 @@
|
||||
<a class="stored-edit <%= docType %>" href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8") %>" target="_blank">
|
||||
<span title="<%= files[i].getName() %>"><%= files[i].getName() %></span>
|
||||
</a>
|
||||
<a href="<%= DocumentManager.GetFileUri(files[i].getName(), false) %>">
|
||||
<a href="IndexServlet?type=download&name=<%=URLEncoder.encode(files[i].getName(), "UTF-8")%>">
|
||||
<img class="icon-download" src="css/img/download-24.png" alt="Download" title="Download" />
|
||||
</a>
|
||||
<a class="delete-file" data-filename="<%= files[i].getName() %>">
|
||||
|
||||
@ -65,7 +65,7 @@ function key(k) {
|
||||
};
|
||||
|
||||
var getDocumentType = function (ext) {
|
||||
if (".doc.docx.docm.dot.dotx.dotm.odt.fodt.ott.rtf.txt.html.htm.mht.pdf.djvu.fb2.epub.xps".indexOf(ext) != -1) return "text";
|
||||
if (".doc.docx.docm.dot.dotx.dotm.odt.fodt.ott.rtf.txt.html.htm.mht.xml.pdf.djvu.fb2.epub.xps".indexOf(ext) != -1) return "text";
|
||||
if (".xls.xlsx.xlsm.xlt.xltx.xltm.ods.fods.ots.csv".indexOf(ext) != -1) return "spreadsheet";
|
||||
if (".pps.ppsx.ppsm.ppt.pptx.pptm.pot.potx.potm.odp.fodp.otp".indexOf(ext) != -1) return "presentation";
|
||||
return null;
|
||||
|
||||
28
web/documentserver-example/nodejs/Dockerfile
Normal file
@ -0,0 +1,28 @@
|
||||
FROM node:buster
|
||||
LABEL maintainer Ascensio System SIA <support@onlyoffice.com>
|
||||
|
||||
ENV LANG=en_US.UTF-8 \
|
||||
LANGUAGE=en_US:en \
|
||||
LC_ALL=en_US.UTF-8 \
|
||||
NODE_ENV=production-linux \
|
||||
NODE_CONFIG_DIR=/etc/onlyoffice/documentserver-example/
|
||||
|
||||
WORKDIR /var/www/onlyoffice/documentserver-example/
|
||||
COPY . /var/www/onlyoffice/documentserver-example/
|
||||
|
||||
RUN groupadd --system --gid 1001 ds && \
|
||||
useradd --system -g ds --no-create-home --shell /sbin/nologin --uid 1001 ds && \
|
||||
chown -R ds:ds /var/www/onlyoffice/documentserver-example/ && \
|
||||
mkdir -p /var/lib/onlyoffice/documentserver-example/ && \
|
||||
chown -R ds:ds /var/lib/onlyoffice/ && \
|
||||
mv files /var/lib/onlyoffice/documentserver-example/ && \
|
||||
mkdir -p /etc/onlyoffice/documentserver-example/ && \
|
||||
chown -R ds:ds /etc/onlyoffice/ && \
|
||||
mv config/* /etc/onlyoffice/documentserver-example/ && \
|
||||
npm install
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
USER ds
|
||||
|
||||
ENTRYPOINT /var/www/onlyoffice/documentserver-example/docker-entrypoint.sh npm start
|
||||
@ -363,110 +363,155 @@ app.post("/track", function (req, res) {
|
||||
|
||||
var processTrack = function (response, body, fileName, userAddress) {
|
||||
|
||||
var processSave = function (downloadUri, body, fileName, userAddress, resp) {
|
||||
var curExt = fileUtility.getFileExtension(fileName);
|
||||
var downloadExt = fileUtility.getFileExtension(downloadUri);
|
||||
|
||||
if (downloadExt != curExt) {
|
||||
var key = documentService.generateRevisionId(downloadUri);
|
||||
|
||||
try {
|
||||
documentService.getConvertedUriSync(downloadUri, downloadExt, curExt, key, function (dUri) {
|
||||
processSave(dUri, body, fileName, userAddress, resp)
|
||||
});
|
||||
return;
|
||||
} catch (ex) {
|
||||
console.log(ex);
|
||||
fileName = docManager.getCorrectName(fileUtility.getFileName(fileName, true) + downloadExt, userAddress)
|
||||
}
|
||||
}
|
||||
|
||||
var callbackProcessSave = function (downloadUri, body, fileName, userAddress, newFileName) {
|
||||
try {
|
||||
var storagePath = docManager.storagePath(newFileName, userAddress);
|
||||
|
||||
var path = docManager.storagePath(fileName, userAddress);
|
||||
|
||||
if (docManager.existsSync(path)) {
|
||||
var historyPath = docManager.historyPath(fileName, userAddress);
|
||||
if (historyPath == "") {
|
||||
historyPath = docManager.historyPath(fileName, userAddress, true);
|
||||
docManager.createDirectory(historyPath);
|
||||
}
|
||||
|
||||
var count_version = docManager.countVersion(historyPath);
|
||||
version = count_version + 1;
|
||||
var versionPath = docManager.versionPath(fileName, userAddress, version);
|
||||
docManager.createDirectory(versionPath);
|
||||
|
||||
var downloadZip = body.changesurl;
|
||||
if (downloadZip) {
|
||||
var path_changes = docManager.diffPath(fileName, userAddress, version);
|
||||
var diffZip = syncRequest("GET", downloadZip);
|
||||
fileSystem.writeFileSync(path_changes, diffZip.getBody());
|
||||
}
|
||||
|
||||
var changeshistory = body.changeshistory || JSON.stringify(body.history);
|
||||
if (changeshistory) {
|
||||
var path_changes_json = docManager.changesPath(fileName, userAddress, version);
|
||||
fileSystem.writeFileSync(path_changes_json, changeshistory);
|
||||
}
|
||||
|
||||
var path_key = docManager.keyPath(fileName, userAddress, version);
|
||||
fileSystem.writeFileSync(path_key, body.key);
|
||||
|
||||
var path_prev = docManager.prevFilePath(fileName, userAddress, version);
|
||||
fileSystem.writeFileSync(path_prev, fileSystem.readFileSync(path));
|
||||
|
||||
var file = syncRequest("GET", downloadUri);
|
||||
fileSystem.writeFileSync(path, file.getBody());
|
||||
|
||||
var forcesavePath = docManager.forcesavePath(fileName, userAddress, false);
|
||||
if (forcesavePath != "") {
|
||||
fileSystem.unlinkSync(forcesavePath);
|
||||
}
|
||||
var historyPath = docManager.historyPath(newFileName, userAddress);
|
||||
if (historyPath == "") {
|
||||
historyPath = docManager.historyPath(newFileName, userAddress, true);
|
||||
docManager.createDirectory(historyPath);
|
||||
}
|
||||
|
||||
var count_version = docManager.countVersion(historyPath);
|
||||
version = count_version + 1;
|
||||
var versionPath = docManager.versionPath(newFileName, userAddress, version);
|
||||
docManager.createDirectory(versionPath);
|
||||
|
||||
var downloadZip = body.changesurl;
|
||||
if (downloadZip) {
|
||||
var path_changes = docManager.diffPath(newFileName, userAddress, version);
|
||||
var diffZip = syncRequest("GET", downloadZip);
|
||||
fileSystem.writeFileSync(path_changes, diffZip.getBody());
|
||||
}
|
||||
|
||||
var changeshistory = body.changeshistory || JSON.stringify(body.history);
|
||||
if (changeshistory) {
|
||||
var path_changes_json = docManager.changesPath(newFileName, userAddress, version);
|
||||
fileSystem.writeFileSync(path_changes_json, changeshistory);
|
||||
}
|
||||
|
||||
var path_key = docManager.keyPath(newFileName, userAddress, version);
|
||||
fileSystem.writeFileSync(path_key, body.key);
|
||||
|
||||
var path_prev = path.join(versionPath, "prev" + fileUtility.getFileExtension(fileName));
|
||||
fileSystem.renameSync(docManager.storagePath(fileName, userAddress), path_prev);
|
||||
|
||||
var file = syncRequest("GET", downloadUri);
|
||||
fileSystem.writeFileSync(storagePath, file.getBody());
|
||||
|
||||
var forcesavePath = docManager.forcesavePath(newFileName, userAddress, false);
|
||||
if (forcesavePath != "") {
|
||||
fileSystem.unlinkSync(forcesavePath);
|
||||
}
|
||||
|
||||
} catch (ex) {
|
||||
console.log(ex);
|
||||
response.write("{\"error\":1}");
|
||||
response.end();
|
||||
return;
|
||||
}
|
||||
|
||||
response.write("{\"error\":0}");
|
||||
response.end();
|
||||
};
|
||||
}
|
||||
|
||||
var processForceSave = function (downloadUri, body, fileName, userAddress, resp) {
|
||||
var processSave = function (downloadUri, body, fileName, userAddress, resp) {
|
||||
var curExt = fileUtility.getFileExtension(fileName);
|
||||
var downloadExt = fileUtility.getFileExtension(downloadUri);
|
||||
var newFileName = fileName;
|
||||
|
||||
if (downloadExt != curExt) {
|
||||
var key = documentService.generateRevisionId(downloadUri);
|
||||
|
||||
newFileName = docManager.getCorrectName(fileUtility.getFileName(fileName, true) + downloadExt, userAddress);
|
||||
try {
|
||||
documentService.getConvertedUriSync(downloadUri, downloadExt, curExt, key, function (dUri) {
|
||||
processForceSave(dUri, body, fileName, userAddress, resp)
|
||||
documentService.getConvertedUriSync(downloadUri, downloadExt, curExt, key, function (err, data) {
|
||||
if (err) {
|
||||
callbackProcessSave(downloadUri, body, fileName, userAddress, newFileName);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
var res = documentService.getResponseUri(data);
|
||||
callbackProcessSave(res.value, body, fileName, userAddress, fileName);
|
||||
return;
|
||||
} catch (ex) {
|
||||
console.log(ex);
|
||||
callbackProcessSave(downloadUri, body, fileName, userAddress, newFileName);
|
||||
return;
|
||||
}
|
||||
});
|
||||
return;
|
||||
} catch (ex) {
|
||||
console.log(ex);
|
||||
fileName = docManager.getCorrectName(fileUtility.getFileName(fileName, true) + downloadExt, userAddress)
|
||||
}
|
||||
}
|
||||
callbackProcessSave(downloadUri, body, fileName, userAddress, newFileName);
|
||||
};
|
||||
|
||||
var callbackProcessForceSave = function (downloadUri, body, fileName, userAddress, newFileName){
|
||||
try {
|
||||
var isSubmitForm = body.forcesavetype === 3; //SubmitForm
|
||||
|
||||
var path = docManager.storagePath(fileName, userAddress);
|
||||
|
||||
var forcesavePath = docManager.forcesavePath(fileName, userAddress, false);
|
||||
if (forcesavePath == "") {
|
||||
forcesavePath = docManager.forcesavePath(fileName, userAddress, true);
|
||||
if (isSubmitForm) {
|
||||
//new file
|
||||
if (newFileName == fileName){
|
||||
newFileName = docManager.getCorrectName(fileName, userAddress);
|
||||
}
|
||||
var forcesavePath = docManager.storagePath(newFileName, userAddress);
|
||||
} else {
|
||||
forcesavePath = docManager.forcesavePath(newFileName, userAddress, false);
|
||||
if (forcesavePath == "") {
|
||||
forcesavePath = docManager.forcesavePath(newFileName, userAddress, true);
|
||||
}
|
||||
}
|
||||
|
||||
var file = syncRequest("GET", downloadUri);
|
||||
fileSystem.writeFileSync(forcesavePath, file.getBody());
|
||||
|
||||
if (isSubmitForm) {
|
||||
var uid =body.actions[0].userid
|
||||
docManager.saveFileData(newFileName, uid, "Filling Form", userAddress);
|
||||
}
|
||||
} catch (ex) {
|
||||
console.log(ex);
|
||||
response.write("{\"error\":1}");
|
||||
response.end();
|
||||
return;
|
||||
}
|
||||
|
||||
response.write("{\"error\":0}");
|
||||
response.end();
|
||||
}
|
||||
|
||||
var processForceSave = function (downloadUri, body, fileName, userAddress, resp) {
|
||||
var curExt = fileUtility.getFileExtension(fileName);
|
||||
var downloadExt = fileUtility.getFileExtension(downloadUri);
|
||||
var newFileName = fileName;
|
||||
|
||||
if (downloadExt != curExt) {
|
||||
var key = documentService.generateRevisionId(downloadUri);
|
||||
try {
|
||||
documentService.getConvertedUriSync(downloadUri, downloadExt, curExt, key, function (err, data) {
|
||||
if (err) {
|
||||
newFileName = docManager.getCorrectName(fileUtility.getFileName(fileName, true) + downloadExt, userAddress);
|
||||
callbackProcessForceSave(downloadUri, body, fileName, userAddress, newFileName);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
var res = documentService.getResponseUri(data);
|
||||
callbackProcessForceSave(res.value, body, fileName, userAddress, newFileName);
|
||||
return;
|
||||
} catch (ex) {
|
||||
console.log(ex);
|
||||
newFileName = docManager.getCorrectName(fileUtility.getFileName(fileName, true) + downloadExt, userAddress);
|
||||
callbackProcessForceSave(downloadUri, body, fileName, userAddress, newFileName);
|
||||
return;
|
||||
}
|
||||
});
|
||||
return;
|
||||
} catch (ex) {
|
||||
console.log(ex);
|
||||
}
|
||||
}
|
||||
callbackProcessForceSave (downloadUri, body, fileName, userAddress, newFileName);
|
||||
};
|
||||
|
||||
if (body.status == 1) { //Editing
|
||||
@ -553,9 +598,22 @@ app.get("/editor", function (req, res) {
|
||||
var historyData = [];
|
||||
var lang = docManager.getLang();
|
||||
var userid = req.query.userid ? req.query.userid : "uid-1";
|
||||
var name = req.query.name ? req.query.name : "John Smith";
|
||||
var name = (userid == "uid-0" ? null : (req.query.name ? req.query.name : "John Smith"));
|
||||
var actionData = req.query.action ? req.query.action : "null";
|
||||
|
||||
var userGroup = null;
|
||||
var reviewGroups = null;
|
||||
if (userid == "uid-2")
|
||||
{
|
||||
userGroup = "group-2";
|
||||
// own and without group
|
||||
reviewGroups = ["group-2", ""];
|
||||
} else if (userid == "uid-3") {
|
||||
userGroup = "group-3";
|
||||
// other group only
|
||||
reviewGroups = ["group-2"];
|
||||
}
|
||||
|
||||
if (fileExt != null) {
|
||||
var fileName = docManager.createDemo(!!req.query.sample, fileExt, userid, name);
|
||||
|
||||
@ -581,6 +639,7 @@ app.get("/editor", function (req, res) {
|
||||
}
|
||||
|
||||
var canEdit = configServer.get('editedDocs').indexOf(fileUtility.getFileExtension(fileName)) != -1;
|
||||
var submitForm = canEdit && (mode == "edit" || mode == "fillForms");
|
||||
|
||||
var countVersion = 1;
|
||||
|
||||
@ -666,7 +725,10 @@ app.get("/editor", function (req, res) {
|
||||
lang: lang,
|
||||
userid: userid,
|
||||
name: name,
|
||||
userGroup: userGroup,
|
||||
reviewGroups: JSON.stringify(reviewGroups),
|
||||
fileChoiceUrl: fileChoiceUrl,
|
||||
submitForm: submitForm,
|
||||
plugins: JSON.stringify(plugins),
|
||||
actionData: actionData
|
||||
},
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
"exampleUrl": null,
|
||||
"viewedDocs": [".pdf", ".djvu", ".xps"],
|
||||
"editedDocs": [".docx", ".xlsx", ".csv", ".pptx", ".txt"],
|
||||
"convertedDocs": [".docm", ".doc", ".dotx", ".dotm", ".dot", ".odt", ".fodt", ".ott", ".xlsm", ".xls", ".xltx", ".xltm", ".xlt", ".ods", ".fods", ".ots", ".pptm", ".ppt", ".ppsx", ".ppsm", ".pps", ".potx", ".potm", ".pot", ".odp", ".fodp", ".otp", ".rtf", ".mht", ".html", ".htm", ".epub", ".fb2"],
|
||||
"convertedDocs": [".docm", ".doc", ".dotx", ".dotm", ".dot", ".odt", ".fodt", ".ott", ".xlsm", ".xls", ".xltx", ".xltm", ".xlt", ".ods", ".fods", ".ots", ".pptm", ".ppt", ".ppsx", ".ppsm", ".pps", ".potx", ".potm", ".pot", ".odp", ".fodp", ".otp", ".rtf", ".mht", ".html", ".htm", ".xml", ".epub", ".fb2"],
|
||||
"storageFolder": "./files",
|
||||
"storagePath": "/files",
|
||||
"maxFileSize": 1073741824,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"server": {
|
||||
"port": 3000,
|
||||
"siteUrl": "http://127.0.0.1:8001/",
|
||||
"siteUrl": "http://127.0.0.1:8000/",
|
||||
"apiUrl": "web-apps/apps/api/documents/api.js",
|
||||
"preloaderUrl": "web-apps/apps/api/documents/cache-scripts.html"
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"server": {
|
||||
"port": 3000,
|
||||
"siteUrl": "http://127.0.0.1:8001/",
|
||||
"siteUrl": "http://127.0.0.1:8000/",
|
||||
"apiUrl": "web-apps/apps/api/documents/api.js",
|
||||
"preloaderUrl": "web-apps/apps/api/documents/cache-scripts.html"
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"server": {
|
||||
"port": 80,
|
||||
"siteUrl": "http://127.0.0.1:8001/",
|
||||
"siteUrl": "http://127.0.0.1:8000/",
|
||||
"apiUrl": "web-apps/apps/api/documents/api.js",
|
||||
"preloaderUrl": "web-apps/apps/api/documents/cache-scripts.html"
|
||||
}
|
||||
|
||||
13
web/documentserver-example/nodejs/docker-entrypoint.sh
Executable file
@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
export NODE_CONFIG='{
|
||||
"server": {
|
||||
"siteUrl": "'${DS_URL:-"/"}'",
|
||||
"token": {
|
||||
"enable": '${JWT_ENABLED:-false}',
|
||||
"secret": "'${JWT_SECRET:-secret}'",
|
||||
"authorizationHeader": "'${JWT_HEADER:-Authorization}'"
|
||||
}
|
||||
}
|
||||
}'
|
||||
exec "$@"
|
||||
@ -110,9 +110,11 @@ docManager.createDemo = function (isSample, fileExt, userid, username) {
|
||||
return fileName;
|
||||
};
|
||||
|
||||
docManager.saveFileData = function (fileName, userid, username) {
|
||||
const userAddress = docManager.curUserHostAddress();
|
||||
const date_create = fileSystem.statSync(docManager.storagePath(fileName)).mtime;
|
||||
docManager.saveFileData = function (fileName, userid, username, userAddress) {
|
||||
if (!userAddress) {
|
||||
userAddress = docManager.curUserHostAddress();
|
||||
}
|
||||
const date_create = fileSystem.statSync(docManager.storagePath(fileName, userAddress)).mtime;
|
||||
const minutes = (date_create.getMinutes() < 10 ? '0' : '') + date_create.getMinutes().toString();
|
||||
const month = (date_create.getMonth() < 10 ? '0' : '') + (parseInt(date_create.getMonth().toString()) + 1);
|
||||
const sec = (date_create.getSeconds() < 10 ? '0' : '') + date_create.getSeconds().toString();
|
||||
|
||||
@ -39,12 +39,7 @@ documentService.userIp = null;
|
||||
|
||||
documentService.getConvertedUriSync = function (documentUri, fromExtension, toExtension, documentRevisionId, callback) {
|
||||
documentService.getConvertedUri(documentUri, fromExtension, toExtension, documentRevisionId, false, function (err, data) {
|
||||
if (err) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
var res = documentService.getResponseUri(data);
|
||||
callback(res.value);
|
||||
callback(err, data);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@ -59,7 +59,7 @@ fileUtility.fileType = {
|
||||
slide: "slide"
|
||||
}
|
||||
|
||||
fileUtility.documentExts = [".doc", ".docx", ".docm", ".dot", ".dotx", ".dotm", ".odt", ".fodt", ".ott", ".rtf", ".txt", ".html", ".htm", ".mht", ".pdf", ".djvu", ".fb2", ".epub", ".xps"];
|
||||
fileUtility.documentExts = [".doc", ".docx", ".docm", ".dot", ".dotx", ".dotm", ".odt", ".fodt", ".ott", ".rtf", ".txt", ".html", ".htm", ".mht", ".xml", ".pdf", ".djvu", ".fb2", ".epub", ".xps"];
|
||||
|
||||
fileUtility.spreadsheetExts = [".xls", ".xlsx", ".xlsm", ".xlt", ".xltx", ".xltm", ".ods", ".fods", ".ots", ".csv"];
|
||||
|
||||
|
||||
BIN
web/documentserver-example/nodejs/public/images/cell.ico
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
web/documentserver-example/nodejs/public/images/slide.ico
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
web/documentserver-example/nodejs/public/images/word.ico
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
@ -20,7 +20,8 @@
|
||||
"fillForms": <%- editor.fillForms %>,
|
||||
"modifyFilter": <%- editor.modifyFilter %>,
|
||||
"modifyContentControl": <%- editor.modifyContentControl %>,
|
||||
"review": <%- editor.review %>
|
||||
"review": <%- editor.review %>,
|
||||
"reviewGroups": <%- editor.reviewGroups %>
|
||||
}
|
||||
},
|
||||
"editorConfig": {
|
||||
@ -29,6 +30,7 @@
|
||||
"lang": "<%- editor.lang %>",
|
||||
"callbackUrl": "<%- editor.callbackUrl %>",
|
||||
"user": {
|
||||
"group": "<%- editor.userGroup %>",
|
||||
"id": "<%- editor.userid %>",
|
||||
"name": "<%- editor.name %>"
|
||||
},
|
||||
@ -46,7 +48,8 @@
|
||||
"forcesave": false,
|
||||
"goback": {
|
||||
"url": "<%- editor.backUrl %>"
|
||||
}
|
||||
},
|
||||
"submitForm": <%- editor.submitForm %>
|
||||
},
|
||||
"fileChoiceUrl": "<%- editor.fileChoiceUrl %>",
|
||||
"plugins": <%- editor.plugins %>
|
||||
|
||||
@ -47,6 +47,7 @@
|
||||
<option value="uid-1">John Smith</option>
|
||||
<option value="uid-2">Mark Pottato</option>
|
||||
<option value="uid-3">Hamish Mitchell</option>
|
||||
<option value="uid-0">anonymous</option>
|
||||
</select>
|
||||
</td>
|
||||
<td valign="middle" width="70%">Select user name before opening the document; you can open the same document using different users in different Web browser sessions, so you can check out multi-user editing functions.</td>
|
||||
|
||||
@ -198,6 +198,23 @@ function getStoragePath($fileName, $userAddress = NULL) {
|
||||
return $directory . basename($fileName);
|
||||
}
|
||||
|
||||
function getForcesavePath($fileName, $userAddress, $create) {
|
||||
$storagePath = trim(str_replace(array('/','\\'), DIRECTORY_SEPARATOR, $GLOBALS['STORAGE_PATH']), DIRECTORY_SEPARATOR);
|
||||
$directory = __DIR__ . DIRECTORY_SEPARATOR . $storagePath . getCurUserHostAddress($userAddress) . DIRECTORY_SEPARATOR;
|
||||
|
||||
if (!is_dir($directory)) return "";
|
||||
|
||||
$directory = $directory . $fileName . "-hist" . DIRECTORY_SEPARATOR;
|
||||
if (!$create && !is_dir($directory)) return "";
|
||||
|
||||
mkdir($directory);
|
||||
|
||||
$directory = $directory . $fileName;
|
||||
if (!$create && !file_exists($directory)) return "";
|
||||
|
||||
return $directory;
|
||||
}
|
||||
|
||||
function getHistoryDir($storagePath) {
|
||||
$directory = $storagePath . "-hist";
|
||||
if (!file_exists($directory) && !is_dir($directory)) {
|
||||
@ -272,8 +289,8 @@ function getVirtualPath($forDocumentServer) {
|
||||
return $virtPath;
|
||||
}
|
||||
|
||||
function createMeta($fileName, $uid = "0") {
|
||||
$histDir = getHistoryDir(getStoragePath($fileName));
|
||||
function createMeta($fileName, $uid = "0", $userAddress = NULL) {
|
||||
$histDir = getHistoryDir(getStoragePath($fileName, $userAddress));
|
||||
|
||||
if (empty($uid)) $uid = "0";
|
||||
|
||||
@ -288,6 +305,9 @@ function createMeta($fileName, $uid = "0") {
|
||||
case 2:
|
||||
$name = "Hamish Mitchell";
|
||||
break;
|
||||
case 3:
|
||||
$name = null;
|
||||
break;
|
||||
}
|
||||
|
||||
$json = [
|
||||
@ -338,14 +358,14 @@ function getFileExts() {
|
||||
return array_merge($GLOBALS['DOC_SERV_VIEWD'], $GLOBALS['DOC_SERV_EDITED'], $GLOBALS['DOC_SERV_CONVERT']);
|
||||
}
|
||||
|
||||
function GetCorrectName($fileName) {
|
||||
function GetCorrectName($fileName, $userAddress = NULL) {
|
||||
$path_parts = pathinfo($fileName);
|
||||
|
||||
$ext = $path_parts['extension'];
|
||||
$name = $path_parts['basename'];
|
||||
$baseNameWithoutExt = substr($name, 0, strlen($name) - strlen($ext) - 1);
|
||||
|
||||
for ($i = 1; file_exists(getStoragePath($name)); $i++)
|
||||
for ($i = 1; file_exists(getStoragePath($name, $userAddress)); $i++)
|
||||
{
|
||||
$name = $baseNameWithoutExt . " (" . $i . ")." . $ext;
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ $GLOBALS['ALONE'] = FALSE;
|
||||
|
||||
$GLOBALS['DOC_SERV_VIEWD'] = array(".pdf", ".djvu", ".xps");
|
||||
$GLOBALS['DOC_SERV_EDITED'] = array(".docx", ".xlsx", ".csv", ".pptx", ".txt");
|
||||
$GLOBALS['DOC_SERV_CONVERT'] = array(".docm", ".doc", ".dotx", ".dotm", ".dot", ".odt", ".fodt", ".ott", ".xlsm", ".xls", ".xltx", ".xltm", ".xlt", ".ods", ".fods", ".ots", ".pptm", ".ppt", ".ppsx", ".ppsm", ".pps", ".potx", ".potm", ".pot", ".odp", ".fodp", ".otp", ".rtf", ".mht", ".html", ".htm", ".epub", ".fb2");
|
||||
$GLOBALS['DOC_SERV_CONVERT'] = array(".docm", ".doc", ".dotx", ".dotm", ".dot", ".odt", ".fodt", ".ott", ".xlsm", ".xls", ".xltx", ".xltm", ".xlt", ".ods", ".fods", ".ots", ".pptm", ".ppt", ".ppsx", ".ppsm", ".pps", ".potx", ".potm", ".pot", ".odp", ".fodp", ".otp", ".rtf", ".mht", ".html", ".htm", ".xml", ".epub", ".fb2");
|
||||
|
||||
$GLOBALS['DOC_SERV_TIMEOUT'] = "120000";
|
||||
|
||||
@ -16,6 +16,7 @@ $GLOBALS['DOC_SERV_SITE_URL'] = "https://documentserver/";
|
||||
$GLOBALS['DOC_SERV_CONVERTER_URL'] = "ConvertService.ashx";
|
||||
$GLOBALS['DOC_SERV_API_URL'] = "web-apps/apps/api/documents/api.js";
|
||||
$GLOBALS['DOC_SERV_PRELOADER_URL'] = "web-apps/apps/api/documents/cache-scripts.html";
|
||||
$GLOBALS['DOC_SERV_COMMAND_URL'] = "coauthoring/CommandService.ashx";
|
||||
|
||||
$GLOBALS['DOC_SERV_JWT_SECRET'] = "";
|
||||
$GLOBALS['DOC_SERV_JWT_HEADER'] = "Authorization";
|
||||
@ -37,7 +38,7 @@ $GLOBALS['ExtsPresentation'] = array(".pps", ".ppsx", ".ppsm",
|
||||
$GLOBALS['ExtsDocument'] = array(".doc", ".docx", ".docm",
|
||||
".dot", ".dotx", ".dotm",
|
||||
".odt", ".fodt", ".ott", ".rtf", ".txt",
|
||||
".html", ".htm", ".mht",
|
||||
".html", ".htm", ".mht", ".xml",
|
||||
".pdf", ".djvu", ".fb2", ".epub", ".xps");
|
||||
|
||||
|
||||
|
||||
BIN
web/documentserver-example/php/css/images/cell.ico
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
web/documentserver-example/php/css/images/slide.ico
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
web/documentserver-example/php/css/images/word.ico
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
@ -57,14 +57,22 @@
|
||||
break;
|
||||
case 1:
|
||||
$uname = "Mark Pottato";
|
||||
$ugroup = "group-2";
|
||||
$reviewGroups = ["group-2", ""];
|
||||
break;
|
||||
case 2:
|
||||
$uname = "Hamish Mitchell";
|
||||
$ugroup = "group-3";
|
||||
$reviewGroups = ["group-2"];
|
||||
break;
|
||||
case 3:
|
||||
$uname = null;
|
||||
break;
|
||||
}
|
||||
|
||||
$editorsMode = empty($_GET["action"]) ? "edit" : $_GET["action"];
|
||||
$canEdit = in_array(strtolower('.' . pathinfo($filename, PATHINFO_EXTENSION)), $GLOBALS['DOC_SERV_EDITED']);
|
||||
$submitForm = $canEdit && ($editorsMode == "edit" || $editorsMode == "fillForms");
|
||||
$mode = $canEdit && $editorsMode != "view" ? "edit" : "view";
|
||||
|
||||
$config = [
|
||||
@ -87,7 +95,8 @@
|
||||
"fillForms" => $editorsMode != "view" && $editorsMode != "comment" && $editorsMode != "embedded" && $editorsMode != "blockcontent",
|
||||
"modifyFilter" => $editorsMode != "filter",
|
||||
"modifyContentControl" => $editorsMode != "blockcontent",
|
||||
"review" => $editorsMode == "edit" || $editorsMode == "review"
|
||||
"review" => $editorsMode == "edit" || $editorsMode == "review",
|
||||
"reviewGroups" => $reviewGroups
|
||||
]
|
||||
],
|
||||
"editorConfig" => [
|
||||
@ -97,7 +106,8 @@
|
||||
"callbackUrl" => getCallbackUrl($filename),
|
||||
"user" => [
|
||||
"id" => $uid,
|
||||
"name" => $uname
|
||||
"name" => $uname,
|
||||
"group" => $ugroup
|
||||
],
|
||||
"embedded" => [
|
||||
"saveUrl" => $fileuriUser,
|
||||
@ -108,6 +118,8 @@
|
||||
"customization" => [
|
||||
"about" => true,
|
||||
"feedback" => true,
|
||||
"forcesave" => false,
|
||||
"submitForm" => $submitForm,
|
||||
"goback" => [
|
||||
"url" => serverPath(),
|
||||
]
|
||||
@ -122,7 +134,7 @@
|
||||
|
||||
$dataCompareFile = [
|
||||
"fileType" => "docx",
|
||||
"url" => serverPath(true) . "/webeditor-ajax.php?type=download&name=sample.docx"
|
||||
"url" => serverPath(true) . "/webeditor-ajax.php?type=assets&name=sample.docx"
|
||||
];
|
||||
|
||||
$dataMailMergeRecipients = [
|
||||
@ -243,7 +255,7 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="mobile-web-app-capable" content="yes" />
|
||||
<link rel="icon" href="./favicon.ico" type="image/x-icon" />
|
||||
<link rel="icon" href="css/images/<?php echo getDocumentType($filename) ?>.ico" type="image/x-icon" />
|
||||
<title>ONLYOFFICE</title>
|
||||
|
||||
<style>
|
||||
|
||||
@ -168,7 +168,7 @@ function SendRequestToConvertService($document_uri, $from_extension, $to_extensi
|
||||
$opts['ssl'] = array( 'verify_peer' => FALSE );
|
||||
}
|
||||
|
||||
$context = stream_context_create($opts);
|
||||
$context = stream_context_create($opts);
|
||||
$response_data = file_get_contents($urlToConverter, FALSE, $context);
|
||||
|
||||
return $response_data;
|
||||
|
||||
@ -77,6 +77,7 @@
|
||||
<option value="0">John Smith</option>
|
||||
<option value="1">Mark Pottato</option>
|
||||
<option value="2">Hamish Mitchell</option>
|
||||
<option value="3">anonymous</option>
|
||||
</select>
|
||||
</td>
|
||||
<td valign="middle" width="70%">Select user name before opening the document; you can open the same document using different users in different Web browser sessions, so you can check out multi-user editing functions.</td>
|
||||
@ -190,7 +191,7 @@
|
||||
echo ' <a class="stored-edit '.$storeFile->documentType.'" href="doceditor.php?fileID='.urlencode($storeFile->name).'&user='.$user.'" target="_blank">';
|
||||
echo ' <span title="'.$storeFile->name.'">'.$storeFile->name.'</span>';
|
||||
echo ' </a>';
|
||||
echo ' <a href="'.FileUri($storeFile->name).'">';
|
||||
echo ' <a href="webeditor-ajax.php?type=download&name='.urlencode($storeFile->name).'">';
|
||||
echo ' <img class="icon-download" src="css/images/download-24.png" alt="Download" title="Download" /></a>';
|
||||
echo ' </a>';
|
||||
echo ' <a class="delete-file" data="'.$storeFile->name.'">';
|
||||
|
||||
234
web/documentserver-example/php/trackmanager.php
Normal file
@ -0,0 +1,234 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2020
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
require_once( dirname(__FILE__) . '/jwtmanager.php' );
|
||||
require_once( dirname(__FILE__) . '/common.php' );
|
||||
require_once( dirname(__FILE__) . '/config.php' );
|
||||
|
||||
|
||||
function readBody() {
|
||||
$result["error"] = 0;
|
||||
|
||||
if (($body_stream = file_get_contents('php://input')) === FALSE) {
|
||||
$result["error"] = "Bad Request";
|
||||
return $result;
|
||||
}
|
||||
|
||||
$data = json_decode($body_stream, TRUE); //json_decode - PHP 5 >= 5.2.0
|
||||
|
||||
if ($data === NULL) {
|
||||
$result["error"] = "Bad Response";
|
||||
return $result;
|
||||
}
|
||||
|
||||
sendlog(" InputStream data: " . serialize($data), "webedior-ajax.log");
|
||||
|
||||
if (isJwtEnabled()) {
|
||||
sendlog(" jwt enabled, checking tokens", "webedior-ajax.log");
|
||||
|
||||
$inHeader = false;
|
||||
$token = "";
|
||||
$jwtHeader = $GLOBALS['DOC_SERV_JWT_HEADER'] == "" ? "Authorization" : $GLOBALS['DOC_SERV_JWT_HEADER'];
|
||||
|
||||
if (!empty($data["token"])) {
|
||||
$token = jwtDecode($data["token"]);
|
||||
} elseif (!empty(apache_request_headers()[$jwtHeader])) {
|
||||
$token = jwtDecode(substr(apache_request_headers()[$jwtHeader], strlen("Bearer ")));
|
||||
$inHeader = true;
|
||||
} else {
|
||||
sendlog(" jwt token wasn't found in body or headers", "webedior-ajax.log");
|
||||
$result["error"] = "Expected JWT";
|
||||
return $result;
|
||||
}
|
||||
if (empty($token)) {
|
||||
sendlog(" token was found but signature is invalid", "webedior-ajax.log");
|
||||
$result["error"] = "Invalid JWT signature";
|
||||
return $result;
|
||||
}
|
||||
|
||||
$data = json_decode($token, true);
|
||||
if ($inHeader) $data = $data["payload"];
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
function processSave($data, $fileName, $userAddress) {
|
||||
$downloadUri = $data["url"];
|
||||
|
||||
$curExt = strtolower('.' . pathinfo($fileName, PATHINFO_EXTENSION));
|
||||
$downloadExt = strtolower('.' . pathinfo($downloadUri, PATHINFO_EXTENSION));
|
||||
$newFileName = $fileName;
|
||||
|
||||
if ($downloadExt != $curExt) {
|
||||
$key = GenerateRevisionId($downloadUri);
|
||||
|
||||
try {
|
||||
sendlog(" Convert " . $downloadUri . " from " . $downloadExt . " to " . $curExt, "webedior-ajax.log");
|
||||
$convertedUri;
|
||||
$percent = GetConvertedUri($downloadUri, $downloadExt, $curExt, $key, FALSE, $convertedUri);
|
||||
if (!empty($convertedUri)) {
|
||||
$downloadUri = $convertedUri;
|
||||
} else {
|
||||
sendlog(" Convert after save convertedUri is empty", "webedior-ajax.log");
|
||||
$baseNameWithoutExt = substr($fileName, 0, strlen($fileName) - strlen($curExt));
|
||||
$newFileName = GetCorrectName($baseNameWithoutExt . $downloadExt, $userAddress);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
sendlog(" Convert after save ".$e->getMessage(), "webedior-ajax.log");
|
||||
$baseNameWithoutExt = substr($fileName, 0, strlen($fileName) - strlen($curExt));
|
||||
$newFileName = GetCorrectName($baseNameWithoutExt . $downloadExt, $userAddress);
|
||||
}
|
||||
}
|
||||
|
||||
$saved = 1;
|
||||
|
||||
if (!(($new_data = file_get_contents($downloadUri)) === FALSE)) {
|
||||
$storagePath = getStoragePath($newFileName, $userAddress);
|
||||
$histDir = getHistoryDir($storagePath);
|
||||
$verDir = getVersionDir($histDir, getFileVersion($histDir));
|
||||
|
||||
mkdir($verDir);
|
||||
|
||||
rename(getStoragePath($fileName, $userAddress), $verDir . DIRECTORY_SEPARATOR . "prev" . $curExt);
|
||||
file_put_contents($storagePath, $new_data, LOCK_EX);
|
||||
|
||||
if ($changesData = file_get_contents($data["changesurl"])) {
|
||||
file_put_contents($verDir . DIRECTORY_SEPARATOR . "diff.zip", $changesData, LOCK_EX);
|
||||
}
|
||||
|
||||
$histData = $data["changeshistory"];
|
||||
if (empty($histData)) {
|
||||
$histData = json_encode($data["history"], JSON_PRETTY_PRINT);
|
||||
}
|
||||
if (!empty($histData)) {
|
||||
file_put_contents($verDir . DIRECTORY_SEPARATOR . "changes.json", $histData, LOCK_EX);
|
||||
}
|
||||
file_put_contents($verDir . DIRECTORY_SEPARATOR . "key.txt", $data["key"], LOCK_EX);
|
||||
|
||||
$forcesavePath = getForcesavePath($newFileName, $userAddress, false);
|
||||
if ($forcesavePath != "") {
|
||||
unlink($forcesavePath);
|
||||
}
|
||||
|
||||
$saved = 0;
|
||||
}
|
||||
|
||||
$result["error"] = $saved;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
function processForceSave($data, $fileName, $userAddress) {
|
||||
$downloadUri = $data["url"];
|
||||
|
||||
$curExt = strtolower('.' . pathinfo($fileName, PATHINFO_EXTENSION));
|
||||
$downloadExt = strtolower('.' . pathinfo($downloadUri, PATHINFO_EXTENSION));
|
||||
$newFileName = $fileName;
|
||||
|
||||
if ($downloadExt != $curExt) {
|
||||
$key = GenerateRevisionId($downloadUri);
|
||||
|
||||
try {
|
||||
sendlog(" Convert " . $downloadUri . " from " . $downloadExt . " to " . $curExt, "webedior-ajax.log");
|
||||
$convertedUri;
|
||||
$percent = GetConvertedUri($downloadUri, $downloadExt, $curExt, $key, FALSE, $convertedUri);
|
||||
if (!empty($convertedUri)) {
|
||||
$downloadUri = $convertedUri;
|
||||
} else {
|
||||
sendlog(" Convert after save convertedUri is empty", "webedior-ajax.log");
|
||||
$baseNameWithoutExt = substr($fileName, 0, strlen($fileName) - strlen($curExt));
|
||||
$newFileName = GetCorrectName($baseNameWithoutExt . $downloadExt, $userAddress);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
sendlog(" Convert after save ".$e->getMessage(), "webedior-ajax.log");
|
||||
$baseNameWithoutExt = substr($fileName, 0, strlen($fileName) - strlen($curExt));
|
||||
$newFileName = GetCorrectName($baseNameWithoutExt . $downloadExt, $userAddress);
|
||||
}
|
||||
}
|
||||
|
||||
$saved = 1;
|
||||
|
||||
if (!(($new_data = file_get_contents($downloadUri)) === FALSE)) {
|
||||
|
||||
$isSubmitForm = $data["forcesavetype"] == 3;
|
||||
|
||||
if ($isSubmitForm) {
|
||||
if ($newFileName == $fileName){
|
||||
$newFileName = GetCorrectName($fileName, $userAddress);
|
||||
}
|
||||
$forcesavePath = getStoragePath($newFileName, $userAddress);
|
||||
} else {
|
||||
$forcesavePath = getForcesavePath($newFileName, $userAddress, false);
|
||||
if ($forcesavePath == "") {
|
||||
$forcesavePath = getForcesavePath($newFileName, $userAddress, true);
|
||||
}
|
||||
}
|
||||
|
||||
file_put_contents($forcesavePath, $new_data, LOCK_EX);
|
||||
|
||||
if ($isSubmitForm) {
|
||||
$user = $data["actions"][0]["userid"];
|
||||
createMeta($newFileName, $user, $userAddress);
|
||||
}
|
||||
|
||||
$saved = 0;
|
||||
}
|
||||
|
||||
$result["error"] = $saved;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
function commandRequest($method, $key){
|
||||
$documentCommandUrl = $GLOBALS['DOC_SERV_SITE_URL'].$GLOBALS['DOC_SERV_COMMAND_URL'];
|
||||
|
||||
$arr = [
|
||||
"c" => $method,
|
||||
"key" => $key
|
||||
];
|
||||
|
||||
$headerToken = "";
|
||||
$jwtHeader = $GLOBALS['DOC_SERV_JWT_HEADER'] == "" ? "Authorization" : $GLOBALS['DOC_SERV_JWT_HEADER'];
|
||||
|
||||
if (isJwtEnabled()) {
|
||||
$headerToken = jwtEncode([ "payload" => $arr ]);
|
||||
$arr["token"] = jwtEncode($arr);
|
||||
}
|
||||
|
||||
$data = json_encode($arr);
|
||||
|
||||
$opts = array('http' => array(
|
||||
'method' => 'POST',
|
||||
'header'=> "Content-type: application/json\r\n" .
|
||||
(empty($headerToken) ? "" : $jwtHeader.": Bearer $headerToken\r\n"),
|
||||
'content' => $data
|
||||
));
|
||||
|
||||
if (substr($documentCommandUrl, 0, strlen("https")) === "https") {
|
||||
$opts['ssl'] = array( 'verify_peer' => FALSE );
|
||||
}
|
||||
|
||||
$context = stream_context_create($opts);
|
||||
$response_data = file_get_contents($documentCommandUrl, FALSE, $context);
|
||||
|
||||
return $response_data;
|
||||
}
|
||||
|
||||
?>
|
||||
@ -25,16 +25,18 @@ require_once( dirname(__FILE__) . '/ajax.php' );
|
||||
require_once( dirname(__FILE__) . '/common.php' );
|
||||
require_once( dirname(__FILE__) . '/functions.php' );
|
||||
require_once( dirname(__FILE__) . '/jwtmanager.php' );
|
||||
require_once( dirname(__FILE__) . '/trackmanager.php' );
|
||||
|
||||
$_trackerStatus = array(
|
||||
0 => 'NotFound',
|
||||
1 => 'Editing',
|
||||
2 => 'MustSave',
|
||||
3 => 'Corrupted',
|
||||
4 => 'Closed'
|
||||
4 => 'Closed',
|
||||
6 => 'MustForceSave',
|
||||
7 => 'CorruptedForceSave'
|
||||
);
|
||||
|
||||
|
||||
if (isset($_GET["type"]) && !empty($_GET["type"])) { //Checks if type value exists
|
||||
$response_array;
|
||||
@header( 'Content-Type: application/json; charset==utf-8');
|
||||
@ -52,6 +54,10 @@ if (isset($_GET["type"]) && !empty($_GET["type"])) { //Checks if type value exis
|
||||
$response_array = upload();
|
||||
$response_array['status'] = isset($response_array['error']) ? 'error' : 'success';
|
||||
die (json_encode($response_array));
|
||||
case "download":
|
||||
$response_array = download();
|
||||
$response_array['status'] = 'success';
|
||||
die (json_encode($response_array));
|
||||
case "convert":
|
||||
$response_array = convert();
|
||||
$response_array['status'] = 'success';
|
||||
@ -64,8 +70,8 @@ if (isset($_GET["type"]) && !empty($_GET["type"])) { //Checks if type value exis
|
||||
$response_array = delete();
|
||||
$response_array['status'] = 'success';
|
||||
die (json_encode($response_array));
|
||||
case "download":
|
||||
$response_array = download();
|
||||
case "assets":
|
||||
$response_array = assets();
|
||||
$response_array['status'] = 'success';
|
||||
die (json_encode($response_array));
|
||||
case "csv":
|
||||
@ -130,116 +136,42 @@ function upload() {
|
||||
|
||||
function track() {
|
||||
sendlog("Track START", "webedior-ajax.log");
|
||||
sendlog("_GET params: " . serialize( $_GET ), "webedior-ajax.log");
|
||||
sendlog(" _GET params: " . serialize( $_GET ), "webedior-ajax.log");
|
||||
|
||||
global $_trackerStatus;
|
||||
$data;
|
||||
$result["error"] = 0;
|
||||
|
||||
if (($body_stream = file_get_contents('php://input'))===FALSE) {
|
||||
$result["error"] = "Bad Request";
|
||||
return $result;
|
||||
}
|
||||
|
||||
$data = json_decode($body_stream, TRUE); //json_decode - PHP 5 >= 5.2.0
|
||||
|
||||
if ($data === NULL) {
|
||||
$result["error"] = "Bad Response";
|
||||
return $result;
|
||||
}
|
||||
|
||||
sendlog("InputStream data: " . serialize($data), "webedior-ajax.log");
|
||||
|
||||
if (isJwtEnabled()) {
|
||||
sendlog("jwt enabled, checking tokens", "webedior-ajax.log");
|
||||
|
||||
$inHeader = false;
|
||||
$token = "";
|
||||
$jwtHeader = $GLOBALS['DOC_SERV_JWT_HEADER'] == "" ? "Authorization" : $GLOBALS['DOC_SERV_JWT_HEADER'];
|
||||
|
||||
if (!empty($data["token"])) {
|
||||
$token = jwtDecode($data["token"]);
|
||||
} elseif (!empty(apache_request_headers()[$jwtHeader])) {
|
||||
$token = jwtDecode(substr(apache_request_headers()[$jwtHeader], strlen("Bearer ")));
|
||||
$inHeader = true;
|
||||
} else {
|
||||
sendlog("jwt token wasn't found in body or headers", "webedior-ajax.log");
|
||||
$result["error"] = "Expected JWT";
|
||||
return $result;
|
||||
}
|
||||
if (empty($token)) {
|
||||
sendlog("token was found but signature is invalid", "webedior-ajax.log");
|
||||
$result["error"] = "Invalid JWT signature";
|
||||
return $result;
|
||||
}
|
||||
|
||||
$data = json_decode($token, true);
|
||||
if ($inHeader) $data = $data["payload"];
|
||||
$data = readBody();
|
||||
if ($data["error"]){
|
||||
return $data;
|
||||
}
|
||||
|
||||
global $_trackerStatus;
|
||||
$status = $_trackerStatus[$data["status"]];
|
||||
|
||||
$userAddress = $_GET["userAddress"];
|
||||
$fileName = basename($_GET["fileName"]);
|
||||
|
||||
switch ($status) {
|
||||
case "Editing":
|
||||
if ($data["actions"] && $data["actions"][0]["type"] == 0) {
|
||||
$user = $data["actions"][0]["userid"];
|
||||
if (array_search($user, $data["users"]) === FALSE) {
|
||||
$commandRequest = commandRequest("forcesave", $data["key"]);
|
||||
sendlog(" CommandRequest forcesave: " . serialize($commandRequest), "webedior-ajax.log");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "MustSave":
|
||||
case "Corrupted":
|
||||
|
||||
$userAddress = $_GET["userAddress"];
|
||||
$fileName = basename($_GET["fileName"]);
|
||||
|
||||
$downloadUri = $data["url"];
|
||||
|
||||
$curExt = strtolower('.' . pathinfo($fileName, PATHINFO_EXTENSION));
|
||||
$downloadExt = strtolower('.' . pathinfo($downloadUri, PATHINFO_EXTENSION));
|
||||
|
||||
if ($downloadExt != $curExt) {
|
||||
$key = getDocEditorKey(downloadUri);
|
||||
|
||||
try {
|
||||
sendlog("Convert " . $downloadUri . " from " . $downloadExt . " to " . $curExt, "webedior-ajax.log");
|
||||
$convertedUri;
|
||||
$percent = GetConvertedUri($downloadUri, $downloadExt, $curExt, $key, FALSE, $convertedUri);
|
||||
$downloadUri = $convertedUri;
|
||||
} catch (Exception $e) {
|
||||
sendlog("Convert after save ".$e->getMessage(), "webedior-ajax.log");
|
||||
$result["error"] = "error: " . $e->getMessage();
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
$saved = 1;
|
||||
|
||||
if (($new_data = file_get_contents($downloadUri)) === FALSE) {
|
||||
$saved = 0;
|
||||
} else {
|
||||
$storagePath = getStoragePath($fileName, $userAddress);
|
||||
$histDir = getHistoryDir($storagePath);
|
||||
$verDir = getVersionDir($histDir, getFileVersion($histDir));
|
||||
|
||||
mkdir($verDir);
|
||||
|
||||
copy($storagePath, $verDir . DIRECTORY_SEPARATOR . "prev" . $downloadExt);
|
||||
file_put_contents($storagePath, $new_data, LOCK_EX);
|
||||
|
||||
if ($changesData = file_get_contents($data["changesurl"])) {
|
||||
file_put_contents($verDir . DIRECTORY_SEPARATOR . "diff.zip", $changesData, LOCK_EX);
|
||||
}
|
||||
|
||||
$histData = $data["changeshistory"];
|
||||
if (empty($histData)) {
|
||||
$histData = json_encode($data["history"], JSON_PRETTY_PRINT);
|
||||
}
|
||||
if (!empty($histData)) {
|
||||
file_put_contents($verDir . DIRECTORY_SEPARATOR . "changes.json", $histData, LOCK_EX);
|
||||
}
|
||||
file_put_contents($verDir . DIRECTORY_SEPARATOR . "key.txt", $data["key"], LOCK_EX);
|
||||
}
|
||||
|
||||
$result["c"] = "saved";
|
||||
$result["status"] = $saved;
|
||||
$result = processSave($data, $fileName, $userAddress);
|
||||
break;
|
||||
case "MustForceSave":
|
||||
case "CorruptedForceSave":
|
||||
$result = processForceSave($data, $fileName, $userAddress);
|
||||
break;
|
||||
}
|
||||
|
||||
sendlog("track result: " . serialize($result), "webedior-ajax.log");
|
||||
sendlog("Track RESULT: " . serialize($result), "webedior-ajax.log");
|
||||
return $result;
|
||||
}
|
||||
|
||||
@ -331,28 +263,44 @@ function files() {
|
||||
}
|
||||
}
|
||||
|
||||
function download() {
|
||||
$fileName = "sample" . DIRECTORY_SEPARATOR . basename($_GET["name"]);
|
||||
downloadFile($fileName);
|
||||
function assets() {
|
||||
$fileName = basename($_GET["name"]);
|
||||
$filePath = dirname(__FILE__) . DIRECTORY_SEPARATOR . "assets" . DIRECTORY_SEPARATOR . "sample" . DIRECTORY_SEPARATOR . $fileName;
|
||||
downloadFile($filePath);
|
||||
}
|
||||
|
||||
function csv() {
|
||||
$fileName = "sample" . DIRECTORY_SEPARATOR . "csv.csv";
|
||||
downloadFile($fileName);
|
||||
$fileName = "csv.csv";
|
||||
$filePath = dirname(__FILE__) . DIRECTORY_SEPARATOR . "assets" . DIRECTORY_SEPARATOR . "sample" . DIRECTORY_SEPARATOR . $fileName;
|
||||
downloadFile($filePath);
|
||||
}
|
||||
|
||||
function downloadFile($fileName) {
|
||||
$file = dirname(__FILE__) . DIRECTORY_SEPARATOR . "assets" . DIRECTORY_SEPARATOR . $fileName;
|
||||
if (file_exists($file)) {
|
||||
function download() {
|
||||
try {
|
||||
$fileName = basename($_GET["name"]);
|
||||
$filePath = getForcesavePath($fileName, null, false);
|
||||
if ($filePath == "") {
|
||||
$filePath = getStoragePath($fileName, null);
|
||||
}
|
||||
downloadFile($filePath);
|
||||
} catch (Exception $e) {
|
||||
sendlog("Download ".$e->getMessage(), "webedior-ajax.log");
|
||||
$result["error"] = "error: File not found";
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
function downloadFile($filePath) {
|
||||
if (file_exists($filePath)) {
|
||||
if (ob_get_level()) {
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
@header('Content-Length: ' . filesize($file));
|
||||
@header('Content-Disposition: attachment; filename*=UTF-8\'\'' . urldecode(basename($file)));
|
||||
@header('Content-Type: ' . mime_content_type($file));
|
||||
@header('Content-Length: ' . filesize($filePath));
|
||||
@header('Content-Disposition: attachment; filename*=UTF-8\'\'' . urldecode(basename($filePath)));
|
||||
@header('Content-Type: ' . mime_content_type($filePath));
|
||||
|
||||
if ($fd = fopen($file, 'rb')) {
|
||||
if ($fd = fopen($filePath, 'rb')) {
|
||||
while (!feof($fd)) {
|
||||
print fread($fd, 1024);
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ DOC_SERV_CONVERT = [
|
||||
".fodt", ".ott", ".xlsm", ".xls", ".xltx", ".xltm",
|
||||
".xlt", ".ods", ".fods", ".ots", ".pptm", ".ppt",
|
||||
".ppsx", ".ppsm", ".pps", ".potx", ".potm", ".pot",
|
||||
".odp", ".fodp", ".otp", ".rtf", ".mht", ".html", ".htm", ".epub", ".fb2"
|
||||
".odp", ".fodp", ".otp", ".rtf", ".mht", ".html", ".htm", ".xml", ".epub", ".fb2"
|
||||
]
|
||||
|
||||
DOC_SERV_TIMEOUT = 120000
|
||||
@ -20,6 +20,7 @@ DOC_SERV_SITE_URL = 'https://documentserver/'
|
||||
DOC_SERV_CONVERTER_URL = 'ConvertService.ashx'
|
||||
DOC_SERV_API_URL = 'web-apps/apps/api/documents/api.js'
|
||||
DOC_SERV_PRELOADER_URL = 'web-apps/apps/api/documents/cache-scripts.html'
|
||||
DOC_SERV_COMMAND_URL='coauthoring/CommandService.ashx'
|
||||
|
||||
EXAMPLE_DOMAIN = None
|
||||
|
||||
@ -43,7 +44,7 @@ EXT_DOCUMENT = [
|
||||
".doc", ".docx", ".docm",
|
||||
".dot", ".dotx", ".dotm",
|
||||
".odt", ".fodt", ".ott", ".rtf", ".txt",
|
||||
".html", ".htm", ".mht",
|
||||
".html", ".htm", ".mht", ".xml",
|
||||
".pdf", ".djvu", ".fb2", ".epub", ".xps"
|
||||
]
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ You should also install following dependencies:
|
||||
```
|
||||
pip install Django==3.1.6
|
||||
pip install requests==2.25.1
|
||||
pip install pyjwt==2.0.1
|
||||
pip install pyjwt==1.7.1
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
@ -32,6 +32,7 @@ from django.contrib.staticfiles.urls import staticfiles_urlpatterns
|
||||
urlpatterns = [
|
||||
path('', index.default),
|
||||
path('upload', actions.upload),
|
||||
path('download', actions.download),
|
||||
path('convert', actions.convert),
|
||||
path('create', actions.createNew),
|
||||
path('edit', actions.edit),
|
||||
|
||||
@ -32,7 +32,10 @@ import io
|
||||
import re
|
||||
import requests
|
||||
import time
|
||||
import urllib.parse
|
||||
import magic
|
||||
|
||||
from django.http import HttpResponse, HttpResponseRedirect, FileResponse
|
||||
from src import settings
|
||||
from . import fileUtils, historyManager
|
||||
|
||||
@ -137,6 +140,29 @@ def getStoragePath(filename, req):
|
||||
|
||||
return os.path.join(directory, fileUtils.getFileName(filename))
|
||||
|
||||
def getForcesavePath(filename, req, create):
|
||||
if isinstance(req, str):
|
||||
curAdr = req
|
||||
else:
|
||||
curAdr = req.META['REMOTE_ADDR']
|
||||
|
||||
directory = os.path.join(config.STORAGE_PATH, curAdr)
|
||||
if not os.path.exists(directory):
|
||||
return ""
|
||||
|
||||
directory = os.path.join(directory, f'{filename}-hist')
|
||||
if (not os.path.exists(directory)):
|
||||
if create:
|
||||
os.makedirs(directory)
|
||||
else:
|
||||
return ""
|
||||
|
||||
directory = os.path.join(directory, filename)
|
||||
if (not os.path.exists(directory) and not create):
|
||||
return ""
|
||||
|
||||
return directory
|
||||
|
||||
def getStoredFiles(req):
|
||||
directory = getRootFolder(req)
|
||||
|
||||
@ -152,21 +178,26 @@ def getStoredFiles(req):
|
||||
return fileInfos
|
||||
|
||||
def createFile(stream, path, req = None, meta = False):
|
||||
bufSize = 8196
|
||||
bufSize = 8192
|
||||
with io.open(path, 'wb') as out:
|
||||
read = stream.read(bufSize)
|
||||
|
||||
while len(read) > 0:
|
||||
out.write(read)
|
||||
read = stream.read(bufSize)
|
||||
|
||||
if meta:
|
||||
historyManager.createMeta(path, req)
|
||||
return
|
||||
|
||||
def createFileResponse(response, path, req, meta):
|
||||
response.raise_for_status()
|
||||
with open(path, 'wb') as file:
|
||||
for chunk in response.iter_content(chunk_size=8192):
|
||||
file.write(chunk)
|
||||
return
|
||||
|
||||
def saveFileFromUri(uri, path, req = None, meta = False):
|
||||
resp = requests.get(uri, stream=True)
|
||||
createFile(resp.raw, path, req, meta)
|
||||
createFileResponse(resp, path, req, meta)
|
||||
return
|
||||
|
||||
def createSample(fileType, sample, req):
|
||||
@ -201,6 +232,13 @@ def generateFileKey(filename, req):
|
||||
replaced = re.sub(r'[^0-9-.a-zA-Z_=]', '_', h)
|
||||
return replaced[:20]
|
||||
|
||||
def generateRevisionId(expectedKey):
|
||||
if (len(expectedKey) > 20):
|
||||
expectedKey = str(hash(expectedKey))
|
||||
|
||||
key = re.sub(r'[^0-9-.a-zA-Z_=]', '_', expectedKey)
|
||||
return key[:20]
|
||||
|
||||
def getFilesInfo(req):
|
||||
fileId = req.GET.get('fileId') if req.GET.get('fileId') else None
|
||||
|
||||
@ -224,4 +262,11 @@ def getFilesInfo(req):
|
||||
if len(resultID) > 0 : return resultID
|
||||
else : return "File not found"
|
||||
else :
|
||||
return result
|
||||
return result
|
||||
|
||||
def download(filePath):
|
||||
response = FileResponse(open(filePath, 'rb'), True)
|
||||
response['Content-Length'] = os.path.getsize(filePath)
|
||||
response['Content-Disposition'] = "attachment;filename*=UTF-8\'\'" + urllib.parse.unquote(os.path.basename(filePath))
|
||||
response['Content-Type'] = magic.from_file(filePath, mime=True)
|
||||
return response
|
||||
@ -95,6 +95,23 @@ def createMeta(storagePath, req):
|
||||
|
||||
return
|
||||
|
||||
def createMetaData(filename, uid, uname, usAddr):
|
||||
histDir = getHistoryDir(docManager.getStoragePath(filename, usAddr))
|
||||
path = getMetaPath(histDir)
|
||||
|
||||
if not os.path.exists(histDir):
|
||||
os.makedirs(histDir)
|
||||
|
||||
obj = {
|
||||
'created': datetime.today().strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'uid': uid,
|
||||
'uname': uname
|
||||
}
|
||||
|
||||
writeFile(path, json.dumps(obj))
|
||||
|
||||
return
|
||||
|
||||
def writeFile(path, content):
|
||||
with io.open(path, 'w') as out:
|
||||
out.write(content)
|
||||
|
||||
153
web/documentserver-example/python/src/utils/trackManager.py
Normal file
@ -0,0 +1,153 @@
|
||||
"""
|
||||
|
||||
(c) Copyright Ascensio System SIA 2020
|
||||
*
|
||||
The MIT License (MIT)
|
||||
|
||||
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.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
import config
|
||||
import requests
|
||||
import os
|
||||
import json
|
||||
from . import jwtManager, docManager, historyManager, fileUtils, serviceConverter
|
||||
|
||||
def readBody(request):
|
||||
body = json.loads(request.body)
|
||||
if (jwtManager.isEnabled()):
|
||||
token = body.get('token')
|
||||
|
||||
if (not token):
|
||||
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:
|
||||
token = token[len('Bearer '):]
|
||||
|
||||
if (not token):
|
||||
raise Exception('Expected JWT')
|
||||
|
||||
body = jwtManager.decode(token)
|
||||
if (body.get('payload')):
|
||||
body = body['payload']
|
||||
return body
|
||||
|
||||
def processSave(body, filename, usAddr):
|
||||
download = body.get('url')
|
||||
changesUri = body.get('changesurl')
|
||||
newFilename = filename
|
||||
|
||||
curExt = fileUtils.getFileExt(filename)
|
||||
downloadExt = fileUtils.getFileExt(download)
|
||||
|
||||
if (curExt != downloadExt):
|
||||
try:
|
||||
newUri = serviceConverter.getConverterUri(download, downloadExt, curExt, docManager.generateRevisionId(download), False)
|
||||
if not newUri:
|
||||
newFilename = docManager.getCorrectName(fileUtils.getFileNameWithoutExt(filename) + downloadExt, usAddr)
|
||||
else:
|
||||
download = newUri
|
||||
except Exception:
|
||||
newFilename = docManager.getCorrectName(fileUtils.getFileNameWithoutExt(filename) + downloadExt, usAddr)
|
||||
|
||||
path = docManager.getStoragePath(newFilename, usAddr)
|
||||
|
||||
histDir = historyManager.getHistoryDir(path)
|
||||
if not os.path.exists(histDir):
|
||||
os.makedirs(histDir)
|
||||
|
||||
versionDir = historyManager.getNextVersionDir(histDir)
|
||||
|
||||
os.rename(docManager.getStoragePath(filename, usAddr), historyManager.getPrevFilePath(versionDir, curExt))
|
||||
docManager.saveFileFromUri(download, path)
|
||||
docManager.saveFileFromUri(changesUri, historyManager.getChangesZipPath(versionDir))
|
||||
|
||||
hist = None
|
||||
hist = body.get('changeshistory')
|
||||
if (not hist) & ('history' in body):
|
||||
hist = json.dumps(body.get('history'))
|
||||
if hist:
|
||||
historyManager.writeFile(historyManager.getChangesHistoryPath(versionDir), hist)
|
||||
|
||||
historyManager.writeFile(historyManager.getKeyPath(versionDir), body.get('key'))
|
||||
|
||||
forcesavePath = docManager.getForcesavePath(newFilename, usAddr, False)
|
||||
if (forcesavePath != ""):
|
||||
os.remove(forcesavePath)
|
||||
|
||||
return
|
||||
|
||||
def processForceSave(body, filename, usAddr):
|
||||
download = body.get('url')
|
||||
|
||||
curExt = fileUtils.getFileExt(filename)
|
||||
downloadExt = fileUtils.getFileExt(download)
|
||||
newFilename = filename
|
||||
|
||||
if (curExt != downloadExt):
|
||||
try:
|
||||
newUri = serviceConverter.getConverterUri(download, downloadExt, curExt, docManager.generateRevisionId(download), False)
|
||||
if not newUri:
|
||||
newFilename = docManager.getCorrectName(fileUtils.getFileNameWithoutExt(filename) + downloadExt, usAddr)
|
||||
else:
|
||||
download = newUri
|
||||
except Exception:
|
||||
newFilename = docManager.getCorrectName(fileUtils.getFileNameWithoutExt(filename) + downloadExt, usAddr)
|
||||
|
||||
isSubmitForm = body.get('forcesavetype') == 3
|
||||
|
||||
if(isSubmitForm):
|
||||
if (newFilename == filename):
|
||||
newFilename = docManager.getCorrectName(filename, usAddr)
|
||||
forcesavePath = docManager.getStoragePath(newFilename, usAddr)
|
||||
else:
|
||||
forcesavePath = docManager.getForcesavePath(newFilename, usAddr, False)
|
||||
if (forcesavePath == ""):
|
||||
forcesavePath = docManager.getForcesavePath(newFilename, usAddr, True)
|
||||
|
||||
docManager.saveFileFromUri(download, forcesavePath)
|
||||
|
||||
if(isSubmitForm):
|
||||
uid = body['actions'][0]['userid']
|
||||
historyManager.createMetaData(newFilename, uid, "Filling Form", usAddr)
|
||||
return
|
||||
|
||||
def commandRequest(method, key):
|
||||
documentCommandUrl = config.DOC_SERV_SITE_URL + config.DOC_SERV_COMMAND_URL
|
||||
|
||||
payload = {
|
||||
'c': method,
|
||||
'key': key
|
||||
}
|
||||
|
||||
headers={'accept': 'application/json'}
|
||||
|
||||
if jwtManager.isEnabled():
|
||||
jwtHeader = 'Authorization' if config.DOC_SERV_JWT_HEADER is None or config.DOC_SERV_JWT_HEADER == '' else config.DOC_SERV_JWT_HEADER
|
||||
headerToken = jwtManager.encode({'payload': payload})
|
||||
headers[jwtHeader] = f'Bearer {headerToken}'
|
||||
|
||||
payload['token'] = jwtManager.encode(payload)
|
||||
|
||||
response = requests.post(documentCommandUrl, json=payload, headers=headers)
|
||||
|
||||
return
|
||||
|
||||
@ -38,6 +38,10 @@ USERS = [
|
||||
{
|
||||
'uid': 'uid-3',
|
||||
'uname': 'Hamish Mitchell'
|
||||
},
|
||||
{
|
||||
'uid': 'uid-0',
|
||||
'uname': 'anonymous'
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@ -33,7 +33,7 @@ import magic
|
||||
from datetime import datetime
|
||||
from django.http import HttpResponse, HttpResponseRedirect, FileResponse
|
||||
from django.shortcuts import render
|
||||
from src.utils import docManager, fileUtils, serviceConverter, users, jwtManager, historyManager
|
||||
from src.utils import docManager, fileUtils, serviceConverter, users, jwtManager, historyManager, trackManager
|
||||
|
||||
|
||||
def upload(request):
|
||||
@ -119,9 +119,18 @@ def edit(request):
|
||||
docKey = docManager.generateFileKey(filename, request)
|
||||
fileType = fileUtils.getFileType(filename)
|
||||
user = users.getUserFromReq(request)
|
||||
userGroup = None
|
||||
reviewGroups = None
|
||||
if (user['uid'] == 'uid-2'):
|
||||
userGroup = 'group-2'
|
||||
reviewGroups = ['group-2', '']
|
||||
if (user['uid'] == 'uid-3'):
|
||||
userGroup = 'group-3'
|
||||
reviewGroups = ['group-2']
|
||||
|
||||
edMode = request.GET.get('mode') if request.GET.get('mode') else 'edit'
|
||||
canEdit = docManager.isCanEdit(ext)
|
||||
submitForm = canEdit & ((edMode == 'edit') | (edMode == 'fillForms'))
|
||||
mode = 'edit' if canEdit & (edMode != 'view') else 'view'
|
||||
|
||||
edType = request.GET.get('type') if request.GET.get('type') else 'desktop'
|
||||
@ -161,7 +170,8 @@ def edit(request):
|
||||
'fillForms': (edMode != 'view') & (edMode != 'comment') & (edMode != 'embedded') & (edMode != "blockcontent"),
|
||||
'modifyFilter': edMode != 'filter',
|
||||
'modifyContentControl': edMode != "blockcontent",
|
||||
'review': (edMode == 'edit') | (edMode == 'review')
|
||||
'review': (edMode == 'edit') | (edMode == 'review'),
|
||||
'reviewGroups': reviewGroups
|
||||
}
|
||||
},
|
||||
'editorConfig': {
|
||||
@ -171,7 +181,8 @@ def edit(request):
|
||||
'callbackUrl': docManager.getCallbackUrl(filename, request),
|
||||
'user': {
|
||||
'id': user['uid'],
|
||||
'name': user['uname']
|
||||
'name': None if user['uid'] == 'uid-0' else user['uname'],
|
||||
'group': userGroup
|
||||
},
|
||||
'embedded': {
|
||||
'saveUrl': fileUriUser,
|
||||
@ -182,6 +193,8 @@ def edit(request):
|
||||
'customization': {
|
||||
'about': True,
|
||||
'feedback': True,
|
||||
'forcesave': False,
|
||||
'submitForm': submitForm,
|
||||
'goback': {
|
||||
'url': docManager.getServerUrl(False, request)
|
||||
}
|
||||
@ -225,51 +238,25 @@ def edit(request):
|
||||
return render(request, 'editor.html', context)
|
||||
|
||||
def track(request):
|
||||
filename = fileUtils.getFileName(request.GET['filename'])
|
||||
usAddr = request.GET['userAddress']
|
||||
|
||||
response = {}
|
||||
|
||||
try:
|
||||
body = json.loads(request.body)
|
||||
|
||||
if jwtManager.isEnabled():
|
||||
token = body.get('token')
|
||||
|
||||
if (not token):
|
||||
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:
|
||||
token = token[len('Bearer '):]
|
||||
|
||||
if (not token):
|
||||
raise Exception('Expected JWT')
|
||||
|
||||
body = jwtManager.decode(token)
|
||||
if (body.get('payload')):
|
||||
body = body['payload']
|
||||
|
||||
body = trackManager.readBody(request)
|
||||
status = body['status']
|
||||
download = body.get('url')
|
||||
|
||||
if (status == 1): # Editing
|
||||
if (body['actions'] and body['actions'][0]['type'] == 0):# finished edit
|
||||
user = body['actions'][0]['userid']
|
||||
if (not user in body['users']):
|
||||
trackManager.commandRequest('forcesave', body['key'])
|
||||
|
||||
filename = fileUtils.getFileName(request.GET['filename'])
|
||||
usAddr = request.GET['userAddress']
|
||||
|
||||
if (status == 2) | (status == 3): # mustsave, corrupted
|
||||
path = docManager.getStoragePath(filename, usAddr)
|
||||
histDir = historyManager.getHistoryDir(path)
|
||||
versionDir = historyManager.getNextVersionDir(histDir)
|
||||
changesUri = body.get('changesurl')
|
||||
|
||||
os.rename(path, historyManager.getPrevFilePath(versionDir, fileUtils.getFileExt(filename)))
|
||||
docManager.saveFileFromUri(download, path)
|
||||
docManager.saveFileFromUri(changesUri, historyManager.getChangesZipPath(versionDir))
|
||||
|
||||
hist = None
|
||||
hist = body.get('changeshistory')
|
||||
if (not hist) & ('history' in body):
|
||||
hist = json.dumps(body.get('history'))
|
||||
if hist:
|
||||
historyManager.writeFile(historyManager.getChangesHistoryPath(versionDir), hist)
|
||||
|
||||
historyManager.writeFile(historyManager.getKeyPath(versionDir), body.get('key'))
|
||||
trackManager.processSave(body, filename, usAddr)
|
||||
if (status == 6) | (status == 7): # mustforcesave, corruptedforcesave
|
||||
trackManager.processForceSave(body, filename, usAddr)
|
||||
|
||||
except Exception as e:
|
||||
response.setdefault('error', 1)
|
||||
@ -298,8 +285,18 @@ def files(request):
|
||||
|
||||
def csv(request):
|
||||
filePath = os.path.join('assets', 'sample', "csv.csv")
|
||||
response = FileResponse(open(filePath, 'rb'), True)
|
||||
response['Content-Length'] = os.path.getsize(filePath)
|
||||
response['Content-Disposition'] = "attachment;filename*=UTF-8\'\'" + urllib.parse.unquote(os.path.basename(filePath))
|
||||
response['Content-Type'] = magic.from_file(filePath, mime=True)
|
||||
return response
|
||||
response = docManager.download(filePath)
|
||||
return response
|
||||
|
||||
def download(request):
|
||||
try:
|
||||
fileName = fileUtils.getFileName(request.GET['filename'])
|
||||
filePath = docManager.getForcesavePath(fileName, request, False)
|
||||
if (filePath == ""):
|
||||
filePath = docManager.getStoragePath(fileName, request)
|
||||
response = docManager.download(filePath)
|
||||
return response
|
||||
except Exception:
|
||||
response = {}
|
||||
response.setdefault('error', 'File not found')
|
||||
return HttpResponse(json.dumps(response), content_type='application/json')
|
||||
BIN
web/documentserver-example/python/static/images/cell.ico
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
web/documentserver-example/python/static/images/slide.ico
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
web/documentserver-example/python/static/images/word.ico
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
@ -137,7 +137,7 @@
|
||||
<a class="stored-edit {{ file.type }}" href="edit?filename={{ file.title }}" target="_blank">
|
||||
<span title="{{ file.title }}">{{ file.title }}</span>
|
||||
</a>
|
||||
<a href="{{ file.url }}">
|
||||
<a href="download?filename={{ file.title }}">
|
||||
<img class="icon-download" src="{% static "images/download-24.png" %}" alt="Download" title="Download" />
|
||||
</a>
|
||||
<a class="delete-file" data-filename="{{ file.title }}">
|
||||
|
||||
BIN
web/documentserver-example/ruby/app/assets/images/cell.ico
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
web/documentserver-example/ruby/app/assets/images/slide.ico
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
web/documentserver-example/ruby/app/assets/images/word.ico
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
@ -57,13 +57,13 @@ class HomeController < ApplicationController
|
||||
raise 'File type is not supported'
|
||||
end
|
||||
|
||||
file_name = DocumentHelper.get_correct_name(file_name)
|
||||
file_name = DocumentHelper.get_correct_name(file_name, nil)
|
||||
|
||||
File.open(DocumentHelper.storage_path(file_name, nil), 'wb') do |file|
|
||||
file.write(http_posted_file.read)
|
||||
end
|
||||
|
||||
DocumentHelper.create_meta(file_name, cookies[:uid], cookies[:uname])
|
||||
DocumentHelper.create_meta(file_name, cookies[:uid], cookies[:uname], nil)
|
||||
|
||||
render plain: '{ "filename": "' + file_name + '"}'
|
||||
rescue => ex
|
||||
@ -89,7 +89,7 @@ class HomeController < ApplicationController
|
||||
return
|
||||
end
|
||||
|
||||
correct_name = DocumentHelper.get_correct_name(File.basename(file_name, extension) + internal_extension)
|
||||
correct_name = DocumentHelper.get_correct_name(File.basename(file_name, extension) + internal_extension, nil)
|
||||
|
||||
uri = URI.parse(new_file_uri)
|
||||
http = Net::HTTP.new(uri.host, uri.port)
|
||||
@ -113,7 +113,7 @@ class HomeController < ApplicationController
|
||||
|
||||
file_name = correct_name
|
||||
|
||||
DocumentHelper.create_meta(file_name, cookies[:uid], cookies[:uname])
|
||||
DocumentHelper.create_meta(file_name, cookies[:uid], cookies[:uname], nil)
|
||||
end
|
||||
|
||||
render plain: '{ "filename" : "' + file_name + '"}'
|
||||
@ -124,110 +124,40 @@ class HomeController < ApplicationController
|
||||
end
|
||||
|
||||
def track
|
||||
|
||||
user_address = params[:userAddress]
|
||||
file_name = File.basename(params[:fileName])
|
||||
|
||||
storage_path = DocumentHelper.storage_path(file_name, user_address)
|
||||
body = request.body.read
|
||||
|
||||
if body == nil || body.empty?
|
||||
file_data = TrackHelper.read_body(request)
|
||||
if file_data == nil || file_data.empty?
|
||||
render plain: '{"error":1}'
|
||||
return
|
||||
end
|
||||
|
||||
file_data = JSON.parse(body)
|
||||
|
||||
if JwtHelper.is_enabled
|
||||
inHeader = false
|
||||
token = nil
|
||||
jwtHeader = Rails.configuration.header.empty? ? "Authorization" : Rails.configuration.header;
|
||||
if file_data["token"]
|
||||
token = JwtHelper.decode(file_data["token"])
|
||||
elsif request.headers[jwtHeader]
|
||||
hdr = request.headers[jwtHeader]
|
||||
hdr.slice!(0, "Bearer ".length)
|
||||
token = JwtHelper.decode(hdr)
|
||||
inHeader = true
|
||||
else
|
||||
raise "Expected JWT"
|
||||
end
|
||||
if !token
|
||||
raise "Invalid JWT signature"
|
||||
end
|
||||
|
||||
file_data = JSON.parse(token)
|
||||
if inHeader
|
||||
file_data = file_data["payload"]
|
||||
end
|
||||
end
|
||||
|
||||
status = file_data['status'].to_i
|
||||
|
||||
if status == 2 || status == 3 #MustSave, Corrupted
|
||||
user_address = params[:userAddress]
|
||||
file_name = File.basename(params[:fileName])
|
||||
|
||||
saved = 0
|
||||
|
||||
begin
|
||||
|
||||
def save_from_uri(path, uristr)
|
||||
uri = URI.parse(uristr)
|
||||
http = Net::HTTP.new(uri.host, uri.port)
|
||||
|
||||
if uristr.start_with?('https')
|
||||
http.use_ssl = true
|
||||
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
||||
end
|
||||
|
||||
req = Net::HTTP::Get.new(uri)
|
||||
res = http.request(req)
|
||||
data = res.body
|
||||
|
||||
if data == nil
|
||||
raise 'stream is null'
|
||||
end
|
||||
|
||||
File.open(path, 'wb') do |file|
|
||||
file.write(data)
|
||||
end
|
||||
end
|
||||
|
||||
hist_dir = DocumentHelper.history_dir(storage_path)
|
||||
ver_dir = DocumentHelper.version_dir(hist_dir, DocumentHelper.get_file_version(hist_dir))
|
||||
|
||||
FileUtils.mkdir_p(ver_dir)
|
||||
|
||||
FileUtils.move(storage_path, File.join(ver_dir, "prev#{File.extname(file_name)}"))
|
||||
save_from_uri(storage_path, file_data['url'])
|
||||
|
||||
if (file_data["changesurl"])
|
||||
save_from_uri(File.join(ver_dir, "diff.zip"), file_data["changesurl"])
|
||||
end
|
||||
|
||||
hist_data = file_data["changeshistory"]
|
||||
if (!hist_data)
|
||||
hist_data = file_data["history"].to_json
|
||||
end
|
||||
if (hist_data)
|
||||
File.open(File.join(ver_dir, "changes.json"), 'wb') do |file|
|
||||
file.write(hist_data)
|
||||
end
|
||||
end
|
||||
|
||||
File.open(File.join(ver_dir, "key.txt"), 'wb') do |file|
|
||||
file.write(file_data["key"])
|
||||
end
|
||||
|
||||
rescue StandardError => msg
|
||||
saved = 1
|
||||
if status == 1 #Editing
|
||||
if file_data['actions'][0]['type'] == 0 #Finished edit
|
||||
user = file_data['actions'][0]['userid']
|
||||
if !file_data['users'].index(user)
|
||||
json_data = TrackHelper.command_request("forcesave", file_data['key'])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if status == 2 || status == 3 #MustSave, Corrupted
|
||||
saved = TrackHelper.process_save(file_data, file_name, user_address)
|
||||
render plain: '{"error":' + saved.to_s + '}'
|
||||
return
|
||||
end
|
||||
|
||||
if status == 6 || status == 7 # MustForceave, CorruptedForcesave
|
||||
saved = TrackHelper.process_force_save(file_data, file_name, user_address)
|
||||
render plain: '{"error":' + saved.to_s + '}'
|
||||
return
|
||||
end
|
||||
|
||||
render plain: '{"error":0}'
|
||||
return
|
||||
|
||||
end
|
||||
|
||||
def remove
|
||||
@ -269,4 +199,22 @@ class HomeController < ApplicationController
|
||||
|
||||
send_file csvPath, :x_sendfile => true
|
||||
end
|
||||
|
||||
def download
|
||||
begin
|
||||
file_name = File.basename(params[:filename])
|
||||
file_path = DocumentHelper.forcesave_path(file_name, nil, false)
|
||||
if file_path.eql?("")
|
||||
file_path = DocumentHelper.storage_path(file_name, nil)
|
||||
end
|
||||
|
||||
response.headers['Content-Length'] = File.size(file_path).to_s
|
||||
response.headers['Content-Type'] = MimeMagic.by_path(file_path).type
|
||||
response.headers['Content-Disposition'] = "attachment;filename*=UTF-8\'\'" + URI.escape(file_name, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
|
||||
|
||||
send_file file_path, :x_sendfile => true
|
||||
rescue => ex
|
||||
render plain: '{ "error": "File not found"}'
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -77,6 +77,32 @@ class DocumentHelper
|
||||
directory.join(File.basename(file_name)).to_s
|
||||
end
|
||||
|
||||
def forcesave_path(file_name, user_address, create)
|
||||
directory = Rails.root.join('public', Rails.configuration.storagePath, cur_user_host_address(user_address))
|
||||
|
||||
unless File.directory?(directory)
|
||||
return ""
|
||||
end
|
||||
|
||||
directory = directory.join("#{File.basename(file_name)}-hist")
|
||||
unless File.directory?(directory)
|
||||
if create
|
||||
FileUtils.mkdir_p(directory)
|
||||
else
|
||||
return ""
|
||||
end
|
||||
end
|
||||
|
||||
directory = directory.join(File.basename(file_name))
|
||||
unless File.file?(directory)
|
||||
if !create
|
||||
return ""
|
||||
end
|
||||
end
|
||||
|
||||
return directory.to_s
|
||||
end
|
||||
|
||||
def history_dir(storage_path)
|
||||
directory = "#{storage_path}-hist"
|
||||
|
||||
@ -108,13 +134,13 @@ class DocumentHelper
|
||||
return ver
|
||||
end
|
||||
|
||||
def get_correct_name(file_name)
|
||||
def get_correct_name(file_name, user_address)
|
||||
ext = File.extname(file_name)
|
||||
base_name = File.basename(file_name, ext)
|
||||
name = base_name + ext
|
||||
index = 1
|
||||
|
||||
while File.exist?(storage_path(name, nil))
|
||||
while File.exist?(storage_path(name, user_address))
|
||||
name = base_name + ' (' + index.to_s + ')' + ext
|
||||
index = index + 1
|
||||
end
|
||||
@ -140,8 +166,8 @@ class DocumentHelper
|
||||
return arr
|
||||
end
|
||||
|
||||
def create_meta(file_name, uid, uname)
|
||||
hist_dir = history_dir(storage_path(file_name, nil))
|
||||
def create_meta(file_name, uid, uname, user_address)
|
||||
hist_dir = history_dir(storage_path(file_name, user_address))
|
||||
|
||||
json = {
|
||||
:created => Time.now.to_formatted_s(:db),
|
||||
@ -156,14 +182,14 @@ class DocumentHelper
|
||||
|
||||
def create_demo(file_ext, sample, uid, uname)
|
||||
demo_name = (sample == 'true' ? 'sample.' : 'new.') + file_ext
|
||||
file_name = get_correct_name demo_name
|
||||
file_name = get_correct_name(demo_name, nil)
|
||||
|
||||
src = Rails.root.join('public', 'assets', sample == 'true' ? 'sample' : 'new', demo_name)
|
||||
dest = storage_path file_name, nil
|
||||
|
||||
FileUtils.cp src, dest
|
||||
|
||||
create_meta(file_name, uid, uname)
|
||||
create_meta(file_name, uid, uname, nil)
|
||||
|
||||
file_name
|
||||
end
|
||||
|
||||
@ -66,7 +66,20 @@ class FileModel
|
||||
def get_config
|
||||
editorsmode = @mode ? @mode : "edit"
|
||||
canEdit = DocumentHelper.edited_exts.include?(file_ext)
|
||||
submitForm = canEdit && (editorsmode.eql?("edit") || editorsmode.eql?("fillForms"))
|
||||
mode = canEdit && editorsmode.eql?("view") ? "view" : "edit"
|
||||
userId = @user_id ? @user_id : "uid-1"
|
||||
user_name = (userId.eql?("uid-0") ? nil : (@user_name ? @user_name : "John Smith"))
|
||||
userGroup = nil
|
||||
reviewGroups = nil
|
||||
if (userId == "uid-2")
|
||||
userGroup = "group-2"
|
||||
reviewGroups = ["group-2", ""]
|
||||
end
|
||||
if (userId == "uid-3")
|
||||
userGroup = "group-3"
|
||||
reviewGroups = ["group-2"]
|
||||
end
|
||||
|
||||
config = {
|
||||
:type => type(),
|
||||
@ -88,7 +101,8 @@ class FileModel
|
||||
:fillForms => !editorsmode.eql?("view") && !editorsmode.eql?("comment") && !editorsmode.eql?("embedded") && !editorsmode.eql?("blockcontent"),
|
||||
:modifyFilter => !editorsmode.eql?("filter"),
|
||||
:modifyContentControl => !editorsmode.eql?("blockcontent"),
|
||||
:review => editorsmode.eql?("edit") || editorsmode.eql?("review")
|
||||
:review => editorsmode.eql?("edit") || editorsmode.eql?("review"),
|
||||
:reviewGroups => reviewGroups
|
||||
}
|
||||
},
|
||||
:editorConfig => {
|
||||
@ -97,8 +111,9 @@ class FileModel
|
||||
:lang => @lang ? @lang : "en",
|
||||
:callbackUrl => callback_url,
|
||||
:user => {
|
||||
:id => @user_id ? @user_id : "uid-0",
|
||||
:name => @user_name ? @user_name : "John Smith"
|
||||
:id => userId,
|
||||
:name => user_name,
|
||||
:group => userGroup
|
||||
},
|
||||
:embedded => {
|
||||
:saveUrl => file_uri_user,
|
||||
@ -106,6 +121,10 @@ class FileModel
|
||||
:shareUrl => file_uri_user,
|
||||
:toolbarDocked => "top"
|
||||
},
|
||||
:customization => {
|
||||
:forcesave => false,
|
||||
:submitForm => submitForm
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -144,14 +163,16 @@ class FileModel
|
||||
obj["version"] = i
|
||||
|
||||
if (i == 1)
|
||||
File.open(File.join(hist_dir, "createdInfo.json"), 'r') do |file|
|
||||
cr_info = JSON.parse(file.read())
|
||||
if File.file?(File.join(hist_dir, "createdInfo.json"))
|
||||
File.open(File.join(hist_dir, "createdInfo.json"), 'r') do |file|
|
||||
cr_info = JSON.parse(file.read())
|
||||
|
||||
obj["created"] = cr_info["created"]
|
||||
obj["user"] = {
|
||||
:id => cr_info["created"],
|
||||
:name => cr_info["name"]
|
||||
}
|
||||
obj["created"] = cr_info["created"]
|
||||
obj["user"] = {
|
||||
:id => cr_info["created"],
|
||||
:name => cr_info["name"]
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
|
||||
class FileUtility
|
||||
|
||||
@@exts_document = %w(.doc .docx .docm .dot .dotx .dotm .odt .fodt .ott .rtf .txt .html .htm .mht .pdf .djvu .fb2 .epub .xps)
|
||||
@@exts_document = %w(.doc .docx .docm .dot .dotx .dotm .odt .fodt .ott .rtf .txt .html .htm .mht .xml .pdf .djvu .fb2 .epub .xps)
|
||||
|
||||
@@exts_spreadsheet = %w(.xls .xlsx .xlsm .xlt .xltx .xltm .ods .fods .ots .csv)
|
||||
|
||||
|
||||
238
web/documentserver-example/ruby/app/models/track_helper.rb
Normal file
@ -0,0 +1,238 @@
|
||||
#
|
||||
# (c) Copyright Ascensio System SIA 2020
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
require 'net/http'
|
||||
|
||||
class TrackHelper
|
||||
|
||||
class << self
|
||||
|
||||
def read_body(request)
|
||||
body = request.body.read
|
||||
|
||||
if body == nil || body.empty?
|
||||
return ""
|
||||
end
|
||||
|
||||
file_data = JSON.parse(body)
|
||||
|
||||
if JwtHelper.is_enabled
|
||||
inHeader = false
|
||||
token = nil
|
||||
jwtHeader = Rails.configuration.header.empty? ? "Authorization" : Rails.configuration.header;
|
||||
if file_data["token"]
|
||||
token = JwtHelper.decode(file_data["token"])
|
||||
elsif request.headers[jwtHeader]
|
||||
hdr = request.headers[jwtHeader]
|
||||
hdr.slice!(0, "Bearer ".length)
|
||||
token = JwtHelper.decode(hdr)
|
||||
inHeader = true
|
||||
else
|
||||
raise "Expected JWT"
|
||||
end
|
||||
|
||||
if !token
|
||||
raise "Invalid JWT signature"
|
||||
end
|
||||
|
||||
file_data = JSON.parse(token)
|
||||
|
||||
if inHeader
|
||||
file_data = file_data["payload"]
|
||||
end
|
||||
end
|
||||
|
||||
return file_data
|
||||
end
|
||||
|
||||
def process_save(file_data, file_name, user_address)
|
||||
download_uri = file_data['url']
|
||||
new_file_name = file_name
|
||||
|
||||
cur_ext = File.extname(file_name)
|
||||
download_ext = File.extname(download_uri)
|
||||
|
||||
if (!cur_ext.eql?(download_ext))
|
||||
key = ServiceConverter.generate_revision_id(download_uri)
|
||||
begin
|
||||
percent, new_file_uri = ServiceConverter.get_converted_uri(download_uri, download_ext.delete('.'), cur_ext.delete('.'), key, false)
|
||||
if (new_file_uri == nil || new_file_uri.empty?)
|
||||
new_file_name = DocumentHelper.get_correct_name(File.basename(file_name, cur_ext) + download_ext, user_address)
|
||||
else
|
||||
download_uri = new_file_uri
|
||||
end
|
||||
rescue StandardError => msg
|
||||
new_file_name = DocumentHelper.get_correct_name(File.basename(file_name, cur_ext) + download_ext, user_address)
|
||||
end
|
||||
end
|
||||
|
||||
saved = 1
|
||||
begin
|
||||
storage_path = DocumentHelper.storage_path(new_file_name, user_address)
|
||||
|
||||
hist_dir = DocumentHelper.history_dir(storage_path)
|
||||
ver_dir = DocumentHelper.version_dir(hist_dir, DocumentHelper.get_file_version(hist_dir))
|
||||
|
||||
FileUtils.mkdir_p(ver_dir)
|
||||
|
||||
FileUtils.move(DocumentHelper.storage_path(file_name, user_address), File.join(ver_dir, "prev#{cur_ext}"))
|
||||
save_from_uri(storage_path, download_uri)
|
||||
|
||||
if (file_data["changesurl"])
|
||||
save_from_uri(File.join(ver_dir, "diff.zip"), file_data["changesurl"])
|
||||
end
|
||||
|
||||
hist_data = file_data["changeshistory"]
|
||||
if (!hist_data)
|
||||
hist_data = file_data["history"].to_json
|
||||
end
|
||||
if (hist_data)
|
||||
File.open(File.join(ver_dir, "changes.json"), 'wb') do |file|
|
||||
file.write(hist_data)
|
||||
end
|
||||
end
|
||||
|
||||
File.open(File.join(ver_dir, "key.txt"), 'wb') do |file|
|
||||
file.write(file_data["key"])
|
||||
end
|
||||
|
||||
forcesave_path = DocumentHelper.forcesave_path(new_file_name, user_address, false)
|
||||
if (!forcesave_path.eql?(""))
|
||||
File.delete(forcesave_path)
|
||||
end
|
||||
|
||||
saved = 0
|
||||
rescue StandardError => msg
|
||||
saved = 1
|
||||
end
|
||||
|
||||
return saved
|
||||
end
|
||||
|
||||
def process_force_save(file_data, file_name, user_address)
|
||||
download_uri = file_data['url']
|
||||
|
||||
cur_ext = File.extname(file_name)
|
||||
download_ext = File.extname(download_uri)
|
||||
new_file_name = file_name
|
||||
|
||||
if (!cur_ext.eql?(download_ext))
|
||||
key = ServiceConverter.generate_revision_id(download_uri)
|
||||
begin
|
||||
percent, new_file_uri = ServiceConverter.get_converted_uri(download_uri, download_ext.delete('.'), cur_ext.delete('.'), key, false)
|
||||
if (new_file_uri == nil || new_file_uri.empty?)
|
||||
new_file_name = DocumentHelper.get_correct_name(File.basename(file_name, cur_ext) + download_ext, user_address)
|
||||
else
|
||||
download_uri = new_file_uri
|
||||
end
|
||||
rescue StandardError => msg
|
||||
new_file_name = DocumentHelper.get_correct_name(File.basename(file_name, cur_ext) + download_ext, user_address)
|
||||
end
|
||||
end
|
||||
|
||||
saved = 1
|
||||
begin
|
||||
is_submit_form = file_data["forcesavetype"].to_i == 3
|
||||
|
||||
if (is_submit_form)
|
||||
if (new_file_name.eql?(file_name))
|
||||
new_file_name = DocumentHelper.get_correct_name(file_name, user_address)
|
||||
end
|
||||
forcesave_path = DocumentHelper.storage_path(new_file_name, user_address)
|
||||
else
|
||||
forcesave_path = DocumentHelper.forcesave_path(new_file_name, user_address, false)
|
||||
if (forcesave_path.eql?(""))
|
||||
forcesave_path = DocumentHelper.forcesave_path(new_file_name, user_address, true)
|
||||
end
|
||||
end
|
||||
|
||||
save_from_uri(forcesave_path, download_uri)
|
||||
|
||||
if (is_submit_form)
|
||||
uid = file_data['actions'][0]['userid']
|
||||
DocumentHelper.create_meta(new_file_name, uid, "Filling Form", user_address)
|
||||
end
|
||||
|
||||
saved = 0
|
||||
rescue StandardError => msg
|
||||
saved = 1
|
||||
end
|
||||
|
||||
return saved
|
||||
end
|
||||
|
||||
def command_request(method, key)
|
||||
document_command_url = Rails.configuration.urlSite + Rails.configuration.commandUrl
|
||||
|
||||
payload = {
|
||||
:c => method,
|
||||
:key => key
|
||||
}
|
||||
|
||||
data = nil
|
||||
begin
|
||||
|
||||
uri = URI.parse(document_command_url)
|
||||
http = Net::HTTP.new(uri.host, uri.port)
|
||||
|
||||
if document_command_url.start_with?('https')
|
||||
http.use_ssl = true
|
||||
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
||||
end
|
||||
|
||||
req = Net::HTTP::Post.new(uri.request_uri)
|
||||
req.add_field("Content-Type", "application/json")
|
||||
|
||||
if JwtHelper.is_enabled
|
||||
payload["token"] = JwtHelper.encode(payload)
|
||||
jwtHeader = Rails.configuration.header.empty? ? "Authorization" : Rails.configuration.header;
|
||||
req.add_field(jwtHeader, "Bearer #{JwtHelper.encode({ :payload => payload })}")
|
||||
end
|
||||
|
||||
req.body = payload.to_json
|
||||
res = http.request(req)
|
||||
data = res.body
|
||||
rescue => ex
|
||||
raise ex.message
|
||||
end
|
||||
|
||||
json_data = JSON.parse(data)
|
||||
return json_data
|
||||
end
|
||||
|
||||
def save_from_uri(path, uristr)
|
||||
uri = URI.parse(uristr)
|
||||
http = Net::HTTP.new(uri.host, uri.port)
|
||||
|
||||
if uristr.start_with?('https')
|
||||
http.use_ssl = true
|
||||
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
||||
end
|
||||
|
||||
req = Net::HTTP::Get.new(uri)
|
||||
res = http.request(req)
|
||||
data = res.body
|
||||
|
||||
if data == nil
|
||||
raise 'stream is null'
|
||||
end
|
||||
|
||||
File.open(path, 'wb') do |file|
|
||||
file.write(data)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -34,6 +34,7 @@
|
||||
<option value="uid-1">John Smith</option>
|
||||
<option value="uid-2">Mark Pottato</option>
|
||||
<option value="uid-3">Hamish Mitchell</option>
|
||||
<option value="uid-0">anonymous</option>
|
||||
</select>
|
||||
</td>
|
||||
<td width="70%" valign="middle">Select user name before opening the document; you can open the same document using different users in different Web browser sessions, so you can check out multi-user editing functions.</td>
|
||||
@ -136,7 +137,7 @@
|
||||
<a class="stored-edit <%= docType %>" href="<%= editUrl %>" target="_blank">
|
||||
<span title="<%= d %>"><%= d %></span>
|
||||
</a>
|
||||
<a href="<%= DocumentHelper.get_file_uri(d, false) %>">
|
||||
<a href="<%= "download?filename=#{URI::encode(d)}" %>">
|
||||
<img class="icon-download" src="assets/download-24.png" alt="Download" title="Download" />
|
||||
</a>
|
||||
<a class="delete-file" data-filename="<%= d %>">
|
||||
|
||||
@ -18,7 +18,14 @@
|
||||
* limitations under the License.
|
||||
*
|
||||
-->
|
||||
<%= favicon_link_tag "favicon.ico" %>
|
||||
<%
|
||||
favicon = "favicon.ico"
|
||||
if (@file)
|
||||
favicon = @file.document_type + ".ico"
|
||||
end
|
||||
%>
|
||||
|
||||
<%= favicon_link_tag favicon %>
|
||||
<title>ONLYOFFICE</title>
|
||||
<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Open+Sans:900,800,700,600,500,400,300&subset=latin,cyrillic-ext,cyrillic,latin-ext" />
|
||||
<%= stylesheet_link_tag "stylesheet" %>
|
||||
|
||||
@ -34,12 +34,14 @@ module OnlineEditorsExampleRuby
|
||||
|
||||
Rails.configuration.viewedDocs=".pdf|.djvu|.xps"
|
||||
Rails.configuration.editedDocs=".docx|.xlsx|.csv|.pptx|.txt"
|
||||
Rails.configuration.convertDocs=".docm|.dotx|.dotm|.dot|.doc|.odt|.fodt|.ott|.xlsm|.xltx|.xltm|.xlt|.xls|.ods|.fods|.ots|.pptm|.ppt|.ppsx|.ppsm|.pps|.potx|.potm|.pot|.odp|.fodp|.otp|.rtf|.mht|.html|.htm|.epub|.fb2"
|
||||
Rails.configuration.convertDocs=".docm|.dotx|.dotm|.dot|.doc|.odt|.fodt|.ott|.xlsm|.xltx|.xltm|.xlt|.xls|.ods|.fods|.ots|.pptm|.ppt|.ppsx|.ppsm|.pps|.potx|.potm|.pot|.odp|.fodp|.otp|.rtf|.mht|.html|.htm|.xml|.epub|.fb2"
|
||||
|
||||
Rails.configuration.urlSite="https://documentserver/"
|
||||
Rails.configuration.urlConverter="ConvertService.ashx"
|
||||
Rails.configuration.urlApi="web-apps/apps/api/documents/api.js"
|
||||
Rails.configuration.urlPreloader="web-apps/apps/api/documents/cache-scripts.html"
|
||||
Rails.configuration.commandUrl="coauthoring/CommandService.ashx"
|
||||
|
||||
Rails.configuration.urlExample=""
|
||||
|
||||
Rails.configuration.jwtSecret = ""
|
||||
|
||||
@ -6,6 +6,7 @@ Rails.application.routes.draw do
|
||||
match '/remove', to: 'home#remove', via: 'get'
|
||||
|
||||
match '/upload', to: 'home#upload', via: 'post'
|
||||
match '/download', to: 'home#download', via: 'get'
|
||||
match '/convert', to: 'home#convert', via: 'get'
|
||||
match '/track', to: 'home#track', via: 'post'
|
||||
match '/csv', to: 'home#csv', via: 'get'
|
||||
|
||||